diff --git a/honk/Makefile b/honk/Makefile index f067aaad5..7b0732cc3 100644 --- a/honk/Makefile +++ b/honk/Makefile @@ -3,16 +3,16 @@ include $(TOPDIR)/rules.mk PKG_NAME:=honk -PKG_VERSION:=0.0.1_beta82 -PKG_RELEASE:=4 +PKG_VERSION:=0.0.1_beta83 +PKG_RELEASE:=5 # Raw upstream release tag. It keeps the dots in qualifiers (e.g. v0.0.1.beta.49) # because that is what the GitHub release asset name uses. -HONK_RELEASE_TAG:=v0.0.1.beta.82 +HONK_RELEASE_TAG:=v0.0.1.beta.83 # SHA256 of each release tarball, kept in sync by scripts/update_honk_version.sh. -HONK_HASH_X86_64:=075db4ebb3dd1b51fb59c8e4c3de5853bd837f5f5ca5fd0ef7698b574f8f9a88 -HONK_HASH_AARCH64:=6b66319bda2110d075e8f2788d728fdf75ca36dffdb3884a192803a34a529c59 +HONK_HASH_X86_64:=0d440bc094a4ceead94a897647b3c598f6ca7630c65a1675ed137e3d9c1c0c56 +HONK_HASH_AARCH64:=bb8c893c676f8f245332598ae701f50b803b922aef308dded4d0805c67692ab3 PKG_LICENSE:=AGPL-3.0-only PKG_LICENSE_FILE:=LICENSE diff --git a/luci-app-fwlive/Makefile b/luci-app-fwlive/Makefile index d3969ef0b..6440cd003 100644 --- a/luci-app-fwlive/Makefile +++ b/luci-app-fwlive/Makefile @@ -12,7 +12,7 @@ LUCI_DEPENDS:=+luci-base +logd +jsonfilter +coreutils-timeout LUCI_PKGARCH:=all PKG_VERSION:=0.1.47 -PKG_RELEASE:=51 +PKG_RELEASE:=52 # Reproducible build: honor SOURCE_DATE_EPOCH from the build environment (set by docker-sdk.sh / CI). ifdef SOURCE_DATE_EPOCH diff --git a/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js b/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js index 19c89a4ef..b9fab1403 100644 --- a/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js +++ b/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js @@ -125,6 +125,7 @@ return view.extend({ manualFetchLinesExplicit: false, rpcPreferencesResolved: false, entries: [], + filteredRowsCache: null, sessionSeen: null, pauseBufferLoading: false, /* Freezes row rendering while polling, health, and cadence updates continue. */ @@ -1057,6 +1058,8 @@ return view.extend({ } } + if (changed) this.invalidateFilteredRows(); + /* Keep buffered rows current without painting a paused or hidden table. */ if (changed && !this.tablePaused && (!this.summaryMode || this.summaryRowsShown)) this.renderRows(true); @@ -1214,7 +1217,7 @@ return view.extend({ await Promise.all([this.loadRulesMap(epoch), this.loadLoggingStatus(epoch)]); /* Recovery RPCs can outlive the poll epoch; don't repaint stale views. */ if (epoch !== this.currentPollEpoch() || this.viewDisposed) return; - this.refreshBufferedRuleLabels(); + /* loadRulesMap refreshes buffered labels when its map read succeeds. */ } catch (_e) { /* A throw here is local UI work after a successful poll. Leave * lastPollError / lastPollErrorCode as applyPollReply set them. */ @@ -1547,7 +1550,7 @@ return view.extend({ if (!card.style) card.style = { display: '' }; card.style.display = this.summaryMode ? 'block' : 'none'; } - this.syncEmptyScrollVisibility(this.filteredRows().length); + this.syncEmptyScrollVisibility(this.filteredRowsState().rows.length); if (toggle) { toggle.textContent = this.summaryRowsShown ? _('Hide rows') : _('Show rows'); toggle.setAttribute('aria-pressed', this.summaryRowsShown ? 'true' : 'false'); @@ -1568,7 +1571,7 @@ return view.extend({ this.summaryData = null; this.updateSummaryUi(); if (this.tablePaused) { - this.syncEmptyScrollVisibility(this.filteredRows().length); + this.syncEmptyScrollVisibility(this.filteredRowsState().rows.length); this.updateStatus(); } else { this.resolvePaintPending = false; @@ -1612,27 +1615,61 @@ return view.extend({ } }, - filteredRows() { - const filters = this.readFilters(); - return this.entries - .filter((row) => log.matchesFilter(row, filters)) - .slice(-this.displayRowCap()) - .reverse(); + invalidateFilteredRows() { + /* Use after in-place edits: free-text query matching reads every row field. */ + this.filteredRowsCache = null; }, - compactCountText(matchCount) { + /* Internal shared result: consumers must treat the state and rows as read-only. + * filteredRows() provides an array copy for callers that need to mutate it. */ + filteredRowsState() { + /* Poll ingest and limit trimming replace the array, even at equal length. + * Rule-label edits invalidate explicitly because query matches all fields. */ + const filters = this.readFilters(); + const filterKey = JSON.stringify(filters); + const rowCap = this.displayRowCap(); + const entries = this.entries; + const cached = this.filteredRowsCache; + + if ( + cached && + cached.entries === entries && + cached.filterKey === filterKey && + cached.rowCap === rowCap + ) + return cached; + + const matching = []; + for (let i = 0; i < entries.length; i++) { + if (log.matchesFilter(entries[i], filters)) matching.push(entries[i]); + } + + const state = { + entries: entries, + filterKey: filterKey, + rowCap: rowCap, + matchCount: matching.length, + rows: matching.slice(-rowCap).reverse() + }; + this.filteredRowsCache = state; + return state; + }, + + filteredRows() { + return this.filteredRowsState().rows.slice(); + }, + + compactCountText(filtered) { const stored = this.entries.length; /* Keep the stored-buffer denominator tied to the user's Limit. A weak * device's rendered-row cap is called out separately in statusSuffix(). */ const limit = this.rowLimit; const suffix = this.statusSuffix(); - /* While the table is paused the buffer can grow past the display limit — count matches - * over the full buffer so "matching" is not capped at visibleRows. */ - let shown = matchCount; - if (this.tablePaused) { - const filters = this.readFilters(); - shown = this.entries.filter((row) => log.matchesFilter(row, filters)).length; - } + /* The filter state contains both visible rows and the full match count, so + * paused status can report matches beyond the display cap without rescanning. */ + const state = + filtered && Array.isArray(filtered.rows) ? filtered : this.filteredRowsState(); + const shown = this.tablePaused ? state.matchCount : state.rows.length; if (this.pauseBufferLoading && stored === 0) return _('loading…') + suffix; @@ -1643,11 +1680,12 @@ return view.extend({ return ''; }, - updateStatus(rows) { + updateStatus(filtered) { const status = document.getElementById('fwlive-status'); if (!status) return; - const matchCount = rows ? rows.length : this.filteredRows().length; + const state = + filtered && Array.isArray(filtered.rows) ? filtered : this.filteredRowsState(); const suffix = this.statusSuffix(); if (this.lastPollError) { @@ -1663,7 +1701,7 @@ return view.extend({ status.className = this.tablePaused ? 'fwlive-status fwlive-status-paused' : 'fwlive-status'; - status.textContent = this.compactCountText(matchCount); + status.textContent = this.compactCountText(state); this.updateAdaptiveBanner(); }, @@ -2079,7 +2117,8 @@ return view.extend({ const scroll = document.getElementById('fwlive-scroll'); this.updateHash(this.readFilters()); - const rows = this.filteredRows(); + const filtered = this.filteredRowsState(); + const rows = filtered.rows.slice(); const paint = this.ensureRenderScheduler().shouldRender( rows, !!force, @@ -2090,7 +2129,7 @@ return view.extend({ if (!paint) { this.updateFloodBanner(); this.syncEmptyScrollVisibility(rows.length); - this.updateStatus(rows); + this.updateStatus(filtered); return; } @@ -2099,7 +2138,7 @@ return view.extend({ const prevScroll = scroll ? scroll.scrollTop : 0; this.syncEmptyScrollVisibility(rows.length); - this.updateStatus(rows); + this.updateStatus(filtered); this.renderFilterChips(); table.renderRows( diff --git a/luci-app-fwlive/po/de/luci-app-fwlive.po b/luci-app-fwlive/po/de/luci-app-fwlive.po index c8a4aacea..8f1bea0b5 100644 --- a/luci-app-fwlive/po/de/luci-app-fwlive.po +++ b/luci-app-fwlive/po/de/luci-app-fwlive.po @@ -12,32 +12,27 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1639 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1676 msgid "%d matching · %d/%d stored" msgstr "%d Treffer · %d/%d gespeichert" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1433 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1436 msgid "%s · requested up to %d raw lines · %d firewall messages returned" -msgstr "" -"%s · bis zu %d Rohzeilen angefordert · %d Firewall-Meldungen zurückgegeben" +msgstr "%s · bis zu %d Rohzeilen angefordert · %d Firewall-Meldungen zurückgegeben" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1423 -msgid "" -"%s · requested up to %d raw lines · server limited fetch to %d · %d firewall " -"messages returned" -msgstr "" -"%s · bis zu %d Rohzeilen angefordert · Server begrenzte Abruf auf %d · %d " -"Firewall-Meldungen zurückgegeben" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1426 +msgid "%s · requested up to %d raw lines · server limited fetch to %d · %d firewall messages returned" +msgstr "%s · bis zu %d Rohzeilen angefordert · Server begrenzte Abruf auf %d · %d Firewall-Meldungen zurückgegeben" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:543 msgid "%s: %s" msgstr "%s: %s" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1641 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1678 msgid "0 matching · %d/%d stored" msgstr "0 Treffer · %d/%d gespeichert" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:453 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:454 msgid "Accessible (teal/orange)" msgstr "Barrierefrei (teal/orange)" @@ -46,50 +41,42 @@ msgstr "Barrierefrei (teal/orange)" msgid "Action" msgstr "Aktion" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:949 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:950 msgid "Administrator access is required to disable logging." -msgstr "" -"Zum Deaktivieren der Protokollierung sind Administratorrechte erforderlich." +msgstr "Zum Deaktivieren der Protokollierung sind Administratorrechte erforderlich." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:914 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:915 msgid "Administrator access is required to enable logging." -msgstr "" -"Zum Aktivieren der Protokollierung sind Administratorrechte erforderlich." +msgstr "Zum Aktivieren der Protokollierung sind Administratorrechte erforderlich." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:214 msgid "Allow/deny rules, LAN logging, or anything else." msgstr "Allow/Deny-Regeln, LAN-Protokollierung oder irgendetwas anderes." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1833 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1871 msgid "Also seen" msgstr "Weitere" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:883 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:926 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:884 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:927 msgid "Another change is staged for the firewall; apply or revert it first." -msgstr "" -"Eine andere Änderung an der Firewall ist vorgemerkt; zuerst anwenden oder " -"verwerfen." +msgstr "Eine andere Änderung an der Firewall ist vorgemerkt; zuerst anwenden oder verwerfen." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:903 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:944 -msgid "" -"Another change overwrote WAN logging after it was saved; check the current " -"state." -msgstr "" -"Eine andere Änderung hat die WAN-Protokollierung nach dem Speichern " -"überschrieben; prüfen Sie den aktuellen Zustand." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:904 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:945 +msgid "Another change overwrote WAN logging after it was saved; check the current state." +msgstr "Eine andere Änderung hat die WAN-Protokollierung nach dem Speichern überschrieben; prüfen Sie den aktuellen Zustand." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2642 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2681 msgid "Any action" msgstr "Beliebige Aktion" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1826 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1864 msgid "Any protocol" msgstr "Beliebiges Protokoll" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1414 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1474 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1417 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1477 msgid "Auto" msgstr "Auto" @@ -97,21 +84,19 @@ msgstr "Auto" msgid "Before you enable logging" msgstr "Bevor Sie die Protokollierung aktivieren" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:880 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:881 msgid "Cannot enable logging until kernel log modules are installed." -msgstr "" -"Protokollierung kann erst aktiviert werden, wenn die Kernel-Log-Module " -"installiert sind." +msgstr "Protokollierung kann erst aktiviert werden, wenn die Kernel-Log-Module installiert sind." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:207 msgid "Changes:" msgstr "Änderungen:" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:452 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:453 msgid "Classic (green/red)" msgstr "Klassisch (grün/rot)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2373 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2412 msgid "Classic uses green/red; Accessible uses teal/orange" msgstr "Klassisch verwendet grün/rot; Barrierefrei verwendet teal/orange" @@ -119,115 +104,97 @@ msgstr "Klassisch verwendet grün/rot; Barrierefrei verwendet teal/orange" msgid "Clear all" msgstr "Alle löschen" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2714 -msgid "" -"Click a cell to filter · ≠ on a chip to exclude · Ctrl+click a rule for " -"firewall settings · in Simple view, click a row for the full message" -msgstr "" -"Zelle anklicken zum Filtern · ≠ auf einem Chip zum Ausschließen · Strg+Klick " -"auf eine Regel für Firewall-Einstellungen · in der Einfachen Ansicht Zeile " -"anklicken für die vollständige Meldung" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2753 +msgid "Click a cell to filter · ≠ on a chip to exclude · Ctrl+click a rule for firewall settings · in Simple view, click a row for the full message" +msgstr "Zelle anklicken zum Filtern · ≠ auf einem Chip zum Ausschließen · Strg+Klick auf eine Regel für Firewall-Einstellungen · in der Einfachen Ansicht Zeile anklicken für die vollständige Meldung" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2441 -msgid "" -"Click a row (Time or other non-link cells) to see the full log line (Simple " -"view)." -msgstr "" -"Klicken Sie auf eine Zeile (Zeit oder andere Nicht-Link-Zellen), um die " -"vollständige Log-Zeile zu sehen (Einfache Ansicht)." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2480 +msgid "Click a row (Time or other non-link cells) to see the full log line (Simple view)." +msgstr "Klicken Sie auf eine Zeile (Zeit oder andere Nicht-Link-Zellen), um die vollständige Log-Zeile zu sehen (Einfache Ansicht)." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:158 msgid "Click a row for the full message" msgstr "Zeile anklicken für die vollständige Meldung" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2446 -msgid "" -"Click an IP, action, or protocol to filter; use the Protocol menu (or ≠ on a " -"chip) to exclude." -msgstr "" -"Klicken Sie auf eine IP, Aktion oder ein Protokoll, um zu filtern; nutzen " -"Sie das Protokoll-Menü (oder ≠ auf einem Chip) zum Ausschließen." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2485 +msgid "Click an IP, action, or protocol to filter; use the Protocol menu (or ≠ on a chip) to exclude." +msgstr "Klicken Sie auf eine IP, Aktion oder ein Protokoll, um zu filtern; nutzen Sie das Protokoll-Menü (oder ≠ auf einem Chip) zum Ausschließen." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1827 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1865 msgid "Common" msgstr "Häufig" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1658 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1696 msgid "Connection lost — retrying…" msgstr "Verbindung verloren — neuer Versuch…" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:888 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:931 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:889 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:932 msgid "Could not acquire the logging lock." msgstr "Die Protokollierungssperre konnte nicht erworben werden." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:898 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:939 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:899 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:940 msgid "Could not clear the WAN zone log option." msgstr "Die WAN-Zonen-Log-Option konnte nicht gelöscht werden." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:946 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:947 msgid "Could not disable logging." msgstr "Protokollierung konnte nicht deaktiviert werden." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:905 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:906 msgid "Could not enable logging." msgstr "Protokollierung konnte nicht aktiviert werden." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:814 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:815 msgid "Could not load logging status." msgstr "Protokollstatus konnte nicht geladen werden." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:813 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:814 msgid "Could not refresh logging status; showing the last known state." -msgstr "" -"Protokollstatus konnte nicht aktualisiert werden; zeige den zuletzt " -"bekannten Zustand." +msgstr "Protokollstatus konnte nicht aktualisiert werden; zeige den zuletzt bekannten Zustand." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:900 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:941 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:901 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:942 msgid "Could not save the firewall configuration." msgstr "Die Firewall-Konfiguration konnte nicht gespeichert werden." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:892 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:893 msgid "Could not snapshot the current logging state." msgstr "Der aktuelle Protokollierungszustand konnte nicht gesichert werden." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:890 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:933 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:891 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:934 msgid "Could not track the logging change safely; logging was not changed." msgstr "Die Änderung der Protokollierung konnte nicht sicher nachverfolgt werden; die Protokollierung wurde nicht geändert." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:896 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:937 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:897 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:938 msgid "Could not write the WAN zone log option." msgstr "Die WAN-Zonen-Log-Option konnte nicht geschrieben werden." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2669 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2708 msgid "Custom protocol (prefix ! to exclude). Overrides the menu when set." -msgstr "" -"Eigenes Protokoll (! zum Ausschließen). Überschreibt das Menü, wenn gesetzt." +msgstr "Eigenes Protokoll (! zum Ausschließen). Überschreibt das Menü, wenn gesetzt." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:47 msgid "DPort" msgstr "Ziel-Port" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1276 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1279 msgid "Degraded — sampling" msgstr "Eingeschränkt — Stichproben" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1445 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1448 msgid "Degraded — sampling (slow poll RTT; cadence reduced)." -msgstr "" -"Eingeschränkt — Stichproben (langsame Poll-Roundtrip-Zeit; Frequenz " -"reduziert)." +msgstr "Eingeschränkt — Stichproben (langsame Poll-Roundtrip-Zeit; Frequenz reduziert)." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:407 #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:45 msgid "Destination" msgstr "Ziel" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2699 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2738 msgid "Destination IP contains (! to exclude)" msgstr "Ziel-IP enthält (! zum Ausschließen)" @@ -235,11 +202,11 @@ msgstr "Ziel-IP enthält (! zum Ausschließen)" msgid "Destination port" msgstr "Ziel-Port" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2704 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2743 msgid "Destination port (! to exclude)" msgstr "Ziel-Port (! zum Ausschließen)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2557 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2596 msgid "Detail" msgstr "Detail" @@ -251,19 +218,17 @@ msgstr "Richtung" msgid "Disabling…" msgstr "Wird deaktiviert…" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1272 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1275 msgid "Display limited to %d rows on this device" msgstr "Anzeige auf %d Zeilen auf diesem Gerät begrenzt" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2314 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2353 msgid "Display options" msgstr "Anzeigeoptionen" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2406 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2445 msgid "Display options on the bar set Limit, row tint, palette, and hostnames." -msgstr "" -"Anzeigeoptionen in der Leiste setzen Limit, Zeilenfärbung, Palette und " -"Hostnamen." +msgstr "Anzeigeoptionen in der Leiste setzen Limit, Zeilenfärbung, Palette und Hostnamen." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:212 msgid "Does not change:" @@ -279,29 +244,22 @@ msgstr "WAN-Drop/Reject-Protokollierung aktivieren" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:189 msgid "Enable WAN zone drop/reject logging (same as Network → Firewall)." -msgstr "" -"Drop/Reject-Protokollierung der WAN-Zone aktivieren (wie unter Netzwerk → " -"Firewall)." +msgstr "Drop/Reject-Protokollierung der WAN-Zone aktivieren (wie unter Netzwerk → Firewall)." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:195 msgid "Enable logging" msgstr "Protokollierung aktivieren" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2402 -msgid "" -"Enable logging turns on WAN zone drop/reject logging only (same as Network → " -"Firewall). It does not add rules or log normal LAN browsing." -msgstr "" -"„Protokollierung aktivieren“ schaltet nur die Drop/Reject-Protokollierung " -"der WAN-Zone ein (wie unter Netzwerk → Firewall). Es fügt keine Regeln hinzu " -"und protokolliert keinen normalen LAN-Verkehr." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2441 +msgid "Enable logging turns on WAN zone drop/reject logging only (same as Network → Firewall). It does not add rules or log normal LAN browsing." +msgstr "„Protokollierung aktivieren“ schaltet nur die Drop/Reject-Protokollierung der WAN-Zone ein (wie unter Netzwerk → Firewall). Es fügt keine Regeln hinzu und protokolliert keinen normalen LAN-Verkehr." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:60 #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:195 msgid "Enabling…" msgstr "Wird aktiviert…" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1840 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1878 msgid "Exclude" msgstr "Ausschließen" @@ -309,17 +267,13 @@ msgstr "Ausschließen" msgid "Exclude instead" msgstr "Stattdessen ausschließen" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2328 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2367 msgid "Fetch budget" msgstr "Abrufbudget" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2410 -msgid "" -"Fetch budget controls raw log lines per poll. Auto derives from Limit; " -"Manual selects a bounded maximum." -msgstr "" -"Das Abrufbudget steuert die Rohzeilen pro Abfrage. Auto leitet es aus dem " -"Limit ab; Manuell wählt ein begrenztes Maximum." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2449 +msgid "Fetch budget controls raw log lines per poll. Auto derives from Limit; Manual selects a bounded maximum." +msgstr "Das Abrufbudget steuert die Rohzeilen pro Abfrage. Auto leitet es aus dem Limit ab; Manuell wählt ein begrenztes Maximum." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/links.js:63 #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/links.js:96 @@ -329,11 +283,9 @@ msgstr "Filtern nach %s" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/links.js:134 msgid "Filter logs by rule (hint: %s). Ctrl+click to open firewall settings." -msgstr "" -"Logs nach Regel filtern (Hinweis: %s). Strg+Klick öffnet die Firewall-" -"Einstellungen." +msgstr "Logs nach Regel filtern (Hinweis: %s). Strg+Klick öffnet die Firewall-Einstellungen." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2484 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2523 #: openwrt-feed/luci-app-fwlive/root/usr/share/luci/menu.d/luci-app-fwlive.json:3 msgid "Firewall Live View" msgstr "Firewall-Live-Ansicht" @@ -346,14 +298,9 @@ msgstr "Flags" msgid "Flow" msgstr "Fluss" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2420 -msgid "" -"For a responsive table on a weak device, keep Limit at 250 rows or below. " -"The weak-device cap affects rendered rows; the buffer can still retain more." -msgstr "" -"Für eine responsive Tabelle auf einem schwachen Gerät sollte Limit auf " -"höchstens 250 Zeilen stehen. Die Schwachgerätebegrenzung betrifft die " -"angezeigten Zeilen; der Puffer kann weiterhin mehr Zeilen behalten." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2459 +msgid "For a responsive table on a weak device, keep Limit at 250 rows or below. The weak-device cap affects rendered rows; the buffer can still retain more." +msgstr "Für eine responsive Tabelle auf einem schwachen Gerät sollte Limit auf höchstens 250 Zeilen stehen. Die Schwachgerätebegrenzung betrifft die angezeigten Zeilen; der Puffer kann weiterhin mehr Zeilen behalten." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:61 msgid "Forwarded" @@ -363,28 +310,23 @@ msgstr "Weitergeleitet" msgid "Grant access to firewall live log view" msgstr "Zugriff auf die Live-Ansicht der Firewall-Protokolle gewähren" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2393 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2432 msgid "Help" msgstr "Hilfe" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1552 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1555 msgid "Hide rows" msgstr "Zeilen ausblenden" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1607 -msgid "" -"High event rate — table refresh is throttled to protect the browser. The " -"buffer still updates; refresh will resume automatically." -msgstr "" -"Hohe Ereignisrate — die Tabellenaktualisierung wird gedrosselt, um den " -"Browser zu schonen. Der Puffer wird weiter aktualisiert; die Anzeige wird " -"automatisch fortgesetzt." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1610 +msgid "High event rate — table refresh is throttled to protect the browser. The buffer still updates; refresh will resume automatically." +msgstr "Hohe Ereignisrate — die Tabellenaktualisierung wird gedrosselt, um den Browser zu schonen. Der Puffer wird weiter aktualisiert; die Anzeige wird automatisch fortgesetzt." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1452 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1455 msgid "Hostname resolve paused while the router is under load." msgstr "Hostnamenauflösung pausiert, solange der Router ausgelastet ist." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1831 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1869 msgid "ICMPv6" msgstr "ICMPv6" @@ -392,23 +334,13 @@ msgstr "ICMPv6" msgid "IN" msgstr "EINGANG" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2457 -msgid "" -"If Row tint looks missing, the active LuCI theme may omit success/error or " -"info/warn CSS variables; fwlive falls back to local colors (air-gapped, no " -"data leaves the device)." -msgstr "" -"Wenn die Zeileneinfärbung fehlt, verwendet das aktive LuCI-Theme " -"möglicherweise keine Erfolgs/Fehler-CSS-Variablen; fwlive fällt auf lokale " -"Farben zurück (air-gapped, keine Daten verlassen das Gerät)." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2496 +msgid "If Row tint looks missing, the active LuCI theme may omit success/error or info/warn CSS variables; fwlive falls back to local colors (air-gapped, no data leaves the device)." +msgstr "Wenn die Zeileneinfärbung fehlt, verwendet das aktive LuCI-Theme möglicherweise keine Erfolgs/Fehler-CSS-Variablen; fwlive fällt auf lokale Farben zurück (air-gapped, keine Daten verlassen das Gerät)." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:331 -msgid "" -"If the WAN is quiet, wait for probes or use the optional ping check in " -"Help / the enabling-logs guide." -msgstr "" -"Wenn das WAN ruhig ist, warten Sie auf Probes oder nutzen Sie den optionalen " -"Ping-Test in der Hilfe / der Anleitung zum Aktivieren der Protokollierung." +msgid "If the WAN is quiet, wait for probes or use the optional ping check in Help / the enabling-logs guide." +msgstr "Wenn das WAN ruhig ist, warten Sie auf Probes oder nutzen Sie den optionalen Ping-Test in der Hilfe / der Anleitung zum Aktivieren der Protokollierung." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:59 msgid "Inbound" @@ -419,14 +351,10 @@ msgid "Include instead" msgstr "Stattdessen einschließen" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:296 -msgid "" -"Install kmod-nf-log and kmod-nf-log6 with the command for your OpenWrt " -"release, then reload the firewall." -msgstr "" -"Installieren Sie kmod-nf-log und kmod-nf-log6 mit dem Befehl für Ihre " -"OpenWrt-Version und laden Sie dann die Firewall neu." +msgid "Install kmod-nf-log and kmod-nf-log6 with the command for your OpenWrt release, then reload the firewall." +msgstr "Installieren Sie kmod-nf-log und kmod-nf-log6 mit dem Befehl für Ihre OpenWrt-Version und laden Sie dann die Firewall neu." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1657 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1695 msgid "Installation is incomplete. Reinstall luci-app-fwlive." msgstr "Installation unvollständig. Installieren Sie luci-app-fwlive neu." @@ -435,7 +363,7 @@ msgstr "Installation unvollständig. Installieren Sie luci-app-fwlive neu." msgid "Interface" msgstr "Schnittstelle" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2684 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2723 msgid "Interface (prefix ! to exclude)" msgstr "Schnittstelle (! voranstellen zum Ausschließen)" @@ -452,53 +380,47 @@ msgstr "Kernel-Logmodule fehlen" msgid "Len" msgstr "Länge" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2317 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2356 msgid "Limit" msgstr "Limit" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:776 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:777 msgid "Live view may be incomplete — a legacy iptables table is registered" -msgstr "" -"Die Live-Ansicht kann unvollständig sein — eine veraltete iptables-Tabelle " -"ist registriert" +msgstr "Die Live-Ansicht kann unvollständig sein — eine veraltete iptables-Tabelle ist registriert" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:339 msgid "Logging is off on this router" msgstr "Protokollierung ist auf diesem Router deaktiviert" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1414 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1475 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1417 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1478 msgid "Manual" msgstr "Manuell" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2346 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2385 msgid "Manual still uses server protection and poll cadence" msgstr "Manuell nutzt weiterhin Serverschutz und Abfrageintervall" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2415 -msgid "" -"Manual still uses server protection and poll cadence; it changes the fetch " -"budget, not the polling interval." -msgstr "" -"Manuell nutzt weiterhin Serverschutz und Abfrageintervall; es ändert das " -"Abrufbudget, nicht das Abfrageintervall." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2454 +msgid "Manual still uses server protection and poll cadence; it changes the fetch budget, not the polling interval." +msgstr "Manuell nutzt weiterhin Serverschutz und Abfrageintervall; es ändert das Abrufbudget, nicht das Abfrageintervall." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:387 msgid "Manual test (System → Terminal):" msgstr "Manueller Test (System → Terminal):" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2340 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2379 msgid "Maximum raw lines" msgstr "Maximale Rohzeilen" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:51 #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:344 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2569 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2576 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2608 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2615 msgid "Message" msgstr "Nachricht" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2679 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2718 msgid "More filters" msgstr "Weitere Filter" @@ -507,22 +429,17 @@ msgid "Network → Firewall" msgstr "Netzwerk → Firewall" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:283 -msgid "" -"No WAN firewall zone found in /etc/config/firewall. Configure zones under:" -msgstr "" -"Keine WAN-Firewallzone in /etc/config/firewall gefunden. Zonen konfigurieren " -"unter:" +msgid "No WAN firewall zone found in /etc/config/firewall. Configure zones under:" +msgstr "Keine WAN-Firewallzone in /etc/config/firewall gefunden. Zonen konfigurieren unter:" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:278 msgid "No WAN zone found" msgstr "Keine WAN-Zone gefunden" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:886 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:929 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:887 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:930 msgid "No WAN zone found; cannot toggle logging without one." -msgstr "" -"Keine WAN-Zone gefunden; Protokollierung kann ohne eine solche nicht " -"umgeschaltet werden." +msgstr "Keine WAN-Zone gefunden; Protokollierung kann ohne eine solche nicht umgeschaltet werden." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:247 msgid "Not now" @@ -536,7 +453,7 @@ msgstr "Nichts ändert sich, bis Sie auf Aktivieren klicken." msgid "OUT" msgstr "AUSGANG" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2599 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2638 msgid "One line" msgstr "Einzeilig" @@ -553,29 +470,23 @@ msgid "OpenWrt 25.12 and newer (apk):" msgstr "OpenWrt 25.12 und neuer (apk):" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:343 -msgid "" -"OpenWrt does not write firewall events to the log until you turn logging on. " -"Live View only shows what the firewall already logs — it does not add allow/" -"deny rules." -msgstr "" -"OpenWrt schreibt Firewall-Ereignisse erst ins Log, wenn Sie die " -"Protokollierung aktivieren. Die Live-Ansicht zeigt nur, was die Firewall " -"bereits protokolliert — sie fügt keine Allow/Deny-Regeln hinzu." +msgid "OpenWrt does not write firewall events to the log until you turn logging on. Live View only shows what the firewall already logs — it does not add allow/deny rules." +msgstr "OpenWrt schreibt Firewall-Ereignisse erst ins Log, wenn Sie die Protokollierung aktivieren. Die Live-Ansicht zeigt nur, was die Firewall bereits protokolliert — sie fügt keine Allow/Deny-Regeln hinzu." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:60 msgid "Outbound" msgstr "Ausgehend" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2367 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2406 msgid "Palette" msgstr "Palette" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1706 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2523 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1744 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2562 msgid "Pause" msgstr "Pause" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1705 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1743 msgid "Paused" msgstr "Pausiert" @@ -584,11 +495,11 @@ msgstr "Pausiert" msgid "Proto" msgstr "Protokoll" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2660 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2699 msgid "Protocol — common values" msgstr "Protokoll — häufige Werte" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2639 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2678 msgid "Quick search" msgstr "Schnellsuche" @@ -596,45 +507,35 @@ msgstr "Schnellsuche" msgid "Remove filter" msgstr "Filter entfernen" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1706 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1744 msgid "Resume" msgstr "Fortsetzen" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2357 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2396 msgid "Row tint" msgstr "Zeileneinfärbung" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2451 -msgid "" -"Row tint shows pass/deny row backgrounds when checked. Choose Classic (green/" -"red, default) or Accessible (teal/orange). Action text stays colored either " -"way." -msgstr "" -"Zeilenfärbung zeigt Pass/Deny-Hintergrundfarben, wenn aktiviert. Wählen Sie " -"Klassisch (grün/rot, Standard) oder Barrierefrei (teal/orange). Aktionstext " -"bleibt in beiden Fällen farbig." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2490 +msgid "Row tint shows pass/deny row backgrounds when checked. Choose Classic (green/red, default) or Accessible (teal/orange). Action text stays colored either way." +msgstr "Zeilenfärbung zeigt Pass/Deny-Hintergrundfarben, wenn aktiviert. Wählen Sie Klassisch (grün/rot, Standard) oder Barrierefrei (teal/orange). Aktionstext bleibt in beiden Fällen farbig." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2507 -msgid "" -"Row tint used a local color fallback because the active LuCI theme did not " -"apply pass/deny backgrounds." -msgstr "" -"Die Zeileneinfärbung verwendete einen lokalen Farbfallback, da das aktive " -"LuCI-Theme keine Erlauben/Verweigern-Hintergründe anwendet." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2546 +msgid "Row tint used a local color fallback because the active LuCI theme did not apply pass/deny backgrounds." +msgstr "Die Zeileneinfärbung verwendete einen lokalen Farbfallback, da das aktive LuCI-Theme keine Erlauben/Verweigern-Hintergründe anwendet." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:38 msgid "Rule" msgstr "Regel" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:767 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:768 msgid "Rule labels incomplete — map truncated" msgstr "Regel-Labels unvollständig — Zuordnung abgeschnitten" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:770 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:771 msgid "Rule labels unavailable" msgstr "Regel-Labels nicht verfügbar" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:769 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:770 msgid "Rule labels unavailable — temp file failed" msgstr "Regel-Labels nicht verfügbar — temporäre Datei fehlgeschlagen" @@ -646,40 +547,40 @@ msgstr "Quell-Port" msgid "Search" msgstr "Suche" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1443 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1446 msgid "Server adaptive protection is disabled." msgstr "Adaptiver Serverschutz ist deaktiviert." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1441 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1444 msgid "Server protection state is unknown." msgstr "Serverschutz-Status unbekannt." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1448 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1451 msgid "Server shedding — at most %d log lines per poll." msgstr "Server reduziert — höchstens %d Protokollzeilen pro Abfrage." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1450 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1453 msgid "Server truncated this poll (adaptive cap)." msgstr "Server hat diese Abfrage gekürzt (adaptives Limit)." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2384 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2423 msgid "Show hostnames" msgstr "Hostnamen anzeigen" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2355 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2394 msgid "Show pass/deny row background colors" msgstr "Pass/Deny-Zeilenhintergrundfarben anzeigen" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1552 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2622 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1555 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2661 msgid "Show rows" msgstr "Zeilen anzeigen" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1509 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1512 msgid "Showing a compact summary of the top of the shown sample." msgstr "Eine kompakte Zusammenfassung des Anfangs der angezeigten Stichprobe." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2546 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2585 msgid "Simple" msgstr "Einfach" @@ -688,7 +589,7 @@ msgstr "Einfach" msgid "Source" msgstr "Quelle" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2689 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2728 msgid "Source IP contains (! to exclude)" msgstr "Quell-IP enthält (! zum Ausschließen)" @@ -696,70 +597,44 @@ msgstr "Quell-IP enthält (! zum Ausschließen)" msgid "Source port" msgstr "Quell-Port" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2694 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2733 msgid "Source port (! to exclude)" msgstr "Quell-Port (! zum Ausschließen)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1511 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1514 msgid "Summary data is unavailable; show rows to inspect the sample." -msgstr "" -"Zusammenfassungsdaten nicht verfügbar; Zeilen anzeigen, um die Stichprobe zu " -"prüfen." +msgstr "Zusammenfassungsdaten nicht verfügbar; Zeilen anzeigen, um die Stichprobe zu prüfen." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2613 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2652 msgid "Summary mode" msgstr "Zusammenfassungsmodus" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1513 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1516 msgid "Summary was bounded before all categories could be included." -msgstr "" -"Die Zusammenfassung wurde begrenzt, bevor alle Kategorien aufgenommen werden " -"konnten." +msgstr "Die Zusammenfassung wurde begrenzt, bevor alle Kategorien aufgenommen werden konnten." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2425 -msgid "" -"Switching tabs pauses polling; returning performs one catch-up poll. " -"Hostnames are off by default because lookups add work." -msgstr "" -"Beim Wechseln des Tabs wird das Polling pausiert; bei der Rückkehr erfolgt " -"eine einmalige Aufholabfrage. Hostnamen sind standardmäßig deaktiviert, da " -"Auflösungen zusätzliche Arbeit verursachen." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2464 +msgid "Switching tabs pauses polling; returning performs one catch-up poll. Hostnames are off by default because lookups add work." +msgstr "Beim Wechseln des Tabs wird das Polling pausiert; bei der Rückkehr erfolgt eine einmalige Aufholabfrage. Hostnamen sind standardmäßig deaktiviert, da Auflösungen zusätzliche Arbeit verursachen." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:894 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:935 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:895 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:936 msgid "The firewall did not reload; saved and live logging may differ." -msgstr "" -"Die Firewall wurde nicht neu geladen; gespeicherte und aktive " -"Protokollierung können voneinander abweichen." +msgstr "Die Firewall wurde nicht neu geladen; gespeicherte und aktive Protokollierung können voneinander abweichen." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2435 -msgid "" -"The rate shown for WAN logging is the firewall zone log_limit. OpenWrt " -"defaults to 10/minute when no explicit limit is configured; fwlive does not " -"impose this cap." -msgstr "" -"Die angezeigte Rate für WAN-Protokollierung ist das Zonen-log_limit. OpenWrt-" -"Standard ist 10/Minute ohne explizites Limit; fwlive setzt diese Grenze " -"nicht." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2474 +msgid "The rate shown for WAN logging is the firewall zone log_limit. OpenWrt defaults to 10/minute when no explicit limit is configured; fwlive does not impose this cap." +msgstr "Die angezeigte Rate für WAN-Protokollierung ist das Zonen-log_limit. OpenWrt-Standard ist 10/Minute ohne explizites Limit; fwlive setzt diese Grenze nicht." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2430 -msgid "" -"The router log ring may evict older events before fwlive reads them. fwlive " -"cannot recover evicted entries or change forwarding behavior." -msgstr "" -"Der Protokollring des Routers kann ältere Ereignisse verdrängen, bevor " -"fwlive sie liest. fwlive kann verdrängte Einträge nicht wiederherstellen und " -"ändert das Weiterleitungsverhalten nicht." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2469 +msgid "The router log ring may evict older events before fwlive reads them. fwlive cannot recover evicted entries or change forwarding behavior." +msgstr "Der Protokollring des Routers kann ältere Ereignisse verdrängen, bevor fwlive sie liest. fwlive kann verdrängte Einträge nicht wiederherstellen und ändert das Weiterleitungsverhalten nicht." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2397 -msgid "" -"The table updates automatically when your firewall logs traffic. Use Pause " -"if it moves too fast." -msgstr "" -"Die Tabelle aktualisiert sich automatisch, wenn Ihre Firewall Verkehr " -"protokolliert. Pause nutzen, wenn es zu schnell wird." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2436 +msgid "The table updates automatically when your firewall logs traffic. Use Pause if it moves too fast." +msgstr "Die Tabelle aktualisiert sich automatisch, wenn Ihre Firewall Verkehr protokolliert. Pause nutzen, wenn es zu schnell wird." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2510 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2549 msgid "Theme tint fallback" msgstr "Theme-Farb-Fallback" @@ -768,85 +643,63 @@ msgid "Then ping the router." msgstr "Dann den Router anpingen." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:313 -msgid "" -"This router reported a logging blocker that Live View does not recognize yet." -msgstr "" -"Dieser Router hat eine Protokollierungsblockade gemeldet, die Live View noch " -"nicht kennt." +msgid "This router reported a logging blocker that Live View does not recognize yet." +msgstr "Dieser Router hat eine Protokollierungsblockade gemeldet, die Live View noch nicht kennt." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:36 msgid "Time" msgstr "Zeit" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1518 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1521 msgid "Top drops" msgstr "Häufigste Drops" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1521 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1524 msgid "Top rules" msgstr "Häufigste Regeln" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1515 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1518 msgid "Top talkers" msgstr "Häufigste Absender" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:219 msgid "Turn it back off with the WAN logging control on the watch strip." -msgstr "" -"Über das WAN-Protokollierungs-Steuerelement in der Beobachtungsleiste wieder " -"deaktivieren." +msgstr "Über das WAN-Protokollierungs-Steuerelement in der Beobachtungsleiste wieder deaktivieren." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:357 -msgid "" -"Turns on WAN zone drop/reject logging (same as Network → Firewall → wan → " -"Log). Rate-limited by the zone log_limit (OpenWrt default 10/minute). Normal " -"LAN browsing is not logged." -msgstr "" -"Aktiviert die Drop/Reject-Protokollierung der WAN-Zone (wie unter Netzwerk → " -"Firewall → wan → Protokoll). Ratenbegrenzt durch das log_limit der Zone " -"(OpenWrt-Standard: 10/Minute). Normales LAN-Surfen wird nicht protokolliert." +msgid "Turns on WAN zone drop/reject logging (same as Network → Firewall → wan → Log). Rate-limited by the zone log_limit (OpenWrt default 10/minute). Normal LAN browsing is not logged." +msgstr "Aktiviert die Drop/Reject-Protokollierung der WAN-Zone (wie unter Netzwerk → Firewall → wan → Protokoll). Ratenbegrenzt durch das log_limit der Zone (OpenWrt-Standard: 10/Minute). Normales LAN-Surfen wird nicht protokolliert." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:209 msgid "Turns on logging for the WAN firewall zone and reloads the firewall." -msgstr "" -"Aktiviert die Protokollierung für die WAN-Firewallzone und lädt die Firewall " -"neu." +msgstr "Aktiviert die Protokollierung für die WAN-Firewallzone und lädt die Firewall neu." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:217 msgid "Undo:" msgstr "Rückgängig:" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2454 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2493 msgid "Use Detail for all columns (flags, length, raw message)." -msgstr "" -"Verwenden Sie „Detail“ für alle Spalten (Flags, Länge, rohe Nachricht)." +msgstr "Verwenden Sie „Detail“ für alle Spalten (Flags, Länge, rohe Nachricht)." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2528 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2534 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2567 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2573 msgid "View" msgstr "Ansicht" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:948 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:949 msgid "WAN drop/reject logging is off." msgstr "WAN-Drop/Reject-Protokollierung ist aus." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:324 -msgid "" -"WAN drop/reject logging is on. Blocked inbound WAN traffic will show up " -"here. Normal LAN browsing will not." -msgstr "" -"WAN-Drop/Reject-Protokollierung ist an. Blockierter eingehender WAN-Verkehr " -"erscheint hier. Normales LAN-Surfen nicht." +msgid "WAN drop/reject logging is on. Blocked inbound WAN traffic will show up here. Normal LAN browsing will not." +msgstr "WAN-Drop/Reject-Protokollierung ist an. Blockierter eingehender WAN-Verkehr erscheint hier. Normales LAN-Surfen nicht." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:910 -msgid "" -"WAN drop/reject logging is on. Blocked inbound traffic should appear here as " -"it happens — not normal LAN browsing." -msgstr "" -"WAN-Drop/Reject-Protokollierung ist an. Blockierter eingehender Verkehr " -"sollte hier in Echtzeit erscheinen — nicht normales LAN-Surfen." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:911 +msgid "WAN drop/reject logging is on. Blocked inbound traffic should appear here as it happens — not normal LAN browsing." +msgstr "WAN-Drop/Reject-Protokollierung ist an. Blockierter eingehender Verkehr sollte hier in Echtzeit erscheinen — nicht normales LAN-Surfen." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:912 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:913 msgid "WAN logging is already enabled." msgstr "WAN-Protokollierung ist bereits aktiviert." @@ -875,25 +728,25 @@ msgstr "WAN-Protokollierung nicht verfügbar: keine WAN-Zone" msgid "Waiting for firewall events" msgstr "Warte auf Firewall-Ereignisse" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1705 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2498 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1743 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2537 msgid "Watching" msgstr "Beobachtet" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2588 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2627 msgid "Wrap" msgstr "Umbrechen" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:71 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2644 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2683 msgid "block" msgstr "blockiert" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1263 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1266 msgid "buffer filling" msgstr "Puffer füllt sich" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1267 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1270 msgid "buffer full" msgstr "Puffer voll" @@ -910,7 +763,7 @@ msgid "does not contain" msgstr "enthält nicht" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:72 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2645 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2684 msgid "drop" msgstr "verworfen" @@ -918,16 +771,16 @@ msgstr "verworfen" msgid "is" msgstr "ist" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1262 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1265 msgid "loading buffer" msgstr "Lade Puffer" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1637 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1674 msgid "loading…" msgstr "lädt…" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1491 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1500 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1494 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1503 msgid "none" msgstr "keine" @@ -935,98 +788,98 @@ msgstr "keine" msgid "not" msgstr "nicht" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1848 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1886 msgid "not AH" msgstr "nicht AH" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1847 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1885 msgid "not ESP" msgstr "nicht ESP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1846 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1884 msgid "not GRE" msgstr "nicht GRE" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1843 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1881 msgid "not ICMP" msgstr "nicht ICMP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1844 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1882 msgid "not ICMPv6" msgstr "nicht ICMPv6" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1845 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1883 msgid "not IGMP" msgstr "nicht IGMP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1849 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1887 msgid "not SCTP" msgstr "nicht SCTP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1841 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1879 msgid "not TCP" msgstr "nicht TCP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1842 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1880 msgid "not UDP" msgstr "nicht UDP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2650 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2689 msgid "not block" msgstr "nicht blockieren" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2649 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2688 msgid "not drop" msgstr "nicht verwerfen" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2648 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2687 msgid "not pass" msgstr "nicht erlauben" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2651 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2690 msgid "not reject" msgstr "nicht zurückweisen" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2652 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2691 msgid "not unknown" msgstr "nicht unbekannt" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2667 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2706 msgid "or type…" msgstr "oder tippen…" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:70 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2643 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2682 msgid "pass" msgstr "erlaubt" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:73 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2646 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2685 msgid "reject" msgstr "abgelehnt" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1269 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1272 msgid "render paused (high rate)" msgstr "Rendering pausiert (hohe Rate)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1278 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1281 msgid "resolve paused (load)" msgstr "Auflösung pausiert (Last)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1280 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1283 msgid "scroll frozen — scroll to top to follow live" msgstr "Scrollen eingefroren — nach oben scrollen für Live-Ansicht" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1277 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1280 msgid "truncated" msgstr "gekürzt" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:62 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2647 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2686 msgid "unknown" msgstr "unbekannt" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:751 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:752 msgid "using fw4" msgstr "mit fw4" @@ -1034,9 +887,5 @@ msgstr "mit fw4" msgid "· %s" msgstr "· %s" -#~ msgid "" -#~ "Kernel netfilter log modules are missing. Install kmod-nf-log and kmod-nf-" -#~ "log6, then reload the firewall." -#~ msgstr "" -#~ "Kernel-Netfilter-Log-Module fehlen. Installieren Sie kmod-nf-log und kmod-" -#~ "nf-log6 und laden Sie dann die Firewall neu." +#~ msgid "Kernel netfilter log modules are missing. Install kmod-nf-log and kmod-nf-log6, then reload the firewall." +#~ msgstr "Kernel-Netfilter-Log-Module fehlen. Installieren Sie kmod-nf-log und kmod-nf-log6 und laden Sie dann die Firewall neu." diff --git a/luci-app-fwlive/po/ru/luci-app-fwlive.po b/luci-app-fwlive/po/ru/luci-app-fwlive.po index 176f6de74..3ed358be7 100644 --- a/luci-app-fwlive/po/ru/luci-app-fwlive.po +++ b/luci-app-fwlive/po/ru/luci-app-fwlive.po @@ -10,34 +10,29 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1639 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1676 msgid "%d matching · %d/%d stored" msgstr "%d совпад. · сохранено %d/%d" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1433 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1436 msgid "%s · requested up to %d raw lines · %d firewall messages returned" msgstr "%s · запрошено до %d сырых строк · возвращено %d сообщений firewall" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1423 -msgid "" -"%s · requested up to %d raw lines · server limited fetch to %d · %d firewall " -"messages returned" -msgstr "" -"%s · запрошено до %d сырых строк · сервер ограничил выборку до %d · " -"возвращено %d сообщений firewall" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1426 +msgid "%s · requested up to %d raw lines · server limited fetch to %d · %d firewall messages returned" +msgstr "%s · запрошено до %d сырых строк · сервер ограничил выборку до %d · возвращено %d сообщений firewall" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:543 msgid "%s: %s" msgstr "%s: %s" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1641 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1678 msgid "0 matching · %d/%d stored" msgstr "0 совпад. · сохранено %d/%d" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:453 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:454 msgid "Accessible (teal/orange)" msgstr "Доступный (бирюзовый/оранжевый)" @@ -46,11 +41,11 @@ msgstr "Доступный (бирюзовый/оранжевый)" msgid "Action" msgstr "Действие" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:949 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:950 msgid "Administrator access is required to disable logging." msgstr "Для отключения журналирования требуются права администратора." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:914 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:915 msgid "Administrator access is required to enable logging." msgstr "Для включения журналирования требуются права администратора." @@ -58,36 +53,30 @@ msgstr "Для включения журналирования требуютс msgid "Allow/deny rules, LAN logging, or anything else." msgstr "Правила allow/deny, журналирование LAN и любые другие настройки." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1833 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1871 msgid "Also seen" msgstr "Также встречаются" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:883 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:926 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:884 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:927 msgid "Another change is staged for the firewall; apply or revert it first." -msgstr "" -"В брандмауэре уже есть другое незафиксированное изменение; сначала примените " -"или отмените его." +msgstr "В брандмауэре уже есть другое незафиксированное изменение; сначала примените или отмените его." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:903 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:944 -msgid "" -"Another change overwrote WAN logging after it was saved; check the current " -"state." -msgstr "" -"Другое изменение перезаписало журналирование WAN после сохранения; проверьте " -"текущее состояние." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:904 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:945 +msgid "Another change overwrote WAN logging after it was saved; check the current state." +msgstr "Другое изменение перезаписало журналирование WAN после сохранения; проверьте текущее состояние." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2642 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2681 msgid "Any action" msgstr "Любое действие" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1826 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1864 msgid "Any protocol" msgstr "Любой протокол" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1414 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1474 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1417 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1477 msgid "Auto" msgstr "Авто" @@ -95,20 +84,19 @@ msgstr "Авто" msgid "Before you enable logging" msgstr "Перед включением журналирования" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:880 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:881 msgid "Cannot enable logging until kernel log modules are installed." -msgstr "" -"Невозможно включить журналирование, пока не установлены модули журнала ядра." +msgstr "Невозможно включить журналирование, пока не установлены модули журнала ядра." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:207 msgid "Changes:" msgstr "Изменения:" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:452 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:453 msgid "Classic (green/red)" msgstr "Классический (зелёный/красный)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2373 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2412 msgid "Classic uses green/red; Accessible uses teal/orange" msgstr "Классический — зелёный/красный; доступный — бирюзовый/оранжевый" @@ -116,91 +104,76 @@ msgstr "Классический — зелёный/красный; доступ msgid "Clear all" msgstr "Очистить всё" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2714 -msgid "" -"Click a cell to filter · ≠ on a chip to exclude · Ctrl+click a rule for " -"firewall settings · in Simple view, click a row for the full message" -msgstr "" -"Щёлкните ячейку для фильтра · ≠ на чипе для исключения · Ctrl+щелчок по " -"правилу для настроек МЭ · в Простом виде щёлкните строку для полного " -"сообщения" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2753 +msgid "Click a cell to filter · ≠ on a chip to exclude · Ctrl+click a rule for firewall settings · in Simple view, click a row for the full message" +msgstr "Щёлкните ячейку для фильтра · ≠ на чипе для исключения · Ctrl+щелчок по правилу для настроек МЭ · в Простом виде щёлкните строку для полного сообщения" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2441 -msgid "" -"Click a row (Time or other non-link cells) to see the full log line (Simple " -"view)." -msgstr "" -"Щёлкните строку (Время или другие ячейки без ссылки), чтобы увидеть полную " -"строку журнала (Простой вид)." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2480 +msgid "Click a row (Time or other non-link cells) to see the full log line (Simple view)." +msgstr "Щёлкните строку (Время или другие ячейки без ссылки), чтобы увидеть полную строку журнала (Простой вид)." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:158 msgid "Click a row for the full message" msgstr "Щёлкните строку для полного сообщения" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2446 -msgid "" -"Click an IP, action, or protocol to filter; use the Protocol menu (or ≠ on a " -"chip) to exclude." -msgstr "" -"Щёлкните по IP, действию или протоколу для фильтрации; для исключения " -"используйте меню «Протокол» (или ≠ на чипе)." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2485 +msgid "Click an IP, action, or protocol to filter; use the Protocol menu (or ≠ on a chip) to exclude." +msgstr "Щёлкните по IP, действию или протоколу для фильтрации; для исключения используйте меню «Протокол» (или ≠ на чипе)." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1827 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1865 msgid "Common" msgstr "Частые" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1658 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1696 msgid "Connection lost — retrying…" msgstr "Соединение потеряно — повторная попытка…" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:888 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:931 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:889 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:932 msgid "Could not acquire the logging lock." msgstr "Не удалось получить блокировку журналирования." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:898 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:939 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:899 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:940 msgid "Could not clear the WAN zone log option." msgstr "Не удалось очистить параметр журнала зоны WAN." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:946 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:947 msgid "Could not disable logging." msgstr "Не удалось отключить журналирование." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:905 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:906 msgid "Could not enable logging." msgstr "Не удалось включить журналирование." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:814 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:815 msgid "Could not load logging status." msgstr "Не удалось загрузить состояние журналирования." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:813 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:814 msgid "Could not refresh logging status; showing the last known state." -msgstr "" -"Не удалось обновить состояние журналирования; показан последний известный " -"статус." +msgstr "Не удалось обновить состояние журналирования; показан последний известный статус." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:900 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:941 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:901 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:942 msgid "Could not save the firewall configuration." msgstr "Не удалось сохранить конфигурацию межсетевого экрана." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:892 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:893 msgid "Could not snapshot the current logging state." msgstr "Не удалось сохранить снимок текущего состояния журналирования." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:890 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:933 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:891 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:934 msgid "Could not track the logging change safely; logging was not changed." msgstr "Не удалось безопасно отследить изменение журналирования; журналирование не изменено." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:896 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:937 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:897 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:938 msgid "Could not write the WAN zone log option." msgstr "Не удалось записать параметр журнала зоны WAN." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2669 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2708 msgid "Custom protocol (prefix ! to exclude). Overrides the menu when set." msgstr "Свой протокол (! для исключения). Переопределяет меню, если задан." @@ -208,11 +181,11 @@ msgstr "Свой протокол (! для исключения). Переоп msgid "DPort" msgstr "Порт назн." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1276 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1279 msgid "Degraded — sampling" msgstr "Упрощённый режим — выборка" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1445 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1448 msgid "Degraded — sampling (slow poll RTT; cadence reduced)." msgstr "Упрощённый режим — выборка (медленный RTT опроса; интервал увеличен)." @@ -221,7 +194,7 @@ msgstr "Упрощённый режим — выборка (медленный R msgid "Destination" msgstr "Назначение" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2699 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2738 msgid "Destination IP contains (! to exclude)" msgstr "IP назначения содержит (! для исключения)" @@ -229,11 +202,11 @@ msgstr "IP назначения содержит (! для исключения) msgid "Destination port" msgstr "Порт назначения" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2704 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2743 msgid "Destination port (! to exclude)" msgstr "Порт назначения (! для исключения)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2557 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2596 msgid "Detail" msgstr "Подробно" @@ -245,19 +218,17 @@ msgstr "Напр." msgid "Disabling…" msgstr "Отключение…" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1272 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1275 msgid "Display limited to %d rows on this device" msgstr "На этом устройстве отображение ограничено %d строками" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2314 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2353 msgid "Display options" msgstr "Параметры отображения" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2406 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2445 msgid "Display options on the bar set Limit, row tint, palette, and hostnames." -msgstr "" -"Параметры отображения на панели задают лимит, окраску строк, палитру и имена " -"узлов." +msgstr "Параметры отображения на панели задают лимит, окраску строк, палитру и имена узлов." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:212 msgid "Does not change:" @@ -273,29 +244,22 @@ msgstr "Включить журналирование drop/reject для WAN" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:189 msgid "Enable WAN zone drop/reject logging (same as Network → Firewall)." -msgstr "" -"Включить журналирование drop/reject для WAN-зоны (как в Сеть → Межсетевой " -"экран)." +msgstr "Включить журналирование drop/reject для WAN-зоны (как в Сеть → Межсетевой экран)." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:195 msgid "Enable logging" msgstr "Включить журнал" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2402 -msgid "" -"Enable logging turns on WAN zone drop/reject logging only (same as Network → " -"Firewall). It does not add rules or log normal LAN browsing." -msgstr "" -"«Включить журналирование» включает только журналирование drop/reject для WAN-" -"зоны (как в Сеть → Межсетевой экран). Оно не добавляет правил и не " -"журналирует обычный LAN-трафик." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2441 +msgid "Enable logging turns on WAN zone drop/reject logging only (same as Network → Firewall). It does not add rules or log normal LAN browsing." +msgstr "«Включить журналирование» включает только журналирование drop/reject для WAN-зоны (как в Сеть → Межсетевой экран). Оно не добавляет правил и не журналирует обычный LAN-трафик." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:60 #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:195 msgid "Enabling…" msgstr "Включение…" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1840 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1878 msgid "Exclude" msgstr "Исключить" @@ -303,17 +267,13 @@ msgstr "Исключить" msgid "Exclude instead" msgstr "Исключить вместо этого" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2328 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2367 msgid "Fetch budget" msgstr "Бюджет выборки" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2410 -msgid "" -"Fetch budget controls raw log lines per poll. Auto derives from Limit; " -"Manual selects a bounded maximum." -msgstr "" -"Бюджет выборки задаёт число сырых строк журнала за опрос. «Авто» выводится " -"из лимита; «Вручную» задаёт ограниченный максимум." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2449 +msgid "Fetch budget controls raw log lines per poll. Auto derives from Limit; Manual selects a bounded maximum." +msgstr "Бюджет выборки задаёт число сырых строк журнала за опрос. «Авто» выводится из лимита; «Вручную» задаёт ограниченный максимум." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/links.js:63 #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/links.js:96 @@ -323,11 +283,9 @@ msgstr "Фильтр по %s" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/links.js:134 msgid "Filter logs by rule (hint: %s). Ctrl+click to open firewall settings." -msgstr "" -"Фильтр журналов по правилу (подсказка: %s). Ctrl+клик открывает настройки " -"файрвола." +msgstr "Фильтр журналов по правилу (подсказка: %s). Ctrl+клик открывает настройки файрвола." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2484 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2523 #: openwrt-feed/luci-app-fwlive/root/usr/share/luci/menu.d/luci-app-fwlive.json:3 msgid "Firewall Live View" msgstr "Просмотр файрвола в реальном времени" @@ -340,14 +298,9 @@ msgstr "Флаги" msgid "Flow" msgstr "Поток" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2420 -msgid "" -"For a responsive table on a weak device, keep Limit at 250 rows or below. " -"The weak-device cap affects rendered rows; the buffer can still retain more." -msgstr "" -"Для отзывчивой таблицы на слабом устройстве установите Лимит не выше 250 " -"строк. Ограничение слабого устройства влияет на отображаемые строки; буфер " -"всё ещё может хранить больше." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2459 +msgid "For a responsive table on a weak device, keep Limit at 250 rows or below. The weak-device cap affects rendered rows; the buffer can still retain more." +msgstr "Для отзывчивой таблицы на слабом устройстве установите Лимит не выше 250 строк. Ограничение слабого устройства влияет на отображаемые строки; буфер всё ещё может хранить больше." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:61 msgid "Forwarded" @@ -357,27 +310,23 @@ msgstr "Транзитный" msgid "Grant access to firewall live log view" msgstr "Предоставить доступ к живому просмотру журнала межсетевого экрана" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2393 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2432 msgid "Help" msgstr "Справка" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1552 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1555 msgid "Hide rows" msgstr "Скрыть строки" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1607 -msgid "" -"High event rate — table refresh is throttled to protect the browser. The " -"buffer still updates; refresh will resume automatically." -msgstr "" -"Высокая частота событий — обновление таблицы ограничено для защиты браузера. " -"Буфер продолжает обновляться; отображение возобновится автоматически." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1610 +msgid "High event rate — table refresh is throttled to protect the browser. The buffer still updates; refresh will resume automatically." +msgstr "Высокая частота событий — обновление таблицы ограничено для защиты браузера. Буфер продолжает обновляться; отображение возобновится автоматически." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1452 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1455 msgid "Hostname resolve paused while the router is under load." msgstr "Разрешение имён приостановлено из-за нагрузки на маршрутизатор." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1831 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1869 msgid "ICMPv6" msgstr "ICMPv6" @@ -385,23 +334,13 @@ msgstr "ICMPv6" msgid "IN" msgstr "ВХОД" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2457 -msgid "" -"If Row tint looks missing, the active LuCI theme may omit success/error or " -"info/warn CSS variables; fwlive falls back to local colors (air-gapped, no " -"data leaves the device)." -msgstr "" -"Если цветовая маркировка строк отсутствует, активная тема LuCI может не " -"содержать CSS-переменные success/error или info/warn; fwlive использует " -"локальные цвета (работает автономно, данные не покидают устройство)." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2496 +msgid "If Row tint looks missing, the active LuCI theme may omit success/error or info/warn CSS variables; fwlive falls back to local colors (air-gapped, no data leaves the device)." +msgstr "Если цветовая маркировка строк отсутствует, активная тема LuCI может не содержать CSS-переменные success/error или info/warn; fwlive использует локальные цвета (работает автономно, данные не покидают устройство)." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:331 -msgid "" -"If the WAN is quiet, wait for probes or use the optional ping check in " -"Help / the enabling-logs guide." -msgstr "" -"Если WAN неактивен, дождитесь проб или используйте необязательную проверку " -"ping в Справке / руководстве по включению журналов." +msgid "If the WAN is quiet, wait for probes or use the optional ping check in Help / the enabling-logs guide." +msgstr "Если WAN неактивен, дождитесь проб или используйте необязательную проверку ping в Справке / руководстве по включению журналов." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:59 msgid "Inbound" @@ -412,14 +351,10 @@ msgid "Include instead" msgstr "Включить вместо этого" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:296 -msgid "" -"Install kmod-nf-log and kmod-nf-log6 with the command for your OpenWrt " -"release, then reload the firewall." -msgstr "" -"Установите kmod-nf-log и kmod-nf-log6 командой для вашей версии OpenWrt, " -"затем перезагрузите файрвол." +msgid "Install kmod-nf-log and kmod-nf-log6 with the command for your OpenWrt release, then reload the firewall." +msgstr "Установите kmod-nf-log и kmod-nf-log6 командой для вашей версии OpenWrt, затем перезагрузите файрвол." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1657 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1695 msgid "Installation is incomplete. Reinstall luci-app-fwlive." msgstr "Установка не завершена. Переустановите luci-app-fwlive." @@ -428,7 +363,7 @@ msgstr "Установка не завершена. Переустановите msgid "Interface" msgstr "Интерфейс" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2684 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2723 msgid "Interface (prefix ! to exclude)" msgstr "Интерфейс (! в начале для исключения)" @@ -445,53 +380,47 @@ msgstr "Отсутствуют модули журналирования ядр msgid "Len" msgstr "Длина" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2317 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2356 msgid "Limit" msgstr "Лимит" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:776 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:777 msgid "Live view may be incomplete — a legacy iptables table is registered" -msgstr "" -"Живой просмотр может быть неполным — зарегистрирована устаревшая таблица " -"iptables" +msgstr "Живой просмотр может быть неполным — зарегистрирована устаревшая таблица iptables" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:339 msgid "Logging is off on this router" msgstr "Журналирование на этом роутере отключено" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1414 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1475 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1417 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1478 msgid "Manual" msgstr "Вручную" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2346 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2385 msgid "Manual still uses server protection and poll cadence" msgstr "«Вручную» по-прежнему использует защиту сервера и частоту опроса" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2415 -msgid "" -"Manual still uses server protection and poll cadence; it changes the fetch " -"budget, not the polling interval." -msgstr "" -"«Вручную» по-прежнему использует защиту сервера и частоту опроса; меняется " -"бюджет выборки, а не интервал опроса." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2454 +msgid "Manual still uses server protection and poll cadence; it changes the fetch budget, not the polling interval." +msgstr "«Вручную» по-прежнему использует защиту сервера и частоту опроса; меняется бюджет выборки, а не интервал опроса." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:387 msgid "Manual test (System → Terminal):" msgstr "Ручной тест (Система → Терминал):" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2340 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2379 msgid "Maximum raw lines" msgstr "Максимум сырых строк" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:51 #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:344 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2569 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2576 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2608 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2615 msgid "Message" msgstr "Сообщение" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2679 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2718 msgid "More filters" msgstr "Больше фильтров" @@ -500,18 +429,15 @@ msgid "Network → Firewall" msgstr "Сеть → Межсетевой экран" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:283 -msgid "" -"No WAN firewall zone found in /etc/config/firewall. Configure zones under:" -msgstr "" -"WAN-зона межсетевого экрана не найдена в /etc/config/firewall. Настройте " -"зоны в разделе:" +msgid "No WAN firewall zone found in /etc/config/firewall. Configure zones under:" +msgstr "WAN-зона межсетевого экрана не найдена в /etc/config/firewall. Настройте зоны в разделе:" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:278 msgid "No WAN zone found" msgstr "WAN-зона не найдена" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:886 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:929 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:887 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:930 msgid "No WAN zone found; cannot toggle logging without one." msgstr "WAN-зона не найдена; без неё нельзя переключить журналирование." @@ -527,7 +453,7 @@ msgstr "Ничего не изменится, пока вы не нажмёте msgid "OUT" msgstr "ВЫХОД" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2599 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2638 msgid "One line" msgstr "Одна строка" @@ -544,29 +470,23 @@ msgid "OpenWrt 25.12 and newer (apk):" msgstr "OpenWrt 25.12 и новее (apk):" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:343 -msgid "" -"OpenWrt does not write firewall events to the log until you turn logging on. " -"Live View only shows what the firewall already logs — it does not add allow/" -"deny rules." -msgstr "" -"OpenWrt не записывает события межсетевого экрана в журнал, пока не включено " -"журналирование. Живой просмотр показывает только то, что firewall уже " -"журналирует — он не добавляет правила allow/deny." +msgid "OpenWrt does not write firewall events to the log until you turn logging on. Live View only shows what the firewall already logs — it does not add allow/deny rules." +msgstr "OpenWrt не записывает события межсетевого экрана в журнал, пока не включено журналирование. Живой просмотр показывает только то, что firewall уже журналирует — он не добавляет правила allow/deny." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:60 msgid "Outbound" msgstr "Исходящий" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2367 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2406 msgid "Palette" msgstr "Палитра" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1706 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2523 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1744 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2562 msgid "Pause" msgstr "Пауза" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1705 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1743 msgid "Paused" msgstr "Пауза" @@ -575,11 +495,11 @@ msgstr "Пауза" msgid "Proto" msgstr "Протокол" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2660 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2699 msgid "Protocol — common values" msgstr "Протокол — частые значения" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2639 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2678 msgid "Quick search" msgstr "Быстрый поиск" @@ -587,45 +507,35 @@ msgstr "Быстрый поиск" msgid "Remove filter" msgstr "Удалить фильтр" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1706 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1744 msgid "Resume" msgstr "Продолжить" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2357 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2396 msgid "Row tint" msgstr "Цвет строк" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2451 -msgid "" -"Row tint shows pass/deny row backgrounds when checked. Choose Classic (green/" -"red, default) or Accessible (teal/orange). Action text stays colored either " -"way." -msgstr "" -"Подсветка строк показывает фоны pass/deny, когда включена. Выберите " -"классический (зелёный/красный, по умолчанию) или доступный (бирюзовый/" -"оранжевый). Цвет текста действия сохраняется в любом случае." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2490 +msgid "Row tint shows pass/deny row backgrounds when checked. Choose Classic (green/red, default) or Accessible (teal/orange). Action text stays colored either way." +msgstr "Подсветка строк показывает фоны pass/deny, когда включена. Выберите классический (зелёный/красный, по умолчанию) или доступный (бирюзовый/оранжевый). Цвет текста действия сохраняется в любом случае." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2507 -msgid "" -"Row tint used a local color fallback because the active LuCI theme did not " -"apply pass/deny backgrounds." -msgstr "" -"Цветовая маркировка строк использовала локальный запасной цвет, так как " -"активная тема LuCI не применяет фон пропуска/отказа." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2546 +msgid "Row tint used a local color fallback because the active LuCI theme did not apply pass/deny backgrounds." +msgstr "Цветовая маркировка строк использовала локальный запасной цвет, так как активная тема LuCI не применяет фон пропуска/отказа." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:38 msgid "Rule" msgstr "Правило" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:767 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:768 msgid "Rule labels incomplete — map truncated" msgstr "Метки правил неполные — таблица обрезана" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:770 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:771 msgid "Rule labels unavailable" msgstr "Метки правил недоступны" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:769 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:770 msgid "Rule labels unavailable — temp file failed" msgstr "Метки правил недоступны — ошибка временного файла" @@ -637,40 +547,40 @@ msgstr "Порт ист." msgid "Search" msgstr "Поиск" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1443 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1446 msgid "Server adaptive protection is disabled." msgstr "Адаптивная защита сервера отключена." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1441 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1444 msgid "Server protection state is unknown." msgstr "Состояние защиты сервера неизвестно." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1448 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1451 msgid "Server shedding — at most %d log lines per poll." msgstr "Сервер ограничивает выдачу — не более %d строк журнала за опрос." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1450 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1453 msgid "Server truncated this poll (adaptive cap)." msgstr "Сервер сократил этот опрос (адаптивный предел)." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2384 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2423 msgid "Show hostnames" msgstr "Показывать имена узлов" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2355 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2394 msgid "Show pass/deny row background colors" msgstr "Показывать цвета фона строк pass/deny" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1552 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2622 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1555 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2661 msgid "Show rows" msgstr "Показать строки" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1509 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1512 msgid "Showing a compact summary of the top of the shown sample." msgstr "Показана краткая сводка верхней части отображаемой выборки." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2546 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2585 msgid "Simple" msgstr "Простой" @@ -679,7 +589,7 @@ msgstr "Простой" msgid "Source" msgstr "Источник" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2689 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2728 msgid "Source IP contains (! to exclude)" msgstr "IP источника содержит (! для исключения)" @@ -687,65 +597,44 @@ msgstr "IP источника содержит (! для исключения)" msgid "Source port" msgstr "Порт источника" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2694 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2733 msgid "Source port (! to exclude)" msgstr "Порт источника (! для исключения)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1511 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1514 msgid "Summary data is unavailable; show rows to inspect the sample." msgstr "Данные сводки недоступны; покажите строки для проверки выборки." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2613 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2652 msgid "Summary mode" msgstr "Режим сводки" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1513 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1516 msgid "Summary was bounded before all categories could be included." msgstr "Сводка ограничена до включения всех категорий." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2425 -msgid "" -"Switching tabs pauses polling; returning performs one catch-up poll. " -"Hostnames are off by default because lookups add work." -msgstr "" -"При переключении вкладки опрос приостанавливается; при возврате выполняется " -"один догоняющий опрос. Имена хостов по умолчанию отключены, поскольку их " -"разрешение создаёт дополнительную нагрузку." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2464 +msgid "Switching tabs pauses polling; returning performs one catch-up poll. Hostnames are off by default because lookups add work." +msgstr "При переключении вкладки опрос приостанавливается; при возврате выполняется один догоняющий опрос. Имена хостов по умолчанию отключены, поскольку их разрешение создаёт дополнительную нагрузку." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:894 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:935 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:895 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:936 msgid "The firewall did not reload; saved and live logging may differ." -msgstr "" -"Брандмауэр не перезагрузился; сохранённые и активные настройки " -"журналирования могут различаться." +msgstr "Брандмауэр не перезагрузился; сохранённые и активные настройки журналирования могут различаться." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2435 -msgid "" -"The rate shown for WAN logging is the firewall zone log_limit. OpenWrt " -"defaults to 10/minute when no explicit limit is configured; fwlive does not " -"impose this cap." -msgstr "" -"Показанная частота WAN-журнала — log_limit зоны. По умолчанию OpenWrt: 10/" -"мин без явного лимита; fwlive сам лимит не задаёт." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2474 +msgid "The rate shown for WAN logging is the firewall zone log_limit. OpenWrt defaults to 10/minute when no explicit limit is configured; fwlive does not impose this cap." +msgstr "Показанная частота WAN-журнала — log_limit зоны. По умолчанию OpenWrt: 10/мин без явного лимита; fwlive сам лимит не задаёт." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2430 -msgid "" -"The router log ring may evict older events before fwlive reads them. fwlive " -"cannot recover evicted entries or change forwarding behavior." -msgstr "" -"Кольцевой журнал маршрутизатора может вытеснить старые события до того, как " -"fwlive их прочитает. fwlive не может восстановить вытесненные записи и не " -"изменяет пересылку." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2469 +msgid "The router log ring may evict older events before fwlive reads them. fwlive cannot recover evicted entries or change forwarding behavior." +msgstr "Кольцевой журнал маршрутизатора может вытеснить старые события до того, как fwlive их прочитает. fwlive не может восстановить вытесненные записи и не изменяет пересылку." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2397 -msgid "" -"The table updates automatically when your firewall logs traffic. Use Pause " -"if it moves too fast." -msgstr "" -"Таблица обновляется автоматически, когда файрвол пишет в журнал. Используйте " -"Паузу, если слишком быстро." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2436 +msgid "The table updates automatically when your firewall logs traffic. Use Pause if it moves too fast." +msgstr "Таблица обновляется автоматически, когда файрвол пишет в журнал. Используйте Паузу, если слишком быстро." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2510 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2549 msgid "Theme tint fallback" msgstr "Запасной цвет темы" @@ -754,85 +643,63 @@ msgid "Then ping the router." msgstr "Затем отправьте ping на роутер." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:313 -msgid "" -"This router reported a logging blocker that Live View does not recognize yet." -msgstr "" -"Этот маршрутизатор сообщил о блоке журналирования, который Live View пока не " -"распознаёт." +msgid "This router reported a logging blocker that Live View does not recognize yet." +msgstr "Этот маршрутизатор сообщил о блоке журналирования, который Live View пока не распознаёт." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:36 msgid "Time" msgstr "Время" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1518 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1521 msgid "Top drops" msgstr "Частые сбросы" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1521 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1524 msgid "Top rules" msgstr "Частые правила" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1515 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1518 msgid "Top talkers" msgstr "Частые источники" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:219 msgid "Turn it back off with the WAN logging control on the watch strip." -msgstr "" -"Отключите её снова элементом управления журналом WAN на панели наблюдения." +msgstr "Отключите её снова элементом управления журналом WAN на панели наблюдения." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:357 -msgid "" -"Turns on WAN zone drop/reject logging (same as Network → Firewall → wan → " -"Log). Rate-limited by the zone log_limit (OpenWrt default 10/minute). Normal " -"LAN browsing is not logged." -msgstr "" -"Включает журналирование drop/reject для WAN-зоны (как в Сеть → Межсетевой " -"экран → wan → Журнал). Ограничено log_limit зоны (по умолчанию в OpenWrt 10/" -"мин). Обычный LAN-трафик не журналируется." +msgid "Turns on WAN zone drop/reject logging (same as Network → Firewall → wan → Log). Rate-limited by the zone log_limit (OpenWrt default 10/minute). Normal LAN browsing is not logged." +msgstr "Включает журналирование drop/reject для WAN-зоны (как в Сеть → Межсетевой экран → wan → Журнал). Ограничено log_limit зоны (по умолчанию в OpenWrt 10/мин). Обычный LAN-трафик не журналируется." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:209 msgid "Turns on logging for the WAN firewall zone and reloads the firewall." -msgstr "" -"Включает журналирование для WAN-зоны межсетевого экрана и перезагружает " -"firewall." +msgstr "Включает журналирование для WAN-зоны межсетевого экрана и перезагружает firewall." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:217 msgid "Undo:" msgstr "Отмена:" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2454 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2493 msgid "Use Detail for all columns (flags, length, raw message)." -msgstr "" -"Используйте «Подробно» для всех столбцов (флаги, длина, исходное сообщение)." +msgstr "Используйте «Подробно» для всех столбцов (флаги, длина, исходное сообщение)." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2528 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2534 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2567 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2573 msgid "View" msgstr "Вид" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:948 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:949 msgid "WAN drop/reject logging is off." msgstr "Журналирование drop/reject для WAN отключено." #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:324 -msgid "" -"WAN drop/reject logging is on. Blocked inbound WAN traffic will show up " -"here. Normal LAN browsing will not." -msgstr "" -"Журналирование drop/reject для WAN включено. Заблокированный входящий WAN-" -"трафик будет отображаться здесь. Обычный LAN-трафик — нет." +msgid "WAN drop/reject logging is on. Blocked inbound WAN traffic will show up here. Normal LAN browsing will not." +msgstr "Журналирование drop/reject для WAN включено. Заблокированный входящий WAN-трафик будет отображаться здесь. Обычный LAN-трафик — нет." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:910 -msgid "" -"WAN drop/reject logging is on. Blocked inbound traffic should appear here as " -"it happens — not normal LAN browsing." -msgstr "" -"Журналирование drop/reject для WAN включено. Заблокированный входящий трафик " -"должен появляться здесь по мере поступления — обычный LAN-трафик не " -"отображается." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:911 +msgid "WAN drop/reject logging is on. Blocked inbound traffic should appear here as it happens — not normal LAN browsing." +msgstr "Журналирование drop/reject для WAN включено. Заблокированный входящий трафик должен появляться здесь по мере поступления — обычный LAN-трафик не отображается." -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:912 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:913 msgid "WAN logging is already enabled." msgstr "WAN-журналирование уже включено." @@ -861,25 +728,25 @@ msgstr "WAN-журналирование недоступно: нет зоны W msgid "Waiting for firewall events" msgstr "Ожидание событий межсетевого экрана" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1705 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2498 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1743 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2537 msgid "Watching" msgstr "Наблюдение" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2588 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2627 msgid "Wrap" msgstr "Перенос" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:71 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2644 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2683 msgid "block" msgstr "заблокирован" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1263 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1266 msgid "buffer filling" msgstr "буфер заполняется" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1267 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1270 msgid "buffer full" msgstr "буфер заполнен" @@ -896,7 +763,7 @@ msgid "does not contain" msgstr "не содержит" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:72 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2645 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2684 msgid "drop" msgstr "отброшен" @@ -904,16 +771,16 @@ msgstr "отброшен" msgid "is" msgstr "есть" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1262 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1265 msgid "loading buffer" msgstr "загрузка буфера" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1637 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1674 msgid "loading…" msgstr "загрузка…" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1491 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1500 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1494 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1503 msgid "none" msgstr "нет" @@ -921,99 +788,98 @@ msgstr "нет" msgid "not" msgstr "не" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1848 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1886 msgid "not AH" msgstr "не AH" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1847 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1885 msgid "not ESP" msgstr "не ESP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1846 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1884 msgid "not GRE" msgstr "не GRE" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1843 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1881 msgid "not ICMP" msgstr "не ICMP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1844 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1882 msgid "not ICMPv6" msgstr "не ICMPv6" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1845 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1883 msgid "not IGMP" msgstr "не IGMP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1849 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1887 msgid "not SCTP" msgstr "не SCTP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1841 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1879 msgid "not TCP" msgstr "не TCP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1842 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1880 msgid "not UDP" msgstr "не UDP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2650 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2689 msgid "not block" msgstr "не блокировать" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2649 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2688 msgid "not drop" msgstr "не отбрасывать" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2648 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2687 msgid "not pass" msgstr "не пропускать" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2651 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2690 msgid "not reject" msgstr "не отклонять" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2652 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2691 msgid "not unknown" msgstr "не неизвестно" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2667 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2706 msgid "or type…" msgstr "или введите…" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:70 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2643 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2682 msgid "pass" msgstr "разрешён" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:73 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2646 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2685 msgid "reject" msgstr "отклонён" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1269 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1272 msgid "render paused (high rate)" msgstr "рендеринг приостановлен (высокая частота)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1278 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1281 msgid "resolve paused (load)" msgstr "Разрешение приостановлено (нагрузка)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1280 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1283 msgid "scroll frozen — scroll to top to follow live" -msgstr "" -"прокрутка заморожена — прокрутите вверх, чтобы следить в реальном времени" +msgstr "прокрутка заморожена — прокрутите вверх, чтобы следить в реальном времени" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1277 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1280 msgid "truncated" msgstr "обрезано" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:62 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2647 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2686 msgid "unknown" msgstr "неизвестно" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:751 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:752 msgid "using fw4" msgstr "используется fw4" @@ -1021,9 +887,5 @@ msgstr "используется fw4" msgid "· %s" msgstr "· %s" -#~ msgid "" -#~ "Kernel netfilter log modules are missing. Install kmod-nf-log and kmod-nf-" -#~ "log6, then reload the firewall." -#~ msgstr "" -#~ "Отсутствуют модули журнала netfilter ядра. Установите kmod-nf-log и kmod-" -#~ "nf-log6, затем перезагрузите файрвол." +#~ msgid "Kernel netfilter log modules are missing. Install kmod-nf-log and kmod-nf-log6, then reload the firewall." +#~ msgstr "Отсутствуют модули журнала netfilter ядра. Установите kmod-nf-log и kmod-nf-log6, затем перезагрузите файрвол." diff --git a/luci-app-fwlive/po/templates/luci-app-fwlive.pot b/luci-app-fwlive/po/templates/luci-app-fwlive.pot index 1e7a51bdc..7cfb21517 100644 --- a/luci-app-fwlive/po/templates/luci-app-fwlive.pot +++ b/luci-app-fwlive/po/templates/luci-app-fwlive.pot @@ -1,15 +1,15 @@ msgid "" msgstr "Content-Type: text/plain; charset=UTF-8" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1639 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1676 msgid "%d matching · %d/%d stored" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1433 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1436 msgid "%s · requested up to %d raw lines · %d firewall messages returned" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1423 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1426 msgid "" "%s · requested up to %d raw lines · server limited fetch to %d · %d firewall " "messages returned" @@ -19,11 +19,11 @@ msgstr "" msgid "%s: %s" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1641 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1678 msgid "0 matching · %d/%d stored" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:453 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:454 msgid "Accessible (teal/orange)" msgstr "" @@ -32,11 +32,11 @@ msgstr "" msgid "Action" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:949 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:950 msgid "Administrator access is required to disable logging." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:914 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:915 msgid "Administrator access is required to enable logging." msgstr "" @@ -44,32 +44,32 @@ msgstr "" msgid "Allow/deny rules, LAN logging, or anything else." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1833 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1871 msgid "Also seen" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:883 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:926 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:884 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:927 msgid "Another change is staged for the firewall; apply or revert it first." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:903 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:944 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:904 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:945 msgid "" "Another change overwrote WAN logging after it was saved; check the current " "state." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2642 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2681 msgid "Any action" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1826 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1864 msgid "Any protocol" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1414 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1474 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1417 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1477 msgid "Auto" msgstr "" @@ -77,7 +77,7 @@ msgstr "" msgid "Before you enable logging" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:880 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:881 msgid "Cannot enable logging until kernel log modules are installed." msgstr "" @@ -85,11 +85,11 @@ msgstr "" msgid "Changes:" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:452 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:453 msgid "Classic (green/red)" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2373 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2412 msgid "Classic uses green/red; Accessible uses teal/orange" msgstr "" @@ -97,13 +97,13 @@ msgstr "" msgid "Clear all" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2714 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2753 msgid "" "Click a cell to filter · ≠ on a chip to exclude · Ctrl+click a rule for " "firewall settings · in Simple view, click a row for the full message" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2441 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2480 msgid "" "Click a row (Time or other non-link cells) to see the full log line (Simple " "view)." @@ -113,66 +113,66 @@ msgstr "" msgid "Click a row for the full message" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2446 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2485 msgid "" "Click an IP, action, or protocol to filter; use the Protocol menu (or ≠ on a " "chip) to exclude." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1827 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1865 msgid "Common" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1658 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1696 msgid "Connection lost — retrying…" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:888 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:931 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:889 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:932 msgid "Could not acquire the logging lock." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:898 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:939 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:899 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:940 msgid "Could not clear the WAN zone log option." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:946 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:947 msgid "Could not disable logging." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:905 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:906 msgid "Could not enable logging." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:814 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:815 msgid "Could not load logging status." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:813 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:814 msgid "Could not refresh logging status; showing the last known state." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:900 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:941 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:901 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:942 msgid "Could not save the firewall configuration." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:892 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:893 msgid "Could not snapshot the current logging state." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:890 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:933 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:891 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:934 msgid "Could not track the logging change safely; logging was not changed." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:896 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:937 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:897 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:938 msgid "Could not write the WAN zone log option." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2669 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2708 msgid "Custom protocol (prefix ! to exclude). Overrides the menu when set." msgstr "" @@ -180,11 +180,11 @@ msgstr "" msgid "DPort" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1276 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1279 msgid "Degraded — sampling" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1445 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1448 msgid "Degraded — sampling (slow poll RTT; cadence reduced)." msgstr "" @@ -193,7 +193,7 @@ msgstr "" msgid "Destination" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2699 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2738 msgid "Destination IP contains (! to exclude)" msgstr "" @@ -201,11 +201,11 @@ msgstr "" msgid "Destination port" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2704 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2743 msgid "Destination port (! to exclude)" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2557 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2596 msgid "Detail" msgstr "" @@ -217,15 +217,15 @@ msgstr "" msgid "Disabling…" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1272 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1275 msgid "Display limited to %d rows on this device" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2314 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2353 msgid "Display options" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2406 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2445 msgid "Display options on the bar set Limit, row tint, palette, and hostnames." msgstr "" @@ -249,7 +249,7 @@ msgstr "" msgid "Enable logging" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2402 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2441 msgid "" "Enable logging turns on WAN zone drop/reject logging only (same as Network → " "Firewall). It does not add rules or log normal LAN browsing." @@ -260,7 +260,7 @@ msgstr "" msgid "Enabling…" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1840 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1878 msgid "Exclude" msgstr "" @@ -268,11 +268,11 @@ msgstr "" msgid "Exclude instead" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2328 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2367 msgid "Fetch budget" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2410 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2449 msgid "" "Fetch budget controls raw log lines per poll. Auto derives from Limit; " "Manual selects a bounded maximum." @@ -288,7 +288,7 @@ msgstr "" msgid "Filter logs by rule (hint: %s). Ctrl+click to open firewall settings." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2484 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2523 #: openwrt-feed/luci-app-fwlive/root/usr/share/luci/menu.d/luci-app-fwlive.json:3 msgid "Firewall Live View" msgstr "" @@ -301,7 +301,7 @@ msgstr "" msgid "Flow" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2420 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2459 msgid "" "For a responsive table on a weak device, keep Limit at 250 rows or below. " "The weak-device cap affects rendered rows; the buffer can still retain more." @@ -315,25 +315,25 @@ msgstr "" msgid "Grant access to firewall live log view" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2393 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2432 msgid "Help" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1552 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1555 msgid "Hide rows" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1607 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1610 msgid "" "High event rate — table refresh is throttled to protect the browser. The " "buffer still updates; refresh will resume automatically." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1452 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1455 msgid "Hostname resolve paused while the router is under load." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1831 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1869 msgid "ICMPv6" msgstr "" @@ -341,7 +341,7 @@ msgstr "" msgid "IN" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2457 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2496 msgid "" "If Row tint looks missing, the active LuCI theme may omit success/error or " "info/warn CSS variables; fwlive falls back to local colors (air-gapped, no " @@ -368,7 +368,7 @@ msgid "" "release, then reload the firewall." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1657 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1695 msgid "Installation is incomplete. Reinstall luci-app-fwlive." msgstr "" @@ -377,7 +377,7 @@ msgstr "" msgid "Interface" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2684 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2723 msgid "Interface (prefix ! to exclude)" msgstr "" @@ -394,11 +394,11 @@ msgstr "" msgid "Len" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2317 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2356 msgid "Limit" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:776 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:777 msgid "Live view may be incomplete — a legacy iptables table is registered" msgstr "" @@ -406,16 +406,16 @@ msgstr "" msgid "Logging is off on this router" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1414 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1475 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1417 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1478 msgid "Manual" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2346 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2385 msgid "Manual still uses server protection and poll cadence" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2415 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2454 msgid "" "Manual still uses server protection and poll cadence; it changes the fetch " "budget, not the polling interval." @@ -425,18 +425,18 @@ msgstr "" msgid "Manual test (System → Terminal):" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2340 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2379 msgid "Maximum raw lines" msgstr "" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:51 #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:344 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2569 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2576 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2608 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2615 msgid "Message" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2679 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2718 msgid "More filters" msgstr "" @@ -453,8 +453,8 @@ msgstr "" msgid "No WAN zone found" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:886 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:929 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:887 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:930 msgid "No WAN zone found; cannot toggle logging without one." msgstr "" @@ -470,7 +470,7 @@ msgstr "" msgid "OUT" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2599 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2638 msgid "One line" msgstr "" @@ -497,16 +497,16 @@ msgstr "" msgid "Outbound" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2367 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2406 msgid "Palette" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1706 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2523 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1744 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2562 msgid "Pause" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1705 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1743 msgid "Paused" msgstr "" @@ -515,11 +515,11 @@ msgstr "" msgid "Proto" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2660 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2699 msgid "Protocol — common values" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2639 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2678 msgid "Quick search" msgstr "" @@ -527,22 +527,22 @@ msgstr "" msgid "Remove filter" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1706 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1744 msgid "Resume" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2357 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2396 msgid "Row tint" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2451 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2490 msgid "" "Row tint shows pass/deny row backgrounds when checked. Choose Classic (green/" "red, default) or Accessible (teal/orange). Action text stays colored either " "way." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2507 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2546 msgid "" "Row tint used a local color fallback because the active LuCI theme did not " "apply pass/deny backgrounds." @@ -552,15 +552,15 @@ msgstr "" msgid "Rule" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:767 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:768 msgid "Rule labels incomplete — map truncated" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:770 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:771 msgid "Rule labels unavailable" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:769 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:770 msgid "Rule labels unavailable — temp file failed" msgstr "" @@ -572,40 +572,40 @@ msgstr "" msgid "Search" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1443 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1446 msgid "Server adaptive protection is disabled." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1441 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1444 msgid "Server protection state is unknown." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1448 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1451 msgid "Server shedding — at most %d log lines per poll." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1450 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1453 msgid "Server truncated this poll (adaptive cap)." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2384 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2423 msgid "Show hostnames" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2355 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2394 msgid "Show pass/deny row background colors" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1552 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2622 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1555 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2661 msgid "Show rows" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1509 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1512 msgid "Showing a compact summary of the top of the shown sample." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2546 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2585 msgid "Simple" msgstr "" @@ -614,7 +614,7 @@ msgstr "" msgid "Source" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2689 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2728 msgid "Source IP contains (! to exclude)" msgstr "" @@ -622,53 +622,53 @@ msgstr "" msgid "Source port" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2694 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2733 msgid "Source port (! to exclude)" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1511 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1514 msgid "Summary data is unavailable; show rows to inspect the sample." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2613 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2652 msgid "Summary mode" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1513 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1516 msgid "Summary was bounded before all categories could be included." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2425 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2464 msgid "" "Switching tabs pauses polling; returning performs one catch-up poll. " "Hostnames are off by default because lookups add work." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:894 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:935 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:895 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:936 msgid "The firewall did not reload; saved and live logging may differ." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2435 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2474 msgid "" "The rate shown for WAN logging is the firewall zone log_limit. OpenWrt " "defaults to 10/minute when no explicit limit is configured; fwlive does not " "impose this cap." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2430 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2469 msgid "" "The router log ring may evict older events before fwlive reads them. fwlive " "cannot recover evicted entries or change forwarding behavior." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2397 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2436 msgid "" "The table updates automatically when your firewall logs traffic. Use Pause " "if it moves too fast." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2510 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2549 msgid "Theme tint fallback" msgstr "" @@ -685,15 +685,15 @@ msgstr "" msgid "Time" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1518 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1521 msgid "Top drops" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1521 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1524 msgid "Top rules" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1515 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1518 msgid "Top talkers" msgstr "" @@ -716,16 +716,16 @@ msgstr "" msgid "Undo:" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2454 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2493 msgid "Use Detail for all columns (flags, length, raw message)." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2528 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2534 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2567 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2573 msgid "View" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:948 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:949 msgid "WAN drop/reject logging is off." msgstr "" @@ -735,13 +735,13 @@ msgid "" "here. Normal LAN browsing will not." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:910 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:911 msgid "" "WAN drop/reject logging is on. Blocked inbound traffic should appear here as " "it happens — not normal LAN browsing." msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:912 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:913 msgid "WAN logging is already enabled." msgstr "" @@ -770,25 +770,25 @@ msgstr "" msgid "Waiting for firewall events" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1705 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2498 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1743 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2537 msgid "Watching" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2588 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2627 msgid "Wrap" msgstr "" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:71 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2644 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2683 msgid "block" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1263 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1266 msgid "buffer filling" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1267 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1270 msgid "buffer full" msgstr "" @@ -805,7 +805,7 @@ msgid "does not contain" msgstr "" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:72 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2645 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2684 msgid "drop" msgstr "" @@ -813,16 +813,16 @@ msgstr "" msgid "is" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1262 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1265 msgid "loading buffer" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1637 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1674 msgid "loading…" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1491 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1500 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1494 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1503 msgid "none" msgstr "" @@ -830,98 +830,98 @@ msgstr "" msgid "not" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1848 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1886 msgid "not AH" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1847 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1885 msgid "not ESP" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1846 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1884 msgid "not GRE" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1843 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1881 msgid "not ICMP" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1844 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1882 msgid "not ICMPv6" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1845 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1883 msgid "not IGMP" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1849 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1887 msgid "not SCTP" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1841 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1879 msgid "not TCP" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1842 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1880 msgid "not UDP" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2650 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2689 msgid "not block" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2649 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2688 msgid "not drop" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2648 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2687 msgid "not pass" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2651 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2690 msgid "not reject" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2652 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2691 msgid "not unknown" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2667 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2706 msgid "or type…" msgstr "" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:70 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2643 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2682 msgid "pass" msgstr "" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:73 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2646 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2685 msgid "reject" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1269 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1272 msgid "render paused (high rate)" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1278 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1281 msgid "resolve paused (load)" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1280 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1283 msgid "scroll frozen — scroll to top to follow live" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1277 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1280 msgid "truncated" msgstr "" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:62 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2647 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2686 msgid "unknown" msgstr "" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:751 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:752 msgid "using fw4" msgstr "" diff --git a/luci-app-fwlive/po/zh_Hans/luci-app-fwlive.po b/luci-app-fwlive/po/zh_Hans/luci-app-fwlive.po index 95f24d3c1..79ff62019 100644 --- a/luci-app-fwlive/po/zh_Hans/luci-app-fwlive.po +++ b/luci-app-fwlive/po/zh_Hans/luci-app-fwlive.po @@ -12,30 +12,27 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1639 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1676 msgid "%d matching · %d/%d stored" msgstr "%d 条匹配 · 已存 %d/%d" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1433 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1436 msgid "%s · requested up to %d raw lines · %d firewall messages returned" msgstr "%s · 请求最多 %d 行原始日志 · 返回 %d 条防火墙消息" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1423 -msgid "" -"%s · requested up to %d raw lines · server limited fetch to %d · %d firewall " -"messages returned" -msgstr "" -"%s · 请求最多 %d 行原始日志 · 服务器将抓取限制为 %d · 返回 %d 条防火墙消息" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1426 +msgid "%s · requested up to %d raw lines · server limited fetch to %d · %d firewall messages returned" +msgstr "%s · 请求最多 %d 行原始日志 · 服务器将抓取限制为 %d · 返回 %d 条防火墙消息" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/log.js:543 msgid "%s: %s" msgstr "%s: %s" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1641 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1678 msgid "0 matching · %d/%d stored" msgstr "0 条匹配 · 已存 %d/%d" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:453 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:454 msgid "Accessible (teal/orange)" msgstr "无障碍(青绿/橙色)" @@ -44,11 +41,11 @@ msgstr "无障碍(青绿/橙色)" msgid "Action" msgstr "动作" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:949 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:950 msgid "Administrator access is required to disable logging." msgstr "需要管理员权限才能禁用日志记录。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:914 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:915 msgid "Administrator access is required to enable logging." msgstr "需要管理员权限才能启用日志记录。" @@ -56,32 +53,30 @@ msgstr "需要管理员权限才能启用日志记录。" msgid "Allow/deny rules, LAN logging, or anything else." msgstr "允许/拒绝规则、LAN 日志记录或任何其他设置。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1833 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1871 msgid "Also seen" msgstr "其他常见" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:883 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:926 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:884 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:927 msgid "Another change is staged for the firewall; apply or revert it first." msgstr "防火墙另有未提交的更改;请先应用或还原。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:903 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:944 -msgid "" -"Another change overwrote WAN logging after it was saved; check the current " -"state." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:904 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:945 +msgid "Another change overwrote WAN logging after it was saved; check the current state." msgstr "保存后另有更改覆盖了 WAN 日志设置;请检查当前状态。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2642 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2681 msgid "Any action" msgstr "所有动作" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1826 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1864 msgid "Any protocol" msgstr "任意协议" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1414 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1474 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1417 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1477 msgid "Auto" msgstr "自动" @@ -89,7 +84,7 @@ msgstr "自动" msgid "Before you enable logging" msgstr "启用日志记录之前" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:880 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:881 msgid "Cannot enable logging until kernel log modules are installed." msgstr "无法启用日志记录,直到内核日志模块已安装。" @@ -97,11 +92,11 @@ msgstr "无法启用日志记录,直到内核日志模块已安装。" msgid "Changes:" msgstr "变更:" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:452 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:453 msgid "Classic (green/red)" msgstr "经典(绿/红)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2373 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2412 msgid "Classic uses green/red; Accessible uses teal/orange" msgstr "经典使用绿/红;无障碍使用青绿/橙色" @@ -109,85 +104,76 @@ msgstr "经典使用绿/红;无障碍使用青绿/橙色" msgid "Clear all" msgstr "全部清除" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2714 -msgid "" -"Click a cell to filter · ≠ on a chip to exclude · Ctrl+click a rule for " -"firewall settings · in Simple view, click a row for the full message" -msgstr "" -"点击单元格筛选 · 芯片上的 ≠ 排除 · Ctrl+点击规则打开防火墙设置 · 在简单视图中" -"点击行查看完整消息" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2753 +msgid "Click a cell to filter · ≠ on a chip to exclude · Ctrl+click a rule for firewall settings · in Simple view, click a row for the full message" +msgstr "点击单元格筛选 · 芯片上的 ≠ 排除 · Ctrl+点击规则打开防火墙设置 · 在简单视图中点击行查看完整消息" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2441 -msgid "" -"Click a row (Time or other non-link cells) to see the full log line (Simple " -"view)." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2480 +msgid "Click a row (Time or other non-link cells) to see the full log line (Simple view)." msgstr "点击一行(时间或其他非链接单元格)可查看完整日志行(简单视图)。" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:158 msgid "Click a row for the full message" msgstr "点击行可查看完整消息" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2446 -msgid "" -"Click an IP, action, or protocol to filter; use the Protocol menu (or ≠ on a " -"chip) to exclude." -msgstr "" -"点击 IP、动作或协议进行筛选;使用协议菜单(或筛选标签上的 ≠)进行排除。" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2485 +msgid "Click an IP, action, or protocol to filter; use the Protocol menu (or ≠ on a chip) to exclude." +msgstr "点击 IP、动作或协议进行筛选;使用协议菜单(或筛选标签上的 ≠)进行排除。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1827 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1865 msgid "Common" msgstr "常用" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1658 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1696 msgid "Connection lost — retrying…" msgstr "连接已断开 — 正在重试…" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:888 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:931 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:889 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:932 msgid "Could not acquire the logging lock." msgstr "无法获取日志记录锁。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:898 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:939 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:899 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:940 msgid "Could not clear the WAN zone log option." msgstr "无法清除 WAN 区域日志选项。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:946 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:947 msgid "Could not disable logging." msgstr "无法禁用日志记录。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:905 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:906 msgid "Could not enable logging." msgstr "无法启用日志记录。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:814 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:815 msgid "Could not load logging status." msgstr "无法加载日志状态。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:813 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:814 msgid "Could not refresh logging status; showing the last known state." msgstr "无法刷新日志状态;显示上次已知状态。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:900 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:941 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:901 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:942 msgid "Could not save the firewall configuration." msgstr "无法保存防火墙配置。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:892 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:893 msgid "Could not snapshot the current logging state." msgstr "无法快照当前日志记录状态。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:890 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:933 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:891 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:934 msgid "Could not track the logging change safely; logging was not changed." msgstr "无法安全跟踪日志记录的更改;日志记录未更改。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:896 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:937 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:897 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:938 msgid "Could not write the WAN zone log option." msgstr "无法写入 WAN 区域日志选项。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2669 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2708 msgid "Custom protocol (prefix ! to exclude). Overrides the menu when set." msgstr "自定义协议(! 排除)。有内容时覆盖菜单。" @@ -195,11 +181,11 @@ msgstr "自定义协议(! 排除)。有内容时覆盖菜单。" msgid "DPort" msgstr "目的端口" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1276 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1279 msgid "Degraded — sampling" msgstr "降级 — 抽样" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1445 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1448 msgid "Degraded — sampling (slow poll RTT; cadence reduced)." msgstr "降级 — 抽样(轮询 RTT 较慢;已降低频率)。" @@ -208,7 +194,7 @@ msgstr "降级 — 抽样(轮询 RTT 较慢;已降低频率)。" msgid "Destination" msgstr "目的地址" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2699 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2738 msgid "Destination IP contains (! to exclude)" msgstr "目的 IP 包含(! 表示排除)" @@ -216,11 +202,11 @@ msgstr "目的 IP 包含(! 表示排除)" msgid "Destination port" msgstr "目标端口" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2704 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2743 msgid "Destination port (! to exclude)" msgstr "目的端口(! 表示排除)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2557 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2596 msgid "Detail" msgstr "详细" @@ -232,15 +218,15 @@ msgstr "方向" msgid "Disabling…" msgstr "正在禁用…" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1272 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1275 msgid "Display limited to %d rows on this device" msgstr "此设备上的显示限制为 %d 行" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2314 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2353 msgid "Display options" msgstr "显示选项" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2406 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2445 msgid "Display options on the bar set Limit, row tint, palette, and hostnames." msgstr "栏上的显示选项可设置行数限制、行着色、调色板和主机名。" @@ -264,20 +250,16 @@ msgstr "启用 WAN 区域的丢弃/拒绝日志记录(同 网络 → 防火墙 msgid "Enable logging" msgstr "启用日志" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2402 -msgid "" -"Enable logging turns on WAN zone drop/reject logging only (same as Network → " -"Firewall). It does not add rules or log normal LAN browsing." -msgstr "" -"启用日志仅开启 WAN 区域的丢弃/拒绝日志记录(同 网络 → 防火墙),不会添加规" -"则,也不会记录正常的 LAN 浏览。" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2441 +msgid "Enable logging turns on WAN zone drop/reject logging only (same as Network → Firewall). It does not add rules or log normal LAN browsing." +msgstr "启用日志仅开启 WAN 区域的丢弃/拒绝日志记录(同 网络 → 防火墙),不会添加规则,也不会记录正常的 LAN 浏览。" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:60 #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:195 msgid "Enabling…" msgstr "正在启用…" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1840 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1878 msgid "Exclude" msgstr "排除" @@ -285,17 +267,13 @@ msgstr "排除" msgid "Exclude instead" msgstr "改为排除" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2328 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2367 msgid "Fetch budget" msgstr "抓取配额" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2410 -msgid "" -"Fetch budget controls raw log lines per poll. Auto derives from Limit; " -"Manual selects a bounded maximum." -msgstr "" -"抓取配额控制每次轮询的原始日志行数。「自动」由行数限制推导;「手动」可选择一" -"个有上限的最大值。" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2449 +msgid "Fetch budget controls raw log lines per poll. Auto derives from Limit; Manual selects a bounded maximum." +msgstr "抓取配额控制每次轮询的原始日志行数。「自动」由行数限制推导;「手动」可选择一个有上限的最大值。" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/links.js:63 #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/links.js:96 @@ -307,7 +285,7 @@ msgstr "按 %s 筛选" msgid "Filter logs by rule (hint: %s). Ctrl+click to open firewall settings." msgstr "按规则筛选日志(提示:%s)。Ctrl+点击可打开防火墙设置。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2484 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2523 #: openwrt-feed/luci-app-fwlive/root/usr/share/luci/menu.d/luci-app-fwlive.json:3 msgid "Firewall Live View" msgstr "防火墙实时视图" @@ -320,13 +298,9 @@ msgstr "标志" msgid "Flow" msgstr "流向" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2420 -msgid "" -"For a responsive table on a weak device, keep Limit at 250 rows or below. " -"The weak-device cap affects rendered rows; the buffer can still retain more." -msgstr "" -"要让弱设备上的表格保持响应,请将 行数限制 保持在 250 行或更少。弱设备限制影响" -"渲染的行数;缓冲区仍可保留更多行。" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2459 +msgid "For a responsive table on a weak device, keep Limit at 250 rows or below. The weak-device cap affects rendered rows; the buffer can still retain more." +msgstr "要让弱设备上的表格保持响应,请将 行数限制 保持在 250 行或更少。弱设备限制影响渲染的行数;缓冲区仍可保留更多行。" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:61 msgid "Forwarded" @@ -336,26 +310,23 @@ msgstr "已转发" msgid "Grant access to firewall live log view" msgstr "授予防火墙实时日志视图的访问权限" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2393 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2432 msgid "Help" msgstr "帮助" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1552 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1555 msgid "Hide rows" msgstr "隐藏行" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1607 -msgid "" -"High event rate — table refresh is throttled to protect the browser. The " -"buffer still updates; refresh will resume automatically." -msgstr "" -"事件速率过高 — 已限制表格刷新以保护浏览器。缓冲区仍在更新;刷新将自动恢复。" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1610 +msgid "High event rate — table refresh is throttled to protect the browser. The buffer still updates; refresh will resume automatically." +msgstr "事件速率过高 — 已限制表格刷新以保护浏览器。缓冲区仍在更新;刷新将自动恢复。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1452 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1455 msgid "Hostname resolve paused while the router is under load." msgstr "路由器负载较高,已暂停主机名解析。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1831 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1869 msgid "ICMPv6" msgstr "ICMPv6" @@ -363,22 +334,13 @@ msgstr "ICMPv6" msgid "IN" msgstr "IN" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2457 -msgid "" -"If Row tint looks missing, the active LuCI theme may omit success/error or " -"info/warn CSS variables; fwlive falls back to local colors (air-gapped, no " -"data leaves the device)." -msgstr "" -"如果行着色看起来缺失,当前 LuCI 主题可能未提供成功/错误或信息/警告 CSS 变量;" -"fwlive 会回退到本地颜色(隔离运行,数据不会离开本设备)。" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2496 +msgid "If Row tint looks missing, the active LuCI theme may omit success/error or info/warn CSS variables; fwlive falls back to local colors (air-gapped, no data leaves the device)." +msgstr "如果行着色看起来缺失,当前 LuCI 主题可能未提供成功/错误或信息/警告 CSS 变量;fwlive 会回退到本地颜色(隔离运行,数据不会离开本设备)。" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:331 -msgid "" -"If the WAN is quiet, wait for probes or use the optional ping check in " -"Help / the enabling-logs guide." -msgstr "" -"如果 WAN 侧较安静,请等待探测报文,或使用「帮助」/启用日志指南中的可选 ping " -"检查。" +msgid "If the WAN is quiet, wait for probes or use the optional ping check in Help / the enabling-logs guide." +msgstr "如果 WAN 侧较安静,请等待探测报文,或使用「帮助」/启用日志指南中的可选 ping 检查。" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:59 msgid "Inbound" @@ -389,14 +351,10 @@ msgid "Include instead" msgstr "改为包含" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:296 -msgid "" -"Install kmod-nf-log and kmod-nf-log6 with the command for your OpenWrt " -"release, then reload the firewall." -msgstr "" -"请使用适用于您 OpenWrt 版本的命令安装 kmod-nf-log 和 kmod-nf-log6,然后重新加" -"载防火墙。" +msgid "Install kmod-nf-log and kmod-nf-log6 with the command for your OpenWrt release, then reload the firewall." +msgstr "请使用适用于您 OpenWrt 版本的命令安装 kmod-nf-log 和 kmod-nf-log6,然后重新加载防火墙。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1657 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1695 msgid "Installation is incomplete. Reinstall luci-app-fwlive." msgstr "安装不完整。请重新安装 luci-app-fwlive。" @@ -405,7 +363,7 @@ msgstr "安装不完整。请重新安装 luci-app-fwlive。" msgid "Interface" msgstr "接口" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2684 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2723 msgid "Interface (prefix ! to exclude)" msgstr "接口(前缀 ! 表示排除)" @@ -422,11 +380,11 @@ msgstr "缺少内核日志模块" msgid "Len" msgstr "长度" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2317 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2356 msgid "Limit" msgstr "行数限制" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:776 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:777 msgid "Live view may be incomplete — a legacy iptables table is registered" msgstr "实时视图可能不完整 — 已注册旧版 iptables 表" @@ -434,38 +392,35 @@ msgstr "实时视图可能不完整 — 已注册旧版 iptables 表" msgid "Logging is off on this router" msgstr "此路由器的日志记录已关闭" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1414 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1475 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1417 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1478 msgid "Manual" msgstr "手动" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2346 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2385 msgid "Manual still uses server protection and poll cadence" msgstr "手动模式仍受服务器保护和轮询节奏约束" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2415 -msgid "" -"Manual still uses server protection and poll cadence; it changes the fetch " -"budget, not the polling interval." -msgstr "" -"手动模式仍受服务器保护和轮询节奏约束;它改变的是抓取配额,而不是轮询间隔。" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2454 +msgid "Manual still uses server protection and poll cadence; it changes the fetch budget, not the polling interval." +msgstr "手动模式仍受服务器保护和轮询节奏约束;它改变的是抓取配额,而不是轮询间隔。" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:387 msgid "Manual test (System → Terminal):" msgstr "手动测试(系统 → 终端):" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2340 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2379 msgid "Maximum raw lines" msgstr "最大原始行数" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:51 #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:344 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2569 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2576 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2608 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2615 msgid "Message" msgstr "消息" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2679 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2718 msgid "More filters" msgstr "更多筛选" @@ -474,17 +429,15 @@ msgid "Network → Firewall" msgstr "网络 → 防火墙" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:283 -msgid "" -"No WAN firewall zone found in /etc/config/firewall. Configure zones under:" -msgstr "" -"在 /etc/config/firewall 中未找到 WAN 防火墙区域。请在以下位置配置区域:" +msgid "No WAN firewall zone found in /etc/config/firewall. Configure zones under:" +msgstr "在 /etc/config/firewall 中未找到 WAN 防火墙区域。请在以下位置配置区域:" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:278 msgid "No WAN zone found" msgstr "未找到 WAN 区域" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:886 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:929 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:887 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:930 msgid "No WAN zone found; cannot toggle logging without one." msgstr "未找到 WAN 区域;没有它无法切换日志记录。" @@ -500,7 +453,7 @@ msgstr "点击「启用」之前不会有任何更改。" msgid "OUT" msgstr "出接口" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2599 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2638 msgid "One line" msgstr "单行" @@ -517,28 +470,23 @@ msgid "OpenWrt 25.12 and newer (apk):" msgstr "OpenWrt 25.12 及更高版本(apk):" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:343 -msgid "" -"OpenWrt does not write firewall events to the log until you turn logging on. " -"Live View only shows what the firewall already logs — it does not add allow/" -"deny rules." -msgstr "" -"开启日志记录之前,OpenWrt 不会将防火墙事件写入日志。实时视图只显示防火墙已记" -"录的内容 — 它不会添加允许/拒绝规则。" +msgid "OpenWrt does not write firewall events to the log until you turn logging on. Live View only shows what the firewall already logs — it does not add allow/deny rules." +msgstr "开启日志记录之前,OpenWrt 不会将防火墙事件写入日志。实时视图只显示防火墙已记录的内容 — 它不会添加允许/拒绝规则。" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:60 msgid "Outbound" msgstr "出站" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2367 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2406 msgid "Palette" msgstr "配色" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1706 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2523 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1744 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2562 msgid "Pause" msgstr "暂停" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1705 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1743 msgid "Paused" msgstr "已暂停" @@ -547,11 +495,11 @@ msgstr "已暂停" msgid "Proto" msgstr "协议" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2660 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2699 msgid "Protocol — common values" msgstr "协议 — 常用值" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2639 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2678 msgid "Quick search" msgstr "快速搜索" @@ -559,42 +507,35 @@ msgstr "快速搜索" msgid "Remove filter" msgstr "移除筛选" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1706 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1744 msgid "Resume" msgstr "继续" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2357 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2396 msgid "Row tint" msgstr "行着色" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2451 -msgid "" -"Row tint shows pass/deny row backgrounds when checked. Choose Classic (green/" -"red, default) or Accessible (teal/orange). Action text stays colored either " -"way." -msgstr "" -"勾选后行着色显示放行/拒绝行背景。可选经典(绿/红,默认)或无障碍(青绿/橙)。" -"操作文本在两种模式下均保持着色。" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2490 +msgid "Row tint shows pass/deny row backgrounds when checked. Choose Classic (green/red, default) or Accessible (teal/orange). Action text stays colored either way." +msgstr "勾选后行着色显示放行/拒绝行背景。可选经典(绿/红,默认)或无障碍(青绿/橙)。操作文本在两种模式下均保持着色。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2507 -msgid "" -"Row tint used a local color fallback because the active LuCI theme did not " -"apply pass/deny backgrounds." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2546 +msgid "Row tint used a local color fallback because the active LuCI theme did not apply pass/deny backgrounds." msgstr "由于当前 LuCI 主题未应用放行/拒绝背景色,行着色使用了本地颜色回退。" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:38 msgid "Rule" msgstr "规则" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:767 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:768 msgid "Rule labels incomplete — map truncated" msgstr "规则标签不完整 — 映射被截断" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:770 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:771 msgid "Rule labels unavailable" msgstr "规则标签不可用" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:769 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:770 msgid "Rule labels unavailable — temp file failed" msgstr "规则标签不可用 — 临时文件创建失败" @@ -606,40 +547,40 @@ msgstr "源端口" msgid "Search" msgstr "搜索" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1443 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1446 msgid "Server adaptive protection is disabled." msgstr "服务器自适应保护已禁用。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1441 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1444 msgid "Server protection state is unknown." msgstr "服务器保护状态未知。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1448 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1451 msgid "Server shedding — at most %d log lines per poll." msgstr "服务器正在削减 — 每次轮询最多 %d 行日志。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1450 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1453 msgid "Server truncated this poll (adaptive cap)." msgstr "服务器已截断本次轮询(自适应上限)。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2384 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2423 msgid "Show hostnames" msgstr "显示主机名" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2355 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2394 msgid "Show pass/deny row background colors" msgstr "显示放行/拒绝行背景色" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1552 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2622 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1555 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2661 msgid "Show rows" msgstr "显示行" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1509 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1512 msgid "Showing a compact summary of the top of the shown sample." msgstr "显示当前样本顶部的简要摘要。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2546 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2585 msgid "Simple" msgstr "简洁" @@ -648,7 +589,7 @@ msgstr "简洁" msgid "Source" msgstr "源地址" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2689 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2728 msgid "Source IP contains (! to exclude)" msgstr "源 IP 包含(! 表示排除)" @@ -656,59 +597,44 @@ msgstr "源 IP 包含(! 表示排除)" msgid "Source port" msgstr "源端口" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2694 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2733 msgid "Source port (! to exclude)" msgstr "源端口(! 表示排除)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1511 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1514 msgid "Summary data is unavailable; show rows to inspect the sample." msgstr "摘要数据不可用;显示行以检查样本。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2613 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2652 msgid "Summary mode" msgstr "摘要模式" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1513 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1516 msgid "Summary was bounded before all categories could be included." msgstr "摘要已受限,无法包含所有类别。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2425 -msgid "" -"Switching tabs pauses polling; returning performs one catch-up poll. " -"Hostnames are off by default because lookups add work." -msgstr "" -"切换到其他标签页会暂停轮询;返回时执行一次追赶轮询。主机名默认关闭,因为解析" -"会增加工作量。" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2464 +msgid "Switching tabs pauses polling; returning performs one catch-up poll. Hostnames are off by default because lookups add work." +msgstr "切换到其他标签页会暂停轮询;返回时执行一次追赶轮询。主机名默认关闭,因为解析会增加工作量。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:894 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:935 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:895 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:936 msgid "The firewall did not reload; saved and live logging may differ." msgstr "防火墙未能重新加载;已保存的日志设置与当前生效状态可能不一致。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2435 -msgid "" -"The rate shown for WAN logging is the firewall zone log_limit. OpenWrt " -"defaults to 10/minute when no explicit limit is configured; fwlive does not " -"impose this cap." -msgstr "" -"WAN 日志显示的速率是防火墙区域的 log_limit。未显式配置时 OpenWrt 默认为 10 " -"条/分钟;此上限并非 fwlive 施加。" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2474 +msgid "The rate shown for WAN logging is the firewall zone log_limit. OpenWrt defaults to 10/minute when no explicit limit is configured; fwlive does not impose this cap." +msgstr "WAN 日志显示的速率是防火墙区域的 log_limit。未显式配置时 OpenWrt 默认为 10 条/分钟;此上限并非 fwlive 施加。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2430 -msgid "" -"The router log ring may evict older events before fwlive reads them. fwlive " -"cannot recover evicted entries or change forwarding behavior." -msgstr "" -"路由器日志环形缓冲区可能在 fwlive 读取前淘汰较旧事件。fwlive 无法恢复已淘汰的" -"条目,也不会改变转发行为。" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2469 +msgid "The router log ring may evict older events before fwlive reads them. fwlive cannot recover evicted entries or change forwarding behavior." +msgstr "路由器日志环形缓冲区可能在 fwlive 读取前淘汰较旧事件。fwlive 无法恢复已淘汰的条目,也不会改变转发行为。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2397 -msgid "" -"The table updates automatically when your firewall logs traffic. Use Pause " -"if it moves too fast." +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2436 +msgid "The table updates automatically when your firewall logs traffic. Use Pause if it moves too fast." msgstr "防火墙记录流量时表格会自动更新。如果滚动太快,请使用「暂停」。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2510 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2549 msgid "Theme tint fallback" msgstr "主题着色回退" @@ -717,23 +643,22 @@ msgid "Then ping the router." msgstr "然后 ping 路由器。" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:313 -msgid "" -"This router reported a logging blocker that Live View does not recognize yet." +msgid "This router reported a logging blocker that Live View does not recognize yet." msgstr "此路由器报告了 Live View 尚无法识别的日志阻止项。" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:36 msgid "Time" msgstr "时间" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1518 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1521 msgid "Top drops" msgstr "主要丢弃" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1521 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1524 msgid "Top rules" msgstr "主要规则" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1515 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1518 msgid "Top talkers" msgstr "主要通信方" @@ -742,13 +667,8 @@ msgid "Turn it back off with the WAN logging control on the watch strip." msgstr "通过监视栏上的 WAN 日志控件将其重新关闭。" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:357 -msgid "" -"Turns on WAN zone drop/reject logging (same as Network → Firewall → wan → " -"Log). Rate-limited by the zone log_limit (OpenWrt default 10/minute). Normal " -"LAN browsing is not logged." -msgstr "" -"开启 WAN 区域的丢弃/拒绝日志记录(同 网络 → 防火墙 → wan → 日志)。受区域 " -"log_limit 限速(OpenWrt 默认 10 条/分钟)。正常的 LAN 浏览不会被记录。" +msgid "Turns on WAN zone drop/reject logging (same as Network → Firewall → wan → Log). Rate-limited by the zone log_limit (OpenWrt default 10/minute). Normal LAN browsing is not logged." +msgstr "开启 WAN 区域的丢弃/拒绝日志记录(同 网络 → 防火墙 → wan → 日志)。受区域 log_limit 限速(OpenWrt 默认 10 条/分钟)。正常的 LAN 浏览不会被记录。" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:209 msgid "Turns on logging for the WAN firewall zone and reloads the firewall." @@ -758,36 +678,28 @@ msgstr "开启 WAN 防火墙区域的日志记录并重新加载防火墙。" msgid "Undo:" msgstr "撤销:" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2454 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2493 msgid "Use Detail for all columns (flags, length, raw message)." msgstr "使用「详细」可查看全部列(标志、长度、原始消息)。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2528 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2534 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2567 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2573 msgid "View" msgstr "视图" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:948 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:949 msgid "WAN drop/reject logging is off." msgstr "WAN 丢弃/拒绝日志记录已关闭。" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/logging.js:324 -msgid "" -"WAN drop/reject logging is on. Blocked inbound WAN traffic will show up " -"here. Normal LAN browsing will not." -msgstr "" -"WAN 丢弃/拒绝日志记录已开启。被阻止的 WAN 入站流量会显示在这里;正常的 LAN 浏" -"览不会。" +msgid "WAN drop/reject logging is on. Blocked inbound WAN traffic will show up here. Normal LAN browsing will not." +msgstr "WAN 丢弃/拒绝日志记录已开启。被阻止的 WAN 入站流量会显示在这里;正常的 LAN 浏览不会。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:910 -msgid "" -"WAN drop/reject logging is on. Blocked inbound traffic should appear here as " -"it happens — not normal LAN browsing." -msgstr "" -"WAN 丢弃/拒绝日志记录已开启。被阻止的入站流量会实时显示在这里 — 正常的 LAN 浏" -"览不会。" +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:911 +msgid "WAN drop/reject logging is on. Blocked inbound traffic should appear here as it happens — not normal LAN browsing." +msgstr "WAN 丢弃/拒绝日志记录已开启。被阻止的入站流量会实时显示在这里 — 正常的 LAN 浏览不会。" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:912 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:913 msgid "WAN logging is already enabled." msgstr "WAN 日志记录已处于启用状态。" @@ -816,25 +728,25 @@ msgstr "WAN 日志不可用:无 WAN 区域" msgid "Waiting for firewall events" msgstr "正在等待防火墙事件" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1705 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2498 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1743 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2537 msgid "Watching" msgstr "监视中" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2588 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2627 msgid "Wrap" msgstr "自动换行" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:71 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2644 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2683 msgid "block" msgstr "拦截" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1263 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1266 msgid "buffer filling" msgstr "缓冲区填充中" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1267 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1270 msgid "buffer full" msgstr "缓冲区已满" @@ -851,7 +763,7 @@ msgid "does not contain" msgstr "不包含" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:72 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2645 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2684 msgid "drop" msgstr "丢弃" @@ -859,16 +771,16 @@ msgstr "丢弃" msgid "is" msgstr "是" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1262 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1265 msgid "loading buffer" msgstr "正在加载缓冲区" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1637 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1674 msgid "loading…" msgstr "加载中…" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1491 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1500 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1494 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1503 msgid "none" msgstr "无" @@ -876,98 +788,98 @@ msgstr "无" msgid "not" msgstr "非" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1848 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1886 msgid "not AH" msgstr "非 AH" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1847 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1885 msgid "not ESP" msgstr "非 ESP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1846 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1884 msgid "not GRE" msgstr "非 GRE" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1843 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1881 msgid "not ICMP" msgstr "非 ICMP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1844 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1882 msgid "not ICMPv6" msgstr "非 ICMPv6" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1845 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1883 msgid "not IGMP" msgstr "非 IGMP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1849 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1887 msgid "not SCTP" msgstr "非 SCTP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1841 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1879 msgid "not TCP" msgstr "非 TCP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1842 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1880 msgid "not UDP" msgstr "非 UDP" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2650 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2689 msgid "not block" msgstr "非阻止" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2649 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2688 msgid "not drop" msgstr "非丢弃" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2648 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2687 msgid "not pass" msgstr "非放行" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2651 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2690 msgid "not reject" msgstr "非拒绝" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2652 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2691 msgid "not unknown" msgstr "非未知" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2667 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2706 msgid "or type…" msgstr "或输入…" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:70 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2643 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2682 msgid "pass" msgstr "通过" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:73 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2646 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2685 msgid "reject" msgstr "拒绝" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1269 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1272 msgid "render paused (high rate)" msgstr "渲染已暂停(速率过高)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1278 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1281 msgid "resolve paused (load)" msgstr "解析已暂停(负载)" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1280 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1283 msgid "scroll frozen — scroll to top to follow live" msgstr "滚动已冻结 — 滚动到顶部以恢复跟随" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1277 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:1280 msgid "truncated" msgstr "已截断" #: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/fwlive/table.js:62 -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2647 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:2686 msgid "unknown" msgstr "未知" -#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:751 +#: openwrt-feed/luci-app-fwlive/htdocs/luci-static/resources/view/status/fwlive.js:752 msgid "using fw4" msgstr "使用 fw4" @@ -975,9 +887,5 @@ msgstr "使用 fw4" msgid "· %s" msgstr "· %s" -#~ msgid "" -#~ "Kernel netfilter log modules are missing. Install kmod-nf-log and kmod-nf-" -#~ "log6, then reload the firewall." -#~ msgstr "" -#~ "缺少内核 netfilter 日志模块。请安装 kmod-nf-log 和 kmod-nf-log6,然后重新" -#~ "加载防火墙。" +#~ msgid "Kernel netfilter log modules are missing. Install kmod-nf-log and kmod-nf-log6, then reload the firewall." +#~ msgstr "缺少内核 netfilter 日志模块。请安装 kmod-nf-log 和 kmod-nf-log6,然后重新加载防火墙。" diff --git a/luci-app-homeproxy-pro/Makefile b/luci-app-homeproxy-pro/Makefile index e63cf2409..cfd6c4f93 100644 --- a/luci-app-homeproxy-pro/Makefile +++ b/luci-app-homeproxy-pro/Makefile @@ -23,7 +23,7 @@ LUCI_DEPENDS:= \ PKG_NAME:=luci-app-homeproxy-pro PKG_VERSION:=28.9.1.14 -PKG_RELEASE:=9 +PKG_RELEASE:=10 # Only files the package actually ships belong here. The previous list named # four paths that exist nowhere in the tree - certs/ and ruleset/ are created at diff --git a/luci-app-homeproxy-pro/README.md b/luci-app-homeproxy-pro/README.md index 43035e787..7c64b2ee3 100644 --- a/luci-app-homeproxy-pro/README.md +++ b/luci-app-homeproxy-pro/README.md @@ -74,38 +74,6 @@ **一句话总结**:pro 的核心价值是**把"单文件能跑"变成"orchestrator + table-driven adapter + 可独立测试的模块"**,并把约束、质量、回滚三件事从靠人盯变成靠代码执行(arch-guard 135 checks 静态锁住跨文件不变量)。 -## 排障要点 - -两条会把人带偏的坑,都是实测踩出来的,写在这里省得下一个人重走一遍。 - -**1. 客户端的 `sing-box-c.log` 里会出现"不是本机做出的决定"** - -代理节点侧的失败会用同样的措辞落进客户端日志。例如目的 IP 的 443 没有服务: - -``` -ERROR connection: open connection to 1.2.3.4:443 using outbound/direct[direct]: - dial tcp 1.2.3.4:443: connect: connection refused -``` - -这行**不代表**本机把该流量送去了直连——它可能是远端节点直连目标失败后的回传。曾据此误判"分流规则失效",实际是节点侧错误被记进了客户端日志。 - -判定真实走向要看**转发层**,不要看日志措辞: - -```sh -# 被重定向到本机代理端口 = 流量确实进入了代理路径 -grep -m1 'dst=.*dport=443' /proc/net/nf_conntrack # 回复方向出现 sport=5331 -# 分流链各分支计数:return 的分支=直连,最后 goto=走代理 -nft list chain inet fw4 homeproxy_redirect -# 大陆集合:防火墙据此判定"直连",与路由侧的 china-ip 规则集同源(china_ip4.txt) -nft list chain inet fw4 homeproxy_redirect | grep mainland_addr_v4 -``` - -**2. `sing-box tools connect/fetch` 不能用来验证分流** - -两者都通过 `instance.Outbound().Default()` 取默认出站(`cmd_tools_connect.go` / `cmd_tools_fetch.go`),**不经过 route 规则**。用它们测"某个域名/IP 会走代理还是直连",得到的结论一定是错的。 - -要验证实际走向,只能让**局域网真实客户端**发起连接,再看上面的 conntrack / nft 计数,或看 `sing-box-c.log` 里的 `outbound/xxx[tag]` 行(那才是本机的出站选择)。 - ## 已知限制 - **试验性**:不承诺 API/配置稳定,重大变更可能在 minor 版本里发生。 diff --git a/luci-app-honk/Makefile b/luci-app-honk/Makefile index 778c3a1ef..8cb94f240 100644 --- a/luci-app-honk/Makefile +++ b/luci-app-honk/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-honk PKG_VERSION:=1.1.4 -PKG_RELEASE:=8 +PKG_RELEASE:=9 LUCI_TITLE:=LuCI support for honk LUCI_PKGARCH:=all diff --git a/luci-app-honk/root/etc/honk/doona/THIRD-PARTY-NOTICES.txt b/luci-app-honk/root/etc/honk/doona/THIRD-PARTY-NOTICES.txt new file mode 100644 index 000000000..ac43f82b5 --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/THIRD-PARTY-NOTICES.txt @@ -0,0 +1,2310 @@ +@codemirror/autocomplete 6.20.3 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (C) 2018-2021 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +@codemirror/commands 6.11.1 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (C) 2018-2021 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +@codemirror/language 6.12.4 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (C) 2018-2021 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +@codemirror/lint 6.9.7 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (C) 2018-2021 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +@codemirror/search 6.7.2 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (C) 2018-2021 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +@codemirror/state 6.7.5 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (C) 2018-2021 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +@codemirror/view 6.43.12 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (C) 2018-2021 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +@internationalized/date 3.12.4 (Apache-2.0) — LICENSE +======================================================================== + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2019 Adobe + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +@internationalized/number 3.6.8 (Apache-2.0) — LICENSE +======================================================================== + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2019 Adobe + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +@internationalized/string 3.2.10 (Apache-2.0) — LICENSE +======================================================================== + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2019 Adobe + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +@lezer/common 1.5.2 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (C) 2018 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +@lezer/highlight 1.2.3 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (C) 2018 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +@lezer/lr 1.4.10 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (C) 2018 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +@marijn/find-cluster-break 1.0.4 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (C) 2024 by Marijn Haverbeke + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +@react-types/shared 3.36.1 (Apache-2.0) — LICENSE +======================================================================== + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2019 Adobe + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +@swc/helpers 0.5.23 (Apache-2.0) — LICENSE +======================================================================== + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2024 SWC contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +aria-hidden 1.2.6 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (c) 2017 Anton Korzunov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +clsx 2.1.1 (MIT) — license +======================================================================== +MIT License + +Copyright (c) Luke Edwards (lukeed.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +crelt 1.0.7 (MIT) — LICENSE +======================================================================== +Copyright (C) 2020 by Marijn Haverbeke + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +d3-path 3.1.0 (ISC) — LICENSE +======================================================================== +Copyright 2015-2022 Mike Bostock + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + + +d3-shape 3.2.0 (ISC) — LICENSE +======================================================================== +Copyright 2010-2022 Mike Bostock + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + + +openapi-fetch 0.17.0 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (c) 2023 Drew Powers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +openapi-typescript-helpers 0.1.0 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (c) 2023 Drew Powers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +react 19.3.0 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (c) Meta Platforms, Inc. and affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +react-aria 3.52.1 (Apache-2.0) — LICENSE +======================================================================== + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2019 Adobe + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +react-aria-components 1.21.1 (Apache-2.0) — LICENSE +======================================================================== + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2019 Adobe + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +react-dom 19.3.0 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (c) Meta Platforms, Inc. and affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +react-stately 3.50.0 (Apache-2.0) — LICENSE +======================================================================== + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2019 Adobe + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +rollup 4.63.2 (MIT) — LICENSE.md +======================================================================== +Only the module namespace objects that Rollup writes into the build ship. + +# Rollup core license +Rollup is released under the MIT license: + +The MIT License (MIT) + +Copyright (c) 2017 [these people](https://github.com/rollup/rollup/graphs/contributors) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +scheduler 0.28.0 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (c) Meta Platforms, Inc. and affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +style-mod 4.1.3 (MIT) — LICENSE +======================================================================== +Copyright (C) 2018 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +tslib 2.8.1 (0BSD) — LICENSE.txt +======================================================================== +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + +use-sync-external-store 1.7.0 (MIT) — LICENSE +======================================================================== +MIT License + +Copyright (c) Meta Platforms, Inc. and affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +vite 6.4.3 (MIT) — LICENSE.md +======================================================================== +Only helper code that Vite writes into the build ships: the module preload polyfill, the preload helper for dynamic imports and the CommonJS interop helper of @rollup/plugin-commonjs, which Vite bundles. + +# Vite core license +Vite is released under the MIT license: + +MIT License + +Copyright (c) 2019-present, VoidZero Inc. and Vite contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +## @rollup/plugin-alias, @rollup/plugin-commonjs, @rollup/plugin-dynamic-import-vars, @rollup/pluginutils +License: MIT +By: Johannes Stein +Repository: rollup/plugins + +License: MIT +By: Rich Harris +Repository: rollup/plugins + +License: MIT +By: LarsDenBakker +Repository: rollup/plugins + +License: MIT +By: Rich Harris +Repository: rollup/plugins + +> The MIT License (MIT) +> +> Copyright (c) 2019 RollupJS Plugin Contributors (https://github.com/rollup/plugins/graphs/contributors) +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in +> all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +> THE SOFTWARE. + + +w3c-keyname 2.2.8 (MIT) — LICENSE +======================================================================== +Copyright (C) 2016 by Marijn Haverbeke and others + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +Packages without a licence file +======================================================================== +client-only 0.0.1 (MIT) diff --git a/luci-app-honk/root/etc/honk/doona/assets/ActionGroup-BKxDwmnT.js b/luci-app-honk/root/etc/honk/doona/assets/ActionGroup-BKxDwmnT.js deleted file mode 100644 index c22d303b5..000000000 --- a/luci-app-honk/root/etc/honk/doona/assets/ActionGroup-BKxDwmnT.js +++ /dev/null @@ -1 +0,0 @@ -import{j as s}from"./vendor-react-Bf71BWbF.js";import{u as o,eb as c,ec as p,ed as x,ee as m,B as u}from"./index-BNBwb-FJ.js";const r=({action:n})=>s.jsxs(u,{isDisabled:n.isDisabled,isPending:n.isPending,onPress:n.onAction,children:[n.icon,n.label]});function h({actions:n,overflowMode:t="collapse"}){const l=o();if(t==="wrap")return s.jsx(s.Fragment,{children:n.map(e=>s.jsx(r,{action:e},e.id))});const[a,...i]=n;return a?s.jsxs(s.Fragment,{children:[s.jsx(r,{action:a}),i.length>0&&s.jsxs(s.Fragment,{children:[s.jsx("span",{className:"rp-wide-only",children:i.map(e=>s.jsx(r,{action:e},e.id))}),s.jsx("span",{className:"rp-narrow-only",children:s.jsx(c,{chevron:!1,label:l("ui.moreActions"),content:s.jsx(x,{"aria-label":l("ui.moreActions"),disabledKeys:i.filter(e=>e.isDisabled||e.isPending).map(e=>e.id),onAction:e=>i.find(d=>d.id===e)?.onAction(),children:i.map(e=>s.jsx(m,{id:e.id,className:"rp-item plain",textValue:e.label,children:e.label},e.id))}),children:s.jsx(p,{})})})]})]}):null}export{h as A}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/ActionGroup-DLxTuKht.js b/luci-app-honk/root/etc/honk/doona/assets/ActionGroup-DLxTuKht.js new file mode 100644 index 000000000..118e191fd --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/ActionGroup-DLxTuKht.js @@ -0,0 +1 @@ +import{j as e}from"./vendor-react-Bf71BWbF.js";import{u as c,ec as o,eW as x,B as p,ed as u,ee as m,eX as d,c as j}from"./index-Bw0aJc9a.js";const a=({action:n})=>e.jsxs(p,{isDisabled:n.isDisabled,isPending:n.isPending,tip:n.reason,onPress:n.onAction,children:[n.icon,n.label]});function $({actions:n,overflowMode:i="collapse"}){if(i==="wrap")return e.jsx(e.Fragment,{children:n.map(l=>e.jsx(a,{action:l},l.id))});const[s,...r]=n;return s?e.jsxs(e.Fragment,{children:[e.jsx(a,{action:s}),r.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"rp-wide-only",children:r.map(l=>e.jsx(a,{action:l},l.id))}),e.jsx("span",{className:"rp-narrow-only",children:e.jsx(b,{actions:r})})]})]}):null}function f({actions:n,label:i}){return e.jsx(u,{"aria-label":i,disabledKeys:n.filter(s=>s.isDisabled||s.isPending).map(s=>s.id),onAction:s=>n.find(r=>r.id===s)?.onAction(),children:n.map(s=>e.jsx(m,{id:s.id,className:j("rp-item plain",s.negative&&"negative"),textValue:s.label,children:e.jsxs("span",{className:"rp-item-text",children:[e.jsx(d,{slot:"label",children:s.label}),s.isDisabled&&s.reason&&e.jsx(d,{slot:"description",className:"desc reason",children:s.reason})]})},s.id))})}function b({actions:n,label:i,small:s,quiet:r}){const l=c(),t=i??l("ui.moreActions");return n.length===0?null:e.jsx(o,{chevron:!1,small:s,quiet:r,label:t,content:e.jsx(f,{actions:n,label:t}),children:e.jsx(x,{})})}export{$ as A,b as M}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/AddCircle-CIj8X2wL.js b/luci-app-honk/root/etc/honk/doona/assets/AddCircle-D11CyK2n.js similarity index 88% rename from luci-app-honk/root/etc/honk/doona/assets/AddCircle-CIj8X2wL.js rename to luci-app-honk/root/etc/honk/doona/assets/AddCircle-D11CyK2n.js index 4e16f93d9..095bc6403 100644 --- a/luci-app-honk/root/etc/honk/doona/assets/AddCircle-CIj8X2wL.js +++ b/luci-app-honk/root/etc/honk/doona/assets/AddCircle-D11CyK2n.js @@ -1 +1 @@ -import{j as r}from"./vendor-react-Bf71BWbF.js";import{c as t}from"./index-BNBwb-FJ.js";function o({className:a,...s}){return r.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:20,height:20,viewBox:"0 0 20 20","aria-hidden":"true",focusable:"false",className:t("rp-icon",a),...s,children:r.jsx("path",{fill:"currentColor",d:"M10 1.5a8.5 8.5 0 1 0 0 17 8.5 8.5 0 0 0 0-17m0 15.5a7 7 0 1 1 0-14 7 7 0 0 1 0 14m3.75-7.75h-3v-3a.75.75 0 0 0-1.5 0v3h-3a.75.75 0 0 0 0 1.5h3v3a.75.75 0 0 0 1.5 0v-3h3a.75.75 0 0 0 0-1.5"})})}export{o as A}; +import{j as r}from"./vendor-react-Bf71BWbF.js";import{c as t}from"./index-Bw0aJc9a.js";function o({className:a,...s}){return r.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:20,height:20,viewBox:"0 0 20 20","aria-hidden":"true",focusable:"false",className:t("rp-icon",a),...s,children:r.jsx("path",{fill:"currentColor",d:"M10 1.5a8.5 8.5 0 1 0 0 17 8.5 8.5 0 0 0 0-17m0 15.5a7 7 0 1 1 0-14 7 7 0 0 1 0 14m3.75-7.75h-3v-3a.75.75 0 0 0-1.5 0v3h-3a.75.75 0 0 0 0 1.5h3v3a.75.75 0 0 0 1.5 0v-3h3a.75.75 0 0 0 0-1.5"})})}export{o as A}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/AreaChart-D20yx2yz.js b/luci-app-honk/root/etc/honk/doona/assets/AreaChart-CO6S-Jvj.js similarity index 61% rename from luci-app-honk/root/etc/honk/doona/assets/AreaChart-D20yx2yz.js rename to luci-app-honk/root/etc/honk/doona/assets/AreaChart-CO6S-Jvj.js index b47d7860d..c109f50e8 100644 --- a/luci-app-honk/root/etc/honk/doona/assets/AreaChart-D20yx2yz.js +++ b/luci-app-honk/root/etc/honk/doona/assets/AreaChart-CO6S-Jvj.js @@ -1 +1 @@ -import{r as u,j as a}from"./vendor-react-Bf71BWbF.js";import{u as ct,aE as it,eQ as rt,eR as ut}from"./index-BNBwb-FJ.js";import{u as ht,e as dt,v as q,C as xt,f as pt,n as ft,g as H}from"./layout-wfdMYi2n.js";import{G as mt,C as yt}from"./AreaCurve-BriPYJva.js";import"./array-C0P64tl-.js";const Mt=l=>{const o=Math.pow(10,Math.floor(Math.log10(l))),e=l/o;return([1,1.2,1.5,2,2.5,3,4,5,6,8,10].find(h=>e<=h)??10)*o},gt=l=>{const o=Math.pow(10,Math.floor(Math.log10(Math.max(l,1e-9)))),e=l/o;return(e<=1?.2:e<=2?.5:e<=5?1:2)*o},F=[30,60,120,300,600,900,1800,3600,7200,21600,43200,86400].map(l=>l*1e3);function kt(l,o){const e=o-l,s=F.find(c=>e/c<=6)??F[F.length-1],h=s>=864e5?new Date(o).getTimezoneOffset()*6e4:0,y=Math.ceil((l-h)/s)*s+h,x=[];for(let c=y;c<=o;c+=s)c-l>=e*.04&&o-c>=e*.04&&x.push(c);return{ticks:x,step:s}}function J(l){const[o,e]=u.useState([]);return u.useLayoutEffect(()=>{const s=document.createElement("span");Object.assign(s.style,{position:"absolute",top:"-20000px",whiteSpace:"pre",fontSize:"11px"}),document.body.appendChild(s),e(l.map(y=>{s.textContent=y;const{width:x,height:c}=s.getBoundingClientRect();return{width:x,height:c}})),s.remove()},[l]),o}function wt({label:l,series:o,timestamps:e,fmt:s,locale:h,height:y=150,baseline:x="zero",window:c,fill:U}){const X=ct(),C=it(),N=u.useId(),[Y,E]=rt(Math.round,120),{tip:Z,showAt:_,hide:L}=ht(),[z,A]=u.useState(null),i=z&&z.indexM!==void 0&&g!==void 0?kt(M,g):void 0,[M,g]),D=p?p.step<6e4:B<180*1e3,I=p?p.step>=864e5:B>2160*60*1e3,R=u.useMemo(()=>new Intl.DateTimeFormat(h,I?{month:"numeric",day:"numeric"}:D?{hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"}:{hour:"2-digit",minute:"2-digit",hourCycle:"h23"}),[h,D,I]),{yDomain:G,yTicks:j}=u.useMemo(()=>{const t=o.flatMap(d=>d.values.filter(w=>w!==null));let n=0,r=Mt(Math.max(1,...t)*1.08);if(x==="auto"&&t.length){const d=Math.min(...t),w=Math.max(...t),b=gt(Math.max(w-d,w*.02,1));n=Math.max(0,Math.floor(d/b)*b-b),r=Math.ceil(w/b)*b+b}return{yDomain:[n,r],yTicks:x==="auto"?[n,(n+r)/2,r]:[r/2,r]}},[o,x]),P=u.useMemo(()=>{const t=e.length-1;return p?p.ticks:[...new Set((D?[0,Math.round(t/2),t]:[0,Math.round(t/3),Math.round(2*t/3),t]).map(n=>e[n]))]},[p,D,e]),K=u.useMemo(()=>M!==void 0&&g!==void 0?[M,g]:[Math.min(...e),Math.max(...e)],[M,g,e]),k=E?.width??0,S=E?.height??y,m=S-30,v=k-64,tt=[Math.min(K[0],...e),Math.max(K[1],...e)],f=t=>H(t,tt,[20,v]),T=t=>H(t,G,[m,8]),et={x:20,y:8,width:v-20,height:m-8},O=(t,n)=>A({index:t,y:n}),W=()=>{A(null),L()};u.useLayoutEffect(()=>{if(i===null){L();return}if(!o.some(t=>t.values[i]!=null)){L();return}_({x:f(e[i]),y:z?.y??(8+m)/2,width:k,bounds:et,label:ut(h).format(e[i]),lines:o.filter(t=>t.values[i]!=null).sort((t,n)=>t.labeln.label?1:0).map(t=>`${t.label}${X("ui.labelSeparator")}${s(t.values[i])}`)})});const $=dt(e.length,O,W),Q=u.useMemo(()=>P.map(t=>R.format(t)),[P,R]),nt=u.useMemo(()=>j.map(s),[j,s]),ot=J(Q),st=J(nt),at=p?q(P.map(f),ot.map(t=>t.width),0,k,16,!0):P.map((t,n)=>({index:n,position:f(t)})),V=q(j.map(T),st.map(t=>t.height),0,S,5,!1),lt=[...new Set([...V.map(t=>T(j[t.index])),8,m])];return a.jsx("div",{ref:Y,style:{height:y,width:"100%",flex:U?"1 1 auto":void 0,position:"relative"},onPointerLeave:$.onPointerLeave,children:e.length>0&&E&&a.jsxs(a.Fragment,{children:[a.jsx(xt,{tip:Z}),a.jsxs("svg",{className:"rp-activity-surface",width:k,height:S,viewBox:`0 0 ${k} ${S}`,style:{display:"block"},role:"application","aria-label":l,tabIndex:0,onFocus:$.onFocus,onBlur:$.onBlur,onKeyDown:$.onKeyDown,onPointerMove:t=>{const{x:n,y:r}=pt(t,t.currentTarget,{width:k,height:S});if(n<20||n>v||r<8||r>m){W();return}const d=ft(e.map(f),n);O(d,r)},children:[a.jsx("g",{className:"rp-area-grid",children:lt.map(t=>a.jsx("line",{x1:20,x2:v,y1:t,y2:t,stroke:C["hl-med"],strokeDasharray:"2 4",fill:"none"},t))}),a.jsx("defs",{children:o.map((t,n)=>a.jsx(mt,{id:N+n,color:t.color},t.label))}),o.map((t,n)=>a.jsx(yt,{points:e.map((r,d)=>t.values[d]==null?null:{x:f(r),y:T(t.values[d])}),baseline:T(Math.max(0,G[0])),color:t.color,id:N+n,strokeWidth:2},t.label)),i!==null&&a.jsx("path",{d:`M${f(e[i])},8L${f(e[i])},${m}`,stroke:C.subtle,strokeDasharray:"3 3",fill:"none",pointerEvents:"none"}),a.jsx("g",{children:at.map(({index:t,position:n})=>a.jsx("text",{x:n,y:m+8,className:"rp-area-tick",fill:C.subtle,textAnchor:"middle",children:a.jsx("tspan",{x:n,dy:"0.71em",children:Q[t]})},t))}),a.jsx("g",{className:"rp-area-y-ticks",children:V.map(({index:t,position:n})=>a.jsx("text",{x:v+8,y:n,className:"rp-area-tick",fill:C.subtle,textAnchor:"start",children:a.jsx("tspan",{x:v+8,dy:"0.355em",children:s(j[t])})},t))}),i!==null&&o.map(t=>t.values[i]==null?null:a.jsx("circle",{cx:f(e[i]),cy:T(t.values[i]),r:4,fill:t.color,stroke:"#fff",strokeWidth:2},t.label))]})]})})}export{wt as AreaPlot}; +import{r as u,j as a}from"./vendor-react-Bf71BWbF.js";import{u as ct,aI as it,fx as rt,fy as ut}from"./index-Bw0aJc9a.js";import{u as ht,e as dt,v as H,C as xt,f as pt,n as ft,g as J}from"./layout-BWzq8YqC.js";import{G as mt,C as yt}from"./AreaCurve-BriPYJva.js";import"./array-C0P64tl-.js";const Mt=l=>{const o=Math.pow(10,Math.floor(Math.log10(l))),e=l/o;return([1,1.2,1.5,2,2.5,3,4,5,6,8,10].find(h=>e<=h)??10)*o},gt=l=>{const o=Math.pow(10,Math.floor(Math.log10(Math.max(l,1e-9)))),e=l/o;return(e<=1?.2:e<=2?.5:e<=5?1:2)*o},I=[30,60,120,300,600,900,1800,3600,7200,21600,43200,86400].map(l=>l*1e3);function kt(l,o){const e=o-l,s=I.find(c=>e/c<=6)??I[I.length-1],h=s>=864e5?new Date(o).getTimezoneOffset()*6e4:0,y=Math.ceil((l-h)/s)*s+h,x=[];for(let c=y;c<=o;c+=s)c-l>=e*.04&&o-c>=e*.04&&x.push(c);return{ticks:x,step:s}}function Q(l){const[o,e]=u.useState([]);return u.useLayoutEffect(()=>{const s=document.createElement("span");Object.assign(s.style,{position:"absolute",top:"-20000px",whiteSpace:"pre",fontSize:"11px"}),document.body.appendChild(s),e(l.map(y=>{s.textContent=y;const{width:x,height:c}=s.getBoundingClientRect();return{width:x,height:c}})),s.remove()},[l]),o}function wt({label:l,series:o,timestamps:e,fmt:s,locale:h,height:y=150,baseline:x="zero",window:c,fill:U}){const X=ct(),C=it(),N=u.useId(),[Y,E]=rt(Math.round,120),{tip:Z,showAt:_,hide:F}=ht(),[z,$]=u.useState(null),i=z&&z.indexM!==void 0&&g!==void 0?kt(M,g):void 0,[M,g]),D=p?p.step<6e4:A<180*1e3,B=p?p.step>=864e5:A>2160*60*1e3,G=u.useMemo(()=>new Intl.DateTimeFormat(h,B?{month:"numeric",day:"numeric"}:D?{hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"}:{hour:"2-digit",minute:"2-digit",hourCycle:"h23"}),[h,D,B]),{yDomain:K,yTicks:j}=u.useMemo(()=>{const t=o.flatMap(d=>d.values.filter(w=>w!==null));let n=0,r=Mt(Math.max(1,...t)*1.08);if(x==="auto"&&t.length){const d=Math.min(...t),w=Math.max(...t),b=gt(Math.max(w-d,w*.02,1));n=Math.max(0,Math.floor(d/b)*b-b),r=Math.ceil(w/b)*b+b}return{yDomain:[n,r],yTicks:x==="auto"?[n,(n+r)/2,r]:[r/2,r]}},[o,x]),P=u.useMemo(()=>{const t=e.length-1;return p?p.ticks:[...new Set((D?[0,Math.round(t/2),t]:[0,Math.round(t/3),Math.round(2*t/3),t]).map(n=>e[n]))]},[p,D,e]),O=u.useMemo(()=>M!==void 0&&g!==void 0?[M,g]:[Math.min(...e),Math.max(...e)],[M,g,e]),k=E?.width??0,S=E?.height??y,m=S-30,v=k-64,tt=[Math.min(O[0],...e),Math.max(O[1],...e)],f=t=>J(t,tt,[20,v]),T=t=>J(t,K,[m,8]),et={x:20,y:8,width:v-20,height:m-8},R=(t,n)=>$({index:t,y:n}),W=()=>{$(null),F()};u.useLayoutEffect(()=>{if(i===null){F();return}if(!o.some(t=>t.values[i]!=null)){F();return}_({x:f(e[i]),y:z?.y??(8+m)/2,width:k,bounds:et,label:ut(h).format(e[i]),lines:o.filter(t=>t.values[i]!=null).sort((t,n)=>t.labeln.label?1:0).map(t=>X("ui.valuePair",{label:t.label,value:s(t.values[i])}))})});const L=dt(e.length,R,W),V=u.useMemo(()=>P.map(t=>G.format(t)),[P,G]),nt=u.useMemo(()=>j.map(s),[j,s]),ot=Q(V),st=Q(nt),at=p?H(P.map(f),ot.map(t=>t.width),0,k,16,!0):P.map((t,n)=>({index:n,position:f(t)})),q=H(j.map(T),st.map(t=>t.height),0,S,5,!1),lt=[...new Set([...q.map(t=>T(j[t.index])),8,m])];return a.jsx("div",{ref:Y,style:{height:y,width:"100%",flex:U?"1 1 auto":void 0,position:"relative"},onPointerLeave:L.onPointerLeave,children:e.length>0&&E&&a.jsxs(a.Fragment,{children:[a.jsx(xt,{tip:Z}),a.jsxs("svg",{className:"rp-activity-surface",width:k,height:S,viewBox:`0 0 ${k} ${S}`,style:{display:"block"},role:"application","aria-label":l,tabIndex:0,onFocus:L.onFocus,onBlur:L.onBlur,onKeyDown:L.onKeyDown,onPointerMove:t=>{const{x:n,y:r}=pt(t,t.currentTarget,{width:k,height:S});if(n<20||n>v||r<8||r>m){W();return}const d=ft(e.map(f),n);R(d,r)},children:[a.jsx("g",{className:"rp-area-grid",children:lt.map(t=>a.jsx("line",{x1:20,x2:v,y1:t,y2:t,stroke:C["hl-med"],strokeDasharray:"2 4",fill:"none"},t))}),a.jsx("defs",{children:o.map((t,n)=>a.jsx(mt,{id:N+n,color:t.color},t.label))}),o.map((t,n)=>a.jsx(yt,{points:e.map((r,d)=>t.values[d]==null?null:{x:f(r),y:T(t.values[d])}),baseline:T(Math.max(0,K[0])),color:t.color,id:N+n,strokeWidth:2},t.label)),i!==null&&a.jsx("path",{d:`M${f(e[i])},8L${f(e[i])},${m}`,stroke:C.subtle,strokeDasharray:"3 3",fill:"none",pointerEvents:"none"}),a.jsx("g",{children:at.map(({index:t,position:n})=>a.jsx("text",{x:n,y:m+8,className:"rp-area-tick",fill:C.subtle,textAnchor:"middle",children:a.jsx("tspan",{x:n,dy:"0.71em",children:V[t]})},t))}),a.jsx("g",{className:"rp-area-y-ticks",children:q.map(({index:t,position:n})=>a.jsx("text",{x:v+8,y:n,className:"rp-area-tick",fill:C.subtle,textAnchor:"start",children:a.jsx("tspan",{x:v+8,dy:"0.355em",children:s(j[t])})},t))}),i!==null&&o.map(t=>t.values[i]==null?null:a.jsx("circle",{cx:f(e[i]),cy:T(t.values[i]),r:4,fill:t.color,stroke:"#fff",strokeWidth:2},t.label))]})]})})}export{wt as AreaPlot}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Arrange-BvqJLS4m.js b/luci-app-honk/root/etc/honk/doona/assets/Arrange-BvqJLS4m.js deleted file mode 100644 index fe132fa8d..000000000 --- a/luci-app-honk/root/etc/honk/doona/assets/Arrange-BvqJLS4m.js +++ /dev/null @@ -1,4 +0,0 @@ -import{r as x,$ as _,a as St,j as f}from"./vendor-react-Bf71BWbF.js";import{eD as Pt,eW as Bt,ex as ae,bX as H,bV as M,eX as Qe,eY as et,eZ as It,bP as Re,eu as F,ev as re,ew as Be,eg as N,eJ as tt,e_ as At,e$ as Ot,f0 as Mt,bM as jt,bY as Nt,c3 as Rt,f1 as Lt,c5 as Vt,c6 as Ht,bK as Gt,eB as zt,c8 as Xt,bH as Yt,ca as Ut,cc as qt,c9 as _t,f2 as Wt,f3 as Jt,bI as ke,aM as Zt,eN as Qt,eK as er,bU as tr,f4 as rt,f5 as nt,f6 as oe,bJ as rr,bF as at,ef as nr,c as Ie,K as Ke,f7 as Le,di as ot,f8 as Ve,f9 as He,dn as it,u as W,a8 as ar,ab as or,aa as Ge,ad as ir,cE as lr,dK as sr,b as ur,be as ze,E as dr,j as cr,I as Q,ai as lt,B as L,de as Xe,af as st,T as ut,a as dt,aK as Ye,aF as pr,bB as fr,a2 as de,L as gr,h as yr,bC as mr,aJ as hr,b4 as Dr,eO as br,eP as $r,fa as vr,aH as Er,bn as xr,ah as ct,cK as wr}from"./index-BNBwb-FJ.js";import{$ as Tr,a as kr}from"./Policies-DiLR7S4N.js";import{d as Kr}from"./Virtualizer-DipGMcji.js";import{$ as Cr}from"./ListLayout-F74Z1Dpf.js";import{D as pt}from"./DaeCode-B8yPDjSE.js";import{b as Fr,g as Sr}from"./policyText-CmeXgUK2.js";import{P as Pr}from"./PolicyPicker-BmHzmXzJ.js";import{$ as Br}from"./useFilter-jz02VVEB.js";import"./useGridSelectionCheckbox-CrCOlZv8.js";var P=(function(e){return e[e.none=0]="none",e[e.cancel=0]="cancel",e[e.move=1]="move",e[e.copy=2]="copy",e[e.link=4]="link",e[e.all=7]="all",e})({});const ft={...P,copyMove:3,copyLink:6,linkMove:5,all:7,uninitialized:7},gt=yt(ft);gt[7]="all";const ee={none:"cancel",link:"link",copy:"copy",move:"move"},De=yt(ee);function yt(e){let t={};for(let r in e)t[e[r]]=r;return t}const Ir=new Set(["text/plain","text/uri-list","text/html"]),fe="application/vnd.react-aria.items+json",ge="application/octet-stream",Ae=new WeakMap,mt=Symbol();function Ar(e){let{id:t}=Ae.get(e)||{};if(!t)throw new Error("Droppable item outside a droppable collection");return t}function Or(e){let{ref:t}=Ae.get(e)||{};if(!t)throw new Error("Droppable item outside a droppable collection");return t}function z(e){let t=new Set;for(let r of e)for(let n of Object.keys(r))t.add(n);return t}function ht(e){return e||(e="virtual"),e==="pointer"&&(e="virtual"),e==="virtual"&&typeof window<"u"&&typeof window.matchMedia=="function"&&window.matchMedia("(pointer: coarse)").matches&&(e="touch"),e}function Oe(){return ht(Pt())}function Dt(){return ht(Bt())}function Ce(e,t){let r=new Map,n=!1,a=[];for(let o of t){let y=Object.keys(o);y.length>1&&(n=!0);let c={};for(let D of y){let v=r.get(D);v?n=!0:(v=[],r.set(D,v));let g=o[D];c[D]=g,v.push(g)}a.push(c)}for(let[o,y]of r)if(Ir.has(o)){let c=y.join(` -`);e.items.add(c,o)}else e.items.add(y[0],o);if(n){let o=JSON.stringify(a);e.items.add(o,fe)}}class ie{constructor(t){this.types=new Set;let r=!1;for(let n of t.items)n.type!==fe&&(n.kind==="file"&&(r=!0),n.type?this.types.add(n.type):this.types.add(ge));this.includesUnknownTypes=!r&&t.types.includes("Files")}has(t){if(Array.isArray(t))return t.some(r=>this.has(r));if(this.includesUnknownTypes||t===mt&&this.types.has(ge)||t==="*/*")return!0;if(typeof t=="string"){if(t.endsWith("/*")){for(let r of this.types)if(r.startsWith(t.slice(0,-2)))return!0;return!1}return this.types.has(t)}return!1}}function bt(e){let t=[];if(!e)return t;let r=!1;if(e.types.includes(fe))try{let n=e.getData(fe),a=JSON.parse(n);for(let o of a)t.push({kind:"text",types:new Set(Object.keys(o)),getText:y=>Promise.resolve(o[y])});r=!0}catch{}if(!r){let n=new Map;for(let a of e.items)if(a.kind==="string")n.set(a.type||ge,e.getData(a.type));else if(a.kind==="file")if(typeof a.webkitGetAsEntry=="function"){let o=a.webkitGetAsEntry();if(!o)continue;o.isFile?t.push(Fe(a.getAsFile())):o.isDirectory&&t.push($t(o))}else t.push(Fe(a.getAsFile()));n.size>0&&t.push({kind:"text",types:new Set(n.keys()),getText:a=>Promise.resolve(n.get(a))})}return t}function Mr(e){return typeof e.text=="function"?e.text():new Promise((t,r)=>{let n=new FileReader;n.onload=()=>{t(n.result)},n.onerror=r,n.readAsText(e)})}function Fe(e){if(!e)throw new Error("No file provided");return{kind:"file",type:e.type||ge,name:e.name,getText:()=>Mr(e),getFile:()=>Promise.resolve(e)}}function $t(e){return{kind:"directory",name:e.name,getEntries:()=>jr(e)}}async function*jr(e){let t=e.createReader(),r;do{r=await new Promise((n,a)=>{t.readEntries(n,a)});for(let n of r)if(n.isFile){let a=await Nr(n);yield Fe(a)}else n.isDirectory&&(yield $t(n))}while(r.length>0)}function Nr(e){return new Promise((t,r)=>e.file(t,r))}function Rr(e){return e.kind==="text"}let B={draggingKeys:new Set};function Lr(e){B.draggingCollectionRef=e}function Vr(e){B.draggingKeys=e}function U(e){B.dropCollectionRef=e}function vt(){B={draggingKeys:new Set}}function Hr(e){B=e}function V(e){let{draggingCollectionRef:t,dropCollectionRef:r}=B;return t?.current!=null&&t.current===(e?.current||r?.current)}let ce;function ye(e){ce=e}let Se=P.none;function be(e){Se=e}let Pe=new Map,te=new Map,R=null,me=new Set;function Et(e){return Pe.set(e.element,e),R?.updateValidDropTargets(),()=>{Pe.delete(e.element),R?.updateValidDropTargets()}}function Gr(e){return te.set(e.element,e),()=>{te.delete(e.element)}}function zr(e,t){if(R)throw new Error("Cannot begin dragging while already dragging");R=new _r(e,t),requestAnimationFrame(()=>{R&&(R.setup(),Dt()==="keyboard"&&R.next())});for(let r of me)r()}function Me(){let[e,t]=x.useState(R);return x.useEffect(()=>{let r=()=>t(R);return me.add(r),()=>{me.delete(r)}},[]),e}function Xr(){return!!R}function Yr(){R=null;for(let e of me)e()}const Ue=["pointerdown","pointermove","pointerenter","pointerleave","pointerover","pointerout","pointerup","mousedown","mousemove","mouseenter","mouseleave","mouseover","mouseout","mouseup","touchstart","touchmove","touchend","focusin","focusout"],Ur=["pointerup","mouseup","touchend"],qr={keyboard:"dragStartedKeyboard",touch:"dragStartedTouch",virtual:"dragStartedVirtual"};class _r{constructor(t,r){this.validDropTargets=[],this.currentDropTarget=null,this.currentDropItem=null,this.dropOperation=null,this.mutationObserver=null,this.restoreAriaHidden=null,this.isVirtualClick=!1,this.dragTarget=t,this.stringFormatter=r,this.onKeyDown=this.onKeyDown.bind(this),this.onKeyUp=this.onKeyUp.bind(this),this.onFocus=this.onFocus.bind(this),this.onBlur=this.onBlur.bind(this),this.onClick=this.onClick.bind(this),this.onPointerDown=this.onPointerDown.bind(this),this.cancelEvent=this.cancelEvent.bind(this),this.initialFocused=!1}setup(){document.addEventListener("keydown",this.onKeyDown,!0),document.addEventListener("keyup",this.onKeyUp,!0),window.addEventListener("focus",this.onFocus,!0),window.addEventListener("blur",this.onBlur,!0),document.addEventListener("click",this.onClick,!0),document.addEventListener("pointerdown",this.onPointerDown,!0);for(let t of Ue)document.addEventListener(t,this.cancelEvent,!0);this.mutationObserver=new MutationObserver(()=>this.updateValidDropTargets()),this.updateValidDropTargets(),ae(this.stringFormatter.format(qr[Dt()]))}teardown(){document.removeEventListener("keydown",this.onKeyDown,!0),document.removeEventListener("keyup",this.onKeyUp,!0),window.removeEventListener("focus",this.onFocus,!0),window.removeEventListener("blur",this.onBlur,!0),document.removeEventListener("click",this.onClick,!0),document.removeEventListener("pointerdown",this.onPointerDown,!0);for(let t of Ue)document.removeEventListener(t,this.cancelEvent,!0);this.mutationObserver?.disconnect(),this.restoreAriaHidden?.()}onKeyDown(t){if(this.cancelEvent(t),t.key==="Escape"){this.cancel();return}t.key==="Tab"&&!(t.metaKey||t.altKey||t.ctrlKey)&&(t.shiftKey?this.previous():this.next()),typeof this.currentDropTarget?.onKeyDown=="function"&&this.currentDropTarget.onKeyDown(t,this.dragTarget)}onKeyUp(t){this.cancelEvent(t),t.key==="Enter"&&(t.altKey||H(this.getCurrentActivateButton(),M(t))?this.activate(this.currentDropTarget,this.currentDropItem):this.drop())}getCurrentActivateButton(){return this.currentDropItem?.activateButtonRef?.current??this.currentDropTarget?.activateButtonRef?.current??null}onFocus(t){let r=this.getCurrentActivateButton(),n=M(t);if(n===r){this.cancelEvent(t);return}if(n!==this.dragTarget.element&&this.cancelEvent(t),!(n instanceof HTMLElement)||n===this.dragTarget.element)return;let a=this.validDropTargets.find(y=>y.element===n)||this.validDropTargets.find(y=>H(y.element,n));if(!a){this.currentDropTarget?this.currentDropTarget.element.focus():this.dragTarget.element.focus();return}let o=te.get(n);a&&this.setCurrentDropTarget(a,o)}onBlur(t){let r=this.getCurrentActivateButton();if(r&&t.relatedTarget===r){this.cancelEvent(t);return}M(t)!==this.dragTarget.element&&this.cancelEvent(t),(!t.relatedTarget||!(t.relatedTarget instanceof HTMLElement))&&(this.currentDropTarget?this.currentDropTarget.element.focus():this.dragTarget.element.focus())}onClick(t){if(this.cancelEvent(t),Qe(t)||this.isVirtualClick){let r=te.values(),n=M(t),a=[...r].find(c=>c.element===n||H(c.activateButtonRef?.current,n)),o=this.validDropTargets.find(c=>H(c.element,n)),y=a?.activateButtonRef?.current??o?.activateButtonRef?.current;if(H(y,n)&&o){this.activate(o,a);return}if(M(t)===this.dragTarget.element){this.cancel();return}o&&(this.setCurrentDropTarget(o,a),this.drop(a))}}onPointerDown(t){this.cancelEvent(t),this.isVirtualClick=et(t)}cancelEvent(t){let r=M(t);(t.type==="focusin"||t.type==="focusout")&&(r===this.dragTarget?.element||r===this.getCurrentActivateButton())||(Ur.includes(t.type)||t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation())}updateValidDropTargets(){if(!this.mutationObserver)return;if(this.mutationObserver.disconnect(),this.restoreAriaHidden&&this.restoreAriaHidden(),this.validDropTargets=Wr(this.dragTarget),this.validDropTargets.length>0){let a=this.findNearestDropTarget();this.validDropTargets=[...this.validDropTargets.slice(a),...this.validDropTargets.slice(0,a)]}this.currentDropTarget&&!this.validDropTargets.includes(this.currentDropTarget)&&this.setCurrentDropTarget(this.validDropTargets[0]);let t=z(this.dragTarget.items),r=[...te.values()].filter(a=>typeof a.getDropOperation=="function"?a.getDropOperation(t,this.dragTarget.allowedDropOperations)!=="cancel":!0),n=this.validDropTargets.filter(a=>!r.some(o=>H(a.element,o.element)));this.restoreAriaHidden=It([this.dragTarget.element,...r.flatMap(a=>a.activateButtonRef?.current?[a.element,a.activateButtonRef?.current]:[a.element]),...n.flatMap(a=>a.activateButtonRef?.current?[a.element,a.activateButtonRef?.current]:[a.element])],{shouldUseInert:!0}),this.mutationObserver.observe(document.body,{subtree:!0,attributes:!0,attributeFilter:["aria-hidden","inert"]})}next(){if(!this.currentDropTarget){this.setCurrentDropTarget(this.validDropTargets[0]);return}let t=this.validDropTargets.indexOf(this.currentDropTarget);if(t<0){this.setCurrentDropTarget(this.validDropTargets[0]);return}t===this.validDropTargets.length-1?this.dragTarget.element.closest('[aria-hidden="true"], [inert]')?this.setCurrentDropTarget(this.validDropTargets[0]):(this.setCurrentDropTarget(null),this.dragTarget.element.focus()):this.setCurrentDropTarget(this.validDropTargets[t+1])}previous(){if(!this.currentDropTarget){this.setCurrentDropTarget(this.validDropTargets[this.validDropTargets.length-1]);return}let t=this.validDropTargets.indexOf(this.currentDropTarget);if(t<0){this.setCurrentDropTarget(this.validDropTargets[this.validDropTargets.length-1]);return}t===0?this.dragTarget.element.closest('[aria-hidden="true"], [inert]')?this.setCurrentDropTarget(this.validDropTargets[this.validDropTargets.length-1]):(this.setCurrentDropTarget(null),this.dragTarget.element.focus()):this.setCurrentDropTarget(this.validDropTargets[t-1])}findNearestDropTarget(){let t=this.dragTarget.element.getBoundingClientRect(),r=1/0,n=-1,a=-1;for(let o=0;o=0?a:n}setCurrentDropTarget(t,r){if(t!==this.currentDropTarget){if(this.currentDropTarget&&typeof this.currentDropTarget.onDropExit=="function"){let n=this.currentDropTarget.element.getBoundingClientRect();this.currentDropTarget.onDropExit({type:"dropexit",x:n.left+n.width/2,y:n.top+n.height/2})}if(this.currentDropTarget=t,t){if(typeof t.onDropEnter=="function"){let n=t.element.getBoundingClientRect();t.onDropEnter({type:"dropenter",x:n.left+n.width/2,y:n.top+n.height/2},this.dragTarget)}r||t?.element.focus()}}if(r!=null&&r!==this.currentDropItem&&(this.currentDropTarget&&typeof this.currentDropTarget.onDropTargetEnter=="function"&&this.currentDropTarget.onDropTargetEnter(r.target),r.element.focus(),this.currentDropItem=r,!this.initialFocused)){let n=r?.element.getAttribute("aria-label");n&&ae(n,"polite"),this.initialFocused=!0}}end(){if(this.teardown(),Yr(),typeof this.dragTarget.onDragEnd=="function"){let r=(this.currentDropTarget&&this.dropOperation!=="cancel"?this.currentDropTarget:this.dragTarget).element.getBoundingClientRect();this.dragTarget.onDragEnd({type:"dragend",x:r.x+r.width/2,y:r.y+r.height/2,dropOperation:this.dropOperation||"cancel"})}this.currentDropTarget&&!this.currentDropTarget.preventFocusOnDrop&&Re()?.dispatchEvent(new FocusEvent("focusin",{bubbles:!0})),this.setCurrentDropTarget(null)}cancel(){this.setCurrentDropTarget(null),this.end(),this.dragTarget.element.closest('[aria-hidden="true"], [inert]')||this.dragTarget.element.focus(),Re()?.dispatchEvent(new FocusEvent("focusin",{bubbles:!0})),ae(this.stringFormatter.format("dropCanceled"))}drop(t){if(!this.currentDropTarget){this.cancel();return}if(typeof t?.getDropOperation=="function"){let r=z(this.dragTarget.items);this.dropOperation=t.getDropOperation(r,this.dragTarget.allowedDropOperations)}else if(typeof this.currentDropTarget.getDropOperation=="function"){let r=z(this.dragTarget.items);this.dropOperation=this.currentDropTarget.getDropOperation(r,this.dragTarget.allowedDropOperations)}else this.dropOperation=this.dragTarget.allowedDropOperations[0];if(typeof this.currentDropTarget.onDrop=="function"){let r=this.dragTarget.items.map(a=>({kind:"text",types:new Set(Object.keys(a)),getText:o=>Promise.resolve(a[o])})),n=this.currentDropTarget.element.getBoundingClientRect();this.currentDropTarget.onDrop({type:"drop",x:n.left+n.width/2,y:n.top+n.height/2,items:r,dropOperation:this.dropOperation},t?.target??null)}this.end(),ae(this.stringFormatter.format("dropComplete"))}activate(t,r){if(t&&typeof t.onDropActivate=="function"){let n=r?.target??null,a=t.element.getBoundingClientRect();t.onDropActivate({type:"dropactivate",x:a.left+a.width/2,y:a.top+a.height/2},n)}}}function Wr(e){let t=z(e.items);return[...Pe.values()].filter(r=>r.element.closest('[aria-hidden="true"], [inert]')?!1:typeof r.getDropOperation=="function"?r.getDropOperation(t,e.allowedDropOperations)!=="cancel":!0)}var xt={};xt={dragItem:e=>`Drag ${e.itemText}`,dragSelectedItems:(e,t)=>`Drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}`,dragDescriptionKeyboard:"Press Enter to start dragging.",dragDescriptionKeyboardAlt:"Press Alt + Enter to start dragging.",dragDescriptionTouch:"Double tap to start dragging.",dragDescriptionVirtual:"Click to start dragging.",dragDescriptionLongPress:"Long press to start dragging.",dragSelectedKeyboard:(e,t)=>`Press Enter to drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}.`,dragSelectedKeyboardAlt:(e,t)=>`Press Alt + Enter to drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}.`,dragSelectedLongPress:(e,t)=>`Long press to drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}.`,dragStartedKeyboard:"Started dragging. Press Tab to navigate to a drop target, then press Enter to drop, or press Escape to cancel.",dragStartedTouch:"Started dragging. Navigate to a drop target, then double tap to drop.",dragStartedVirtual:"Started dragging. Navigate to a drop target, then click or press Enter to drop.",endDragKeyboard:"Dragging. Press Enter to cancel drag.",endDragTouch:"Dragging. Double tap to cancel drag.",endDragVirtual:"Dragging. Click to cancel drag.",dropDescriptionKeyboard:"Press Enter to drop. Press Escape to cancel drag.",dropDescriptionTouch:"Double tap to drop.",dropDescriptionVirtual:"Click to drop.",dropCanceled:"Drop canceled.",dropComplete:"Drop complete.",dropIndicator:"drop indicator",dropOnRoot:"Drop on",dropOnItem:e=>`Drop on ${e.itemText}`,insertBefore:e=>`Insert before ${e.itemText}`,insertBetween:e=>`Insert between ${e.beforeItemText} and ${e.afterItemText}`,insertAfter:e=>`Insert after ${e.itemText}`};var wt={};wt={dragDescriptionKeyboard:"按 Enter 开始拖动。",dragDescriptionKeyboardAlt:"按 Alt + Enter 开始拖动。",dragDescriptionLongPress:"长按以开始拖动。",dragDescriptionTouch:"双击开始拖动。",dragDescriptionVirtual:"单击开始拖动。",dragItem:e=>`拖动 ${e.itemText}`,dragSelectedItems:(e,t)=>`拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 选中项目`,other:()=>`${t.number(e.count)} 选中项目`})}`,dragSelectedKeyboard:(e,t)=>`按 Enter 以拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 个选定项`,other:()=>`${t.number(e.count)} 个选定项`})}。`,dragSelectedKeyboardAlt:(e,t)=>`按 Alt + Enter 以拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 个选定项`,other:()=>`${t.number(e.count)} 个选定项`})}。`,dragSelectedLongPress:(e,t)=>`长按以拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 个选定项`,other:()=>`${t.number(e.count)} 个选定项`})}。`,dragStartedKeyboard:"已开始拖动。按 Tab 导航到放置目标,然后按 Enter 放置或按 Escape 取消。",dragStartedTouch:"已开始拖动。导航到放置目标,然后双击放置。",dragStartedVirtual:"已开始拖动。导航到放置目标,然后单击或按 Enter 放置。",dropCanceled:"放置已取消。",dropComplete:"放置已完成。",dropDescriptionKeyboard:"按 Enter 放置。按 Escape 取消拖动。",dropDescriptionTouch:"双击放置。",dropDescriptionVirtual:"单击放置。",dropIndicator:"放置标记",dropOnItem:e=>`放置于 ${e.itemText}`,dropOnRoot:"放置于",endDragKeyboard:"正在拖动。按 Enter 取消拖动。",endDragTouch:"正在拖动。双击取消拖动。",endDragVirtual:"正在拖动。单击取消拖动。",insertAfter:e=>`插入到 ${e.itemText} 之后`,insertBefore:e=>`插入到 ${e.itemText} 之前`,insertBetween:e=>`插入到 ${e.beforeItemText} 和 ${e.afterItemText} 之间`};var Tt={};Tt={dragDescriptionKeyboard:"按 Enter 鍵以開始拖曳。",dragDescriptionKeyboardAlt:"按 Alt+Enter 鍵以開始拖曳。",dragDescriptionLongPress:"長按以開始拖曳。",dragDescriptionTouch:"輕點兩下以開始拖曳。",dragDescriptionVirtual:"按一下滑鼠以開始拖曳。",dragItem:e=>`拖曳「${e.itemText}」`,dragSelectedItems:(e,t)=>`拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}`,dragSelectedKeyboard:(e,t)=>`按 Enter 鍵以拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}。`,dragSelectedKeyboardAlt:(e,t)=>`按 Alt+Enter 鍵以拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}。`,dragSelectedLongPress:(e,t)=>`長按以拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}。`,dragStartedKeyboard:"已開始拖曳。按 Tab 鍵以瀏覽至放置目標,然後按 Enter 鍵以放置,或按 Escape 鍵以取消。",dragStartedTouch:"已開始拖曳。瀏覽至放置目標,然後輕點兩下以放置。",dragStartedVirtual:"已開始拖曳。瀏覽至放置目標,然後按一下滑鼠或按 Enter 鍵以放置。",dropCanceled:"放置已取消。",dropComplete:"放置已完成。",dropDescriptionKeyboard:"按 Enter 鍵以放置。按 Escape 鍵以取消拖曳。",dropDescriptionTouch:"輕點兩下以放置。",dropDescriptionVirtual:"按一下滑鼠以放置。",dropIndicator:"放置指示器",dropOnItem:e=>`放置在「${e.itemText}」上`,dropOnRoot:"放置在",endDragKeyboard:"拖曳中。按 Enter 鍵以取消拖曳。",endDragTouch:"拖曳中。輕點兩下以取消拖曳。",endDragVirtual:"拖曳中。按一下滑鼠以取消拖曳。",insertAfter:e=>`插入至「${e.itemText}」之後`,insertBefore:e=>`插入至「${e.itemText}」之前`,insertBetween:e=>`插入至「${e.beforeItemText}」和「${e.afterItemText}」之間`};var ne={};ne={"ar-AE":F,"bg-BG":F,"cs-CZ":F,"da-DK":F,"de-DE":F,"el-GR":F,"en-US":xt,"es-ES":F,"et-EE":F,"fi-FI":F,"fr-FR":F,"he-IL":F,"hr-HR":F,"hu-HU":F,"it-IT":F,"ja-JP":F,"ko-KR":F,"lt-LT":F,"lv-LV":F,"nb-NO":F,"nl-NL":F,"pl-PL":F,"pt-BR":F,"pt-PT":F,"ro-RO":F,"ru-RU":F,"sk-SK":F,"sl-SI":F,"sr-SP":F,"sv-SE":F,"tr-TR":F,"uk-UA":F,"zh-CN":wt,"zh-TW":Tt};function Jr(e){return e&&e.__esModule?e.default:e}const Zr={keyboard:"dropDescriptionKeyboard",touch:"dropDescriptionTouch",virtual:"dropDescriptionVirtual"};function kt(){let e=re(Jr(ne),"@react-aria/dnd"),t=Oe(),r=Me();return{dropProps:{...Be(r?e.format(Zr[t]):""),onClick:()=>{}}}}const Qr=800;function Kt(e){let{hasDropButton:t,isDisabled:r}=e,[n,a]=x.useState(!1),o=x.useRef({x:0,y:0,dragOverElements:new Set,dropEffect:"none",allowedOperations:P.all,dropActivateTimer:void 0}).current,y=i=>{if(a(!0),typeof e.onDropEnter=="function"){let s=i.currentTarget.getBoundingClientRect();e.onDropEnter({type:"dropenter",x:i.clientX-s.x,y:i.clientY-s.y})}},c=i=>{if(a(!1),typeof e.onDropExit=="function"){let s=i.currentTarget.getBoundingClientRect();e.onDropExit({type:"dropexit",x:i.clientX-s.x,y:i.clientY-s.y})}},D=i=>{i.preventDefault(),i.stopPropagation();let s=qe(i);if(i.clientX===o.x&&i.clientY===o.y&&s===o.allowedOperations){i.dataTransfer.dropEffect=o.dropEffect;return}o.x=i.clientX,o.y=i.clientY;let u=o.dropEffect;if(s!==o.allowedOperations){let h=$e(s),w=h[0];if(typeof e.getDropOperation=="function"){let k=new ie(i.dataTransfer);w=le(s,e.getDropOperation(k,h))}o.dropEffect=De[w]||"none"}if(typeof e.getDropOperationForPoint=="function"){let h=new ie(i.dataTransfer),w=i.currentTarget.getBoundingClientRect(),k=le(s,e.getDropOperationForPoint(h,$e(s),o.x-w.x,o.y-w.y));o.dropEffect=De[k]||"none"}if(o.allowedOperations=s,i.dataTransfer.dropEffect=o.dropEffect,o.dropEffect==="none"&&u!=="none"?c(i):o.dropEffect!=="none"&&u==="none"&&y(i),typeof e.onDropMove=="function"&&o.dropEffect!=="none"){let h=i.currentTarget.getBoundingClientRect();e.onDropMove({type:"dropmove",x:o.x-h.x,y:o.y-h.y})}if(clearTimeout(o.dropActivateTimer),e.onDropActivate&&typeof e.onDropActivate=="function"&&o.dropEffect!=="none"){let h=e.onDropActivate,w=i.currentTarget.getBoundingClientRect();o.dropActivateTimer=setTimeout(()=>{h({type:"dropactivate",x:o.x-w.x,y:o.y-w.y})},Qr)}},v=i=>{if(i.preventDefault(),i.stopPropagation(),o.dragOverElements.add(M(i)),o.dragOverElements.size>1)return;let s=qe(i),u=$e(s),h=u[0];if(typeof e.getDropOperation=="function"){let w=new ie(i.dataTransfer);h=le(s,e.getDropOperation(w,u))}if(typeof e.getDropOperationForPoint=="function"){let w=new ie(i.dataTransfer),k=i.currentTarget.getBoundingClientRect();h=le(s,e.getDropOperationForPoint(w,u,i.clientX-k.x,i.clientY-k.y))}o.x=i.clientX,o.y=i.clientY,o.allowedOperations=s,o.dropEffect=De[h]||"none",i.dataTransfer.dropEffect=o.dropEffect,h!=="cancel"&&y(i)},g=i=>{i.preventDefault(),i.stopPropagation();let s=M(i);if(o.dragOverElements.delete(s),s===i.currentTarget)for(let u of o.dragOverElements)H(i.currentTarget,u)||o.dragOverElements.delete(u);o.dragOverElements.size>0||(o.dropEffect!=="none"&&c(i),clearTimeout(o.dropActivateTimer))},$=i=>{if(i.preventDefault(),i.stopPropagation(),ye(o.dropEffect),typeof e.onDrop=="function"){let u=ee[o.dropEffect],h=bt(i.dataTransfer),w=i.currentTarget.getBoundingClientRect(),k={type:"drop",x:i.clientX-w.x,y:i.clientY-w.y,items:h,dropOperation:u};e.onDrop(k)}let s={...B};o.dragOverElements.clear(),c(i),clearTimeout(o.dropActivateTimer),s.draggingCollectionRef==null?ye(void 0):Hr(s)},l=N(i=>{typeof e.onDropEnter=="function"&&e.onDropEnter(i)}),d=N(i=>{typeof e.onDropExit=="function"&&e.onDropExit(i)}),p=N(i=>{typeof e.onDropActivate=="function"&&e.onDropActivate(i)}),b=N(i=>{typeof e.onDrop=="function"&&e.onDrop(i)}),m=N((i,s)=>e.getDropOperation?e.getDropOperation(i,s):s[0]),{ref:E}=e;tt(()=>{if(!(r||!E.current))return Et({element:E.current,getDropOperation:m,onDropEnter(i){a(!0),l(i)},onDropExit(i){a(!1),d(i)},onDrop:b,onDropActivate:p})},[r,E]);let{dropProps:T}=kt();return r?{dropProps:{},dropButtonProps:{isDisabled:!0},isDropTarget:!1}:{dropProps:{...!t&&T,onDragEnter:v,onDragOver:D,onDragLeave:g,onDrop:$},dropButtonProps:{...t&&T},isDropTarget:n}}function qe(e){let t=ft[e.dataTransfer.effectAllowed];Se&&(t&=Se);let r=P.none;return At()?(e.altKey&&(r|=P.copy),e.ctrlKey&&!Ot()&&(r|=P.link),e.metaKey&&(r|=P.move)):(e.altKey&&(r|=P.link),e.shiftKey&&(r|=P.move),e.ctrlKey&&(r|=P.copy)),r?t&r:t}function $e(e){let t=[];return e&P.move&&t.push("move"),e&P.copy&&t.push("copy"),e&P.link&&t.push("link"),t}function le(e,t){let r=P[t];return e&r?t:"cancel"}const ve=new Map;function q(e,t){let r=ve.get(e);if(!r){let n=new Set,a=o=>{for(let y of n)y(o)};r={listener:a,handlers:n},ve.set(e,r),document.addEventListener(e,a)}return r.handlers.add(t),()=>{r.handlers.delete(t),r.handlers.size===0&&(document.removeEventListener(e,r.listener),ve.delete(e))}}function en(e){let{isDisabled:t}=e,r=x.useRef(!1),{focusProps:n}=Mt({onFocusChange:g=>{r.current=g}}),a=N(g=>{r.current&&e.getItems&&g.preventDefault()}),o=N(g=>{!r.current||!e.getItems||(g.preventDefault(),g.clipboardData&&(Ce(g.clipboardData,e.getItems({action:"copy"})),e.onCopy?.()))}),y=N(g=>{r.current&&e.onCut&&e.getItems&&g.preventDefault()}),c=N(g=>{!r.current||!e.onCut||!e.getItems||(g.preventDefault(),g.clipboardData&&(Ce(g.clipboardData,e.getItems({action:"cut"})),e.onCut()))}),D=N(g=>{r.current&&e.onPaste&&g.preventDefault()}),v=N(g=>{if(!(!r.current||!e.onPaste)&&(g.preventDefault(),g.clipboardData)){let $=bt(g.clipboardData);e.onPaste($)}});return x.useEffect(()=>{if(!t)return jt(q("beforecopy",a),q("copy",o),q("beforecut",y),q("cut",c),q("beforepaste",D),q("paste",v))},[t]),{clipboardProps:n}}function tn(e){return e&&e.__esModule?e.default:e}const rn=x.createContext(null),nn=x.forwardRef(function(t,r){let{isDisabled:n=!1}=t;[t,r]=Nt(t,r,rn);let a=Rt(r),o=x.useRef(null),{dropProps:y,dropButtonProps:c,isDropTarget:D}=Kt({...t,ref:o,hasDropButton:!0}),{buttonProps:v}=Lt(c||{},o),{hoverProps:g,isHovered:$}=Vt(t),{focusProps:l,isFocused:d,isFocusVisible:p}=Ht(),b=re(tn(Qt),"react-aria-components"),m=Gt(),E=t["aria-label"]||b.format("dropzoneLabel"),T=t["aria-labelledby"],i=[m,T].filter(Boolean).join(" "),s=zt({"aria-label":E,"aria-labelledby":i}),{clipboardProps:u}=en({isDisabled:n,onPaste:k=>t.onDrop?.({type:"drop",items:k,x:0,y:0,dropOperation:"copy"})}),h=Xt({...t,values:{isHovered:$,isFocused:d,isFocusVisible:p,isDropTarget:D,isDisabled:n},defaultClassName:"react-aria-DropZone"}),w=Yt(t,{global:!0});return delete w.id,_.createElement(Ut,{values:[[qt,{id:m,slot:"label"}]]},_.createElement(_t.div,{...ke(w,h,y,g),slot:t.slot||void 0,ref:a,onClick:k=>{let C=M(k);for(;C&&H(a.current,C)&&!Wt(C);){if(C===a.current&&o.current){Jt(o.current);break}C=C.parentElement}},"data-hovered":$||void 0,"data-focused":d||void 0,"data-focus-visible":p||void 0,"data-drop-target":D||void 0,"data-disabled":n||void 0},_.createElement(Zt,null,_.createElement("button",{...ke(v,l,u,s),ref:o})),h.children))});function an(e,t,r,n,a=!1,o=!1){switch(n){case"left":return a?Ee(e,t,r,o,"left"):xe(e,t,r,o,"left");case"right":return a?xe(e,t,r,o,"right"):Ee(e,t,r,o,"right");case"up":return xe(e,t,r,o);case"down":return Ee(e,t,r,o)}}function Ee(e,t,r,n=!1,a=null){if(!r)return{type:"root"};if(r.type==="root"){let o=e.getFirstKey?.()??null;return o!=null?{type:"item",key:o,dropPosition:"before"}:null}if(r.type==="item"){let o=null;a?o=a==="right"?e.getKeyRightOf?.(r.key,{includeDisabled:!0}):e.getKeyLeftOf?.(r.key,{includeDisabled:!0}):o=e.getKeyBelow?.(r.key,{includeDisabled:!0});let y=je(t,r.key,c=>t.getKeyAfter(c));if(o!=null&&o!==y)return{type:"item",key:o,dropPosition:r.dropPosition};switch(r.dropPosition){case"before":return{type:"item",key:r.key,dropPosition:"on"};case"on":{let c=t.getItem(r.key),D=o!=null?t.getItem(o):null;return c&&D&&D.level>=c.level?{type:"item",key:D.key,dropPosition:"before"}:{type:"item",key:r.key,dropPosition:"after"}}case"after":{let c=t.getItem(r.key),D=c?.nextKey!=null?t.getItem(c.nextKey):null;for(;D!=null&&D.type!=="item";)D=D.nextKey!=null?t.getItem(D.nextKey):null;if(c&&D==null&&c.parentKey!=null){let v=t.getItem(c.parentKey);const g=v?.nextKey!=null?t.getItem(v.nextKey):null;if(g?.type==="item")return{type:"item",key:g.key,dropPosition:"before"};if(v?.type==="item")return{type:"item",key:v.key,dropPosition:"after"}}if(D)return{type:"item",key:D.key,dropPosition:"on"}}}}return n?{type:"root"}:null}function xe(e,t,r,n=!1,a=null){if(!r||n&&r.type==="root"){let o=null,y=e.getLastKey?.();for(;y!=null;){let c=t.getItem(y);if(c?.type!=="item")break;o=y,y=c?.parentKey}return o!=null?{type:"item",key:o,dropPosition:"after"}:null}if(r.type==="item"){let o=null;a?o=a==="left"?e.getKeyLeftOf?.(r.key,{includeDisabled:!0}):e.getKeyRightOf?.(r.key,{includeDisabled:!0}):o=e.getKeyAbove?.(r.key,{includeDisabled:!0});let y=je(t,r.key,c=>t.getKeyBefore(c));if(o!=null&&o!==y)return{type:"item",key:o,dropPosition:r.dropPosition};switch(r.dropPosition){case"before":{let c=t.getItem(r.key);if(c&&c.prevKey!=null){let D=_e(t,c.prevKey);if(D)return D}return o!=null?{type:"item",key:o,dropPosition:"on"}:{type:"root"}}case"on":return{type:"item",key:r.key,dropPosition:"before"};case"after":{let c=_e(t,r.key);return c||{type:"item",key:r.key,dropPosition:"on"}}}}return r.type!=="root"?{type:"root"}:null}function _e(e,t){let r=e.getItem(t),n=je(e,t,o=>e.getKeyAfter(o)),a=n!=null?e.getItem(n):null;if(r&&a&&a.level>r.level){let o=null;if("lastChildKey"in r)for(o=r.lastChildKey!=null?e.getItem(r.lastChildKey):null;o&&o.type!=="item"&&o.prevKey!=null;)o=e.getItem(o.prevKey);else o=Array.from(r.childNodes).findLast(y=>y.type==="item")||null;if(o)return{type:"item",key:o.key,dropPosition:"after"}}return null}function je(e,t,r){let n=r(t),a=n!=null?e.getItem(n):null;for(;a&&a.type!=="item";)n=r(a.key),a=n!=null?e.getItem(n):null;return n}const se=20;function on(e){let t=x.useRef(null),r=x.useRef(!0),n=x.useRef(!0);x.useEffect(()=>{if(e.current){t.current=er(e.current)?e.current:tr(e.current);let y=window.getComputedStyle(t.current);r.current=/(auto|scroll)/.test(y.overflowX),n.current=/(auto|scroll)/.test(y.overflowY)}},[e]);let a=x.useRef({timer:void 0,dx:0,dy:0}).current;x.useEffect(()=>()=>{a.timer&&(cancelAnimationFrame(a.timer),a.timer=void 0)},[a]);let o=x.useCallback(()=>{r.current&&t.current&&(t.current.scrollLeft+=a.dx),n.current&&t.current&&(t.current.scrollTop+=a.dy),a.timer&&(a.timer=requestAnimationFrame(o))},[t,a]);return{move(y,c){if(!rt()||nt()||!t.current)return;let D=t.current.getBoundingClientRect(),v=se,g=se,$=D.height-se,l=D.width-se;yl||c$?(yl&&(a.dx=y-l),c$&&(a.dy=c-$),a.timer||(a.timer=requestAnimationFrame(o))):this.stop()},stop(){a.timer&&(cancelAnimationFrame(a.timer),a.timer=void 0)}}}function ln(e,t,r){let n=x.useRef({props:e,state:t,nextTarget:null,dropOperation:null}).current;n.props=e,n.state=t;let a=x.useCallback(async l=>{let{onInsert:d,onRootDrop:p,onItemDrop:b,onReorder:m,onMove:E,acceptedDragTypes:T="all",shouldAcceptItemDrop:i}=n.props,{draggingKeys:s}=B,u=V(r),{target:h,dropOperation:w,items:k}=l,C=k;(T!=="all"||i)&&(C=k.filter(S=>{let I;return S.kind==="directory"?I=new Set([mt]):I=S.kind==="file"?new Set([S.type]):S.types,T==="all"||T.some(G=>I.has(G))?h.type==="item"&&h.dropPosition==="on"&&i?i(h,I):!0:!1})),C.length>0&&(h.type==="root"&&p&&await p({items:C,dropOperation:w}),h.type==="item"&&(h.dropPosition==="on"&&b&&await b({items:C,dropOperation:w,isInternal:u,target:h}),E&&u&&await E({keys:s,dropOperation:w,target:h}),h.dropPosition!=="on"&&(!u&&d&&await d({items:C,dropOperation:w,target:h}),u&&m&&await m({keys:s,dropOperation:w,target:h}))))},[n,r]),o=on(r),{dropProps:y}=Kt({ref:r,onDropEnter(){n.nextTarget!=null&&t.setTarget(n.nextTarget)},onDropMove(l){n.nextTarget!=null&&t.setTarget(n.nextTarget),o.move(l.x,l.y)},getDropOperationForPoint(l,d,p,b){let{draggingKeys:m,dropCollectionRef:E}=B,T=V(r),i=u=>t.getDropOperation({target:u,types:l,allowedOperations:d,isInternal:T,draggingKeys:m})!=="cancel",s=e.dropTargetDelegate.getDropTargetFromPoint(p,b,i);if(!s)return n.dropOperation="cancel",n.nextTarget=null,"cancel";if(n.dropOperation=t.getDropOperation({target:s,types:l,allowedOperations:d,isInternal:T,draggingKeys:m}),n.dropOperation==="cancel"){let u={type:"root"},h=t.getDropOperation({target:u,types:l,allowedOperations:d,isInternal:T,draggingKeys:m});h!=="cancel"&&(s=u,n.dropOperation=h)}return s&&n.dropOperation!=="cancel"&&r?.current!==E?.current&&U(r),n.nextTarget=n.dropOperation==="cancel"?null:s,n.dropOperation},onDropExit(){U(void 0),t.setTarget(null),o.stop()},onDropActivate(l){t.target?.type==="item"&&typeof e.onDropActivate=="function"&&e.onDropActivate({type:"dropactivate",x:l.x,y:l.y,target:t.target})},onDrop(l){U(r),t.target&&v(l,t.target);let{draggingCollectionRef:d}=B;d==null&&vt()}}),c=x.useRef(null),D=x.useCallback(()=>{let{state:l}=n;if(c.current){let{target:d,collection:p,selectedKeys:b,focusedKey:m,isInternal:E,draggingKeys:T}=c.current;if(l.collection.size>p.size&&l.selectionManager.isSelectionEqual(b)){let i=new Set,s=l.collection.getFirstKey();for(;s!=null;){let u=l.collection.getItem(s);u?.type==="item"&&!p.getItem(u.key)&&i.add(u.key),u?.hasChildNodes&&l.collection.getItem(u.lastChildKey)?.type==="item"?s=u.firstChildKey:s=l.collection.getKeyAfter(s)}if(l.selectionManager.setSelectedKeys(i),l.selectionManager.focusedKey===m){let u=i.keys().next().value;if(u!=null){let h=l.collection.getItem(u),w=c.current.target,k=l.collection.expandedKeys?l.collection.expandedKeys.has(h?.parentKey):!1;h&&(h?.type==="cell"||w.type==="item"&&w.dropPosition==="on"&&!k)&&(u=h.parentKey),u!=null&&l.selectionManager.setFocusedKey(u),l.selectionManager.selectionMode==="none"&&oe("keyboard")}}}else m!=null&&l.selectionManager.focusedKey===m&&E&&d.type==="item"&&d.dropPosition!=="on"&&T.has(l.collection.getItem(m)?.parentKey)?(l.selectionManager.setFocusedKey(l.collection.getItem(m)?.parentKey??null),oe("keyboard")):l.selectionManager.focusedKey===m&&d.type==="item"&&d.dropPosition==="on"&&l.collection.getItem(d.key)!=null?(l.selectionManager.setFocusedKey(d.key),oe("keyboard")):l.selectionManager.focusedKey!=null&&!l.selectionManager.isSelected(l.selectionManager.focusedKey)&&oe("keyboard");l.selectionManager.setFocused(!0)}},[n]),v=x.useCallback((l,d)=>{let{state:p}=n;c.current={timeout:void 0,focusedKey:p.selectionManager.focusedKey,collection:p.collection,selectedKeys:p.selectionManager.selectedKeys,draggingKeys:B.draggingKeys,isInternal:V(r),target:d},(n.props.onDrop||a)({type:"drop",x:l.x,y:l.y,target:d,items:l.items,dropOperation:l.dropOperation}),c.current.timeout=setTimeout(()=>{D(),c.current=null},50)},[n,a,r,D]);x.useEffect(()=>()=>{c.current&&clearTimeout(c.current.timeout)},[]),tt(()=>{c.current&&t.collection!==c.current.collection&&D()});let{direction:g}=rr();x.useEffect(()=>{if(!r.current)return;let l=(b,m=!0,E="down")=>an(n.props.keyboardDelegate,n.state.collection,b,E,g==="rtl",m),d=(b,m=!0)=>l(b,m,"up"),p=(b,m,E,T,i=!0)=>{let s=0,u,{draggingKeys:h}=B,w=V(r);do{let k=T(b,i);if(!k)return null;b=k,u=n.state.getDropOperation({target:k,types:m,allowedOperations:E,isInternal:w,draggingKeys:h}),b.type==="root"&&s++}while(u==="cancel"&&!n.state.isDropTarget(b)&&s<2);return u==="cancel"?null:b};return Et({element:r.current,preventFocusOnDrop:!0,getDropOperation(b,m){if(n.state.target){let{draggingKeys:T}=B,i=V(r);return n.state.getDropOperation({target:n.state.target,types:b,allowedOperations:m,isInternal:i,draggingKeys:T})}return p(null,b,m,l)?"move":"cancel"},onDropEnter(b,m){let E=z(m.items),T=n.state.selectionManager,i=null;U(r);let s=T.focusedKey,u="after",h=s!=null?n.state.collection.getItem(s):null;if(h?.type==="cell"&&(s=h.parentKey),s!=null&&T.isSelected(s)&&(T.selectedKeys.size>1&&T.firstSelectedKey===s?u="before":s=T.lastSelectedKey),s!=null){i={type:"item",key:s,dropPosition:u};let{draggingKeys:w}=B,k=V(r);n.state.getDropOperation({target:i,types:E,allowedOperations:m.allowedDropOperations,isInternal:k,draggingKeys:w})==="cancel"&&(i=p(i,E,m.allowedDropOperations,l,!1)??p(i,E,m.allowedDropOperations,d,!1))}i||(i=p(null,E,m.allowedDropOperations,l)),n.state.setTarget(i)},onDropExit(){U(void 0),n.state.setTarget(null)},onDropTargetEnter(b){n.state.setTarget(b)},onDropActivate(b,m){m?.type==="item"&&m?.dropPosition==="on"&&typeof n.props.onDropActivate=="function"&&n.props.onDropActivate({type:"dropactivate",x:b.x,y:b.y,target:m})},onDrop(b,m){U(r),n.state.target&&v(b,m||n.state.target)},onKeyDown(b,m){let{keyboardDelegate:E}=n.props,T=z(m.items);switch(b.key){case"ArrowDown":if(E.getKeyBelow){let i=p(n.state.target,T,m.allowedDropOperations,(s,u)=>l(s,u,"down"));n.state.setTarget(i)}break;case"ArrowUp":if(E.getKeyAbove){let i=p(n.state.target,T,m.allowedDropOperations,(s,u)=>l(s,u,"up"));n.state.setTarget(i)}break;case"ArrowLeft":if(E.getKeyLeftOf){let i=p(n.state.target,T,m.allowedDropOperations,(s,u)=>l(s,u,"left"));n.state.setTarget(i)}break;case"ArrowRight":if(E.getKeyRightOf){let i=p(n.state.target,T,m.allowedDropOperations,(s,u)=>l(s,u,"right"));n.state.setTarget(i)}break;case"Home":if(E.getFirstKey){let i=p(null,T,m.allowedDropOperations,l);n.state.setTarget(i)}break;case"End":if(E.getLastKey){let i=p(null,T,m.allowedDropOperations,d);n.state.setTarget(i)}break;case"PageDown":if(E.getKeyPageBelow){let i=n.state.target;if(!i)i=p(null,T,m.allowedDropOperations,l);else{let s=E.getFirstKey?.();i.type==="item"&&(s=i.key);let u=null;s!=null&&(u=E.getKeyPageBelow(s));let h=i.type==="item"?i.dropPosition:"after";if((u==null||i.type==="item"&&i.key===E.getLastKey?.())&&(u=E.getLastKey?.()??null,h="after"),u==null)break;i={type:"item",key:u,dropPosition:h};let{draggingCollectionRef:w,draggingKeys:k}=B,C=w?.current===r?.current;n.state.getDropOperation({target:i,types:T,allowedOperations:m.allowedDropOperations,isInternal:C,draggingKeys:k})==="cancel"&&(i=p(i,T,m.allowedDropOperations,l,!1)??p(i,T,m.allowedDropOperations,d,!1))}n.state.setTarget(i??n.state.target)}break;case"PageUp":{if(!E.getKeyPageAbove)break;let i=n.state.target;if(!i)i=p(null,T,m.allowedDropOperations,d);else if(i.type==="item"){if(i.key===E.getFirstKey?.())i={type:"root"};else{let w=E.getKeyPageAbove(i.key),k=i.dropPosition;if(w==null&&(w=E.getFirstKey?.(),k="before"),w==null)break;i={type:"item",key:w,dropPosition:k}}let{draggingKeys:s}=B,u=V(r);n.state.getDropOperation({target:i,types:T,allowedOperations:m.allowedDropOperations,isInternal:u,draggingKeys:s})==="cancel"&&(i=p(i,T,m.allowedDropOperations,d,!1)??p(i,T,m.allowedDropOperations,l,!1))}n.state.setTarget(i??n.state.target);break}}n.props.onKeyDown?.(b)}})},[n,r,v,g]);let $=at();return Ae.set(t,{id:$,ref:r}),{collectionProps:ke(y,{id:$,"aria-describedby":null})}}function Ct(e,t,r){let{dropProps:n}=kt(),a=Or(t);x.useEffect(()=>{if(r.current)return Gr({element:r.current,target:e.target,getDropOperation(g,$){let{draggingKeys:l}=B,d=V(a);return t.getDropOperation({target:e.target,types:g,allowedOperations:$,isInternal:d,draggingKeys:l})},activateButtonRef:e.activateButtonRef})},[r,e.target,t,a,e.activateButtonRef]);let o=Me(),{draggingKeys:y}=B,c=V(a),D=o&&t.getDropOperation({target:e.target,types:z(o.dragTarget.items),allowedOperations:o.dragTarget.allowedDropOperations,isInternal:c,draggingKeys:y})!=="cancel",v=t.isDropTarget(e.target);return x.useEffect(()=>{o&&v&&r.current&&r.current.focus()},[v,o,r]),{dropProps:{...n,"aria-hidden":!o||D?void 0:"true"},isDropTarget:v}}function sn(e){return e&&e.__esModule?e.default:e}function un(e,t,r){let{target:n}=e,{collection:a}=t,o=re(sn(ne),"@react-aria/dnd"),y=Me(),{dropProps:c}=Ct(e,t,r),D=at(),v=p=>p==null?"":a.getTextValue?.(p)??a.getItem(p)?.textValue??"",g="",$;if(n.type==="root")g=o.format("dropOnRoot"),$=`${D} ${Ar(t)}`;else if(n.dropPosition==="on")g=o.format("dropOnItem",{itemText:v(n.key)});else{let p,b;if(n.dropPosition==="before"){let m=a.getItem(n.key)?.prevKey,E=m!=null?a.getItem(m):null;p=E?.type==="item"?E.key:null}else p=n.key;if(n.dropPosition==="after"){let m=a.getItem(n.key)?.nextKey,E=m!=null?a.getItem(m):null;b=E?.type==="item"?E.key:null}else b=n.key;p!=null&&b!=null?g=o.format("insertBetween",{beforeItemText:v(p),afterItemText:v(b)}):p!=null?g=o.format("insertAfter",{itemText:v(p)}):b!=null&&(g=o.format("insertBefore",{itemText:v(b)}))}let l=t.isDropTarget(n),d=y?c["aria-hidden"]:"true";return{dropIndicatorProps:{...c,id:D,"aria-roledescription":o.format("dropIndicator"),"aria-label":g,"aria-labelledby":$,"aria-hidden":d,tabIndex:-1},isDropTarget:l,isHidden:!l&&!!d}}function dn(e){return e&&e.__esModule?e.default:e}const We={keyboard:{start:"dragDescriptionKeyboard",end:"endDragKeyboard"},touch:{start:"dragDescriptionTouch",end:"endDragTouch"},virtual:{start:"dragDescriptionVirtual",end:"endDragVirtual"}};function cn(e){let{hasDragButton:t,isDisabled:r}=e,n=re(dn(ne),"@react-aria/dnd"),a=x.useRef({options:e,x:0,y:0}).current;a.options=e;let o=x.useRef(null),[y,c]=x.useState(!1),D=u=>{o.current=u,c(!!u)},{addGlobalListener:v,removeAllGlobalListeners:g}=nr(),$=x.useRef(null),l=u=>{if(u.defaultPrevented)return;if(u.stopPropagation(),$.current==="virtual"){u.preventDefault(),m(M(u)),$.current=null;return}typeof e.onDragStart=="function"&&e.onDragStart({type:"dragstart",x:u.clientX,y:u.clientY});let h=e.getItems();u.dataTransfer.clearData?.(),Ce(u.dataTransfer,h);let w=P.all;if(typeof e.getAllowedDropOperations=="function"){let S=e.getAllowedDropOperations();w=P.none;for(let I of S)w|=P[I]||P.none}be(w);let k=gt[w]||"none";u.dataTransfer.effectAllowed=k==="cancel"?"none":k,typeof e.preview?.current=="function"&&e.preview.current(h,(S,I,G)=>{if(!S)return;let j=S.getBoundingClientRect(),X=u.currentTarget.getBoundingClientRect(),J=u.clientX-X.x,Z=u.clientY-X.y;(J>j.width||Z>j.height)&&(J=j.width/2,Z=j.height/2);let Y=J,K=Z;typeof I=="number"&&typeof G=="number"&&(Y=I,K=G),Y=Math.max(0,Math.min(Y,j.width)),K=Math.max(0,Math.min(K,j.height));let A=2*Math.round(j.height/2);S.style.height=`${A}px`,u.dataTransfer.setDragImage(S,Y,K)}),v(window,"drop",S=>{S.preventDefault(),S.stopPropagation(),console.warn("Drags initiated from the React Aria useDrag hook may only be dropped on a target created with useDrop. This ensures that a keyboard and screen reader accessible alternative is available.")},{once:!0}),a.x=u.clientX,a.y=u.clientY;let C=M(u);requestAnimationFrame(()=>{D(C)})},d=u=>{u.stopPropagation(),!(u.clientX===a.x&&u.clientY===a.y)&&(typeof e.onDragMove=="function"&&e.onDragMove({type:"dragmove",x:u.clientX,y:u.clientY}),a.x=u.clientX,a.y=u.clientY)},p=u=>{if(u.stopPropagation(),typeof e.onDragEnd=="function"){let h={type:"dragend",x:u.clientX,y:u.clientY,dropOperation:ee[u.dataTransfer.dropEffect]};ce&&(h.dropOperation=ee[ce]),e.onDragEnd(h)}D(null),g(),be(P.none),ye(void 0)};x.useEffect(()=>()=>{if(o.current&&(!o.current.isConnected||parseInt(x.version,10)<17)){if(typeof a.options.onDragEnd=="function"){let u={type:"dragend",x:0,y:0,dropOperation:ee[ce||"none"]};a.options.onDragEnd(u)}D(null),be(P.none),ye(void 0)}},[a]);let b=u=>{u.pointerType!=="keyboard"&&u.pointerType!=="virtual"||m(u.target)},m=u=>{if(typeof a.options.onDragStart=="function"){let h=u.getBoundingClientRect();a.options.onDragStart({type:"dragstart",x:h.x+h.width/2,y:h.y+h.height/2})}zr({element:u,items:a.options.getItems(),allowedDropOperations:typeof a.options.getAllowedDropOperations=="function"?a.options.getAllowedDropOperations():["move","copy","link"],onDragEnd(h){D(null),typeof a.options.onDragEnd=="function"&&a.options.onDragEnd(h)}},n),D(u)},E=Oe(),T=y?We[E].end:We[E].start,i=Be(n.format(T)),s={};return t||(s={...i,onPointerDown(u){if($.current=et(u.nativeEvent)?"virtual":u.pointerType,u.width<1&&u.height<1&&nt()&&rt())$.current="virtual";else{let h=u.currentTarget.getBoundingClientRect(),w=u.clientX-h.x,k=u.clientY-h.y,C=h.width/2,S=h.height/2;Math.abs(w-C)<=.5&&Math.abs(k-S)<=.5?$.current="virtual":$.current=u.pointerType}},onKeyDownCapture(u){M(u)===u.currentTarget&&u.key==="Enter"&&(u.preventDefault(),u.stopPropagation())},onKeyUpCapture(u){M(u)===u.currentTarget&&u.key==="Enter"&&(u.preventDefault(),u.stopPropagation(),m(M(u)))},onClick(u){(Qe(u.nativeEvent)||$.current==="virtual")&&(u.preventDefault(),u.stopPropagation(),m(M(u)))}}),r?{dragProps:{draggable:"false"},dragButtonProps:{},isDragging:!1}:{dragProps:{...s,draggable:"true",onDragStart:l,onDrag:d,onDragEnd:p},dragButtonProps:{...i,onPress:b},isDragging:y}}function pn(e){return e&&e.__esModule?e.default:e}const fn={keyboard:{selected:"dragSelectedKeyboard",notSelected:"dragDescriptionKeyboard"},touch:{selected:"dragSelectedLongPress",notSelected:"dragDescriptionLongPress"},virtual:{selected:"dragDescriptionVirtual",notSelected:"dragDescriptionVirtual"}};function gn(e,t){let r=re(pn(ne),"@react-aria/dnd"),n=t.isDisabled||t.selectionManager.isDisabled(e.key),{dragProps:a,dragButtonProps:o}=cn({getItems(){return t.getItems(e.key)},preview:t.preview,getAllowedDropOperations:t.getAllowedDropOperations,hasDragButton:e.hasDragButton,onDragStart(d){t.startDrag(e.key,d),Vr(t.draggingKeys)},onDragMove(d){t.moveDrag(d)},onDragEnd(d){let{dropOperation:p}=d,b=p==="cancel"?!1:V();t.endDrag({...d,keys:t.draggingKeys,isInternal:b}),vt()}}),y=t.collection.getItem(e.key),c=t.getKeysForDrag(e.key).size,D=c>1&&t.selectionManager.isSelected(e.key),v,g,$=Oe();if(!e.hasDragButton&&t.selectionManager.selectionMode!=="none"){let d=fn[$][D?"selected":"notSelected"];e.hasAction&&$==="keyboard"&&(d+="Alt"),D?g=r.format(d,{count:c}):g=r.format(d),delete a.onClick}else if(D)v=r.format("dragSelectedItems",{count:c});else{let d=t.collection.getTextValue?.(e.key)??y?.textValue??"";v=r.format("dragItem",{itemText:d})}let l=Be(g);if(g&&Object.assign(a,l),!e.hasDragButton&&e.hasAction){let{onKeyDownCapture:d,onKeyUpCapture:p}=a;$==="touch"&&delete a["aria-describedby"],a.onKeyDownCapture=b=>{b.altKey&&d?.(b)},a.onKeyUpCapture=b=>{b.altKey&&p?.(b)}}return{dragProps:n?{}:a,dragButtonProps:{...o,isDisabled:n,"aria-label":v}}}function yn(e,t,r){let{draggingCollectionRef:n}=B;t.draggingKeys.size>0&&n?.current!==r.current&&Lr(r)}const mn=_.forwardRef(function(t,r){let n=t.children,[a,o]=x.useState(null),y=x.useRef(null),c=x.useRef(void 0);return x.useImperativeHandle(r,()=>(D,v)=>{let g=n(D),$,l,d;g&&typeof g=="object"&&"element"in g?($=g.element,l=g.x,d=g.y):$=g,St.flushSync(()=>{o($)}),v(y.current,l,d),c.current=requestAnimationFrame(()=>{o(null)})},[n]),x.useEffect(()=>()=>{c.current&&cancelAnimationFrame(c.current)},[]),a?_.createElement("div",{style:{zIndex:-100,position:"fixed",top:0,left:-1e5},ref:y},a):null});function hn(e){let{getItems:t,isDisabled:r,collection:n,selectionManager:a,onDragStart:o,onDragMove:y,onDragEnd:c,preview:D,getAllowedDropOperations:v}=e,[,g]=x.useState(!1),$=x.useRef(new Set),l=x.useRef(null),d=p=>{let b=new Set;if(a.isSelected(p))for(let m of a.selectedKeys){let E=n.getItem(m);if(E){let T=!1,i=E.parentKey;for(;i!=null;){if(a.selectedKeys.has(i)){T=!0;break}let s=n.getItem(i);i=s?s.parentKey:null}T||b.add(m)}}else b.add(p);return b};return{collection:n,selectionManager:a,get draggedKey(){return l.current},get draggingKeys(){return $.current},isDragging(p){return $.current.has(p)},getKeysForDrag:d,getItems(p){let b=d(p),m=[];for(let E of b){let T=n.getItem(E)?.value;T!=null&&m.push(T)}return t(d(p),m)},isDisabled:r,preview:D,getAllowedDropOperations:v,startDrag(p,b){let m=d(p);$.current=m,l.current=p,a.setFocused(!1),g(!0),typeof o=="function"&&o({...b,keys:m})},moveDrag(p){typeof y=="function"&&y({...p,keys:$.current})},endDrag(p){let{isInternal:b}=p;typeof c=="function"&&c({...p,keys:$.current,isInternal:b}),$.current=new Set,l.current=null,g(!1)}}}function Dn(e){let{acceptedDragTypes:t="all",isDisabled:r,onInsert:n,onRootDrop:a,onItemDrop:o,onReorder:y,onMove:c,shouldAcceptItemDrop:D,collection:v,selectionManager:g,onDropEnter:$,getDropOperation:l,onDrop:d}=e,[p,b]=x.useState(null),m=x.useRef(null),E=i=>{if(i.dropPosition==="before"){let s=v.getItem(i.key);return s&&s.prevKey!=null?{type:"item",key:s.prevKey,dropPosition:"after"}:null}else if(i.dropPosition==="after"){let s=v.getItem(i.key);return s&&s.nextKey!=null?{type:"item",key:s.nextKey,dropPosition:"before"}:null}return null},T=x.useCallback(i=>{let{target:s,types:u,allowedOperations:h,isInternal:w,draggingKeys:k}=i;if(r||!s)return"cancel";if(t==="all"||t.some(C=>u.has(C))){let C=n&&s.type==="item"&&!w&&(s.dropPosition==="before"||s.dropPosition==="after"),S=y&&s.type==="item"&&w&&(s.dropPosition==="before"||s.dropPosition==="after")&&bn(v,s,k),I=s.type!=="item"||s.dropPosition!=="on"||!D||D(s,u),G=c&&s.type==="item"&&w&&I,j=a&&s.type==="root"&&!w,X=o&&s.type==="item"&&s.dropPosition==="on"&&!(w&&s.key!=null&&k.has(s.key))&&I;if(d||C||S||G||j||X)return l?l(s,u,h):h[0]}return"cancel"},[r,v,t,l,n,a,o,D,y,c,d]);return{collection:v,selectionManager:g,isDisabled:r,target:p,setTarget(i){if(this.isDropTarget(i))return;let s=m.current;s&&typeof e.onDropExit=="function"&&e.onDropExit({type:"dropexit",x:0,y:0,target:s}),i&&typeof $=="function"&&$({type:"dropenter",x:0,y:0,target:i}),m.current=i??null,b(i??null)},isDropTarget(i){let s=m.current;return!s||!i?!1:we(i,s)?!0:i?.type==="item"&&s?.type==="item"&&i.key!==s.key&&i.dropPosition!==s.dropPosition&&i.dropPosition!=="on"&&s.dropPosition!=="on"?we(E(i),s)||we(i,E(s)):!1},getDropOperation(i){let{target:s,isInternal:u,draggingKeys:h}=i;if(u&&s.type==="item"&&h.size>0){if(h.has(s.key)&&s.dropPosition==="on")return"cancel";let w=s.key;for(;w!=null;){let C=v.getItem(w)?.parentKey;if(C!=null&&h.has(C))return"cancel";w=C??null}}return T(i)}}}function we(e,t){if(!e)return!t;switch(e.type){case"root":return t?.type==="root";case"item":return t?.type==="item"&&t?.key===e.key&&t?.dropPosition===e.dropPosition}}function bn(e,t,r){let n=e.getItem(t.key);for(let a of r)if(e.getItem(a)?.parentKey!==n?.parentKey)return!1;return!0}class $n{constructor(t,r,n){this.collection=t,this.ref=r,this.layout=n?.layout||"stack",this.orientation=n?.orientation||"vertical",this.direction=n?.direction||"ltr"}getPrimaryStart(t){return this.orientation==="horizontal"?t.left:t.top}getPrimaryEnd(t){return this.orientation==="horizontal"?t.right:t.bottom}getSecondaryStart(t){return this.orientation==="horizontal"?t.top:t.left}getSecondaryEnd(t){return this.orientation==="horizontal"?t.bottom:t.right}getFlowStart(t){return this.layout==="stack"?this.getPrimaryStart(t):this.getSecondaryStart(t)}getFlowEnd(t){return this.layout==="stack"?this.getPrimaryEnd(t):this.getSecondaryEnd(t)}getFlowSize(t){return this.getFlowEnd(t)-this.getFlowStart(t)}getDropTargetFromPoint(t,r,n){if(this.collection[Symbol.iterator]().next().done||!this.ref.current)return{type:"root"};let a=this.ref.current.getBoundingClientRect(),o=this.orientation==="horizontal"?t:r,y=this.orientation==="horizontal"?r:t;o+=this.getPrimaryStart(a),y+=this.getSecondaryStart(a);let c=this.layout==="stack"?o:y,D=this.orientation==="horizontal"&&this.direction==="rtl",v=this.layout==="grid"&&this.orientation==="vertical"&&this.direction==="rtl",g=this.layout==="stack"?D:v,$=this.ref.current?.dataset.collection,l=this.ref.current.querySelectorAll($?`[data-collection="${CSS.escape($)}"]`:"[data-key]"),d=new Map;for(let i of l)i instanceof HTMLElement&&i.dataset.key!=null&&d.set(i.dataset.key,i);let p=[...this.collection].filter(i=>i.type==="item");if(p.length<1)return{type:"root"};let b=0,m=p.length;for(;b{k?b=i+1:m=i};if(othis.getPrimaryEnd(h))w(!D);else if(ythis.getSecondaryEnd(h))w(!v);else{let k={type:"item",key:s.key,dropPosition:"on"};if(n(k))c<=this.getFlowStart(h)+5&&n({...k,dropPosition:"before"})?k.dropPosition=g?"after":"before":c>=this.getFlowEnd(h)-5&&n({...k,dropPosition:"after"})&&(k.dropPosition=g?"before":"after");else{let C=this.getFlowStart(h)+this.getFlowSize(h)/2;c<=C&&n({...k,dropPosition:"before"})?k.dropPosition=g?"after":"before":c>=C&&n({...k,dropPosition:"after"})&&(k.dropPosition=g?"before":"after")}return k}}let E=p[Math.min(b,p.length-1)];return a=d.get(String(E.key))?.getBoundingClientRect(),a&&(o{let{onDrop:r,onInsert:n,onItemDrop:a,onReorder:o,onMove:y,onRootDrop:c,getItems:D,renderDragPreview:v,renderDropIndicator:g,dropTargetDelegate:$}=e,l=!!D,d=!!(r||n||a||o||y||c),p={};return l&&(p.useDraggableCollectionState=function(m){return hn({...m,...e})},p.useDraggableCollection=yn,p.useDraggableItem=gn,p.DragPreview=mn,p.renderDragPreview=v,p.isVirtualDragging=Xr),d&&(p.useDroppableCollectionState=function(m){return Dn({...m,...e})},p.useDroppableItem=Ct,p.useDroppableCollection=function(m,E,T){return ln({...m,...e},E,T)},p.useDropIndicator=un,p.renderDropIndicator=g,p.dropTargetDelegate=$,p.ListDropTargetDelegate=$n),p},[e])}}function ue({children:e,tone:t,action:r}){return f.jsxs("span",{className:Ie("rp-tag",t),children:[f.jsx("span",{className:"rp-tag-label",children:e}),r]})}function Je({label:e,children:t}){return f.jsx("div",{className:"rp-tags",role:"group","aria-label":e,children:t})}function En({label:e,message:t,children:r}){return f.jsxs("div",{className:"rp-actionbar",role:"region","aria-label":e,children:[f.jsx("span",{"aria-live":"polite",children:t}),f.jsx("div",{className:"rp-toolbar",children:r})]})}function xn({className:e,...t}){return f.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:12,height:12,viewBox:"0 0 12 12","aria-hidden":"true",focusable:"false",className:Ie("rp-icon",e),...t,children:[1.6,6,10.4].flatMap(r=>[3.8,8.2].map(n=>f.jsx("circle",{cx:n,cy:r,r:1.1,fill:"currentColor"},`${n}-${r}`)))})}function wn(e,t){return e.flatMap(r=>{if(r.kind!=="subscription")return[];const n=t.filter(o=>o.provider_id===r.id),a=new Set(n.map(o=>o.subscription_tag).filter(Boolean));return a.size!==1?[]:[{tag:[...a][0],label:r.name,count:n.length}]})}const Ze=6;function Tn(e,t,r,n,a){const o=new Map(Ke(e).map(l=>[l.name,Le(l)])),y=ot(e,t),c=Ke(y),D=new Map(r.map(l=>[l.tag,l])),v=a("arrange.lastMember"),g=c.map(l=>{const d=Le(l),p=o.get(l.name),b=Ve(l.filters),m=d.rules.length?Ve(d.rules):null,E=t.filter(s=>s.group===l.name),T=new Set(E.flatMap(s=>s.kind==="removeNode"?n.filter(u=>u.name===s.value):s.kind==="removeSubscription"?n.filter(u=>u.subscription_tag===s.value):[])),i=m?n.filter(m).map(s=>s.name):[];return{name:l.name,isNew:!p,holdsAll:l.filters.length===0,names:d.names.map(s=>({name:s,isNew:!!p&&!p.names.includes(s),blocked:He(l,"name",s)?v:null})),subscriptions:d.subtags.map(s=>({tag:s,label:D.get(s)?.label??s,count:D.get(s)?.count??null,isNew:!!p&&!p.subtags.includes(s),blocked:He(l,"subtag",s)?v:null})),rules:d.rules,ruleNote:d.rules.length?a("arrange.ruleNote",{n:d.rules.length}):null,ruleNodes:i.slice(0,Ze),ruleMore:Math.max(0,i.length-Ze),stillIn:[...T].filter(b).map(s=>s.name),removedNames:E.flatMap(s=>s.kind==="removeNode"?[s.value]:[]),removedSubscriptions:E.flatMap(s=>s.kind==="removeSubscription"?[{tag:s.value,label:D.get(s.value)?.label??s.value}]:[])}}),$=new Set(n.map(l=>l.name));return{groups:g,stagedText:y,unknown:new Set(g.flatMap(l=>l.names.filter(d=>!$.has(d.name)).map(d=>d.name))),emptyNew:g.filter(l=>l.isNew&&l.holdsAll).map(l=>l.name)}}function kn(e,t){return t?null:[...e.names,...e.subscriptions].find(r=>r.blocked)?.blocked??null}function Kn(e,t,r){return e??(t.length?r("arrange.emptyNew",{group:t[0]}):null)}function Ft(e,t){return e?t.kind==="node"?e.names.some(r=>r.name===t.value):e.subscriptions.some(r=>r.tag===t.value):!1}function Cn(e){try{const t=JSON.parse(e);if(!t||typeof t!="object")return null;const{kind:r,value:n}=t;return(r==="node"||r==="subscription")&&typeof n=="string"&&n?{kind:r,value:n}:null}catch{return null}}function Fn(e,t,r){const n=a=>t.find(o=>o.tag===a)?.label??a;switch(e.kind){case"addNode":return r("arrange.change.addNode",{name:e.value,group:e.group});case"removeNode":return r("arrange.change.removeNode",{name:e.value,group:e.group});case"addSubscription":return r("arrange.change.addSubscription",{name:n(e.value),group:e.group});case"removeSubscription":return r("arrange.change.removeSubscription",{name:n(e.value),group:e.group});case"createGroup":return r("arrange.change.createGroup",{group:e.group})}}function Te(e,t){const r={addNode:"removeNode",removeNode:"addNode",addSubscription:"removeSubscription",removeSubscription:"addSubscription"};if(t.kind==="createGroup")return e.some(a=>a.kind==="createGroup"&&a.group===t.group)?e:[...e,t];if((t.kind==="addNode"||t.kind==="addSubscription")&&!it(t.value))return e;const n=e.findIndex(a=>a.kind===r[t.kind]&&a.group===t.group&&"value"in a&&a.value===t.value);return n!==-1?e.filter((a,o)=>o!==n):e.some(a=>a.kind===t.kind&&a.group===t.group&&"value"in a&&a.value===t.value)?e:[...e,t]}function Sn(e,t){const r=e[t];return e.filter((n,a)=>a!==t&&!(r.kind==="createGroup"&&n.group===r.group))}const pe="application/x-doona-placeable";function Pn(e){const t=W(),r=ar(),n=r.data?.resources,a=or(Ge(n,"nodes",{whileLoading:!1})),o=ir(Ge(n,"providers",{whileLoading:!1})),y=a.data,[c,D]=x.useState([]),v=lr(c.length>0,()=>D([])),g=e.main?.content??"",$=x.useMemo(()=>wn(o.data?.providers??[],y??[]),[o.data,y]),l=x.useMemo(()=>Tn(g,c,$,y??[],t),[g,c,$,y,t]),d=x.useMemo(()=>new Map(l.groups.map(K=>[K.name,K])),[l.groups]),{contains:p}=Br({sensitivity:"base"}),[b,m]=x.useState(""),E=x.useDeferredValue(b).trim(),T=x.useMemo(()=>(y??[]).filter(K=>!E||p(K.name,E)||p(K.protocol??"",E)),[y,E,p]),i=x.useMemo(()=>$.filter(K=>!E||p(K.label,E)),[$,E,p]),[s,u]=x.useState(!1),[h,w]=x.useState(!1),[k,C]=x.useState(null),S=e.writable?e.main?null:"arrange.noMain":"arrange.readOnly",I=K=>{h||(C(null),D(K))},G=(K,A)=>{A.some(O=>!it(O.value))&&ze("negative",t("config.unquotable")),I(O=>A.filter(he=>!Ft(d.get(K),he)).reduce((he,Ne)=>Te(he,{kind:Ne.kind==="node"?"addNode":"addSubscription",group:K,value:Ne.value}),O))},j=(K,A)=>I(O=>Te(O,{kind:A.kind==="node"?"removeNode":"removeSubscription",group:K,value:A.value})),X=new Set(l.groups.map(K=>K.name)),J=K=>Fr(K,X,t),Z=async()=>{w(!0),C(null);try{const K=await e.apply(A=>ot(A,c));K.kind==="invalid"&&C(t("ui.writeInvalid",{n:K.errors})),K.kind==="failed"&&C(t("arrange.failed",{error:ur(K.error,t)})),K.kind==="ok"&&(ze("positive",t("arrange.applied",{n:c.length})),D([]),v.clear(),u(!1))}finally{w(!1)}},Y=x.useMemo(()=>{if(!c.length)return[];const K=l.stagedText.split(` -`),A=new Set(c.map(O=>O.group));return Ke(l.stagedText).filter(O=>A.has(O.name)).map(O=>({group:O.name,text:K.slice(O.from,O.to+1).join(` -`)}))},[l.stagedText,c]);return{groups:l.groups,unknown:l.unknown,byGroup:d,subscriptions:i,nodes:T,search:b,setSearch:m,loading:r.loading&&!r.data||a.loading&&!y||o.loading&&!o.data,error:[r,a,o].find(K=>K.error&&!K.data)?.error??(e.main?null:e.error),retry:x.useCallback(()=>void sr(),[]),blocked:S?t(S):null,busy:e.busy||h,applying:h,failure:k,changes:c,changeLines:c.map(K=>Fn(K,$,t)),pendingText:t("arrange.pending",{n:c.length}),place:G,unplace:j,drop:K=>I(A=>Sn(A,K)),discard:()=>I(()=>[]),nameProblem:J,create:(K,A)=>I(O=>Te(O,{kind:"createGroup",group:K,policy:A})),reviewing:s&&c.length>0,setReviewing:K=>{h||u(K)},preview:Y,canApply:c.length>0&&l.emptyNew.length===0&&!S&&!h,applyNote:Kn(S?t(S):null,l.emptyNew,t),apply:Z}}function Yn({source:e,groups:t}){const r=W(),n=Pn(e),a=x.useMemo(()=>new Map((t??[]).map(o=>[o.name,o])),[t]);return n.error?f.jsx(dr,{error:n.error,onRetry:n.retry}):n.loading?f.jsx(cr,{}):f.jsxs("div",{className:"rp-arrange",children:[f.jsxs("div",{className:"rp-row",children:[f.jsxs("p",{className:"rp-note rp-grow",children:[f.jsx("span",{className:"rp-wide-only",children:r("arrange.note")}),f.jsx("span",{className:"rp-narrow-only",children:r("arrange.selectHint")})]}),f.jsx(An,{m:n})]}),n.blocked&&f.jsx(Q,{tone:"informative",children:n.blocked}),f.jsxs("div",{className:"rp-arrange-grid",children:[f.jsx("div",{className:"rp-col",children:n.groups.length?n.groups.map(o=>f.jsx(Bn,{group:o,live:a.get(o.name),m:n},o.name)):f.jsx(lt,{children:r("policy.empty")})}),f.jsx(In,{m:n})]}),n.changes.length>0&&f.jsxs(En,{label:r("arrange.pendingRegion"),message:n.pendingText,children:[f.jsx(L,{quiet:!0,onPress:n.discard,isDisabled:n.busy,children:r("arrange.discard")}),f.jsx(L,{accent:!0,onPress:()=>n.setReviewing(!0),children:r("arrange.review")})]}),f.jsx(On,{m:n})]})}function Bn({group:e,live:t,m:r}){const n=W(),a=dt(),o=x.useId(),y=!!r.blocked,c=t?Sr(t.policy,n):null,D=async $=>{const l=await Promise.all($.filter(Rr).filter(d=>d.types.has(pe)).map(d=>d.getText(pe)));r.place(e.name,l.flatMap(d=>Cn(d)??[]))},v=($,l,d)=>f.jsx(L,{quiet:!0,icon:!0,small:!0,label:n("arrange.remove",{name:$,group:e.name}),isDisabled:y||r.applying||!!d,onPress:()=>r.unplace(e.name,l),children:f.jsx(ct,{})}),g=($,l)=>f.jsx(L,{quiet:!0,small:!0,label:n("arrange.undoRemove",{name:$}),isDisabled:r.applying,onPress:()=>r.place(e.name,[l]),children:n("arrange.undoShort")});return f.jsx(nn,{className:mr("rp-drop"),"aria-label":n("arrange.dropInto",{group:e.name}),isDisabled:y||r.applying,getDropOperation:$=>$.has(pe)?"copy":"cancel",onDrop:$=>void D($.items),children:({isDropTarget:$})=>f.jsxs(f.Fragment,{children:[f.jsx("div",{className:"rp-row",children:f.jsxs("span",{className:"rp-cluster",children:[f.jsx("h3",{className:"rp-h3",id:o,children:e.name}),c&&f.jsx(Ye,{tip:c.id,children:c.label}),t&&f.jsx(pr,{small:!0,tone:"neutral",children:n("arrange.memberCount",{n:t.member_count})}),e.isNew&&f.jsx(Ye,{children:n("arrange.new")})]})}),e.holdsAll&&f.jsx("p",{className:"rp-note",children:n("arrange.holdsAll")}),f.jsxs(fr,{reason:kn(e,y||r.applying),children:[(e.names.length>0||e.removedNames.length>0)&&f.jsxs(Je,{label:n("arrange.byName"),children:[f.jsx("span",{className:"rp-label rp-tags-title",children:n("arrange.byName")}),e.names.map(l=>f.jsx(ue,{tone:l.isNew?"new":void 0,action:v(l.name,{kind:"node",value:l.name},l.blocked),children:l.name},l.name)),e.removedNames.map(l=>f.jsx(ue,{tone:"removed",action:g(l,{kind:"node",value:l}),children:l},l))]}),(e.subscriptions.length>0||e.removedSubscriptions.length>0)&&f.jsxs(Je,{label:n("arrange.bySubscription"),children:[f.jsx("span",{className:"rp-label rp-tags-title",children:n("arrange.bySubscription")}),e.subscriptions.map(l=>f.jsx(ue,{tone:l.isNew?"new":void 0,action:v(l.label,{kind:"subscription",value:l.tag},l.blocked),children:l.count===null?l.label:n("arrange.subscriptionCount",{name:l.label,n:l.count})},l.tag)),e.removedSubscriptions.map(l=>f.jsx(ue,{tone:"removed",action:g(l.label,{kind:"subscription",value:l.tag}),children:l.label},l.tag))]})]}),e.rules.length>0&&f.jsxs("div",{className:"rp-arrange-rules",children:[f.jsx("span",{className:"rp-label",children:n("arrange.byRule")}),e.rules.map(l=>f.jsx(pt,{as:"code",text:l},l)),e.ruleNodes.length>0&&f.jsx("span",{children:e.ruleMore?n("arrange.ruleSelectsMore",{names:de(a,e.ruleNodes),n:e.ruleMore}):n("arrange.ruleSelects",{names:de(a,e.ruleNodes)})}),f.jsxs("span",{className:"rp-label",children:[e.ruleNote," ",f.jsx(gr,{appearance:"link",href:yr("config",{tab:"source"}),children:n("arrange.editSource")})]})]}),e.stillIn.length>0&&f.jsx(Q,{tone:"informative",children:n("arrange.stillIn",{names:de(a,e.stillIn)})}),$&&f.jsx("div",{className:"rp-drop-hint","aria-hidden":"true",children:n("arrange.dropHint")})]})})}function In({m:e}){const t=W(),r=x.useId(),n=!!e.blocked||e.applying,[a,o]=x.useState("all"),[y,c]=x.useState(new Set),D=x.useMemo(()=>[...a==="node"?[]:e.subscriptions.map(d=>({id:"subscription:"+d.tag,item:{kind:"subscription",value:d.tag},label:d.label,meta:t("arrange.subscriptionMeta",{n:d.count})})),...a==="subscription"?[]:e.nodes.map(d=>({id:"node:"+d.name,item:{kind:"node",value:d.name},label:d.name,meta:d.protocol??""}))],[a,e.subscriptions,e.nodes,t]),v=x.useMemo(()=>new Map(D.map(d=>[d.id,d])),[D]),g=y==="all"?D:[...y].flatMap(d=>v.get(String(d))??[]),{dragAndDropHooks:$}=vn({getItems:d=>[...d].flatMap(p=>v.has(String(p))?[{[pe]:JSON.stringify(v.get(String(p)).item),"text/plain":v.get(String(p)).label}]:[]),getAllowedDropOperations:()=>["copy"],isDisabled:n}),l=e.groups.filter(d=>g.some(p=>!Ft(d,p.item)));return f.jsxs(hr,{title:t("arrange.tray"),titleId:r,className:"rp-tray",children:[f.jsx(ut,{search:!0,label:t("arrange.search"),value:e.search,onChange:e.setSearch}),f.jsx(Dr,{label:t("arrange.show"),value:a,onChange:d=>o(d),items:[["all",t("ui.all")],["subscription",t("arrange.subscriptions")],["node",t("arrange.nodes")]]}),f.jsx(Kr,{layout:Cr,layoutOptions:{rowHeight:48},children:f.jsx(Tr,{"aria-labelledby":r,className:"rp-tray-list",items:D,selectionMode:"multiple",selectionBehavior:"toggle",selectedKeys:y,onSelectionChange:c,dragAndDropHooks:$,renderEmptyState:()=>f.jsx(lt,{children:t("arrange.trayEmpty")}),children:d=>f.jsxs(kr,{id:d.id,textValue:d.label,className:"rp-item rp-tray-row",children:[f.jsx(br,{slot:"drag",className:Ie($r({quiet:!0,icon:!0,small:!0}),"rp-drag"),"aria-label":t("arrange.drag",{name:d.label}),children:f.jsx(xn,{})}),f.jsx(vr,{}),f.jsxs("span",{className:"rp-grow",children:[f.jsx(Er,{children:d.label}),f.jsx("span",{className:"desc",children:d.meta})]})]})})}),f.jsxs("div",{className:"rp-tray-bar",children:[f.jsx("span",{className:"rp-grow rp-label","aria-live":"polite",children:g.length?t("arrange.selected",{n:g.length}):t("arrange.selectHint")}),g.length>0&&f.jsx(L,{quiet:!0,small:!0,onPress:()=>c(new Set),children:t("arrange.clear")}),f.jsx(xr,{label:t("arrange.addSelected"),isDisabled:n||!l.length,items:l.map(d=>({id:d.name,label:d.name})),onAction:d=>{e.place(d,g.map(p=>p.item)),c(new Set)},children:t("arrange.addSelected")})]})]})}function An({m:e}){const t=W(),r=x.useId(),[n,a]=x.useState(!1),[o,y]=x.useState(""),[c,D]=x.useState(Xe[0].id),[v,g]=x.useState(!1),$=e.nameProblem(o.trim()),l=()=>{y(""),D(Xe[0].id),g(!1)};return f.jsxs(f.Fragment,{children:[f.jsx(L,{small:!0,onPress:()=>a(!0),isDisabled:!!e.blocked||e.applying,children:t("arrange.newGroup")}),f.jsx(st,{title:t("arrange.newGroup"),narrow:!0,isOpen:n,onOpenChange:d=>{a(d),d||l()},footer:d=>f.jsxs(f.Fragment,{children:[f.jsx(L,{onPress:d,children:t("ui.cancel")}),f.jsx(L,{accent:!0,type:"submit",form:r,children:t("arrange.create")})]}),children:f.jsxs("form",{id:r,className:"rp-form",onSubmit:d=>{d.preventDefault(),g(!0),!$&&(e.create(o.trim(),c),a(!1),l())},children:[f.jsx(ut,{label:t("arrange.groupName"),value:o,onChange:y,description:t("arrange.groupNameHint"),error:v&&$?$:void 0,spellCheck:!1}),f.jsx(Pr,{value:c,onChange:D}),f.jsx("p",{className:"rp-label",children:t("arrange.newGroupNote")})]})})]})}function On({m:e}){const t=W(),r=dt();return f.jsxs(st,{title:t("arrange.reviewTitle"),isOpen:e.reviewing,onOpenChange:e.setReviewing,footer:n=>f.jsxs(f.Fragment,{children:[f.jsx(L,{onPress:n,isDisabled:e.applying,children:t("ui.cancel")}),f.jsx(L,{accent:!0,isPending:e.applying,isDisabled:!e.canApply,onPress:()=>void e.apply(),children:t("config.save")})]}),children:[e.failure&&f.jsx(Q,{takeFocus:!0,children:e.failure}),e.applyNote&&f.jsx(Q,{children:e.applyNote}),e.unknown.size>0&&f.jsx(Q,{tone:"informative",children:t("arrange.unknown",{names:de(r,[...e.unknown])})}),f.jsx("ol",{className:"rp-arrange-changes",children:e.changeLines.map((n,a)=>f.jsxs("li",{className:"rp-row",children:[f.jsx("span",{className:"rp-grow",children:n}),f.jsx(L,{quiet:!0,icon:!0,small:!0,label:t("arrange.undo",{change:n}),isDisabled:e.applying,onPress:()=>e.drop(a),children:f.jsx(ct,{})})]},a))}),f.jsx(wr,{title:t("arrange.showText"),children:e.preview.map(n=>f.jsx(pt,{as:"pre",className:"rp-arrange-preview",text:n.text},n.group))}),f.jsx("p",{className:"rp-label",children:t("arrange.applyNote")})]})}export{Yn as Arrange}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Arrange-BwxzZLbt.js b/luci-app-honk/root/etc/honk/doona/assets/Arrange-BwxzZLbt.js new file mode 100644 index 000000000..617481c5c --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/Arrange-BwxzZLbt.js @@ -0,0 +1,4 @@ +import{r as E,$ as W,a as Pt,j as f}from"./vendor-react-Bf71BWbF.js";import{fk as Bt,fE as It,fe as ie,ca as H,c8 as M,fF as et,fG as tt,fH as At,c2 as Le,fb as S,fc as ae,fd as Ie,eZ as R,fq as rt,fI as Ot,fJ as Mt,fK as jt,b$ as Nt,cb as Rt,ci as Lt,fL as Vt,ck as Gt,cl as Ht,bZ as zt,fi as Yt,cn as Ut,bW as Xt,cp as qt,cr as _t,co as Wt,fM as Jt,fN as Zt,bX as Ke,aQ as Qt,fu as er,fr as tr,c7 as rr,fO as nt,fP as at,fQ as le,bY as nr,bU as ot,eY as ar,c as Ae,M as Ce,dR as Ve,dY as it,fR as Ge,fS as He,e6 as lt,u as J,aa as or,ad as ir,ac as ze,af as lr,cS as sr,et as ur,b as dr,bm as Ye,E as cr,j as pr,I as te,ak as st,B as V,dT as Ue,ah as ut,T as dt,a as ct,aO as Xe,aJ as fr,bQ as gr,a3 as pe,L as yr,h as mr,bR as hr,aN as Dr,bs as br,fv as $r,fw as vr,fT as Er,aL as xr,br as wr,aj as pt,cY as Tr}from"./index-Bw0aJc9a.js";import{$ as kr,a as Kr}from"./Policies-Dgwc4tfn.js";import{d as Cr}from"./Virtualizer-DCY9HC9Z.js";import{$ as Sr}from"./ListLayout-_fDlx5XY.js";import{D as ft}from"./DaeCode-B8yPDjSE.js";import{b as Fr,g as Pr}from"./policyText-CltaDVEo.js";import{P as Br}from"./openGroup-Dk9B33qx.js";import{$ as Ir}from"./useFilter-Tjznm3lB.js";import"./ActionGroup-DLxTuKht.js";import"./useGridSelectionCheckbox-COXIVEmS.js";import"./nav-BASDWt23.js";var P=(function(e){return e[e.none=0]="none",e[e.cancel=0]="cancel",e[e.move=1]="move",e[e.copy=2]="copy",e[e.link=4]="link",e[e.all=7]="all",e})({});const gt={...P,copyMove:3,copyLink:6,linkMove:5,all:7,uninitialized:7},yt=mt(gt);yt[7]="all";const re={none:"cancel",link:"link",copy:"copy",move:"move"},be=mt(re);function mt(e){let t={};for(let r in e)t[e[r]]=r;return t}const Ar=new Set(["text/plain","text/uri-list","text/html"]),ye="application/vnd.react-aria.items+json",me="application/octet-stream",Oe=new WeakMap,ht=Symbol();function Or(e){let{id:t}=Oe.get(e)||{};if(!t)throw new Error("Droppable item outside a droppable collection");return t}function Mr(e){let{ref:t}=Oe.get(e)||{};if(!t)throw new Error("Droppable item outside a droppable collection");return t}function z(e){let t=new Set;for(let r of e)for(let n of Object.keys(r))t.add(n);return t}function Dt(e){return e||(e="virtual"),e==="pointer"&&(e="virtual"),e==="virtual"&&typeof window<"u"&&typeof window.matchMedia=="function"&&window.matchMedia("(pointer: coarse)").matches&&(e="touch"),e}function Me(){return Dt(Bt())}function bt(){return Dt(It())}function Se(e,t){let r=new Map,n=!1,a=[];for(let o of t){let g=Object.keys(o);g.length>1&&(n=!0);let c={};for(let y of g){let $=r.get(y);$?n=!0:($=[],r.set(y,$));let m=o[y];c[y]=m,$.push(m)}a.push(c)}for(let[o,g]of r)if(Ar.has(o)){let c=g.join(` +`);e.items.add(c,o)}else e.items.add(g[0],o);if(n){let o=JSON.stringify(a);e.items.add(o,ye)}}class se{constructor(t){this.types=new Set;let r=!1;for(let n of t.items)n.type!==ye&&(n.kind==="file"&&(r=!0),n.type?this.types.add(n.type):this.types.add(me));this.includesUnknownTypes=!r&&t.types.includes("Files")}has(t){if(Array.isArray(t))return t.some(r=>this.has(r));if(this.includesUnknownTypes||t===ht&&this.types.has(me)||t==="*/*")return!0;if(typeof t=="string"){if(t.endsWith("/*")){for(let r of this.types)if(r.startsWith(t.slice(0,-2)))return!0;return!1}return this.types.has(t)}return!1}}function $t(e){let t=[];if(!e)return t;let r=!1;if(e.types.includes(ye))try{let n=e.getData(ye),a=JSON.parse(n);for(let o of a)t.push({kind:"text",types:new Set(Object.keys(o)),getText:g=>Promise.resolve(o[g])});r=!0}catch{}if(!r){let n=new Map;for(let a of e.items)if(a.kind==="string")n.set(a.type||me,e.getData(a.type));else if(a.kind==="file")if(typeof a.webkitGetAsEntry=="function"){let o=a.webkitGetAsEntry();if(!o)continue;o.isFile?t.push(Fe(a.getAsFile())):o.isDirectory&&t.push(vt(o))}else t.push(Fe(a.getAsFile()));n.size>0&&t.push({kind:"text",types:new Set(n.keys()),getText:a=>Promise.resolve(n.get(a))})}return t}function jr(e){return typeof e.text=="function"?e.text():new Promise((t,r)=>{let n=new FileReader;n.onload=()=>{t(n.result)},n.onerror=r,n.readAsText(e)})}function Fe(e){if(!e)throw new Error("No file provided");return{kind:"file",type:e.type||me,name:e.name,getText:()=>jr(e),getFile:()=>Promise.resolve(e)}}function vt(e){return{kind:"directory",name:e.name,getEntries:()=>Nr(e)}}async function*Nr(e){let t=e.createReader(),r;do{r=await new Promise((n,a)=>{t.readEntries(n,a)});for(let n of r)if(n.isFile){let a=await Rr(n);yield Fe(a)}else n.isDirectory&&(yield vt(n))}while(r.length>0)}function Rr(e){return new Promise((t,r)=>e.file(t,r))}function Lr(e){return e.kind==="text"}let B={draggingKeys:new Set};function Vr(e){B.draggingCollectionRef=e}function Gr(e){B.draggingKeys=e}function q(e){B.dropCollectionRef=e}function Et(){B={draggingKeys:new Set}}function Hr(e){B=e}function G(e){let{draggingCollectionRef:t,dropCollectionRef:r}=B;return t?.current!=null&&t.current===(e?.current||r?.current)}let fe;function he(e){fe=e}let Pe=P.none;function $e(e){Pe=e}let Be=new Map,ne=new Map,L=null,De=new Set;function xt(e){return Be.set(e.element,e),L?.updateValidDropTargets(),()=>{Be.delete(e.element),L?.updateValidDropTargets()}}function zr(e){return ne.set(e.element,e),()=>{ne.delete(e.element)}}function Yr(e,t){if(L)throw new Error("Cannot begin dragging while already dragging");L=new Wr(e,t),requestAnimationFrame(()=>{L&&(L.setup(),bt()==="keyboard"&&L.next())});for(let r of De)r()}function je(){let[e,t]=E.useState(L);return E.useEffect(()=>{let r=()=>t(L);return De.add(r),()=>{De.delete(r)}},[]),e}function Ur(){return!!L}function Xr(){L=null;for(let e of De)e()}const qe=["pointerdown","pointermove","pointerenter","pointerleave","pointerover","pointerout","pointerup","mousedown","mousemove","mouseenter","mouseleave","mouseover","mouseout","mouseup","touchstart","touchmove","touchend","focusin","focusout"],qr=["pointerup","mouseup","touchend"],_r={keyboard:"dragStartedKeyboard",touch:"dragStartedTouch",virtual:"dragStartedVirtual"};class Wr{constructor(t,r){this.validDropTargets=[],this.currentDropTarget=null,this.currentDropItem=null,this.dropOperation=null,this.mutationObserver=null,this.restoreAriaHidden=null,this.isVirtualClick=!1,this.dragTarget=t,this.stringFormatter=r,this.onKeyDown=this.onKeyDown.bind(this),this.onKeyUp=this.onKeyUp.bind(this),this.onFocus=this.onFocus.bind(this),this.onBlur=this.onBlur.bind(this),this.onClick=this.onClick.bind(this),this.onPointerDown=this.onPointerDown.bind(this),this.cancelEvent=this.cancelEvent.bind(this),this.initialFocused=!1}setup(){document.addEventListener("keydown",this.onKeyDown,!0),document.addEventListener("keyup",this.onKeyUp,!0),window.addEventListener("focus",this.onFocus,!0),window.addEventListener("blur",this.onBlur,!0),document.addEventListener("click",this.onClick,!0),document.addEventListener("pointerdown",this.onPointerDown,!0);for(let t of qe)document.addEventListener(t,this.cancelEvent,!0);this.mutationObserver=new MutationObserver(()=>this.updateValidDropTargets()),this.updateValidDropTargets(),ie(this.stringFormatter.format(_r[bt()]))}teardown(){document.removeEventListener("keydown",this.onKeyDown,!0),document.removeEventListener("keyup",this.onKeyUp,!0),window.removeEventListener("focus",this.onFocus,!0),window.removeEventListener("blur",this.onBlur,!0),document.removeEventListener("click",this.onClick,!0),document.removeEventListener("pointerdown",this.onPointerDown,!0);for(let t of qe)document.removeEventListener(t,this.cancelEvent,!0);this.mutationObserver?.disconnect(),this.restoreAriaHidden?.()}onKeyDown(t){if(this.cancelEvent(t),t.key==="Escape"){this.cancel();return}t.key==="Tab"&&!(t.metaKey||t.altKey||t.ctrlKey)&&(t.shiftKey?this.previous():this.next()),typeof this.currentDropTarget?.onKeyDown=="function"&&this.currentDropTarget.onKeyDown(t,this.dragTarget)}onKeyUp(t){this.cancelEvent(t),t.key==="Enter"&&(t.altKey||H(this.getCurrentActivateButton(),M(t))?this.activate(this.currentDropTarget,this.currentDropItem):this.drop())}getCurrentActivateButton(){return this.currentDropItem?.activateButtonRef?.current??this.currentDropTarget?.activateButtonRef?.current??null}onFocus(t){let r=this.getCurrentActivateButton(),n=M(t);if(n===r){this.cancelEvent(t);return}if(n!==this.dragTarget.element&&this.cancelEvent(t),!(n instanceof HTMLElement)||n===this.dragTarget.element)return;let a=this.validDropTargets.find(g=>g.element===n)||this.validDropTargets.find(g=>H(g.element,n));if(!a){this.currentDropTarget?this.currentDropTarget.element.focus():this.dragTarget.element.focus();return}let o=ne.get(n);a&&this.setCurrentDropTarget(a,o)}onBlur(t){let r=this.getCurrentActivateButton();if(r&&t.relatedTarget===r){this.cancelEvent(t);return}M(t)!==this.dragTarget.element&&this.cancelEvent(t),(!t.relatedTarget||!(t.relatedTarget instanceof HTMLElement))&&(this.currentDropTarget?this.currentDropTarget.element.focus():this.dragTarget.element.focus())}onClick(t){if(this.cancelEvent(t),et(t)||this.isVirtualClick){let r=ne.values(),n=M(t),a=[...r].find(c=>c.element===n||H(c.activateButtonRef?.current,n)),o=this.validDropTargets.find(c=>H(c.element,n)),g=a?.activateButtonRef?.current??o?.activateButtonRef?.current;if(H(g,n)&&o){this.activate(o,a);return}if(M(t)===this.dragTarget.element){this.cancel();return}o&&(this.setCurrentDropTarget(o,a),this.drop(a))}}onPointerDown(t){this.cancelEvent(t),this.isVirtualClick=tt(t)}cancelEvent(t){let r=M(t);(t.type==="focusin"||t.type==="focusout")&&(r===this.dragTarget?.element||r===this.getCurrentActivateButton())||(qr.includes(t.type)||t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation())}updateValidDropTargets(){if(!this.mutationObserver)return;if(this.mutationObserver.disconnect(),this.restoreAriaHidden&&this.restoreAriaHidden(),this.validDropTargets=Jr(this.dragTarget),this.validDropTargets.length>0){let a=this.findNearestDropTarget();this.validDropTargets=[...this.validDropTargets.slice(a),...this.validDropTargets.slice(0,a)]}this.currentDropTarget&&!this.validDropTargets.includes(this.currentDropTarget)&&this.setCurrentDropTarget(this.validDropTargets[0]);let t=z(this.dragTarget.items),r=[...ne.values()].filter(a=>typeof a.getDropOperation=="function"?a.getDropOperation(t,this.dragTarget.allowedDropOperations)!=="cancel":!0),n=this.validDropTargets.filter(a=>!r.some(o=>H(a.element,o.element)));this.restoreAriaHidden=At([this.dragTarget.element,...r.flatMap(a=>a.activateButtonRef?.current?[a.element,a.activateButtonRef?.current]:[a.element]),...n.flatMap(a=>a.activateButtonRef?.current?[a.element,a.activateButtonRef?.current]:[a.element])],{shouldUseInert:!0}),this.mutationObserver.observe(document.body,{subtree:!0,attributes:!0,attributeFilter:["aria-hidden","inert"]})}next(){if(!this.currentDropTarget){this.setCurrentDropTarget(this.validDropTargets[0]);return}let t=this.validDropTargets.indexOf(this.currentDropTarget);if(t<0){this.setCurrentDropTarget(this.validDropTargets[0]);return}t===this.validDropTargets.length-1?this.dragTarget.element.closest('[aria-hidden="true"], [inert]')?this.setCurrentDropTarget(this.validDropTargets[0]):(this.setCurrentDropTarget(null),this.dragTarget.element.focus()):this.setCurrentDropTarget(this.validDropTargets[t+1])}previous(){if(!this.currentDropTarget){this.setCurrentDropTarget(this.validDropTargets[this.validDropTargets.length-1]);return}let t=this.validDropTargets.indexOf(this.currentDropTarget);if(t<0){this.setCurrentDropTarget(this.validDropTargets[this.validDropTargets.length-1]);return}t===0?this.dragTarget.element.closest('[aria-hidden="true"], [inert]')?this.setCurrentDropTarget(this.validDropTargets[this.validDropTargets.length-1]):(this.setCurrentDropTarget(null),this.dragTarget.element.focus()):this.setCurrentDropTarget(this.validDropTargets[t-1])}findNearestDropTarget(){let t=this.dragTarget.element.getBoundingClientRect(),r=1/0,n=-1,a=-1;for(let o=0;o=0?a:n}setCurrentDropTarget(t,r){if(t!==this.currentDropTarget){if(this.currentDropTarget&&typeof this.currentDropTarget.onDropExit=="function"){let n=this.currentDropTarget.element.getBoundingClientRect();this.currentDropTarget.onDropExit({type:"dropexit",x:n.left+n.width/2,y:n.top+n.height/2})}if(this.currentDropTarget=t,t){if(typeof t.onDropEnter=="function"){let n=t.element.getBoundingClientRect();t.onDropEnter({type:"dropenter",x:n.left+n.width/2,y:n.top+n.height/2},this.dragTarget)}r||t?.element.focus()}}if(r!=null&&r!==this.currentDropItem&&(this.currentDropTarget&&typeof this.currentDropTarget.onDropTargetEnter=="function"&&this.currentDropTarget.onDropTargetEnter(r.target),r.element.focus(),this.currentDropItem=r,!this.initialFocused)){let n=r?.element.getAttribute("aria-label");n&&ie(n,"polite"),this.initialFocused=!0}}end(){if(this.teardown(),Xr(),typeof this.dragTarget.onDragEnd=="function"){let r=(this.currentDropTarget&&this.dropOperation!=="cancel"?this.currentDropTarget:this.dragTarget).element.getBoundingClientRect();this.dragTarget.onDragEnd({type:"dragend",x:r.x+r.width/2,y:r.y+r.height/2,dropOperation:this.dropOperation||"cancel"})}this.currentDropTarget&&!this.currentDropTarget.preventFocusOnDrop&&Le()?.dispatchEvent(new FocusEvent("focusin",{bubbles:!0})),this.setCurrentDropTarget(null)}cancel(){this.setCurrentDropTarget(null),this.end(),this.dragTarget.element.closest('[aria-hidden="true"], [inert]')||this.dragTarget.element.focus(),Le()?.dispatchEvent(new FocusEvent("focusin",{bubbles:!0})),ie(this.stringFormatter.format("dropCanceled"))}drop(t){if(!this.currentDropTarget){this.cancel();return}if(typeof t?.getDropOperation=="function"){let r=z(this.dragTarget.items);this.dropOperation=t.getDropOperation(r,this.dragTarget.allowedDropOperations)}else if(typeof this.currentDropTarget.getDropOperation=="function"){let r=z(this.dragTarget.items);this.dropOperation=this.currentDropTarget.getDropOperation(r,this.dragTarget.allowedDropOperations)}else this.dropOperation=this.dragTarget.allowedDropOperations[0];if(typeof this.currentDropTarget.onDrop=="function"){let r=this.dragTarget.items.map(a=>({kind:"text",types:new Set(Object.keys(a)),getText:o=>Promise.resolve(a[o])})),n=this.currentDropTarget.element.getBoundingClientRect();this.currentDropTarget.onDrop({type:"drop",x:n.left+n.width/2,y:n.top+n.height/2,items:r,dropOperation:this.dropOperation},t?.target??null)}this.end(),ie(this.stringFormatter.format("dropComplete"))}activate(t,r){if(t&&typeof t.onDropActivate=="function"){let n=r?.target??null,a=t.element.getBoundingClientRect();t.onDropActivate({type:"dropactivate",x:a.left+a.width/2,y:a.top+a.height/2},n)}}}function Jr(e){let t=z(e.items);return[...Be.values()].filter(r=>r.element.closest('[aria-hidden="true"], [inert]')?!1:typeof r.getDropOperation=="function"?r.getDropOperation(t,e.allowedDropOperations)!=="cancel":!0)}var wt={};wt={dragItem:e=>`Drag ${e.itemText}`,dragSelectedItems:(e,t)=>`Drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}`,dragDescriptionKeyboard:"Press Enter to start dragging.",dragDescriptionKeyboardAlt:"Press Alt + Enter to start dragging.",dragDescriptionTouch:"Double tap to start dragging.",dragDescriptionVirtual:"Click to start dragging.",dragDescriptionLongPress:"Long press to start dragging.",dragSelectedKeyboard:(e,t)=>`Press Enter to drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}.`,dragSelectedKeyboardAlt:(e,t)=>`Press Alt + Enter to drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}.`,dragSelectedLongPress:(e,t)=>`Long press to drag ${t.plural(e.count,{one:()=>`${t.number(e.count)} selected item`,other:()=>`${t.number(e.count)} selected items`})}.`,dragStartedKeyboard:"Started dragging. Press Tab to navigate to a drop target, then press Enter to drop, or press Escape to cancel.",dragStartedTouch:"Started dragging. Navigate to a drop target, then double tap to drop.",dragStartedVirtual:"Started dragging. Navigate to a drop target, then click or press Enter to drop.",endDragKeyboard:"Dragging. Press Enter to cancel drag.",endDragTouch:"Dragging. Double tap to cancel drag.",endDragVirtual:"Dragging. Click to cancel drag.",dropDescriptionKeyboard:"Press Enter to drop. Press Escape to cancel drag.",dropDescriptionTouch:"Double tap to drop.",dropDescriptionVirtual:"Click to drop.",dropCanceled:"Drop canceled.",dropComplete:"Drop complete.",dropIndicator:"drop indicator",dropOnRoot:"Drop on",dropOnItem:e=>`Drop on ${e.itemText}`,insertBefore:e=>`Insert before ${e.itemText}`,insertBetween:e=>`Insert between ${e.beforeItemText} and ${e.afterItemText}`,insertAfter:e=>`Insert after ${e.itemText}`};var Tt={};Tt={dragDescriptionKeyboard:"按 Enter 开始拖动。",dragDescriptionKeyboardAlt:"按 Alt + Enter 开始拖动。",dragDescriptionLongPress:"长按以开始拖动。",dragDescriptionTouch:"双击开始拖动。",dragDescriptionVirtual:"单击开始拖动。",dragItem:e=>`拖动 ${e.itemText}`,dragSelectedItems:(e,t)=>`拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 选中项目`,other:()=>`${t.number(e.count)} 选中项目`})}`,dragSelectedKeyboard:(e,t)=>`按 Enter 以拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 个选定项`,other:()=>`${t.number(e.count)} 个选定项`})}。`,dragSelectedKeyboardAlt:(e,t)=>`按 Alt + Enter 以拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 个选定项`,other:()=>`${t.number(e.count)} 个选定项`})}。`,dragSelectedLongPress:(e,t)=>`长按以拖动 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 个选定项`,other:()=>`${t.number(e.count)} 个选定项`})}。`,dragStartedKeyboard:"已开始拖动。按 Tab 导航到放置目标,然后按 Enter 放置或按 Escape 取消。",dragStartedTouch:"已开始拖动。导航到放置目标,然后双击放置。",dragStartedVirtual:"已开始拖动。导航到放置目标,然后单击或按 Enter 放置。",dropCanceled:"放置已取消。",dropComplete:"放置已完成。",dropDescriptionKeyboard:"按 Enter 放置。按 Escape 取消拖动。",dropDescriptionTouch:"双击放置。",dropDescriptionVirtual:"单击放置。",dropIndicator:"放置标记",dropOnItem:e=>`放置于 ${e.itemText}`,dropOnRoot:"放置于",endDragKeyboard:"正在拖动。按 Enter 取消拖动。",endDragTouch:"正在拖动。双击取消拖动。",endDragVirtual:"正在拖动。单击取消拖动。",insertAfter:e=>`插入到 ${e.itemText} 之后`,insertBefore:e=>`插入到 ${e.itemText} 之前`,insertBetween:e=>`插入到 ${e.beforeItemText} 和 ${e.afterItemText} 之间`};var kt={};kt={dragDescriptionKeyboard:"按 Enter 鍵以開始拖曳。",dragDescriptionKeyboardAlt:"按 Alt+Enter 鍵以開始拖曳。",dragDescriptionLongPress:"長按以開始拖曳。",dragDescriptionTouch:"輕點兩下以開始拖曳。",dragDescriptionVirtual:"按一下滑鼠以開始拖曳。",dragItem:e=>`拖曳「${e.itemText}」`,dragSelectedItems:(e,t)=>`拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}`,dragSelectedKeyboard:(e,t)=>`按 Enter 鍵以拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}。`,dragSelectedKeyboardAlt:(e,t)=>`按 Alt+Enter 鍵以拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}。`,dragSelectedLongPress:(e,t)=>`長按以拖曳 ${t.plural(e.count,{one:()=>`${t.number(e.count)} 個選定項目`,other:()=>`${t.number(e.count)} 個選定項目`})}。`,dragStartedKeyboard:"已開始拖曳。按 Tab 鍵以瀏覽至放置目標,然後按 Enter 鍵以放置,或按 Escape 鍵以取消。",dragStartedTouch:"已開始拖曳。瀏覽至放置目標,然後輕點兩下以放置。",dragStartedVirtual:"已開始拖曳。瀏覽至放置目標,然後按一下滑鼠或按 Enter 鍵以放置。",dropCanceled:"放置已取消。",dropComplete:"放置已完成。",dropDescriptionKeyboard:"按 Enter 鍵以放置。按 Escape 鍵以取消拖曳。",dropDescriptionTouch:"輕點兩下以放置。",dropDescriptionVirtual:"按一下滑鼠以放置。",dropIndicator:"放置指示器",dropOnItem:e=>`放置在「${e.itemText}」上`,dropOnRoot:"放置在",endDragKeyboard:"拖曳中。按 Enter 鍵以取消拖曳。",endDragTouch:"拖曳中。輕點兩下以取消拖曳。",endDragVirtual:"拖曳中。按一下滑鼠以取消拖曳。",insertAfter:e=>`插入至「${e.itemText}」之後`,insertBefore:e=>`插入至「${e.itemText}」之前`,insertBetween:e=>`插入至「${e.beforeItemText}」和「${e.afterItemText}」之間`};var oe={};oe={"ar-AE":S,"bg-BG":S,"cs-CZ":S,"da-DK":S,"de-DE":S,"el-GR":S,"en-US":wt,"es-ES":S,"et-EE":S,"fi-FI":S,"fr-FR":S,"he-IL":S,"hr-HR":S,"hu-HU":S,"it-IT":S,"ja-JP":S,"ko-KR":S,"lt-LT":S,"lv-LV":S,"nb-NO":S,"nl-NL":S,"pl-PL":S,"pt-BR":S,"pt-PT":S,"ro-RO":S,"ru-RU":S,"sk-SK":S,"sl-SI":S,"sr-SP":S,"sv-SE":S,"tr-TR":S,"uk-UA":S,"zh-CN":Tt,"zh-TW":kt};function Zr(e){return e&&e.__esModule?e.default:e}const Qr={keyboard:"dropDescriptionKeyboard",touch:"dropDescriptionTouch",virtual:"dropDescriptionVirtual"};function Kt(){let e=ae(Zr(oe),"@react-aria/dnd"),t=Me(),r=je();return{dropProps:{...Ie(r?e.format(Qr[t]):""),onClick:()=>{}}}}const en=800;function Ct(e){let{hasDropButton:t,isDisabled:r}=e,[n,a]=E.useState(!1),o=E.useRef({x:0,y:0,dragOverElements:new Set,dropEffect:"none",allowedOperations:P.all,dropActivateTimer:void 0}).current,g=i=>{if(a(!0),typeof e.onDropEnter=="function"){let s=i.currentTarget.getBoundingClientRect();e.onDropEnter({type:"dropenter",x:i.clientX-s.x,y:i.clientY-s.y})}},c=i=>{if(a(!1),typeof e.onDropExit=="function"){let s=i.currentTarget.getBoundingClientRect();e.onDropExit({type:"dropexit",x:i.clientX-s.x,y:i.clientY-s.y})}},y=i=>{i.preventDefault(),i.stopPropagation();let s=_e(i);if(i.clientX===o.x&&i.clientY===o.y&&s===o.allowedOperations){i.dataTransfer.dropEffect=o.dropEffect;return}o.x=i.clientX,o.y=i.clientY;let u=o.dropEffect;if(s!==o.allowedOperations){let D=ve(s),w=D[0];if(typeof e.getDropOperation=="function"){let k=new se(i.dataTransfer);w=ue(s,e.getDropOperation(k,D))}o.dropEffect=be[w]||"none"}if(typeof e.getDropOperationForPoint=="function"){let D=new se(i.dataTransfer),w=i.currentTarget.getBoundingClientRect(),k=ue(s,e.getDropOperationForPoint(D,ve(s),o.x-w.x,o.y-w.y));o.dropEffect=be[k]||"none"}if(o.allowedOperations=s,i.dataTransfer.dropEffect=o.dropEffect,o.dropEffect==="none"&&u!=="none"?c(i):o.dropEffect!=="none"&&u==="none"&&g(i),typeof e.onDropMove=="function"&&o.dropEffect!=="none"){let D=i.currentTarget.getBoundingClientRect();e.onDropMove({type:"dropmove",x:o.x-D.x,y:o.y-D.y})}if(clearTimeout(o.dropActivateTimer),e.onDropActivate&&typeof e.onDropActivate=="function"&&o.dropEffect!=="none"){let D=e.onDropActivate,w=i.currentTarget.getBoundingClientRect();o.dropActivateTimer=setTimeout(()=>{D({type:"dropactivate",x:o.x-w.x,y:o.y-w.y})},en)}},$=i=>{if(i.preventDefault(),i.stopPropagation(),o.dragOverElements.add(M(i)),o.dragOverElements.size>1)return;let s=_e(i),u=ve(s),D=u[0];if(typeof e.getDropOperation=="function"){let w=new se(i.dataTransfer);D=ue(s,e.getDropOperation(w,u))}if(typeof e.getDropOperationForPoint=="function"){let w=new se(i.dataTransfer),k=i.currentTarget.getBoundingClientRect();D=ue(s,e.getDropOperationForPoint(w,u,i.clientX-k.x,i.clientY-k.y))}o.x=i.clientX,o.y=i.clientY,o.allowedOperations=s,o.dropEffect=be[D]||"none",i.dataTransfer.dropEffect=o.dropEffect,D!=="cancel"&&g(i)},m=i=>{i.preventDefault(),i.stopPropagation();let s=M(i);if(o.dragOverElements.delete(s),s===i.currentTarget)for(let u of o.dragOverElements)H(i.currentTarget,u)||o.dragOverElements.delete(u);o.dragOverElements.size>0||(o.dropEffect!=="none"&&c(i),clearTimeout(o.dropActivateTimer))},v=i=>{if(i.preventDefault(),i.stopPropagation(),he(o.dropEffect),typeof e.onDrop=="function"){let u=re[o.dropEffect],D=$t(i.dataTransfer),w=i.currentTarget.getBoundingClientRect(),k={type:"drop",x:i.clientX-w.x,y:i.clientY-w.y,items:D,dropOperation:u};e.onDrop(k)}let s={...B};o.dragOverElements.clear(),c(i),clearTimeout(o.dropActivateTimer),s.draggingCollectionRef==null?he(void 0):Hr(s)},l=R(i=>{typeof e.onDropEnter=="function"&&e.onDropEnter(i)}),d=R(i=>{typeof e.onDropExit=="function"&&e.onDropExit(i)}),p=R(i=>{typeof e.onDropActivate=="function"&&e.onDropActivate(i)}),b=R(i=>{typeof e.onDrop=="function"&&e.onDrop(i)}),h=R((i,s)=>e.getDropOperation?e.getDropOperation(i,s):s[0]),{ref:x}=e;rt(()=>{if(!(r||!x.current))return xt({element:x.current,getDropOperation:h,onDropEnter(i){a(!0),l(i)},onDropExit(i){a(!1),d(i)},onDrop:b,onDropActivate:p})},[r,x]);let{dropProps:T}=Kt();return r?{dropProps:{},dropButtonProps:{isDisabled:!0},isDropTarget:!1}:{dropProps:{...!t&&T,onDragEnter:$,onDragOver:y,onDragLeave:m,onDrop:v},dropButtonProps:{...t&&T},isDropTarget:n}}function _e(e){let t=gt[e.dataTransfer.effectAllowed];Pe&&(t&=Pe);let r=P.none;return Ot()?(e.altKey&&(r|=P.copy),e.ctrlKey&&!Mt()&&(r|=P.link),e.metaKey&&(r|=P.move)):(e.altKey&&(r|=P.link),e.shiftKey&&(r|=P.move),e.ctrlKey&&(r|=P.copy)),r?t&r:t}function ve(e){let t=[];return e&P.move&&t.push("move"),e&P.copy&&t.push("copy"),e&P.link&&t.push("link"),t}function ue(e,t){let r=P[t];return e&r?t:"cancel"}const Ee=new Map;function _(e,t){let r=Ee.get(e);if(!r){let n=new Set,a=o=>{for(let g of n)g(o)};r={listener:a,handlers:n},Ee.set(e,r),document.addEventListener(e,a)}return r.handlers.add(t),()=>{r.handlers.delete(t),r.handlers.size===0&&(document.removeEventListener(e,r.listener),Ee.delete(e))}}function tn(e){let{isDisabled:t}=e,r=E.useRef(!1),{focusProps:n}=jt({onFocusChange:m=>{r.current=m}}),a=R(m=>{r.current&&e.getItems&&m.preventDefault()}),o=R(m=>{!r.current||!e.getItems||(m.preventDefault(),m.clipboardData&&(Se(m.clipboardData,e.getItems({action:"copy"})),e.onCopy?.()))}),g=R(m=>{r.current&&e.onCut&&e.getItems&&m.preventDefault()}),c=R(m=>{!r.current||!e.onCut||!e.getItems||(m.preventDefault(),m.clipboardData&&(Se(m.clipboardData,e.getItems({action:"cut"})),e.onCut()))}),y=R(m=>{r.current&&e.onPaste&&m.preventDefault()}),$=R(m=>{if(!(!r.current||!e.onPaste)&&(m.preventDefault(),m.clipboardData)){let v=$t(m.clipboardData);e.onPaste(v)}});return E.useEffect(()=>{if(!t)return Nt(_("beforecopy",a),_("copy",o),_("beforecut",g),_("cut",c),_("beforepaste",y),_("paste",$))},[t]),{clipboardProps:n}}function rn(e){return e&&e.__esModule?e.default:e}const nn=E.createContext(null),an=E.forwardRef(function(t,r){let{isDisabled:n=!1}=t;[t,r]=Rt(t,r,nn);let a=Lt(r),o=E.useRef(null),{dropProps:g,dropButtonProps:c,isDropTarget:y}=Ct({...t,ref:o,hasDropButton:!0}),{buttonProps:$}=Vt(c||{},o),{hoverProps:m,isHovered:v}=Gt(t),{focusProps:l,isFocused:d,isFocusVisible:p}=Ht(),b=ae(rn(er),"react-aria-components"),h=zt(),x=t["aria-label"]||b.format("dropzoneLabel"),T=t["aria-labelledby"],i=[h,T].filter(Boolean).join(" "),s=Yt({"aria-label":x,"aria-labelledby":i}),{clipboardProps:u}=tn({isDisabled:n,onPaste:k=>t.onDrop?.({type:"drop",items:k,x:0,y:0,dropOperation:"copy"})}),D=Ut({...t,values:{isHovered:v,isFocused:d,isFocusVisible:p,isDropTarget:y,isDisabled:n},defaultClassName:"react-aria-DropZone"}),w=Xt(t,{global:!0});return delete w.id,W.createElement(qt,{values:[[_t,{id:h,slot:"label"}]]},W.createElement(Wt.div,{...Ke(w,D,g,m),slot:t.slot||void 0,ref:a,onClick:k=>{let C=M(k);for(;C&&H(a.current,C)&&!Jt(C);){if(C===a.current&&o.current){Zt(o.current);break}C=C.parentElement}},"data-hovered":v||void 0,"data-focused":d||void 0,"data-focus-visible":p||void 0,"data-drop-target":y||void 0,"data-disabled":n||void 0},W.createElement(Qt,null,W.createElement("button",{...Ke($,l,u,s),ref:o})),D.children))});function on(e,t,r,n,a=!1,o=!1){switch(n){case"left":return a?xe(e,t,r,o,"left"):we(e,t,r,o,"left");case"right":return a?we(e,t,r,o,"right"):xe(e,t,r,o,"right");case"up":return we(e,t,r,o);case"down":return xe(e,t,r,o)}}function xe(e,t,r,n=!1,a=null){if(!r)return{type:"root"};if(r.type==="root"){let o=e.getFirstKey?.()??null;return o!=null?{type:"item",key:o,dropPosition:"before"}:null}if(r.type==="item"){let o=null;a?o=a==="right"?e.getKeyRightOf?.(r.key,{includeDisabled:!0}):e.getKeyLeftOf?.(r.key,{includeDisabled:!0}):o=e.getKeyBelow?.(r.key,{includeDisabled:!0});let g=Ne(t,r.key,c=>t.getKeyAfter(c));if(o!=null&&o!==g)return{type:"item",key:o,dropPosition:r.dropPosition};switch(r.dropPosition){case"before":return{type:"item",key:r.key,dropPosition:"on"};case"on":{let c=t.getItem(r.key),y=o!=null?t.getItem(o):null;return c&&y&&y.level>=c.level?{type:"item",key:y.key,dropPosition:"before"}:{type:"item",key:r.key,dropPosition:"after"}}case"after":{let c=t.getItem(r.key),y=c?.nextKey!=null?t.getItem(c.nextKey):null;for(;y!=null&&y.type!=="item";)y=y.nextKey!=null?t.getItem(y.nextKey):null;if(c&&y==null&&c.parentKey!=null){let $=t.getItem(c.parentKey);const m=$?.nextKey!=null?t.getItem($.nextKey):null;if(m?.type==="item")return{type:"item",key:m.key,dropPosition:"before"};if($?.type==="item")return{type:"item",key:$.key,dropPosition:"after"}}if(y)return{type:"item",key:y.key,dropPosition:"on"}}}}return n?{type:"root"}:null}function we(e,t,r,n=!1,a=null){if(!r||n&&r.type==="root"){let o=null,g=e.getLastKey?.();for(;g!=null;){let c=t.getItem(g);if(c?.type!=="item")break;o=g,g=c?.parentKey}return o!=null?{type:"item",key:o,dropPosition:"after"}:null}if(r.type==="item"){let o=null;a?o=a==="left"?e.getKeyLeftOf?.(r.key,{includeDisabled:!0}):e.getKeyRightOf?.(r.key,{includeDisabled:!0}):o=e.getKeyAbove?.(r.key,{includeDisabled:!0});let g=Ne(t,r.key,c=>t.getKeyBefore(c));if(o!=null&&o!==g)return{type:"item",key:o,dropPosition:r.dropPosition};switch(r.dropPosition){case"before":{let c=t.getItem(r.key);if(c&&c.prevKey!=null){let y=We(t,c.prevKey);if(y)return y}return o!=null?{type:"item",key:o,dropPosition:"on"}:{type:"root"}}case"on":return{type:"item",key:r.key,dropPosition:"before"};case"after":{let c=We(t,r.key);return c||{type:"item",key:r.key,dropPosition:"on"}}}}return r.type!=="root"?{type:"root"}:null}function We(e,t){let r=e.getItem(t),n=Ne(e,t,o=>e.getKeyAfter(o)),a=n!=null?e.getItem(n):null;if(r&&a&&a.level>r.level){let o=null;if("lastChildKey"in r)for(o=r.lastChildKey!=null?e.getItem(r.lastChildKey):null;o&&o.type!=="item"&&o.prevKey!=null;)o=e.getItem(o.prevKey);else o=Array.from(r.childNodes).findLast(g=>g.type==="item")||null;if(o)return{type:"item",key:o.key,dropPosition:"after"}}return null}function Ne(e,t,r){let n=r(t),a=n!=null?e.getItem(n):null;for(;a&&a.type!=="item";)n=r(a.key),a=n!=null?e.getItem(n):null;return n}const de=20;function ln(e){let t=E.useRef(null),r=E.useRef(!0),n=E.useRef(!0);E.useEffect(()=>{if(e.current){t.current=tr(e.current)?e.current:rr(e.current);let g=window.getComputedStyle(t.current);r.current=/(auto|scroll)/.test(g.overflowX),n.current=/(auto|scroll)/.test(g.overflowY)}},[e]);let a=E.useRef({timer:void 0,dx:0,dy:0}).current;E.useEffect(()=>()=>{a.timer&&(cancelAnimationFrame(a.timer),a.timer=void 0)},[a]);let o=E.useCallback(()=>{r.current&&t.current&&(t.current.scrollLeft+=a.dx),n.current&&t.current&&(t.current.scrollTop+=a.dy),a.timer&&(a.timer=requestAnimationFrame(o))},[t,a]);return{move(g,c){if(!nt()||at()||!t.current)return;let y=t.current.getBoundingClientRect(),$=de,m=de,v=y.height-de,l=y.width-de;g<$||g>l||cv?(g<$?a.dx=g-$:g>l&&(a.dx=g-l),cv&&(a.dy=c-v),a.timer||(a.timer=requestAnimationFrame(o))):this.stop()},stop(){a.timer&&(cancelAnimationFrame(a.timer),a.timer=void 0)}}}function sn(e,t,r){let n=E.useRef({props:e,state:t,nextTarget:null,dropOperation:null}).current;n.props=e,n.state=t;let a=E.useCallback(async l=>{let{onInsert:d,onRootDrop:p,onItemDrop:b,onReorder:h,onMove:x,acceptedDragTypes:T="all",shouldAcceptItemDrop:i}=n.props,{draggingKeys:s}=B,u=G(r),{target:D,dropOperation:w,items:k}=l,C=k;(T!=="all"||i)&&(C=k.filter(F=>{let I;return F.kind==="directory"?I=new Set([ht]):I=F.kind==="file"?new Set([F.type]):F.types,T==="all"||T.some(j=>I.has(j))?D.type==="item"&&D.dropPosition==="on"&&i?i(D,I):!0:!1})),C.length>0&&(D.type==="root"&&p&&await p({items:C,dropOperation:w}),D.type==="item"&&(D.dropPosition==="on"&&b&&await b({items:C,dropOperation:w,isInternal:u,target:D}),x&&u&&await x({keys:s,dropOperation:w,target:D}),D.dropPosition!=="on"&&(!u&&d&&await d({items:C,dropOperation:w,target:D}),u&&h&&await h({keys:s,dropOperation:w,target:D}))))},[n,r]),o=ln(r),{dropProps:g}=Ct({ref:r,onDropEnter(){n.nextTarget!=null&&t.setTarget(n.nextTarget)},onDropMove(l){n.nextTarget!=null&&t.setTarget(n.nextTarget),o.move(l.x,l.y)},getDropOperationForPoint(l,d,p,b){let{draggingKeys:h,dropCollectionRef:x}=B,T=G(r),i=u=>t.getDropOperation({target:u,types:l,allowedOperations:d,isInternal:T,draggingKeys:h})!=="cancel",s=e.dropTargetDelegate.getDropTargetFromPoint(p,b,i);if(!s)return n.dropOperation="cancel",n.nextTarget=null,"cancel";if(n.dropOperation=t.getDropOperation({target:s,types:l,allowedOperations:d,isInternal:T,draggingKeys:h}),n.dropOperation==="cancel"){let u={type:"root"},D=t.getDropOperation({target:u,types:l,allowedOperations:d,isInternal:T,draggingKeys:h});D!=="cancel"&&(s=u,n.dropOperation=D)}return s&&n.dropOperation!=="cancel"&&r?.current!==x?.current&&q(r),n.nextTarget=n.dropOperation==="cancel"?null:s,n.dropOperation},onDropExit(){q(void 0),t.setTarget(null),o.stop()},onDropActivate(l){t.target?.type==="item"&&typeof e.onDropActivate=="function"&&e.onDropActivate({type:"dropactivate",x:l.x,y:l.y,target:t.target})},onDrop(l){q(r),t.target&&$(l,t.target);let{draggingCollectionRef:d}=B;d==null&&Et()}}),c=E.useRef(null),y=E.useCallback(()=>{let{state:l}=n;if(c.current){let{target:d,collection:p,selectedKeys:b,focusedKey:h,isInternal:x,draggingKeys:T}=c.current;if(l.collection.size>p.size&&l.selectionManager.isSelectionEqual(b)){let i=new Set,s=l.collection.getFirstKey();for(;s!=null;){let u=l.collection.getItem(s);u?.type==="item"&&!p.getItem(u.key)&&i.add(u.key),u?.hasChildNodes&&l.collection.getItem(u.lastChildKey)?.type==="item"?s=u.firstChildKey:s=l.collection.getKeyAfter(s)}if(l.selectionManager.setSelectedKeys(i),l.selectionManager.focusedKey===h){let u=i.keys().next().value;if(u!=null){let D=l.collection.getItem(u),w=c.current.target,k=l.collection.expandedKeys?l.collection.expandedKeys.has(D?.parentKey):!1;D&&(D?.type==="cell"||w.type==="item"&&w.dropPosition==="on"&&!k)&&(u=D.parentKey),u!=null&&l.selectionManager.setFocusedKey(u),l.selectionManager.selectionMode==="none"&&le("keyboard")}}}else h!=null&&l.selectionManager.focusedKey===h&&x&&d.type==="item"&&d.dropPosition!=="on"&&T.has(l.collection.getItem(h)?.parentKey)?(l.selectionManager.setFocusedKey(l.collection.getItem(h)?.parentKey??null),le("keyboard")):l.selectionManager.focusedKey===h&&d.type==="item"&&d.dropPosition==="on"&&l.collection.getItem(d.key)!=null?(l.selectionManager.setFocusedKey(d.key),le("keyboard")):l.selectionManager.focusedKey!=null&&!l.selectionManager.isSelected(l.selectionManager.focusedKey)&&le("keyboard");l.selectionManager.setFocused(!0)}},[n]),$=E.useCallback((l,d)=>{let{state:p}=n;c.current={timeout:void 0,focusedKey:p.selectionManager.focusedKey,collection:p.collection,selectedKeys:p.selectionManager.selectedKeys,draggingKeys:B.draggingKeys,isInternal:G(r),target:d},(n.props.onDrop||a)({type:"drop",x:l.x,y:l.y,target:d,items:l.items,dropOperation:l.dropOperation}),c.current.timeout=setTimeout(()=>{y(),c.current=null},50)},[n,a,r,y]);E.useEffect(()=>()=>{c.current&&clearTimeout(c.current.timeout)},[]),rt(()=>{c.current&&t.collection!==c.current.collection&&y()});let{direction:m}=nr();E.useEffect(()=>{if(!r.current)return;let l=(b,h=!0,x="down")=>on(n.props.keyboardDelegate,n.state.collection,b,x,m==="rtl",h),d=(b,h=!0)=>l(b,h,"up"),p=(b,h,x,T,i=!0)=>{let s=0,u,{draggingKeys:D}=B,w=G(r);do{let k=T(b,i);if(!k)return null;b=k,u=n.state.getDropOperation({target:k,types:h,allowedOperations:x,isInternal:w,draggingKeys:D}),b.type==="root"&&s++}while(u==="cancel"&&!n.state.isDropTarget(b)&&s<2);return u==="cancel"?null:b};return xt({element:r.current,preventFocusOnDrop:!0,getDropOperation(b,h){if(n.state.target){let{draggingKeys:T}=B,i=G(r);return n.state.getDropOperation({target:n.state.target,types:b,allowedOperations:h,isInternal:i,draggingKeys:T})}return p(null,b,h,l)?"move":"cancel"},onDropEnter(b,h){let x=z(h.items),T=n.state.selectionManager,i=null;q(r);let s=T.focusedKey,u="after",D=s!=null?n.state.collection.getItem(s):null;if(D?.type==="cell"&&(s=D.parentKey),s!=null&&T.isSelected(s)&&(T.selectedKeys.size>1&&T.firstSelectedKey===s?u="before":s=T.lastSelectedKey),s!=null){i={type:"item",key:s,dropPosition:u};let{draggingKeys:w}=B,k=G(r);n.state.getDropOperation({target:i,types:x,allowedOperations:h.allowedDropOperations,isInternal:k,draggingKeys:w})==="cancel"&&(i=p(i,x,h.allowedDropOperations,l,!1)??p(i,x,h.allowedDropOperations,d,!1))}i||(i=p(null,x,h.allowedDropOperations,l)),n.state.setTarget(i)},onDropExit(){q(void 0),n.state.setTarget(null)},onDropTargetEnter(b){n.state.setTarget(b)},onDropActivate(b,h){h?.type==="item"&&h?.dropPosition==="on"&&typeof n.props.onDropActivate=="function"&&n.props.onDropActivate({type:"dropactivate",x:b.x,y:b.y,target:h})},onDrop(b,h){q(r),n.state.target&&$(b,h||n.state.target)},onKeyDown(b,h){let{keyboardDelegate:x}=n.props,T=z(h.items);switch(b.key){case"ArrowDown":if(x.getKeyBelow){let i=p(n.state.target,T,h.allowedDropOperations,(s,u)=>l(s,u,"down"));n.state.setTarget(i)}break;case"ArrowUp":if(x.getKeyAbove){let i=p(n.state.target,T,h.allowedDropOperations,(s,u)=>l(s,u,"up"));n.state.setTarget(i)}break;case"ArrowLeft":if(x.getKeyLeftOf){let i=p(n.state.target,T,h.allowedDropOperations,(s,u)=>l(s,u,"left"));n.state.setTarget(i)}break;case"ArrowRight":if(x.getKeyRightOf){let i=p(n.state.target,T,h.allowedDropOperations,(s,u)=>l(s,u,"right"));n.state.setTarget(i)}break;case"Home":if(x.getFirstKey){let i=p(null,T,h.allowedDropOperations,l);n.state.setTarget(i)}break;case"End":if(x.getLastKey){let i=p(null,T,h.allowedDropOperations,d);n.state.setTarget(i)}break;case"PageDown":if(x.getKeyPageBelow){let i=n.state.target;if(!i)i=p(null,T,h.allowedDropOperations,l);else{let s=x.getFirstKey?.();i.type==="item"&&(s=i.key);let u=null;s!=null&&(u=x.getKeyPageBelow(s));let D=i.type==="item"?i.dropPosition:"after";if((u==null||i.type==="item"&&i.key===x.getLastKey?.())&&(u=x.getLastKey?.()??null,D="after"),u==null)break;i={type:"item",key:u,dropPosition:D};let{draggingCollectionRef:w,draggingKeys:k}=B,C=w?.current===r?.current;n.state.getDropOperation({target:i,types:T,allowedOperations:h.allowedDropOperations,isInternal:C,draggingKeys:k})==="cancel"&&(i=p(i,T,h.allowedDropOperations,l,!1)??p(i,T,h.allowedDropOperations,d,!1))}n.state.setTarget(i??n.state.target)}break;case"PageUp":{if(!x.getKeyPageAbove)break;let i=n.state.target;if(!i)i=p(null,T,h.allowedDropOperations,d);else if(i.type==="item"){if(i.key===x.getFirstKey?.())i={type:"root"};else{let w=x.getKeyPageAbove(i.key),k=i.dropPosition;if(w==null&&(w=x.getFirstKey?.(),k="before"),w==null)break;i={type:"item",key:w,dropPosition:k}}let{draggingKeys:s}=B,u=G(r);n.state.getDropOperation({target:i,types:T,allowedOperations:h.allowedDropOperations,isInternal:u,draggingKeys:s})==="cancel"&&(i=p(i,T,h.allowedDropOperations,d,!1)??p(i,T,h.allowedDropOperations,l,!1))}n.state.setTarget(i??n.state.target);break}}n.props.onKeyDown?.(b)}})},[n,r,$,m]);let v=ot();return Oe.set(t,{id:v,ref:r}),{collectionProps:Ke(g,{id:v,"aria-describedby":null})}}function St(e,t,r){let{dropProps:n}=Kt(),a=Mr(t);E.useEffect(()=>{if(r.current)return zr({element:r.current,target:e.target,getDropOperation(m,v){let{draggingKeys:l}=B,d=G(a);return t.getDropOperation({target:e.target,types:m,allowedOperations:v,isInternal:d,draggingKeys:l})},activateButtonRef:e.activateButtonRef})},[r,e.target,t,a,e.activateButtonRef]);let o=je(),{draggingKeys:g}=B,c=G(a),y=o&&t.getDropOperation({target:e.target,types:z(o.dragTarget.items),allowedOperations:o.dragTarget.allowedDropOperations,isInternal:c,draggingKeys:g})!=="cancel",$=t.isDropTarget(e.target);return E.useEffect(()=>{o&&$&&r.current&&r.current.focus()},[$,o,r]),{dropProps:{...n,"aria-hidden":!o||y?void 0:"true"},isDropTarget:$}}function un(e){return e&&e.__esModule?e.default:e}function dn(e,t,r){let{target:n}=e,{collection:a}=t,o=ae(un(oe),"@react-aria/dnd"),g=je(),{dropProps:c}=St(e,t,r),y=ot(),$=p=>p==null?"":a.getTextValue?.(p)??a.getItem(p)?.textValue??"",m="",v;if(n.type==="root")m=o.format("dropOnRoot"),v=`${y} ${Or(t)}`;else if(n.dropPosition==="on")m=o.format("dropOnItem",{itemText:$(n.key)});else{let p,b;if(n.dropPosition==="before"){let h=a.getItem(n.key)?.prevKey,x=h!=null?a.getItem(h):null;p=x?.type==="item"?x.key:null}else p=n.key;if(n.dropPosition==="after"){let h=a.getItem(n.key)?.nextKey,x=h!=null?a.getItem(h):null;b=x?.type==="item"?x.key:null}else b=n.key;p!=null&&b!=null?m=o.format("insertBetween",{beforeItemText:$(p),afterItemText:$(b)}):p!=null?m=o.format("insertAfter",{itemText:$(p)}):b!=null&&(m=o.format("insertBefore",{itemText:$(b)}))}let l=t.isDropTarget(n),d=g?c["aria-hidden"]:"true";return{dropIndicatorProps:{...c,id:y,"aria-roledescription":o.format("dropIndicator"),"aria-label":m,"aria-labelledby":v,"aria-hidden":d,tabIndex:-1},isDropTarget:l,isHidden:!l&&!!d}}function cn(e){return e&&e.__esModule?e.default:e}const Je={keyboard:{start:"dragDescriptionKeyboard",end:"endDragKeyboard"},touch:{start:"dragDescriptionTouch",end:"endDragTouch"},virtual:{start:"dragDescriptionVirtual",end:"endDragVirtual"}};function pn(e){let{hasDragButton:t,isDisabled:r}=e,n=ae(cn(oe),"@react-aria/dnd"),a=E.useRef({options:e,x:0,y:0}).current;a.options=e;let o=E.useRef(null),[g,c]=E.useState(!1),y=u=>{o.current=u,c(!!u)},{addGlobalListener:$,removeAllGlobalListeners:m}=ar(),v=E.useRef(null),l=u=>{if(u.defaultPrevented)return;if(u.stopPropagation(),v.current==="virtual"){u.preventDefault(),h(M(u)),v.current=null;return}typeof e.onDragStart=="function"&&e.onDragStart({type:"dragstart",x:u.clientX,y:u.clientY});let D=e.getItems();u.dataTransfer.clearData?.(),Se(u.dataTransfer,D);let w=P.all;if(typeof e.getAllowedDropOperations=="function"){let F=e.getAllowedDropOperations();w=P.none;for(let I of F)w|=P[I]||P.none}$e(w);let k=yt[w]||"none";u.dataTransfer.effectAllowed=k==="cancel"?"none":k,typeof e.preview?.current=="function"&&e.preview.current(D,(F,I,j)=>{if(!F)return;let N=F.getBoundingClientRect(),Y=u.currentTarget.getBoundingClientRect(),Z=u.clientX-Y.x,Q=u.clientY-Y.y;(Z>N.width||Q>N.height)&&(Z=N.width/2,Q=N.height/2);let U=Z,X=Q;typeof I=="number"&&typeof j=="number"&&(U=I,X=j),U=Math.max(0,Math.min(U,N.width)),X=Math.max(0,Math.min(X,N.height));let K=2*Math.round(N.height/2);F.style.height=`${K}px`,u.dataTransfer.setDragImage(F,U,X)}),$(window,"drop",F=>{F.preventDefault(),F.stopPropagation(),console.warn("Drags initiated from the React Aria useDrag hook may only be dropped on a target created with useDrop. This ensures that a keyboard and screen reader accessible alternative is available.")},{once:!0}),a.x=u.clientX,a.y=u.clientY;let C=M(u);requestAnimationFrame(()=>{y(C)})},d=u=>{u.stopPropagation(),!(u.clientX===a.x&&u.clientY===a.y)&&(typeof e.onDragMove=="function"&&e.onDragMove({type:"dragmove",x:u.clientX,y:u.clientY}),a.x=u.clientX,a.y=u.clientY)},p=u=>{if(u.stopPropagation(),typeof e.onDragEnd=="function"){let D={type:"dragend",x:u.clientX,y:u.clientY,dropOperation:re[u.dataTransfer.dropEffect]};fe&&(D.dropOperation=re[fe]),e.onDragEnd(D)}y(null),m(),$e(P.none),he(void 0)};E.useEffect(()=>()=>{if(o.current&&(!o.current.isConnected||parseInt(E.version,10)<17)){if(typeof a.options.onDragEnd=="function"){let u={type:"dragend",x:0,y:0,dropOperation:re[fe||"none"]};a.options.onDragEnd(u)}y(null),$e(P.none),he(void 0)}},[a]);let b=u=>{u.pointerType!=="keyboard"&&u.pointerType!=="virtual"||h(u.target)},h=u=>{if(typeof a.options.onDragStart=="function"){let D=u.getBoundingClientRect();a.options.onDragStart({type:"dragstart",x:D.x+D.width/2,y:D.y+D.height/2})}Yr({element:u,items:a.options.getItems(),allowedDropOperations:typeof a.options.getAllowedDropOperations=="function"?a.options.getAllowedDropOperations():["move","copy","link"],onDragEnd(D){y(null),typeof a.options.onDragEnd=="function"&&a.options.onDragEnd(D)}},n),y(u)},x=Me(),T=g?Je[x].end:Je[x].start,i=Ie(n.format(T)),s={};return t||(s={...i,onPointerDown(u){if(v.current=tt(u.nativeEvent)?"virtual":u.pointerType,u.width<1&&u.height<1&&at()&&nt())v.current="virtual";else{let D=u.currentTarget.getBoundingClientRect(),w=u.clientX-D.x,k=u.clientY-D.y,C=D.width/2,F=D.height/2;Math.abs(w-C)<=.5&&Math.abs(k-F)<=.5?v.current="virtual":v.current=u.pointerType}},onKeyDownCapture(u){M(u)===u.currentTarget&&u.key==="Enter"&&(u.preventDefault(),u.stopPropagation())},onKeyUpCapture(u){M(u)===u.currentTarget&&u.key==="Enter"&&(u.preventDefault(),u.stopPropagation(),h(M(u)))},onClick(u){(et(u.nativeEvent)||v.current==="virtual")&&(u.preventDefault(),u.stopPropagation(),h(M(u)))}}),r?{dragProps:{draggable:"false"},dragButtonProps:{},isDragging:!1}:{dragProps:{...s,draggable:"true",onDragStart:l,onDrag:d,onDragEnd:p},dragButtonProps:{...i,onPress:b},isDragging:g}}function fn(e){return e&&e.__esModule?e.default:e}const gn={keyboard:{selected:"dragSelectedKeyboard",notSelected:"dragDescriptionKeyboard"},touch:{selected:"dragSelectedLongPress",notSelected:"dragDescriptionLongPress"},virtual:{selected:"dragDescriptionVirtual",notSelected:"dragDescriptionVirtual"}};function yn(e,t){let r=ae(fn(oe),"@react-aria/dnd"),n=t.isDisabled||t.selectionManager.isDisabled(e.key),{dragProps:a,dragButtonProps:o}=pn({getItems(){return t.getItems(e.key)},preview:t.preview,getAllowedDropOperations:t.getAllowedDropOperations,hasDragButton:e.hasDragButton,onDragStart(d){t.startDrag(e.key,d),Gr(t.draggingKeys)},onDragMove(d){t.moveDrag(d)},onDragEnd(d){let{dropOperation:p}=d,b=p==="cancel"?!1:G();t.endDrag({...d,keys:t.draggingKeys,isInternal:b}),Et()}}),g=t.collection.getItem(e.key),c=t.getKeysForDrag(e.key).size,y=c>1&&t.selectionManager.isSelected(e.key),$,m,v=Me();if(!e.hasDragButton&&t.selectionManager.selectionMode!=="none"){let d=gn[v][y?"selected":"notSelected"];e.hasAction&&v==="keyboard"&&(d+="Alt"),y?m=r.format(d,{count:c}):m=r.format(d),delete a.onClick}else if(y)$=r.format("dragSelectedItems",{count:c});else{let d=t.collection.getTextValue?.(e.key)??g?.textValue??"";$=r.format("dragItem",{itemText:d})}let l=Ie(m);if(m&&Object.assign(a,l),!e.hasDragButton&&e.hasAction){let{onKeyDownCapture:d,onKeyUpCapture:p}=a;v==="touch"&&delete a["aria-describedby"],a.onKeyDownCapture=b=>{b.altKey&&d?.(b)},a.onKeyUpCapture=b=>{b.altKey&&p?.(b)}}return{dragProps:n?{}:a,dragButtonProps:{...o,isDisabled:n,"aria-label":$}}}function mn(e,t,r){let{draggingCollectionRef:n}=B;t.draggingKeys.size>0&&n?.current!==r.current&&Vr(r)}const hn=W.forwardRef(function(t,r){let n=t.children,[a,o]=E.useState(null),g=E.useRef(null),c=E.useRef(void 0);return E.useImperativeHandle(r,()=>(y,$)=>{let m=n(y),v,l,d;m&&typeof m=="object"&&"element"in m?(v=m.element,l=m.x,d=m.y):v=m,Pt.flushSync(()=>{o(v)}),$(g.current,l,d),c.current=requestAnimationFrame(()=>{o(null)})},[n]),E.useEffect(()=>()=>{c.current&&cancelAnimationFrame(c.current)},[]),a?W.createElement("div",{style:{zIndex:-100,position:"fixed",top:0,left:-1e5},ref:g},a):null});function Dn(e){let{getItems:t,isDisabled:r,collection:n,selectionManager:a,onDragStart:o,onDragMove:g,onDragEnd:c,preview:y,getAllowedDropOperations:$}=e,[,m]=E.useState(!1),v=E.useRef(new Set),l=E.useRef(null),d=p=>{let b=new Set;if(a.isSelected(p))for(let h of a.selectedKeys){let x=n.getItem(h);if(x){let T=!1,i=x.parentKey;for(;i!=null;){if(a.selectedKeys.has(i)){T=!0;break}let s=n.getItem(i);i=s?s.parentKey:null}T||b.add(h)}}else b.add(p);return b};return{collection:n,selectionManager:a,get draggedKey(){return l.current},get draggingKeys(){return v.current},isDragging(p){return v.current.has(p)},getKeysForDrag:d,getItems(p){let b=d(p),h=[];for(let x of b){let T=n.getItem(x)?.value;T!=null&&h.push(T)}return t(d(p),h)},isDisabled:r,preview:y,getAllowedDropOperations:$,startDrag(p,b){let h=d(p);v.current=h,l.current=p,a.setFocused(!1),m(!0),typeof o=="function"&&o({...b,keys:h})},moveDrag(p){typeof g=="function"&&g({...p,keys:v.current})},endDrag(p){let{isInternal:b}=p;typeof c=="function"&&c({...p,keys:v.current,isInternal:b}),v.current=new Set,l.current=null,m(!1)}}}function bn(e){let{acceptedDragTypes:t="all",isDisabled:r,onInsert:n,onRootDrop:a,onItemDrop:o,onReorder:g,onMove:c,shouldAcceptItemDrop:y,collection:$,selectionManager:m,onDropEnter:v,getDropOperation:l,onDrop:d}=e,[p,b]=E.useState(null),h=E.useRef(null),x=i=>{if(i.dropPosition==="before"){let s=$.getItem(i.key);return s&&s.prevKey!=null?{type:"item",key:s.prevKey,dropPosition:"after"}:null}else if(i.dropPosition==="after"){let s=$.getItem(i.key);return s&&s.nextKey!=null?{type:"item",key:s.nextKey,dropPosition:"before"}:null}return null},T=E.useCallback(i=>{let{target:s,types:u,allowedOperations:D,isInternal:w,draggingKeys:k}=i;if(r||!s)return"cancel";if(t==="all"||t.some(C=>u.has(C))){let C=n&&s.type==="item"&&!w&&(s.dropPosition==="before"||s.dropPosition==="after"),F=g&&s.type==="item"&&w&&(s.dropPosition==="before"||s.dropPosition==="after")&&$n($,s,k),I=s.type!=="item"||s.dropPosition!=="on"||!y||y(s,u),j=c&&s.type==="item"&&w&&I,N=a&&s.type==="root"&&!w,Y=o&&s.type==="item"&&s.dropPosition==="on"&&!(w&&s.key!=null&&k.has(s.key))&&I;if(d||C||F||j||N||Y)return l?l(s,u,D):D[0]}return"cancel"},[r,$,t,l,n,a,o,y,g,c,d]);return{collection:$,selectionManager:m,isDisabled:r,target:p,setTarget(i){if(this.isDropTarget(i))return;let s=h.current;s&&typeof e.onDropExit=="function"&&e.onDropExit({type:"dropexit",x:0,y:0,target:s}),i&&typeof v=="function"&&v({type:"dropenter",x:0,y:0,target:i}),h.current=i??null,b(i??null)},isDropTarget(i){let s=h.current;return!s||!i?!1:Te(i,s)?!0:i?.type==="item"&&s?.type==="item"&&i.key!==s.key&&i.dropPosition!==s.dropPosition&&i.dropPosition!=="on"&&s.dropPosition!=="on"?Te(x(i),s)||Te(i,x(s)):!1},getDropOperation(i){let{target:s,isInternal:u,draggingKeys:D}=i;if(u&&s.type==="item"&&D.size>0){if(D.has(s.key)&&s.dropPosition==="on")return"cancel";let w=s.key;for(;w!=null;){let C=$.getItem(w)?.parentKey;if(C!=null&&D.has(C))return"cancel";w=C??null}}return T(i)}}}function Te(e,t){if(!e)return!t;switch(e.type){case"root":return t?.type==="root";case"item":return t?.type==="item"&&t?.key===e.key&&t?.dropPosition===e.dropPosition}}function $n(e,t,r){let n=e.getItem(t.key);for(let a of r)if(e.getItem(a)?.parentKey!==n?.parentKey)return!1;return!0}class vn{constructor(t,r,n){this.collection=t,this.ref=r,this.layout=n?.layout||"stack",this.orientation=n?.orientation||"vertical",this.direction=n?.direction||"ltr"}getPrimaryStart(t){return this.orientation==="horizontal"?t.left:t.top}getPrimaryEnd(t){return this.orientation==="horizontal"?t.right:t.bottom}getSecondaryStart(t){return this.orientation==="horizontal"?t.top:t.left}getSecondaryEnd(t){return this.orientation==="horizontal"?t.bottom:t.right}getFlowStart(t){return this.layout==="stack"?this.getPrimaryStart(t):this.getSecondaryStart(t)}getFlowEnd(t){return this.layout==="stack"?this.getPrimaryEnd(t):this.getSecondaryEnd(t)}getFlowSize(t){return this.getFlowEnd(t)-this.getFlowStart(t)}getDropTargetFromPoint(t,r,n){if(this.collection[Symbol.iterator]().next().done||!this.ref.current)return{type:"root"};let a=this.ref.current.getBoundingClientRect(),o=this.orientation==="horizontal"?t:r,g=this.orientation==="horizontal"?r:t;o+=this.getPrimaryStart(a),g+=this.getSecondaryStart(a);let c=this.layout==="stack"?o:g,y=this.orientation==="horizontal"&&this.direction==="rtl",$=this.layout==="grid"&&this.orientation==="vertical"&&this.direction==="rtl",m=this.layout==="stack"?y:$,v=this.ref.current?.dataset.collection,l=this.ref.current.querySelectorAll(v?`[data-collection="${CSS.escape(v)}"]`:"[data-key]"),d=new Map;for(let i of l)i instanceof HTMLElement&&i.dataset.key!=null&&d.set(i.dataset.key,i);let p=[...this.collection].filter(i=>i.type==="item");if(p.length<1)return{type:"root"};let b=0,h=p.length;for(;b{k?b=i+1:h=i};if(othis.getPrimaryEnd(D))w(!y);else if(gthis.getSecondaryEnd(D))w(!$);else{let k={type:"item",key:s.key,dropPosition:"on"};if(n(k))c<=this.getFlowStart(D)+5&&n({...k,dropPosition:"before"})?k.dropPosition=m?"after":"before":c>=this.getFlowEnd(D)-5&&n({...k,dropPosition:"after"})&&(k.dropPosition=m?"before":"after");else{let C=this.getFlowStart(D)+this.getFlowSize(D)/2;c<=C&&n({...k,dropPosition:"before"})?k.dropPosition=m?"after":"before":c>=C&&n({...k,dropPosition:"after"})&&(k.dropPosition=m?"before":"after")}return k}}let x=p[Math.min(b,p.length-1)];return a=d.get(String(x.key))?.getBoundingClientRect(),a&&(o{let{onDrop:r,onInsert:n,onItemDrop:a,onReorder:o,onMove:g,onRootDrop:c,getItems:y,renderDragPreview:$,renderDropIndicator:m,dropTargetDelegate:v}=e,l=!!y,d=!!(r||n||a||o||g||c),p={};return l&&(p.useDraggableCollectionState=function(h){return Dn({...h,...e})},p.useDraggableCollection=mn,p.useDraggableItem=yn,p.DragPreview=hn,p.renderDragPreview=$,p.isVirtualDragging=Ur),d&&(p.useDroppableCollectionState=function(h){return bn({...h,...e})},p.useDroppableItem=St,p.useDroppableCollection=function(h,x,T){return sn({...h,...e},x,T)},p.useDropIndicator=dn,p.renderDropIndicator=m,p.dropTargetDelegate=v,p.ListDropTargetDelegate=vn),p},[e])}}function ce({children:e,tone:t,action:r}){return f.jsxs("span",{className:Ae("rp-tag",t),children:[f.jsx("span",{className:"rp-tag-label",children:e}),r]})}function Ze({label:e,children:t}){return f.jsx("div",{className:"rp-tags",role:"group","aria-label":e,children:t})}function xn({label:e,message:t,children:r}){return f.jsxs("div",{className:"rp-actionbar",role:"region","aria-label":e,children:[f.jsx("span",{"aria-live":"polite",children:t}),f.jsx("div",{className:"rp-toolbar",children:r})]})}function wn({className:e,...t}){return f.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:12,height:12,viewBox:"0 0 12 12","aria-hidden":"true",focusable:"false",className:Ae("rp-icon",e),...t,children:[1.6,6,10.4].flatMap(r=>[3.8,8.2].map(n=>f.jsx("circle",{cx:n,cy:r,r:1.1,fill:"currentColor"},`${n}-${r}`)))})}function Tn(e,t){return e.flatMap(r=>{if(r.kind!=="subscription")return[];const n=t.filter(o=>o.provider_id===r.id),a=new Set(n.map(o=>o.subscription_tag).filter(Boolean));return a.size!==1?[]:[{tag:[...a][0],label:r.name,count:n.length}]})}const Qe=6;function kn(e,t,r,n,a){const o=new Map(Ce(e).map(l=>[l.name,Ve(l)])),g=it(e,t),c=Ce(g),y=new Map(r.map(l=>[l.tag,l])),$=a("arrange.lastMember"),m=c.map(l=>{const d=Ve(l),p=o.get(l.name),b=Ge(l.filters),h=d.rules.length?Ge(d.rules):null,x=t.filter(s=>s.group===l.name),T=new Set(x.flatMap(s=>s.kind==="removeNode"?n.filter(u=>u.name===s.value):s.kind==="removeSubscription"?n.filter(u=>u.subscription_tag===s.value):[])),i=h?n.filter(h).map(s=>s.name):[];return{name:l.name,isNew:!p,holdsAll:l.filters.length===0,names:d.names.map(s=>({name:s,isNew:!!p&&!p.names.includes(s),blocked:He(l,"name",s)?$:null})),subscriptions:d.subtags.map(s=>({tag:s,label:y.get(s)?.label??s,count:y.get(s)?.count??null,isNew:!!p&&!p.subtags.includes(s),blocked:He(l,"subtag",s)?$:null})),rules:d.rules,ruleNote:d.rules.length?a("arrange.ruleNote",{n:d.rules.length}):null,ruleNodes:i.slice(0,Qe),ruleMore:Math.max(0,i.length-Qe),stillIn:[...T].filter(b).map(s=>s.name),removedNames:x.flatMap(s=>s.kind==="removeNode"?[s.value]:[]),removedSubscriptions:x.flatMap(s=>s.kind==="removeSubscription"?[{tag:s.value,label:y.get(s.value)?.label??s.value}]:[])}}),v=new Set(n.map(l=>l.name));return{groups:m,stagedText:g,unknown:new Set(m.flatMap(l=>l.names.filter(d=>!v.has(d.name)).map(d=>d.name))),emptyNew:m.filter(l=>l.isNew&&l.holdsAll).map(l=>l.name)}}function Kn(e,t){return t?null:[...e.names,...e.subscriptions].find(r=>r.blocked)?.blocked??null}function Cn(e,t,r){return e??(t.length?r("arrange.emptyNew",{group:t[0]}):null)}function Ft(e,t){return e?t.kind==="node"?e.names.some(r=>r.name===t.value):e.subscriptions.some(r=>r.tag===t.value):!1}function Sn(e){try{const t=JSON.parse(e);if(!t||typeof t!="object")return null;const{kind:r,value:n}=t;return(r==="node"||r==="subscription")&&typeof n=="string"&&n?{kind:r,value:n}:null}catch{return null}}function Fn(e,t,r){const n=a=>t.find(o=>o.tag===a)?.label??a;switch(e.kind){case"addNode":return r("arrange.change.addNode",{name:e.value,group:e.group});case"removeNode":return r("arrange.change.removeNode",{name:e.value,group:e.group});case"addSubscription":return r("arrange.change.addSubscription",{name:n(e.value),group:e.group});case"removeSubscription":return r("arrange.change.removeSubscription",{name:n(e.value),group:e.group});case"createGroup":return r("arrange.change.createGroup",{group:e.group})}}function ke(e,t){const r={addNode:"removeNode",removeNode:"addNode",addSubscription:"removeSubscription",removeSubscription:"addSubscription"};if(t.kind==="createGroup")return e.some(a=>a.kind==="createGroup"&&a.group===t.group)?e:[...e,t];if((t.kind==="addNode"||t.kind==="addSubscription")&&!lt(t.value))return e;const n=e.findIndex(a=>a.kind===r[t.kind]&&a.group===t.group&&"value"in a&&a.value===t.value);return n!==-1?e.filter((a,o)=>o!==n):e.some(a=>a.kind===t.kind&&a.group===t.group&&"value"in a&&a.value===t.value)?e:[...e,t]}function Pn(e,t){const r=e[t];return e.filter((n,a)=>a!==t&&!(r.kind==="createGroup"&&n.group===r.group))}const ge="application/x-doona-placeable";function Bn(e,t){const r=J(),n=or(),a=n.data?.resources,o=ir(ze(a,"nodes",{whileLoading:!1})),g=lr(ze(a,"providers",{whileLoading:!1})),c=o.data,[y,$]=E.useState([]),m=sr(y.length>0,()=>$([])),v=e.main?.content??"",l=E.useMemo(()=>Tn(g.data?.providers??[],c??[]),[g.data,c]),d=E.useMemo(()=>kn(v,y,l,c??[],r),[v,y,l,c,r]),p=E.useMemo(()=>new Map(d.groups.map(K=>[K.name,K])),[d.groups]),{contains:b}=Ir({sensitivity:"base"}),[h,x]=E.useState(""),T=E.useDeferredValue(h).trim(),i=E.useMemo(()=>(c??[]).filter(K=>!T||b(K.name,T)||b(K.protocol??"",T)),[c,T,b]),s=E.useMemo(()=>l.filter(K=>!T||b(K.label,T)),[l,T,b]),[u,D]=E.useState(!1),[w,k]=E.useState(!1),[C,F]=E.useState(null),I=e.writable?e.main?null:"arrange.noMain":"arrange.readOnly",j=K=>{w||(F(null),$(K))},N=(K,O)=>{O.some(A=>!lt(A.value))&&Ye("negative",r("config.unquotable")),j(A=>O.filter(ee=>!Ft(p.get(K),ee)).reduce((ee,Re)=>ke(ee,{kind:Re.kind==="node"?"addNode":"addSubscription",group:K,value:Re.value}),A))},Y=(K,O)=>j(A=>ke(A,{kind:O.kind==="node"?"removeNode":"removeSubscription",group:K,value:O.value})),Z=new Set(d.groups.map(K=>K.name)),Q=K=>Fr(K,Z,r),U=async()=>{k(!0),F(null);try{const K=await e.apply(O=>it(O,y));if(K.kind==="invalid"&&F(r("ui.writeInvalid",{n:K.errors})),K.kind==="failed"&&F(r("arrange.failed",{error:dr(K.error,r)})),K.kind==="ok"){const O=[...new Set(y.map(ee=>ee.group))],A=O.length===1?O[0]:null;Ye("positive",r("arrange.applied",{n:y.length}),{action:{label:r(A===null?"policy.viewGroups":"policy.viewGroup"),onAction:()=>t(A),closeOnAction:!0}}),$([]),m.clear(),D(!1)}}finally{k(!1)}},X=E.useMemo(()=>{if(!y.length)return[];const K=d.stagedText.split(` +`),O=new Set(y.map(A=>A.group));return Ce(d.stagedText).filter(A=>O.has(A.name)).map(A=>({group:A.name,text:K.slice(A.from,A.to+1).join(` +`)}))},[d.stagedText,y]);return{groups:d.groups,unknown:d.unknown,byGroup:p,subscriptions:s,nodes:i,search:h,setSearch:x,loading:n.loading&&!n.data||o.loading&&!c||g.loading&&!g.data,error:[n,o,g].find(K=>K.error&&!K.data)?.error??(e.main?null:e.error),retry:E.useCallback(()=>void ur(),[]),blocked:I?r(I):null,busy:e.busy||w,applying:w,failure:C,changes:y,changeLines:y.map(K=>Fn(K,l,r)),pendingText:r("arrange.pending",{n:y.length}),place:N,unplace:Y,drop:K=>j(O=>Pn(O,K)),discard:()=>j(()=>[]),nameProblem:Q,create:(K,O)=>j(A=>ke(A,{kind:"createGroup",group:K,policy:O})),reviewing:u&&y.length>0,setReviewing:K=>{w||D(K)},preview:X,canApply:y.length>0&&d.emptyNew.length===0&&!I&&!w,applyNote:Cn(I?r(I):null,d.emptyNew,r),apply:U}}function _n({source:e,groups:t,viewGroup:r}){const n=J(),a=Bn(e,r),o=E.useMemo(()=>new Map((t??[]).map(g=>[g.name,g])),[t]);return a.error?f.jsx(cr,{error:a.error,onRetry:a.retry}):a.loading?f.jsx(pr,{}):f.jsxs("div",{className:"rp-arrange",children:[f.jsxs("div",{className:"rp-row",children:[f.jsxs("p",{className:"rp-note rp-grow",children:[f.jsx("span",{className:"rp-wide-only",children:n("arrange.note")}),f.jsx("span",{className:"rp-narrow-only",children:n("arrange.selectHint")})]}),f.jsx(On,{m:a})]}),a.blocked&&f.jsx(te,{tone:"informative",children:a.blocked}),f.jsxs("div",{className:"rp-arrange-grid",children:[f.jsx("div",{className:"rp-col",children:a.groups.length?a.groups.map(g=>f.jsx(In,{group:g,live:o.get(g.name),m:a},g.name)):f.jsx(st,{children:n("policy.empty")})}),f.jsx(An,{m:a})]}),a.changes.length>0&&f.jsxs(xn,{label:n("arrange.pendingRegion"),message:a.pendingText,children:[f.jsx(V,{quiet:!0,onPress:a.discard,isDisabled:a.busy,children:n("arrange.discard")}),f.jsx(V,{accent:!0,onPress:()=>a.setReviewing(!0),children:n("arrange.review")})]}),f.jsx(Mn,{m:a})]})}function In({group:e,live:t,m:r}){const n=J(),a=ct(),o=E.useId(),g=!!r.blocked,c=t?Pr(t.policy,n):null,y=async v=>{const l=await Promise.all(v.filter(Lr).filter(d=>d.types.has(ge)).map(d=>d.getText(ge)));r.place(e.name,l.flatMap(d=>Sn(d)??[]))},$=(v,l,d)=>f.jsx(V,{quiet:!0,icon:!0,small:!0,label:n("arrange.remove",{name:v,group:e.name}),isDisabled:g||r.applying||!!d,onPress:()=>r.unplace(e.name,l),children:f.jsx(pt,{})}),m=(v,l)=>f.jsx(V,{quiet:!0,small:!0,label:n("arrange.undoRemove",{name:v}),isDisabled:r.applying,onPress:()=>r.place(e.name,[l]),children:n("arrange.undoShort")});return f.jsx(an,{className:hr("rp-drop"),"aria-label":n("arrange.dropInto",{group:e.name}),isDisabled:g||r.applying,getDropOperation:v=>v.has(ge)?"copy":"cancel",onDrop:v=>void y(v.items),children:({isDropTarget:v})=>f.jsxs(f.Fragment,{children:[f.jsx("div",{className:"rp-row",children:f.jsxs("span",{className:"rp-cluster",children:[f.jsx("h3",{className:"rp-h3",id:o,children:e.name}),c&&f.jsx(Xe,{tip:c.id,children:c.label}),t&&f.jsx(fr,{small:!0,tone:"neutral",children:n("arrange.memberCount",{n:t.member_count})}),e.isNew&&f.jsx(Xe,{children:n("arrange.new")})]})}),e.holdsAll&&f.jsx("p",{className:"rp-note",children:n("arrange.holdsAll")}),f.jsxs(gr,{reason:Kn(e,g||r.applying),children:[(e.names.length>0||e.removedNames.length>0)&&f.jsxs(Ze,{label:n("arrange.byName"),children:[f.jsx("span",{className:"rp-label rp-tags-title",children:n("arrange.byName")}),e.names.map(l=>f.jsx(ce,{tone:l.isNew?"new":void 0,action:$(l.name,{kind:"node",value:l.name},l.blocked),children:l.name},l.name)),e.removedNames.map(l=>f.jsx(ce,{tone:"removed",action:m(l,{kind:"node",value:l}),children:l},l))]}),(e.subscriptions.length>0||e.removedSubscriptions.length>0)&&f.jsxs(Ze,{label:n("arrange.bySubscription"),children:[f.jsx("span",{className:"rp-label rp-tags-title",children:n("arrange.bySubscription")}),e.subscriptions.map(l=>f.jsx(ce,{tone:l.isNew?"new":void 0,action:$(l.label,{kind:"subscription",value:l.tag},l.blocked),children:l.count===null?l.label:n("arrange.subscriptionCount",{name:l.label,n:l.count})},l.tag)),e.removedSubscriptions.map(l=>f.jsx(ce,{tone:"removed",action:m(l.label,{kind:"subscription",value:l.tag}),children:l.label},l.tag))]})]}),e.rules.length>0&&f.jsxs("div",{className:"rp-arrange-rules",children:[f.jsx("span",{className:"rp-label",children:n("arrange.byRule")}),e.rules.map(l=>f.jsx(ft,{as:"code",text:l},l)),e.ruleNodes.length>0&&f.jsx("span",{children:e.ruleMore?n("arrange.ruleSelectsMore",{names:pe(a,e.ruleNodes),n:e.ruleMore}):n("arrange.ruleSelects",{names:pe(a,e.ruleNodes)})}),f.jsxs("span",{className:"rp-label",children:[e.ruleNote," ",f.jsx(yr,{appearance:"link",href:mr("config",{tab:"source"}),children:n("arrange.editSource")})]})]}),e.stillIn.length>0&&f.jsx(te,{tone:"informative",children:n("arrange.stillIn",{names:pe(a,e.stillIn)})}),v&&f.jsx("div",{className:"rp-drop-hint","aria-hidden":"true",children:n("arrange.dropHint")})]})})}function An({m:e}){const t=J(),r=E.useId(),n=!!e.blocked||e.applying,[a,o]=E.useState("all"),[g,c]=E.useState(new Set),y=E.useMemo(()=>[...a==="node"?[]:e.subscriptions.map(d=>({id:"subscription:"+d.tag,item:{kind:"subscription",value:d.tag},label:d.label,meta:t("arrange.subscriptionMeta",{n:d.count})})),...a==="subscription"?[]:e.nodes.map(d=>({id:"node:"+d.name,item:{kind:"node",value:d.name},label:d.name,meta:d.protocol??""}))],[a,e.subscriptions,e.nodes,t]),$=E.useMemo(()=>new Map(y.map(d=>[d.id,d])),[y]),m=g==="all"?y:[...g].flatMap(d=>$.get(String(d))??[]),{dragAndDropHooks:v}=En({getItems:d=>[...d].flatMap(p=>$.has(String(p))?[{[ge]:JSON.stringify($.get(String(p)).item),"text/plain":$.get(String(p)).label}]:[]),getAllowedDropOperations:()=>["copy"],isDisabled:n}),l=e.groups.filter(d=>m.some(p=>!Ft(d,p.item)));return f.jsxs(Dr,{title:t("arrange.tray"),titleId:r,className:"rp-tray",children:[f.jsx(dt,{search:!0,label:t("arrange.search"),value:e.search,onChange:e.setSearch}),f.jsx(br,{label:t("arrange.show"),value:a,onChange:d=>o(d),items:[["all",t("ui.all")],["subscription",t("arrange.subscriptions")],["node",t("arrange.nodes")]]}),f.jsx(Cr,{layout:Sr,layoutOptions:{rowHeight:48},children:f.jsx(kr,{"aria-labelledby":r,className:"rp-tray-list",items:y,selectionMode:"multiple",selectionBehavior:"toggle",selectedKeys:g,onSelectionChange:c,dragAndDropHooks:v,renderEmptyState:()=>f.jsx(st,{children:t("arrange.trayEmpty")}),children:d=>f.jsxs(Kr,{id:d.id,textValue:d.label,className:"rp-item rp-tray-row",children:[f.jsx($r,{slot:"drag",className:Ae(vr({quiet:!0,icon:!0,small:!0}),"rp-drag"),"aria-label":t("arrange.drag",{name:d.label}),children:f.jsx(wn,{})}),f.jsx(Er,{}),f.jsxs("span",{className:"rp-grow",children:[f.jsx(xr,{children:d.label}),f.jsx("span",{className:"desc",children:d.meta})]})]})})}),f.jsxs("div",{className:"rp-tray-bar",children:[f.jsx("span",{className:"rp-grow rp-label","aria-live":"polite",children:m.length?t("arrange.selected",{n:m.length}):t("arrange.selectHint")}),m.length>0&&f.jsx(V,{quiet:!0,small:!0,onPress:()=>c(new Set),children:t("arrange.clear")}),f.jsx(wr,{label:t("arrange.addSelected"),isDisabled:n||!l.length,items:l.map(d=>({id:d.name,label:d.name})),onAction:d=>{e.place(d,m.map(p=>p.item)),c(new Set)},children:t("arrange.addSelected")})]})]})}function On({m:e}){const t=J(),r=E.useId(),[n,a]=E.useState(!1),[o,g]=E.useState(""),[c,y]=E.useState(Ue[0].id),[$,m]=E.useState(!1),v=e.nameProblem(o.trim()),l=()=>{g(""),y(Ue[0].id),m(!1)};return f.jsxs(f.Fragment,{children:[f.jsx(V,{small:!0,onPress:()=>a(!0),isDisabled:!!e.blocked||e.applying,children:t("arrange.newGroup")}),f.jsx(ut,{title:t("arrange.newGroup"),narrow:!0,isOpen:n,onOpenChange:d=>{a(d),d||l()},footer:d=>f.jsxs(f.Fragment,{children:[f.jsx(V,{onPress:d,children:t("ui.cancel")}),f.jsx(V,{accent:!0,type:"submit",form:r,children:t("arrange.create")})]}),children:f.jsxs("form",{id:r,className:"rp-form",onSubmit:d=>{d.preventDefault(),m(!0),!v&&(e.create(o.trim(),c),a(!1),l())},children:[f.jsx(dt,{label:t("arrange.groupName"),value:o,onChange:g,description:t("arrange.groupNameHint"),error:$&&v?v:void 0,spellCheck:!1}),f.jsx(Br,{value:c,onChange:y}),f.jsx("p",{className:"rp-label",children:t("arrange.newGroupNote")})]})})]})}function Mn({m:e}){const t=J(),r=ct();return f.jsxs(ut,{title:t("arrange.reviewTitle"),isOpen:e.reviewing,onOpenChange:e.setReviewing,footer:n=>f.jsxs(f.Fragment,{children:[f.jsx(V,{onPress:n,isDisabled:e.applying,children:t("ui.cancel")}),f.jsx(V,{accent:!0,isPending:e.applying,isDisabled:!e.canApply,onPress:()=>void e.apply(),children:t("config.save")})]}),children:[e.failure&&f.jsx(te,{takeFocus:!0,children:e.failure}),e.applyNote&&f.jsx(te,{children:e.applyNote}),e.unknown.size>0&&f.jsx(te,{tone:"informative",children:t("arrange.unknown",{names:pe(r,[...e.unknown])})}),f.jsx("ol",{className:"rp-arrange-changes",children:e.changeLines.map((n,a)=>f.jsxs("li",{className:"rp-row",children:[f.jsx("span",{className:"rp-grow",children:n}),f.jsx(V,{quiet:!0,icon:!0,small:!0,label:t("arrange.undo",{change:n}),isDisabled:e.applying,onPress:()=>e.drop(a),children:f.jsx(pt,{})})]},a))}),f.jsx(Tr,{title:t("arrange.showText"),children:e.preview.map(n=>f.jsx(ft,{as:"pre",className:"rp-arrange-preview",text:n.text},n.group))}),f.jsx("p",{className:"rp-label",children:t("arrange.applyNote")})]})}export{_n as Arrange}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Config-163650iV.js b/luci-app-honk/root/etc/honk/doona/assets/Config-163650iV.js new file mode 100644 index 000000000..e37f834b0 --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/Config-163650iV.js @@ -0,0 +1,4 @@ +import{r as b,j as o}from"./vendor-react-Bf71BWbF.js";import{a4 as Oe,aw as Ae,av as sn,e4 as tn,d9 as Y,e5 as de,a5 as je,dX as He,e6 as on,a3 as $e,y as _e,h as I,Q as re,O as rn,e7 as an,df as Be,u as F,a6 as ne,a as se,aa as ln,ag as cn,ac as Se,cP as ue,aF as Ie,ap as Ve,bk as dn,bj as un,A as fn,e8 as pn,bm as $,de as Ke,a0 as ae,bg as Z,cS as fe,e9 as We,ea as gn,D as mn,eb as bn,C as hn,B as T,ec as vn,ed as xn,ee as wn,I as ce,aN as pe,bQ as ee,aO as ge,L as Ue,aJ as B,ef as yn,eg as jn,eh as Sn,ei as kn,cR as Nn,ej as Dn,J as Cn,ek as Mn,b as Pn,ah as Rn,bt as me,T as K,bS as Tn,bs as En,aL as Ge,el as zn,bq as Ln,aj as Fn,em as On,aM as An,E as Hn,j as $n,aK as _n,bx as Bn}from"./index-Bw0aJc9a.js";import{d as In}from"./files-BxEOxSF8.js";import{r as Vn,d as Kn,a as Wn,t as ke,b as Un,w as Ne,v as Gn,c as qn,n as Jn}from"./setup-DLvQ_6ZI.js";import{g as Qn}from"./policyText-CltaDVEo.js";import{a as Xn,s as Yn,c as Zn}from"./nav-BFiTWnsa.js";import{S as es,a as ns,E as _,C as te,b as be,l as ss,h as ts,c as De,r as os,d as rs,e as as,f as is,i as ls,g as cs,s as ds,k as us,t as qe,j as Ce,m as fs,n as ps,o as gs,p as ms,q as bs,u as hs,v as vs,w as xs,x as ws,y as Je,D as q,R as ys,z as js,A as Ss,B as ks,F as Ns,G as Ds,H as Qe,I as Cs,J as V,K as Ms}from"./vendor-editor-2EGeBPxF.js";import{d as Ps,s as Rs,D as Xe}from"./DaeCode-B8yPDjSE.js";import{A as Ts}from"./AddCircle-D11CyK2n.js";import{D as Es}from"./Table-Km6Zv-S8.js";import"./useGridSelectionCheckbox-COXIVEmS.js";import"./Virtualizer-DCY9HC9Z.js";import"./ListLayout-_fDlx5XY.js";const zs=["global","subscription","node","group","dns","routing"],Ls=(s,t,e)=>s?e("config.moduleEditBlocked"):t?e("ui.changeApplying"):void 0;function Me(s,t){return`${Y(s)}:${t.line+1}-${t.endLine+1}`}function Fs(s,t,e){return s.slice(0,t.from)+e+s.slice(t.to)}function Os(s,t){const{section:e,text:n}=s,a=t.find(f=>f.id===e.id);if(a?.source?.content_sha256===e.source.content_sha256)return{next:null,conflict:!1};if(!a?.source?.content||!a.block)return{next:null,conflict:!0};const r=a.source.content.slice(a.block.from,a.block.to),l=e.source.content.slice(e.block.from,e.block.to);return{next:{section:{...a,source:a.source,block:a.block},text:n===l?r:n},conflict:r!==l&&n!==l&&r!==n}}function As(s,t,e,n,a){const r=e.line+n.split(` +`).length;return s.filter(l=>l.source_id===t&&l.line!==null&&l.line>e.line&&l.line<=r).map(l=>({line:l.line-e.line,column:l.column,level:l.level,message:he(de(l,a),a)}))}function Hs(s,t,e){return s.filter(n=>n.source_id===t&&n.line!==null).map(n=>({line:n.line,column:n.column,level:n.level,message:he(de(n,e),e)}))}function he({summary:s,detail:t},e,n=s){return t?e("config.backendDetail",{text:n,message:t}):n}function ie(s,t,e){return e.filter(n=>n.from>t.open&&n.to<=t.close&&n.depth===t.depth+1&&n.parens===0&&n.kind==="text"&&s.slice(n.from,n.to)==="->").length}function Pe(s,t,e){const n=t.filter(a=>a.from>s.open&&a.to<=s.close&&a.depth===s.depth+1&&a.parens===0&&(a.kind==="quoted"||a.kind==="text")&&!e.some(r=>a.from>=r.from&&a.to<=r.to));return e.length+n.length}function $s(s,t,e,n,a,r){const l=re(t,e,n);switch(s){case"global":return r("config.moduleSettings",{n:l.length});case"subscription":return r("config.moduleSubscriptions",{n:Pe(e,n,l)});case"node":return r("config.moduleNodes",{n:Pe(e,n,l)});case"group":return r("config.moduleGroups",{n:e.children.length,policies:$e(a,e.children.map(c=>{const f=re(t,c,n).find(p=>p.name==="policy")?.value;if(!f)return c.name;const i=rn(f);return r("ui.valuePair",{label:c.name,value:i?Qn({kind:i,native:f},r).label:f})}))});case"dns":{const c=e.children.filter(i=>i.name==="upstream"),f=e.children.filter(i=>i.name==="routing").flatMap(i=>i.children);return[r("config.moduleDnsUpstreams",{n:c.reduce((i,p)=>i+re(t,p,n).length,0)}),r("config.moduleDnsRequests",{n:f.filter(i=>i.name==="request").reduce((i,p)=>i+ie(t,p,n),0)}),r("config.moduleDnsResponses",{n:f.filter(i=>i.name==="response").reduce((i,p)=>i+ie(t,p,n),0)})].join(r("ui.listSeparator"))}case"routing":{const c=r("config.moduleRules",{n:ie(t,e,n)}),f=l.find(i=>i.name==="fallback")?.value;return f?c+r("ui.separator")+r("ui.valuePair",{label:"fallback",value:f}):c}}}const _s={global:null,subscription:I("nodes"),node:I("nodes"),group:I("policies"),dns:I("rules",{tab:"dns"}),routing:I("rules",{tab:"list"})};function Bs(s,t,e,n){const r=s.filter(i=>i.kind==="main"||i.kind==="include").map(i=>({source:i,..._e(i.content)})),l=s.find(i=>i.kind==="main")??null,c=zs.flatMap(i=>{const p=_s[i],g=r.flatMap(({source:u,blocks:v,tokens:N})=>v.filter(x=>x.name===i).map((x,w)=>({id:`${u.id}:${i}:${w}`,kind:i,source:u,block:x,href:p,range:Me(u,x),summary:$s(i,u.content,x,N,e,n),note:null})));return g.length?g:[{id:i,kind:i,source:l,block:null,href:p,range:l?Y(l):"config.dae",summary:l?.writable?n("config.moduleAbsent",{file:Y(l)}):n("config.moduleAbsentReadOnly"),note:null}]}),f=r.flatMap(({source:i,blocks:p})=>t.redactedSections(p).map(({block:g,name:u},v)=>({id:`${i.id}:${g.name}:${v}`,kind:u,source:i,block:null,href:null,range:Me(i,g),summary:"",note:n("config.incomplete")})));return[...c,...f]}function J(s,t,e){const n=Oe(Xn,s.kind,e);return{id:s.id,label:tn(s)?`${n} ${s.id.slice(0,8)}`:s.path,kind:n,facts:e("config.sourceFacts",{n:s.line_count,size:sn(String(s.bytes),t)}),loaded:e("config.loadedAt",{time:Ae(s.loaded_at,t)})}}const Is={generated:{label:"config.kind.generated",note:"config.generatedNote"},subscription:{label:"config.kind.subscription",note:"config.subscriptionNote"},disabled:{label:"config.readOnly",note:"config.readOnlyNote",help:"config.readOnlyHelp"},secret:{label:"config.secretSource",note:"config.secretNote"},refused:{label:"config.readOnly",note:"config.refusedNote"},redacted:{label:"config.redactedSource",note:"config.redactedNote"}};function Vs(s,t,e,n,a){const r=s.kind==="generated"||s.kind==="subscription"?s.kind:t?s.writable?e===!1?"redacted":null:n.holdsCredentials(s)?"secret":"refused":"disabled";if(!r)return null;const l=Is[r],c=a(l.label);return{reason:r,label:c,note:a(l.note),...l.help&&{help:{title:c,text:a(l.help)}}}}const Ks={error:"err",warning:"warn",info:"info"},Ws={error:"config.level.error",warning:"config.level.warning",info:"config.level.info"};function oe(s,t,e,n){const a=new Map(t.map(l=>[l.id,Y(l)])),r=new Map;for(const l of s){const c=JSON.stringify([l.level,l.source_id,l.line,l.column,l.code,l.message,l.params]),f=r.get(c);f?f.count++:r.set(c,{item:l,count:1})}return[...r].map(([l,{item:c,count:f}])=>{const i=a.get(c.source_id)??c.source_id,p=de(c,n),g=p.summary,u=f>1?n("config.repeated",{text:g,n:je(f,e)}):g,v=he(p,n,u);return{id:l,level:c.level,tone:Ks[c.level],levelText:Oe(Ws,c.level,n),sourceId:c.source_id,line:c.line,where:c.line===null?i:`${i}:${c.line}`,message:u,code:c.code,detail:c.line===null?v:n("config.atFile",{file:i,line:je(c.line,e),message:v}),count:f}})}function le(s){return{...Vn(s),rules:s.trim()?"keep":Kn}}function Us(s,t,e){return t.content_sha256===e.content_sha256?null:s?"conflict":"follow"}function Gs(s,t,e){return{groupUsedText:s.rules==="keep"?null:ke[s.rules].groups.length?e("config.wizardNamedGroups",{names:$e(t,ke[s.rules].groups.map(n=>n.name))}):e("config.wizardGroupUsed",{name:s.group??Un}),rows:s.subscriptions.flatMap((n,a)=>n.raw!==void 0&&!n.raw.trim()?[]:[{index:a,name:n.name,url:n.url,raw:n.raw!==void 0&&!n.name?n.raw.trim():null,nameError:n.raw===void 0&&!on(n.name.trim())?e("config.unquotable"):void 0,error:n.url!==""&&!Wn(n.url)?e("config.wizardSubscriptionHelp"):n.raw===void 0&&!He(n.url.trim())?e("config.unquotable"):void 0,description:a===0?e("config.wizardSubscriptionHelp"):void 0,removeLabel:e("config.wizardRemove",{name:n.name||n.raw?.trim()||""})}])}}function qs(s,t,e,n,a){if(!t&&e)return{disabled:!0,tip:e};const r=a(s==="validate"?"config.saveValidating":n?"config.saveShortcutMac":"config.saveShortcut");return{disabled:!!s||!t,tip:r}}function ve({busy:s,complete:t=!0,conflict:e,invalid:n=null},a){return s||t===null?null:t?e?a("config.saveConflict"):n:a("config.incomplete")}function Ye(s,t,e,n){if(s)return null;const a=t.filter(l=>l.kind==="main"||l.kind==="include");if(a.some(l=>e(l)===void 0))return null;const r=a.find(l=>l.kind==="main");return n(r&&e(r)?"config.validateOther":"config.validateNoMain")}function Js(s,t){return[{label:t("config.revision"),value:s,help:{title:t("config.revision"),text:t("config.revisionHelp")}}]}function xe(s,t,e){const n=e?.id,a=e?.content;return b.useMemo(()=>{const r=s.filter(l=>l.kind==="main"||l.kind==="include");return r.some(l=>t(l)===void 0)?null:an(r.filter(l=>t(l)),n!==void 0&&a!==void 0?{id:n,content:a}:void 0)},[s,t,n,a])}const Qs=600,Xs=()=>{};function Ze(s,t){const{validate:e,cancel:n}=Be(Xs);b.useEffect(()=>{if(!s)return;let a=!0;const r=setTimeout(()=>{e({sources:s,mode:"full"}).then(l=>{a&&l&&t(l.diagnostics)})},Qs);return()=>{a=!1,clearTimeout(r),n()}},[s,e,n,t])}function Ys(s){const t=F(),e=Be(s),n=b.useMemo(()=>e.error instanceof fn&&e.error.status===422?e.error.details?.diagnostics??[]:null,[e.error]);return b.useEffect(()=>{if(e.error)if(n){const a=pn(n);$("negative",a?t("config.writeRestart",{n:a}):t("ui.writeInvalid",{n:n.filter(r=>r.level==="error").length}))}else Ke(e.error,t,t("ui.writeFailed"))},[e.error,n,t]),{...e,diagnostics:n}}function Zs({go:s,query:t}){const e=F(),n=ne[se()],a=ln().data?.resources,r=cn(Se(a,"config",{whileLoading:!0})),l=Ys(r.refetch),c=b.useMemo(()=>new URLSearchParams(t),[t]),f=b.useMemo(()=>r.data?.sources??[],[r.data]),i=f.find(C=>C.kind==="main")??null,p=f.find(C=>C.id===c.get("source"))??f[0]??null,g=p?.id??null,u=C=>s("config",ae(t,{source:C,line:null})),v=(C,z)=>s("config",ae(t,{tab:"source",source:C,line:z===null?null:String(z)})),N=Number(c.get("line"))||null,x=b.useMemo(()=>(r.data?.diagnostics??[]).filter(C=>C.source_id===g),[r.data,g]),w=b.useMemo(()=>{const C=r.data?.diagnostics??[];return{error:C.filter(z=>z.level==="error").length,warning:C.filter(z=>z.level==="warning").length}},[r.data]),h=Yn(a,i),y=Zn(h),P=Se(a,"config_validate",{whileLoading:!1})&&(a?.config_validate.modes??[]).includes("full"),D=a?.config.writable===!0,S=ue(f),m=Ie().data,k=b.useMemo(()=>Ve(m),[m]),M=p?Vs(p,D,S(p),k,e):null,R=!!p&&!M,O=c.has("source")||i?.content===void 0?"source":!i.content.trim()&&h?"setup":"modules",H=dn(t,y.map(C=>C.id),O),j=p?{source:p,sources:f,open:v,diagnostics:x,canValidate:P&&R,canWrite:R,readOnly:M,isComplete:S,editor:l,focusLine:N}:null,L=h&&i?{main:i,editor:l,onDone:()=>s("config",ae(t,{tab:"setup"}),{replace:!0}),next:[{id:"nodes",label:e("nav.nodes"),href:I("nodes")},{id:"policies",label:e("nav.policies"),href:I("policies")},{id:"rules",label:e("rule.listTitle"),href:I("rules",{tab:"list"})},{id:"source",label:e("config.openSource"),href:I("config",{tab:"source",source:i.id})}]}:null,W=a?.config.create===!0&&a.config.writable===!0?{sources:f,refetch:r.refetch,open:C=>v(C,null)}:null,U=r.data?{config:r.data,editor:l,canValidate:P,open:v}:null;return{error:r.error,reload:r.refetch,loading:r.loading&&!r.data,ready:!!r.data,metadata:r.data?Js(r.data.revision,e):[],redacted:!!r.data?.secrets_redacted,tabs:y.map(C=>({id:C.id,label:e(C.titleKey)})),tab:H,setTab:C=>s("config",un(t,C,null)),selectedId:g??"",select:u,sourceProps:j,newSourceProps:W,wizardProps:L,modulesProps:r.data?{config:r.data,editor:l,canWrite:D,canValidate:P,open:v}:null,validateProps:U,sourceModel:p?{...J(p,n,e),readOnly:M}:null,sourceOptions:f.map(C=>{const z=J(C,n,e);return{id:z.id,label:z.label,desc:z.kind}}),exportSource:()=>{p&&In(Y(p),p.content,"text/plain;charset=utf-8")},summaryTone:w.error?"err":w.warning?"warn":"ok",summaryText:w.error?e("config.errors",{n:w.error}):w.warning?e("config.warnings",{n:w.warning}):e("config.clean")}}function et({source:s,sources:t,diagnostics:e,canValidate:n,canWrite:a,readOnly:r,isComplete:l,editor:c,focusLine:f}){const i=F(),p=ne[se()],[g,u]=b.useState(null),[v,N]=b.useState(null),x=a&&l(s)===!0,w=b.useRef(!1),y=(c.errorSource===s.id?c.diagnostics:null)??v??e,P=b.useMemo(()=>Hs(y,s.id,i),[y,s.id,i]),D=g?.text??s.content??"",S=()=>We(t,{id:s.id,content:D}),[m,k]=b.useState(null);Z(f,()=>k(null));const M=g!==null&&g.text!==s.content,R=M&&g.origin.content_sha256!==s.content_sha256,O=fe(M,()=>{u(null),N(null)});b.useEffect(()=>c.cancel,[c.cancel,O.revision]);const H=g?.text,j=xe(t,l,{id:s.id,content:D});Ze(n&&H!==void 0?j:null,N);const L=(d,E=!0)=>{N(d.diagnostics);const A=d.diagnostics.find(G=>G.source_id===s.id&&G.level==="error"&&G.line!==null);return k(A?A.line:null),d.valid?E&&$("positive",i("config.valid")):$("negative",i("config.invalid",{n:d.diagnostics.filter(G=>G.level==="error").length})),d.valid},W=async()=>{if(!j)return!1;const d=await c.validate({sources:j,mode:"full"});return d?L(d):!1},U=async()=>{if(g===null||c.busy||!x||R)return;const d=await c.apply(g.origin,g.text);if(N(null),!!d){if(d.diagnostics){L({valid:!1,diagnostics:d.diagnostics},!1);return}$("positive",i("config.saved",{path:J(s,p,i).label})),O.clear(),u(null)}},C=()=>{u(null),N(null)},z=d=>{d===s.content?C():u(E=>({text:d,origin:E?.origin??s}))},Q=r?()=>{w.current||(w.current=!0,$("info",i("config.readOnlyAttempt"),{detail:r.note}))}:void 0,X=J(s,p,i);return{writable:x,note:r?.note??i(n?"config.editNoteValidate":"config.editNote"),refused:Q,shown:oe(y,t,p,i),marks:P,text:D,outbounds:S,focus:m??f,dirty:M,conflict:R?i("config.changedOnDisk"):null,keep:()=>u(d=>d&&{...d,origin:s}),validate:W,save:U,cancel:C,change:z,view:X,busy:!!c.busy,validating:c.busy==="validate",saving:c.busy==="save",saveButton:R?{disabled:!0,tip:i("config.changedOnDisk")}:qs(c.busy,x,r?.note??null,gn,i),validateDisabled:!!c.busy||!j,reason:M?!x&&r?r.note:ve({busy:!!c.busy,conflict:!!R},i):n&&!c.busy?Ye(j,t,l,i):null}}function nt({config:s,editor:t}){const e=F(),n=ne[se()],[a,r]=b.useState("all"),[l,c]=b.useState(null),[f,i]=b.useState(null);Z(s.generation_id,()=>{c(null),i(null)});const p=b.useMemo(()=>oe(l?.diagnostics??s.diagnostics,s.sources,n,e),[l,s.diagnostics,s.sources,n,e]),g=y=>p.reduce((P,D)=>P+(D.level===y?D.count:0),0),u=g("error"),v=g("warning"),N=a==="all"?p:p.filter(y=>y.level===a),x=ue(s.sources),w=xe(s.sources,x);return{level:a,setLevel:r,selected:f,setSelected:i,shown:N,validate:()=>{w&&t.validate({sources:w,mode:"full"}).then(y=>{y&&(c(y),i(null))})},summaryTone:u?"err":v?"warn":"ok",summary:u?e("config.failed",{errors:e("config.errors",{n:u}),warnings:e("config.warnings",{n:v})}):v?e("config.passedWarnings",{n:v}):e("config.passed"),lastRun:l?e("config.lastRun",{time:Ae(l.validated_at,n)}):e("config.acceptedDiagnostics",{generation:s.generation_id}),validating:t.busy==="validate",blocked:!!t.busy||!w,reason:t.busy?null:Ye(w,s.sources,x,e),levels:[["all",e("config.levelAll",{n:u+v+g("info")})],["error",e("config.levelErrors",{n:u})],["warning",e("config.levelWarnings",{n:v})],["info",e("config.levelInfo",{n:g("info")})]]}}const st=es.define({name:"dae",languageData:{commentTokens:{line:"#"},closeBrackets:{brackets:["(","{","'",'"']}},startState:Rs,token:Ps}),tt=["global","subscription","node","group","dns","routing"].map(s=>({label:s,type:"keyword"})),ot=hn.map(s=>({label:s,type:"property",apply:s+": "})),rt=["domain","dip","sip","dport","sport","l4proto","ipversion","pname","mac","dscp","qname","qtype","upstream"].map(s=>({label:s,type:"function",apply:s+"("})),at=["geosite","geoip","suffix","full","keyword","regex"].map(s=>({label:s,type:"constant",apply:s+":"})),Re=bn.map(s=>({label:s,type:"constant"})),it=mn.map(s=>({label:s,type:"keyword"})),lt=[{label:"fallback",type:"keyword",apply:"fallback: "},{label:"include",type:"keyword",apply:"include "}];function ct(s,t){const e=s.matchBefore(/[\w.-]*/);if(!e)return null;const n=s.state.doc.lineAt(s.pos),a=n.text.slice(0,s.pos-n.from),r=/->\s*[\w.-]*$/.test(a)||/^\s*fallback:\s*[\w.-]*$/.test(a);if(e.from===e.to&&!s.explicit&&!r)return null;const l=s.state.doc.sliceString(0,s.pos),{blocks:c,tokens:f}=_e(l),i=f.at(-1);if(i?.to===s.pos&&(i.kind==="quoted"||i.kind==="comment"))return null;const p=c.find(u=>u.close===s.pos)?.name;let g;if(r)g=[...t().map(u=>({label:u.name,apply:u.written,type:"variable"})),...it];else if(/\b(domain|dip|sip|qname)\(\s*[\w.-]*$/.test(a))g=at;else if(p===void 0)g=tt.map(u=>({...u,apply:(v,N,x,w)=>{const h=u.label+` { + +}`;v.dispatch({changes:{from:x,to:w,insert:h},selection:{anchor:x+u.label.length+4}})}}));else if(p==="routing"||p==="dns")g=[...rt,...lt];else if(p==="global")g=ot;else if(p==="group")g=/\bpolicy\s*:\s*[\w.-]*$/.test(a)?Re:[...Re.map(u=>({...u,apply:"policy: "+u.label})),{label:"filter",type:"property",apply:"filter: "}];else return null;return{from:e.from,options:g,validFor:/^[\w.-]*$/}}function dt(s){return ns({override:[t=>ct(t,s)]})}function ut(s,t){return t.filter(e=>e.line>=1&&e.line<=s.doc.lines).map(e=>{const n=s.doc.line(e.line),a=Math.max(0,(e.column??1)-1),r=new TextEncoder().encode(n.text);let l=0;for(let f=0;fa)break;f+=i,l+=i===4?2:1}return{from:n.from+l,to:n.to,severity:e.level,message:e.message}})}function ft(s){return s.key==="Backspace"||s.key==="Delete"||s.key==="Enter"?!0:[...s.key].length===1&&!s.ctrlKey&&!s.metaKey}function pt(s){let t=!1;const e=n=>(n.state.readOnly&&s(),!1);return _.domEventHandlers({keydown:(n,a)=>ft(n)&&e(a),paste:(n,a)=>e(a),cut:(n,a)=>e(a),pointerdown:n=>(t=n.pointerType==="touch",!1),click:(n,a)=>t&&e(a)})}const gt=[["Completions","cm.completions"],["Find","cm.find"],["Replace","cm.replace"],["next","cm.next"],["previous","cm.previous"],["all","cm.all"],["match case","cm.matchCase"],["regexp","cm.regexp"],["by word","cm.byWord"],["replace","cm.replaceOne"],["replace all","cm.replaceAll"],["close","ui.close"],["Go to line","cm.gotoLine"],["go","cm.go"],["current match","cm.currentMatch"],["replaced $ matches","cm.replacedMatches"],["replaced match on line $","cm.replacedOnLine"],["on line","cm.onLine"],["Selection deleted","cm.selectionDeleted"],["Control character","cm.controlCharacter"]],Te=s=>be.phrases.of(Object.fromEntries(gt.map(([t,e])=>[t,s(e)]))),mt=_.theme({"&":{backgroundColor:"var(--rp-base)",color:"var(--rp-text)",border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-md)",fontSize:"var(--rp-text-sm)"},"&.cm-focused":{outline:"none",borderColor:"var(--rp-accent)",boxShadow:"0 0 0 1px var(--rp-accent)"},".cm-scroller":{fontFamily:"ui-monospace, 'SF Mono', Menlo, Consolas, 'JetBrains Mono', 'Fira Code', 'DejaVu Sans Mono', 'Liberation Mono', 'Noto Sans Mono', monospace",lineHeight:"20px",maxHeight:"70vh",fontVariantLigatures:"none",borderRadius:"calc(var(--rp-r-md) - 1px)"},".cm-content":{padding:"8px 0",caretColor:"var(--rp-text)"},".cm-line":{padding:"0 12px"},".cm-gutters":{backgroundColor:"var(--rp-base)",color:"var(--rp-muted)",border:"none"},".cm-lineNumbers .cm-gutterElement":{padding:"0 8px 0 12px",minWidth:"40px"},".cm-activeLine, .cm-focusLine":{backgroundColor:"color-mix(in srgb, var(--rp-hl-med) 60%, transparent)"},".cm-activeLineGutter":{backgroundColor:"transparent",color:"var(--rp-text)"},".cm-selectionBackground, &.cm-focused .cm-selectionBackground, ::selection":{backgroundColor:"var(--rp-hl-high)"},".cm-cursor":{borderLeftColor:"var(--rp-text)"},".cm-matchingBracket":{backgroundColor:"color-mix(in srgb, var(--rp-accent) 20%, transparent)",outline:"none"},".cm-selectionMatch":{backgroundColor:"color-mix(in srgb, var(--rp-notice) 25%, transparent)"},".cm-tooltip.cm-tooltip-lint":{backgroundColor:"var(--rp-text)",color:"var(--rp-on-text)",border:"none",borderRadius:"var(--rp-r-sm)",padding:"2px 0"},".cm-tooltip-lint .cm-diagnostic":{border:"none",padding:"2px 8px",fontSize:"var(--rp-text-xs)",lineHeight:"16px",fontFamily:"inherit"},".cm-tooltip-lint .cm-diagnosticText":{color:"inherit"},".cm-diag-line-error":{backgroundColor:"color-mix(in srgb, var(--rp-negative) 14%, transparent)"},".cm-diag-line-warning":{backgroundColor:"color-mix(in srgb, var(--rp-notice) 16%, transparent)"},".cm-diag-line-info":{backgroundColor:"color-mix(in srgb, var(--rp-foam) 14%, transparent)"},".cm-lintRange-error":{backgroundImage:"none",textDecoration:"underline wavy var(--rp-negative)",textUnderlineOffset:"3px"},".cm-lintRange-warning":{backgroundImage:"none",textDecoration:"underline wavy var(--rp-notice)",textUnderlineOffset:"3px"},".cm-lintRange-info":{backgroundImage:"none",textDecoration:"underline dotted var(--rp-foam)",textUnderlineOffset:"3px"},".cm-tooltip":{backgroundColor:"var(--rp-surface)",border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-md)",color:"var(--rp-text)"},".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]":{backgroundColor:"var(--rp-selected)",color:"var(--rp-text)"},".cm-tooltip.cm-tooltip-autocomplete > ul":{fontFamily:"ui-monospace, 'SF Mono', Menlo, Consolas, 'JetBrains Mono', 'Fira Code', 'DejaVu Sans Mono', 'Liberation Mono', 'Noto Sans Mono', monospace"},".cm-panels":{backgroundColor:"var(--rp-surface)",color:"var(--rp-text)"},".cm-panels-bottom":{borderTop:"1px solid var(--rp-hl-med)"},".cm-textfield":{border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-sm)",backgroundColor:"var(--rp-base)",color:"var(--rp-text)"},".cm-button":{border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-sm)",backgroundImage:"none",backgroundColor:"var(--rp-overlay)",color:"var(--rp-text)"}}),bt=Cs.define([{tag:V.comment,color:"var(--rp-code-comment)"},{tag:V.keyword,color:"var(--rp-code-keyword)",fontWeight:"700"},{tag:V.string,color:"var(--rp-code-string)"},{tag:V.number,color:"var(--rp-code-number)"},{tag:V.propertyName,color:"var(--rp-code-propertyName)"},{tag:V.variableName,color:"var(--rp-code-variableName)"},{tag:V.operator,color:"var(--rp-code-operator)"},{tag:V.punctuation,color:"var(--rp-code-punctuation)"}]),ht=js.of((s,t)=>{const e=s.lineAt(t,-1),n=e.from>0?s.lineAt(e.from-1,-1):null;if(!n)return 0;const a=/^\s*/.exec(n.text)[0].length,r=/\{\s*(#.*)?$/.test(n.text),l=/^\s*\}/.test(e.text);return Math.max(0,a+(r?2:0)-(l?2:0))}),en=Qe.define(),vt={error:q.line({class:"cm-diag-line cm-diag-line-error"}),warning:q.line({class:"cm-diag-line cm-diag-line-warning"}),info:q.line({class:"cm-diag-line cm-diag-line-info"})},xt=Je.define({create:()=>q.none,update(s,t){let e=s.map(t.changes);for(const n of t.effects){if(!n.is(en))continue;const a=new ys,r={error:0,warning:1,info:2},l=new Map;for(const c of n.value){if(c.line<1||c.line>t.state.doc.lines)continue;const f=l.get(c.line);(!f||r[c.level]f-i)){const f=t.state.doc.line(c).from;a.add(f,f,vt[l.get(c).level])}e=a.finish()}return e},provide:s=>_.decorations.from(s)}),Ee=[{id:"undo",label:"cm.undo",run:xs},{id:"redo",label:"cm.redo",run:ws},{id:"comment",label:"cm.toggleComment",run:qe}],wt=[],ze=Ds.define(),nn=Qe.define(),yt=q.line({class:"cm-focusLine"}),jt=Je.define({create:()=>q.none,update(s,t){let e=s.map(t.changes);for(const n of t.effects)n.is(nn)&&(e=q.set(yt.range(t.state.doc.line(n.value).from)));return e},provide:s=>_.decorations.from(s)}),Le=s=>[be.readOnly.of(s),_.editable.of(!s),s?jt:[Ss(),ks(),Ns()]];function we({value:s,onChange:t,readOnly:e=!1,marks:n=wt,focusLine:a,label:r,outbounds:l,onSave:c,onReadOnlyAttempt:f,compact:i}){const p=b.useRef(null),g=b.useRef(null),u=b.useRef(t),v=b.useRef(l),N=b.useRef(c),x=b.useRef(f);b.useEffect(()=>{u.current=t,v.current=l,N.current=c,x.current=f});const w=b.useRef(new te),h=F(),y=b.useRef(new te),P=b.useRef(new te),D=b.useRef(new te);b.useLayoutEffect(()=>{const m=new _({parent:p.current,state:be.create({doc:s,extensions:[ss(),ts(),D.current.of(De()),os(),xt,rs(),as(),is(),ls.of(" "),cs(),ht,dt(()=>v.current?.()??[]),st,ds(bt),mt,us.of([{key:"Mod-s",run:()=>(N.current?.(),!0)},{key:"Mod-/",run:qe},{key:"Mod-g",run:Ce},...fs,...ps,...gs,...ms,...bs,hs]),w.current.of(Le(e)),y.current.of(Te(h)),P.current.of(_.contentAttributes.of({"aria-label":r,tabindex:"0"})),pt(()=>x.current?.()),_.updateListener.of(k=>{k.docChanged&&!k.transactions.some(M=>M.annotation(ze))&&u.current?.(k.state.doc.toString())})]})});return g.current=m,()=>{m.destroy(),g.current=null}},[]),b.useEffect(()=>{const m=g.current;m&&m.dispatch({effects:w.current.reconfigure(Le(e))})},[e]),b.useEffect(()=>{g.current?.dispatch({effects:y.current.reconfigure(Te(h))})},[h]),b.useEffect(()=>{g.current?.dispatch({effects:P.current.reconfigure(_.contentAttributes.of({"aria-label":r,tabindex:"0"}))})},[r]),b.useEffect(()=>{const m=g.current;!m||m.state.doc.toString()===s||(m.dispatch({changes:{from:0,to:m.state.doc.length,insert:s},annotations:ze.of(!0),effects:D.current.reconfigure([])}),m.dispatch({effects:D.current.reconfigure(De())}))},[s]),b.useEffect(()=>{const m=g.current;if(!m)return;const k=vs(m.state,ut(m.state,n)),M=Array.isArray(k.effects)?k.effects:k.effects?[k.effects]:[];m.dispatch({...k,effects:[...M,en.of(n)]})},[n]),b.useEffect(()=>{const m=g.current;if(!m||!a||a<1||a>m.state.doc.lines)return;const k=m.state.doc.line(a);m.dispatch({selection:{anchor:k.from},effects:[nn.of(a),_.scrollIntoView(k.from,{y:"center"})]}),m.focus()},[a]);const S=m=>{g.current&&m(g.current)};return o.jsxs(o.Fragment,{children:[!i&&o.jsxs("div",{className:"rp-toolbar",children:[o.jsx(T,{onPress:()=>S(Ms),children:h(e?"cm.find":"cm.findReplace")}),o.jsx(T,{onPress:()=>S(Ce),children:h("cm.gotoLine")}),t&&o.jsx(vn,{label:h("cm.commands"),isDisabled:e,content:o.jsx(xn,{"aria-label":h("cm.commands"),onAction:m=>{const k=Ee.find(M=>M.id===m);k&&S(k.run)},children:Ee.map(m=>o.jsx(wn,{id:m.id,className:"rp-item plain",textValue:h(m.label),children:h(m.label)},m.id))}),children:h("cm.commands")})]}),o.jsx("div",{className:i?"rp-editor compact":"rp-editor",ref:p})]})}function ye({message:s,busy:t,keep:e,discard:n}){const a=F();return o.jsx(ce,{action:(e||n)&&o.jsxs("span",{className:"rp-toolbar",children:[e&&o.jsx(T,{isDisabled:t,onPress:e,children:a("config.keepChanges")}),n&&o.jsx(T,{isDisabled:t,onPress:n,children:a("config.discard")})]}),children:s})}function St({config:s,editor:t,canWrite:e,canValidate:n,open:a}){const r=F(),l=se(),c=ne[l],f=Ie().data,i=b.useMemo(()=>Ve(f),[f]),p=b.useMemo(()=>Bs(s.sources,i,l,r),[s,i,l,r]),g=ue(s.sources),[u,v]=b.useState(null),[N,x]=b.useState(null),w=u!==null&&u.text!==u.section.source.content.slice(u.section.block.from,u.section.block.to),h=b.useMemo(()=>u?Os(u,p):null,[u,p]),y=!!h?.conflict;Z(h&&!h.conflict?h.next:null,d=>{d&&v(d)});const P=fe(w,()=>{v(null),x(null)}),{clear:D}=P;b.useEffect(()=>t.cancel,[t.cancel,P.revision]);const S=b.useMemo(()=>u?Fs(u.section.source.content,u.section.block,u.text):null,[u]),m=u?.section.source.id,k=xe(s.sources,g,m&&S!==null?{id:m,content:S}:void 0);Ze(n&&S!==null?k:null,x);const M=(t.errorSource===m?t.diagnostics:null)??N??s.diagnostics,R=b.useMemo(()=>M.filter(d=>d.source_id===m),[M,m]),O=u?.section.id,H=b.useMemo(()=>({own:R,sectionId:O,t:r}),[R,O,r]),[j,L]=b.useState([]);Z(H,d=>L(u?As(d.own,u.section.source.id,u.section.block,u.text,d.t):[]));const W=b.useMemo(()=>We(s.sources,m&&S!==null?{id:m,content:S}:void 0),[m,S,s]),U=()=>{t.cancel(),D(),v(null),x(null)},C=(d,E)=>{x(E),$(d?"positive":"negative",d?r("config.valid"):r("config.invalid",{n:E.filter(A=>A.level==="error").length}))},z=async()=>{if(!u||!k||S===null||t.busy)return;const d=await t.validate({sources:k,mode:"full"});d&&C(d.valid,d.diagnostics)},Q=async()=>{if(!u||S===null||t.busy||!w||y)return;const d=await t.apply(u.section.source,S);if(d){if(d.diagnostics){C(!1,d.diagnostics);return}$("positive",r("config.saved",{path:J(u.section.source,c,r).label})),D(),v(null),x(null)}};return{cards:(u&&!p.some(d=>d.id===u.section.id)?[...p,u.section]:p).map(d=>{const E=u?.section.id===d.id,A=e&&!!d.source?.writable&&!!d.block&&g(d.source)===!0;return{...d,editing:E,canEdit:A,editDisabled:w||!!t.busy,editTip:Ls(w,!!t.busy,r),editReason:A&&!E&&w?r("config.moduleEditBlocked"):null,note:d.note??(d.source&&d.block&&g(d.source)===!1?r("config.incomplete"):null),muted:!d.block,manual:d.source?()=>a(d.source.id,d.block?d.block.line+1:null):null,edit:()=>{w||t.busy||!e||!d.source?.writable||!d.block||g(d.source)!==!0||(x(null),v({section:{...d,source:d.source,block:d.block},text:d.source.content.slice(d.block.from,d.block.to)}))}}}),text:u?.text??"",change:d=>v(E=>E?{...E,text:d}:null),marks:j,diagnostics:oe(R,s.sources,c,r),outbounds:()=>W,dirty:w,saveReason:ve({busy:!!t.busy,conflict:!!y},r),conflict:y?r("config.changedOnDisk"):null,keep:y&&h?.next?()=>v(h.next):null,busy:!!t.busy,saving:t.busy==="save",validating:t.busy==="validate",canValidate:n&&!!k,validate:z,save:Q,cancel:U}}function kt(s){const t=F(),e=St(s);return o.jsx("div",{className:"rp-page",children:e.cards.map(n=>o.jsxs(pe,{"aria-label":n.kind,children:[o.jsx(ee,{reason:n.editReason,children:o.jsxs("div",{className:"rp-row",children:[o.jsxs("span",{className:"rp-cluster",children:[o.jsx("h3",{className:"rp-h3 rp-code",children:n.kind}),o.jsx("span",{className:"rp-label rp-code",children:n.range}),n.editing&&e.dirty&&o.jsx(ge,{tone:"warn",children:t("config.unsaved")})]}),o.jsxs("span",{className:"rp-cluster",children:[n.href&&o.jsx(Ue,{appearance:"button",href:n.href,children:t("config.moduleOpen")}),n.canEdit&&!n.editing&&o.jsx(T,{isDisabled:n.editDisabled,tip:n.editTip,onPress:n.edit,children:t("config.edit")}),n.manual&&!n.editing&&o.jsx(T,{quiet:!0,tip:t("config.moduleManualTip"),onPress:n.manual,children:t("config.moduleManual")})]})]})}),o.jsx(B,{small:!0,tone:n.muted?"muted":"info",children:n.summary}),n.note&&o.jsx(B,{small:!0,tone:"muted",children:n.note}),n.editing&&o.jsxs(o.Fragment,{children:[o.jsx(we,{label:n.range,value:e.text,onChange:e.change,readOnly:e.busy,marks:e.marks,outbounds:e.outbounds,onSave:e.dirty&&!e.busy?()=>void e.save():void 0}),e.conflict&&o.jsx(ye,{message:e.conflict,busy:e.busy,keep:e.keep}),e.diagnostics.length>0&&o.jsx("div",{className:"rp-list rp-config-diagnostics",role:"list","aria-label":t("config.diagnostics"),children:e.diagnostics.map(a=>o.jsx("div",{role:"listitem",children:o.jsx(B,{small:!0,tone:a.tone,children:a.detail})},a.id))}),o.jsx(ee,{reason:e.saveReason,children:o.jsxs("div",{className:"rp-cluster",children:[e.canValidate&&o.jsx(T,{isPending:e.validating,isDisabled:e.busy,onPress:()=>void e.validate(),children:t("config.validate")}),o.jsx(T,{accent:!0,isPending:e.saving,isDisabled:e.busy||!e.dirty||!!e.conflict,onPress:()=>void e.save(),children:t("config.save")}),o.jsx(T,{isDisabled:e.busy,onPress:e.cancel,children:t("ui.cancel")})]})})]})]},n.id))})}function Nt({sources:s,refetch:t,open:e}){const n=F(),a=s.find(D=>D.kind==="main"),r=b.useMemo(()=>a?yn(a.content):null,[a]),l=b.useMemo(()=>jn(r??[]),[r]),c=b.useMemo(()=>Sn(s),[s]),[f,i]=b.useState(null),[p,g]=b.useState(null),{busy:u,create:v}=kn(t),N=Nn(),x=f?.text??"",w=l.find(D=>D.pattern===f?.pattern)??null,h=w?w.prefix+x+w.suffix:x,y=x?w?Dn(x,w):Cn(x):null,P=async D=>{if(!x||y||u)return;const S=N.start();try{const m=await v(h);if(!m||($("positive",n("config.newSourceCreated",{path:h})),!S()))return;D(),m.id&&e(m.id)}catch(m){S()?g(k=>({id:(k?.id??0)+1,text:Pn(m,n)})):Ke(m,n,n("config.newSourceFailed",{path:h}))}};return{isOpen:f!==null,show:()=>{N.next(),g(null),i({text:l.length?"":Mn(r??[]),pattern:l[0]?.pattern??""})},hide:()=>{N.next(),i(null)},choices:l,choice:w,setChoice:D=>i(S=>S&&{...S,pattern:D}),text:x,setText:D=>i(S=>S&&{...S,text:D}),error:y?n(y):void 0,unmatched:!!x&&!y&&c!==null&&!c(h),problem:p,busy:u,canSubmit:!!x&&!y&&!u,submit:P}}function Dt(s){const t=F(),e=Nt(s);return o.jsxs(o.Fragment,{children:[o.jsxs(T,{onPress:e.show,children:[o.jsx(Ts,{}),t("config.newSource")]}),o.jsxs(Rn,{title:t("config.newSourceTitle"),narrow:!0,isOpen:e.isOpen,onOpenChange:n=>{n||e.hide()},footer:n=>o.jsxs(o.Fragment,{children:[o.jsx(T,{onPress:n,children:t("ui.cancel")}),o.jsx(T,{accent:!0,isDisabled:!e.canSubmit,isPending:e.busy,onPress:()=>void e.submit(n),children:t("config.newSourceCreate")})]}),children:[e.problem&&o.jsx(ce,{takeFocus:!0,children:e.problem.text},e.problem.id),o.jsxs("div",{className:"rp-list",children:[o.jsx("span",{className:"rp-label",children:t(e.choice?"config.newSourceNameHelp":"config.newSourceHelp")}),e.choices.length>1&&o.jsx(me,{label:t("config.newSourcePattern"),items:e.choices.map(n=>({id:n.pattern,label:n.pattern})),value:e.choice?.pattern??"",onChange:e.setChoice,isDisabled:e.busy}),e.choice?o.jsx(K,{isDisabled:e.busy,label:t("config.newSourceName"),value:e.text,prefix:e.choice.prefix,suffix:e.choice.suffix,placeholder:"extra",spellCheck:!1,error:e.error,onChange:e.setText}):o.jsx(K,{isDisabled:e.busy,label:t("config.newSourcePath"),value:e.text,placeholder:"config.d/extra.dae",spellCheck:!1,error:e.error,onChange:e.setText}),e.unmatched&&o.jsx(ce,{tone:"informative",children:t("config.newSourceUnmatched")})]})]})]})}function Ct(s){const{canValidate:t}=s,e=F(),{writable:n,note:a,refused:r,shown:l,marks:c,text:f,outbounds:i,focus:p,dirty:g,conflict:u,keep:v,validate:N,save:x,cancel:w,change:h,view:y,busy:P,validating:D,saving:S,saveButton:m,validateDisabled:k,reason:M}=et(s);return o.jsxs(pe,{"aria-label":y.label,children:[o.jsx(ee,{reason:M,children:o.jsxs("div",{className:"rp-row rp-source-note",children:[o.jsx("span",{className:"rp-cluster",children:g?o.jsxs(o.Fragment,{children:[o.jsx(ge,{tone:"warn",children:e("config.unsaved")}),o.jsx("span",{className:"rp-label",children:e("config.unsavedHint")})]}):o.jsx("span",{className:"rp-label",children:a})}),(t||g)&&o.jsxs("span",{className:"rp-cluster nowrap",children:[t&&o.jsx(T,{isPending:D,isDisabled:k,onPress:()=>void N(),children:e("config.validate")}),g&&o.jsxs(o.Fragment,{children:[o.jsx(T,{isDisabled:P,onPress:w,children:e("ui.cancel")}),o.jsx(T,{accent:!0,isPending:S,isDisabled:m.disabled,tip:m.tip,onPress:()=>void x(),children:e("config.save")})]})]})]})}),u&&o.jsx(ye,{message:u,busy:P,keep:v}),l.length>0&&o.jsx("div",{className:"rp-list rp-config-diagnostics",role:"list","aria-label":e("config.diagnostics"),children:l.map((R,O)=>o.jsxs("div",{className:"rp-cluster",role:"listitem",children:[o.jsx(B,{small:!0,tone:R.tone,children:R.detail}),o.jsx(T,{small:!0,quiet:!0,label:e("config.openSourceAt",{where:R.where}),onPress:()=>s.open(R.sourceId,R.line),children:e("config.openSource")})]},O))}),o.jsx(we,{label:y.label,value:f,readOnly:!n||P,onChange:h,onReadOnlyAttempt:r,marks:c,focusLine:p,outbounds:i,onSave:g&&!P?()=>void x():void 0})]})}function Mt(s){const{canValidate:t,open:e}=s,n=F(),{level:a,setLevel:r,selected:l,setSelected:c,shown:f,validate:i,summaryTone:p,summary:g,lastRun:u,validating:v,blocked:N,reason:x,levels:w}=nt(s);return o.jsxs(o.Fragment,{children:[o.jsx(ee,{reason:t?x:null,children:o.jsxs("div",{className:"rp-toolbar",children:[o.jsx(B,{small:!0,tone:p,children:g}),o.jsx("span",{className:"rp-label",children:u}),o.jsx("span",{className:"rp-grow"}),t&&o.jsxs(T,{isPending:v,isDisabled:N,onPress:i,children:[o.jsx(Tn,{className:"rp-spin-on-press"}),n("config.revalidate")]})]})}),o.jsx("span",{className:"rp-label",children:n("config.validateNote")}),o.jsx(En,{label:n("config.level"),value:a,onChange:r,items:w}),o.jsx(Es,{label:n("config.diagnostics"),rows:f,height:360,selected:l,onSelect:c,detail:h=>o.jsxs("div",{className:"rp-cluster rp-config-diagnostics",children:[o.jsx(B,{small:!0,tone:h.tone,children:h.detail}),o.jsx(T,{label:n("config.openSourceAt",{where:h.where}),onPress:()=>e(h.sourceId,h.line),children:n("config.openSource")})]}),empty:n("config.noDiagnostics"),cols:[{id:"level",label:n("config.level"),minWidth:96,grow:0,render:h=>o.jsx(B,{small:!0,tone:h.tone,children:h.levelText})},{id:"where",label:n("config.where"),minWidth:150,grow:0,render:h=>o.jsx("span",{className:"rp-code",children:h.where})},{id:"message",label:n("config.message"),minWidth:240,grow:2,isRowHeader:!0,render:h=>o.jsx(Ge,{children:h.message})},{id:"code",label:n("config.code"),minWidth:140,drop:1,render:h=>o.jsx(Xe,{text:h.code})}]})]})}const Pt=["global","bypass","gfw","mini","standard","full"],Fe={global:["config.wizardGlobal","config.wizardGlobalHelp"],bypass:["config.wizardBypass","config.wizardBypassHelp"],gfw:["config.wizardGfw","config.wizardGfwHelp"],mini:["config.wizardMini","config.wizardMiniHelp"],standard:["config.wizardStandard","config.wizardStandardHelp"],full:["config.wizardFull","config.wizardFullHelp"]};function Rt({main:s,editor:t,onDone:e}){const n=F(),a=se(),r=ne[a],[l,c]=b.useState(()=>s),f=zn(l),i=l.content??"",[p,g]=b.useState(()=>le(i)),u=b.useMemo(()=>Ne(i,le(i)),[i]),v=b.useMemo(()=>{try{return{text:f?Ne(i,p):i,error:null}}catch(d){return{text:i,error:d}}},[f,i,p]),{text:N}=v,x=!!t.busy,[w,h]=b.useState(!1),y=!w&&(v.error!==null||f===!0&&N!==u),P=y||f===!0&&!i.trim(),[D,S]=b.useState(null),m=()=>{c(s),g(le(s.content??"")),S(null)},k=fe(y,m);b.useEffect(()=>t.cancel,[t.cancel,k.revision]);const M=Us(y,l,s),R=M==="conflict";Z(M==="follow"?s:null,d=>{d&&m()});const O=Gn(p.subscriptions),H=!!i.trim()||qn(p),j=O&&H,L=d=>{S(null),h(!1),g(E=>({...E,...d}))},W=(d,E)=>L({subscriptions:p.subscriptions.map((A,G)=>G===d?{...A,...E,raw:void 0}:A)}),U=async()=>{if(x||!j||R)return;if(v.error){$("negative",n("config.previewFailed"),Ln(v.error,n));return}const d=await t.apply(l,N);if(d){if(d.diagnostics){S(d.diagnostics),$("negative",n("ui.writeInvalid",{n:d.diagnostics.filter(E=>E.level==="error").length}));return}$("positive",n("config.saved",{path:C})),k.clear(),h(!0),e()}},C=J(s,r,n).label,z=Gs(p,a,n),Q=(t.errorSource===l.id?t.diagnostics:null)??D??[],X=d=>He(d.trim())?void 0:n("config.unquotable");return{state:p,text:N,busy:x,rows:z.rows,diagnostics:oe(Q,[s],r,n),defaultDnsError:X(p.defaultDns),chinaDnsError:X(p.chinaDns),groupUsedText:z.groupUsedText,templateHelp:p.rules==="keep"?null:n("config.wizardPresetHelp"),networkError:H?void 0:n("config.wizardNetworkError"),patch:L,setSubscription:W,apply:U,conflict:R?n("config.changedOnDisk"):null,keep:()=>c(s),discard:m,saveDisabled:!f||!j||x||!P||R,saving:t.busy==="save",saved:w,saveReason:ve({busy:x,complete:f,conflict:R,invalid:O?H?null:n("config.wizardNetworkError"):n("config.wizardSubsInvalid")},n),writeHelp:i.trim()?n("config.wizardWriteHelp",{path:C}):null,showLan:!i.trim(),templates:[...i.trim()?[{id:"keep",label:n("config.wizardKeep"),desc:n("config.wizardKeepHelp")}]:[],...Pt.map(d=>({id:d,label:n(Fe[d][0]),desc:n(Fe[d][1])}))],add:()=>L({subscriptions:[...p.subscriptions,{name:Jn(p.subscriptions),url:""}]}),remove:d=>L({subscriptions:p.subscriptions.filter((E,A)=>A!==d)})}}function Tt({next:s,...t}){const e=F(),{state:n,text:a,busy:r,rows:l,diagnostics:c,defaultDnsError:f,chinaDnsError:i,groupUsedText:p,templateHelp:g,networkError:u,patch:v,setSubscription:N,apply:x,conflict:w,keep:h,discard:y,saveDisabled:P,saving:D,saved:S,saveReason:m,writeHelp:k,showLan:M,templates:R,add:O,remove:H}=Rt(t);return o.jsxs(pe,{"aria-label":e("config.wizard"),children:[o.jsx("span",{className:"rp-label",children:e("config.wizardNote")}),o.jsx("h3",{className:"rp-h3",children:e("config.wizardSubscriptions")}),o.jsxs("div",{className:"rp-list",children:[l.map(j=>o.jsxs("div",{className:j.raw===null?"rp-toolbar top rp-sub-row":"rp-toolbar top",children:[j.raw!==null?o.jsx(Xe,{text:j.raw,className:"rp-grow rp-config-raw"}):o.jsxs(o.Fragment,{children:[o.jsx(K,{isDisabled:r,label:e("config.wizardSubscriptionName"),value:j.name,width:140,error:j.nameError,onChange:L=>N(j.index,{name:L})}),o.jsx(K,{isDisabled:r,className:"rp-sub-url",label:e("config.wizardSubscription"),value:j.url,width:520,placeholder:"https://example.org/sub?token=…",error:j.error,description:j.description,onChange:L=>N(j.index,{url:L})})]}),o.jsx("span",{className:j.raw===null?"rp-field-row rp-sub-remove":void 0,children:o.jsx(T,{isDisabled:r,quiet:!0,small:!0,label:j.removeLabel,onPress:()=>H(j.index),children:o.jsx(Fn,{})})})]},j.index)),o.jsx("div",{children:o.jsx(T,{isDisabled:r,small:!0,onPress:O,children:e("config.wizardAddSubscription")})})]}),o.jsx("h3",{className:"rp-h3",children:e("config.wizardTemplate")}),o.jsxs("div",{className:"rp-toolbar top",children:[o.jsx(me,{isDisabled:r,label:e("config.wizardTemplate"),value:n.rules,onChange:j=>v({rules:j}),items:R}),M&&o.jsx(K,{isDisabled:r,label:e("config.wizardLan"),value:n.lanInterface,width:140,placeholder:"auto",onChange:j=>v({lanInterface:j})})]}),p&&o.jsx("span",{className:"rp-label",children:p}),g&&o.jsx("span",{className:"rp-label",children:g}),M&&o.jsxs("div",{className:"rp-toolbar top",children:[o.jsx(K,{isDisabled:r,label:e("config.wizardListenerPort"),value:n.listenerPort,width:140,onChange:j=>v({listenerPort:j}),error:u}),o.jsx(K,{isDisabled:r,label:e("config.wizardDefaultDns"),value:n.defaultDns,error:f,onChange:j=>v({defaultDns:j})}),o.jsx(K,{isDisabled:r,label:e("config.wizardChinaDns"),value:n.chinaDns,error:i,onChange:j=>v({chinaDns:j})})]}),o.jsx("h3",{className:"rp-h3",children:e("config.wizardPreview")}),o.jsx(we,{label:e("config.wizardPreview"),value:a,readOnly:!0,compact:!0}),c.length>0&&o.jsx("div",{className:"rp-list rp-config-diagnostics",role:"list","aria-label":e("config.diagnostics"),children:c.map(j=>o.jsx("div",{role:"listitem",children:o.jsx(B,{small:!0,tone:j.tone,children:j.detail})},j.id))}),w&&o.jsx(ye,{message:w,busy:r,keep:h,discard:y}),o.jsx(ee,{reason:m,children:o.jsxs("div",{className:"rp-toolbar",children:[o.jsx(T,{accent:!0,isDisabled:P,isPending:D,onPress:()=>void x(),children:e("config.save")}),k&&o.jsx("span",{className:"rp-label",children:k}),S&&s.map(j=>o.jsx(Ue,{appearance:"button",quiet:!0,href:j.href,children:j.label},j.id))]})})]})}function Wt(s){const t=F(),{error:e,reload:n,loading:a,ready:r,metadata:l,redacted:c,tabs:f,tab:i,setTab:p,selectedId:g,select:u,sourceProps:v,newSourceProps:N,wizardProps:x,validateProps:w,modulesProps:h,sourceModel:y,sourceOptions:P,exportSource:D,summaryTone:S,summaryText:m}=Zs(s),k={modules:h&&o.jsx(kt,{...h}),setup:x&&o.jsx(Tt,{...x}),source:o.jsxs(o.Fragment,{children:[o.jsxs("div",{className:"rp-toolbar",children:[o.jsxs("span",{className:"rp-cluster nowrap rp-source-pick",children:[o.jsx(me,{side:!0,cut:"start",label:t("config.source"),value:g,onChange:u,items:P}),y&&o.jsxs(o.Fragment,{children:[y.readOnly&&o.jsxs("span",{className:"rp-help-row",children:[o.jsx(ge,{children:y.readOnly.label}),y.readOnly.help&&o.jsx(On,{...y.readOnly.help})]}),o.jsx(Ge,{className:"rp-label",text:y.loaded,children:y.facts})]})]}),(N||y)&&o.jsxs("span",{className:"rp-cluster nowrap",children:[N&&o.jsx(Dt,{...N}),y&&o.jsxs(T,{onPress:D,children:[o.jsx(An,{}),t("config.export")]})]})]}),y&&o.jsx("span",{className:"rp-label",children:t("config.exportWarning")}),v&&o.jsx(Ct,{...v},y.id)]}),validate:w&&o.jsx(Mt,{...w})};return o.jsxs("div",{className:"rp-page",children:[o.jsx(Hn,{error:e,onRetry:n}),a&&o.jsx($n,{}),r&&o.jsxs("div",{className:"rp-toolbar",children:[o.jsx(_n,{row:!0,items:l}),o.jsx(B,{small:!0,tone:S,children:m}),c&&o.jsx(B,{small:!0,tone:"muted",children:t("config.redacted")})]}),r&&o.jsx(Bn,{label:t("nav.config"),value:i,onChange:p,items:f.map(M=>({...M,content:k[M.id]}))})]})}export{Wt as Config}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Config-DgoxfEHn.js b/luci-app-honk/root/etc/honk/doona/assets/Config-DgoxfEHn.js deleted file mode 100644 index 2ff602269..000000000 --- a/luci-app-honk/root/etc/honk/doona/assets/Config-DgoxfEHn.js +++ /dev/null @@ -1,4 +0,0 @@ -import{r as m,j as o}from"./vendor-react-Bf71BWbF.js";import{a3 as Te,at as ze,as as Xe,dk as Ye,cS as q,aq as Ze,a4 as xe,dl as en,dm as Le,dn as nn,a2 as Fe,y as Oe,h as we,O as oe,N as tn,dp as sn,cW as He,u as F,a5 as ee,a as ne,a8 as on,ae as rn,aa as ye,dq as ce,aB as Ae,dr as _e,bj as an,bi as ln,A as cn,ds as dn,be as A,cV as Be,$ as re,bf as Y,cE as de,dt as Ie,du as un,D as fn,dv as pn,C as gn,I as le,B as R,aJ as ue,bB as Z,aK as fe,L as mn,aF as B,dw as hn,dx as bn,dy as vn,dz as xn,cD as wn,dA as yn,H as jn,dB as kn,b as $e,af as Sn,b5 as pe,T as G,ai as Cn,bD as Dn,b4 as Nn,aH as We,dC as Mn,ah as Pn,dD as En,aI as Rn,E as Tn,j as zn,aG as Ln,br as Fn}from"./index-BNBwb-FJ.js";import{d as On}from"./files-BxEOxSF8.js";import{r as Hn,d as An,a as _n,t as je,b as Bn,w as ke,v as In,c as $n,n as Wn}from"./setup-d2VGFWY1.js";import{g as Vn}from"./policyText-CmeXgUK2.js";import{a as Kn,s as Gn,c as Un}from"./nav-BeFLfZq8.js";import{S as qn,a as Jn,E as _,C as te,b as ge,l as Qn,h as Xn,c as Se,r as Yn,d as Zn,e as et,f as nt,i as tt,g as st,s as ot,k as rt,t as at,j as it,m as lt,n as ct,o as dt,p as ut,q as ft,u as pt,v as gt,w as Ve,D as J,R as mt,x as ht,y as bt,z as vt,A as xt,B as wt,F as Ke,H as yt,G as K}from"./vendor-editor-CF5uj9id.js";import{d as jt,s as kt,D as Ge}from"./DaeCode-B8yPDjSE.js";import{A as St}from"./AddCircle-CIj8X2wL.js";import{D as Ct}from"./Table-DyWJelc_.js";import"./useGridSelectionCheckbox-CrCOlZv8.js";import"./Virtualizer-DipGMcji.js";import"./ListLayout-F74Z1Dpf.js";const Dt=["global","subscription","node","group","dns","routing"],Nt=(t,s,e)=>t?e("config.moduleEditBlocked"):s?e("ui.changeApplying"):void 0;function Ce(t,s){return`${q(t)}:${s.line+1}-${s.endLine+1}`}function Mt(t,s,e){return t.slice(0,s.from)+e+t.slice(s.to)}function Pt(t,s){const{section:e,text:n}=t,a=s.find(f=>f.id===e.id);if(a?.source?.content_sha256===e.source.content_sha256)return{next:null,conflict:!1};if(!a?.source?.content||!a.block)return{next:null,conflict:!0};const r=a.source.content.slice(a.block.from,a.block.to),l=e.source.content.slice(e.block.from,e.block.to);return{next:{section:{...a,source:a.source,block:a.block},text:n===l?r:n},conflict:r!==l&&n!==l&&r!==n}}function Et(t,s,e,n){const a=e.line+n.split(` -`).length;return t.filter(r=>r.source_id===s&&r.line!==null&&r.line>e.line&&r.line<=a).map(r=>({line:r.line-e.line,column:r.column,level:r.level,message:r.message}))}function Rt(t,s){return t.filter(e=>e.source_id===s&&e.line!==null).map(e=>({line:e.line,column:e.column,level:e.level,message:e.message}))}function ae(t,s,e){return e.filter(n=>n.from>s.open&&n.to<=s.close&&n.depth===s.depth+1&&n.parens===0&&n.kind==="text"&&t.slice(n.from,n.to)==="->").length}function De(t,s,e){const n=s.filter(a=>a.from>t.open&&a.to<=t.close&&a.depth===t.depth+1&&a.parens===0&&(a.kind==="quoted"||a.kind==="text")&&!e.some(r=>a.from>=r.from&&a.to<=r.to));return e.length+n.length}function Tt(t,s,e,n,a,r){const l=oe(s,e,n);switch(t){case"global":return r("config.moduleSettings",{n:l.length});case"subscription":return r("config.moduleSubscriptions",{n:De(e,n,l)});case"node":return r("config.moduleNodes",{n:De(e,n,l)});case"group":return r("config.moduleGroups",{n:e.children.length,policies:Fe(a,e.children.map(c=>{const f=oe(s,c,n).find(u=>u.name==="policy")?.value;if(!f)return c.name;const i=tn(f);return r("ui.valuePair",{label:c.name,value:i?Vn({kind:i,native:f},r).label:f})}))});case"dns":{const c=e.children.filter(i=>i.name==="upstream"),f=e.children.filter(i=>i.name==="routing").flatMap(i=>i.children);return[r("config.moduleDnsUpstreams",{n:c.reduce((i,u)=>i+oe(s,u,n).length,0)}),r("config.moduleDnsRequests",{n:f.filter(i=>i.name==="request").reduce((i,u)=>i+ae(s,u,n),0)}),r("config.moduleDnsResponses",{n:f.filter(i=>i.name==="response").reduce((i,u)=>i+ae(s,u,n),0)})].join(r("ui.listSeparator"))}case"routing":{const c=r("config.moduleRules",{n:ae(s,e,n)}),f=l.find(i=>i.name==="fallback")?.value;return f?c+r("ui.separator")+r("ui.valuePair",{label:"fallback",value:f}):c}}}function zt(t,s,e,n){const r=t.filter(i=>i.kind==="main"||i.kind==="include").map(i=>({source:i,...Oe(i.content??"")})),l=t.find(i=>i.kind==="main")??null,c=Dt.flatMap(i=>{const u=i==="group"?we("policies"):i==="node"||i==="subscription"?we("nodes"):null,g=r.flatMap(({source:d,blocks:v,tokens:S})=>v.filter(w=>w.name===i).map((w,b)=>({id:`${d.id}:${i}:${b}`,kind:i,source:d,block:w,href:u,range:Ce(d,w),summary:Tt(i,d.content,w,S,e,n),note:null})));return g.length||l&&l.content===void 0?g:[{id:i,kind:i,source:l,block:null,href:u,range:l?q(l):"config.dae",summary:l?.content===void 0?"":l.writable?n("config.moduleAbsent",{file:q(l)}):n("config.moduleAbsentReadOnly"),note:l?.content===void 0?n("config.contentWithheld"):null}]}),f=r.flatMap(({source:i,blocks:u})=>i.content===void 0?[{id:i.id,kind:q(i),source:i,block:null,href:null,range:q(i),summary:"",note:n("config.contentWithheld")}]:s.redactedSections(u).map(({block:g,name:d},v)=>({id:`${i.id}:${g.name}:${v}`,kind:d,source:i,block:null,href:null,range:Ce(i,g),summary:"",note:n("config.incomplete")})));return[...c,...f]}function Q(t,s,e){const n=Te(Kn,t.kind,e);return{id:t.id,label:Ye(t)?`${n} ${t.id.slice(0,8)}`:t.path,kind:n,facts:e("config.sourceFacts",{n:t.line_count,size:Xe(String(t.bytes),s)}),loaded:e("config.loadedAt",{time:ze(t.loaded_at,s)}),hasContent:t.content!==void 0}}const Lt={generated:{label:"config.kind.generated",note:"config.generatedNote"},subscription:{label:"config.kind.subscription",note:"config.subscriptionNote"},disabled:{label:"config.readOnly",note:"config.readOnlyNote",help:"config.readOnlyHelp"},secret:{label:"config.secretSource",note:"config.secretNote"},refused:{label:"config.readOnly",note:"config.refusedNote"},withheld:{label:"config.withheldSource",note:"config.contentWithheld"},redacted:{label:"config.redactedSource",note:"config.redactedNote"}};function Ft(t,s,e,n,a){const r=t.kind==="generated"||t.kind==="subscription"?t.kind:s?t.writable?t.content===void 0?"withheld":e===!1?"redacted":null:n.holdsCredentials(t)?"secret":"refused":"disabled";if(!r)return null;const l=Lt[r],c=a(l.label);return{reason:r,label:c,note:a(l.note),...l.help&&{help:{title:c,text:a(l.help)}}}}const Ot={error:"err",warning:"warn",info:"info"},Ht={error:"config.level.error",warning:"config.level.warning",info:"config.level.info"};function se(t,s,e,n){const a=new Map(s.map(l=>[l.id,q(l)])),r=new Map;for(const l of t){const c=JSON.stringify([l.level,l.source_id,l.line,l.column,l.code,l.message]),f=r.get(c);f?f.count++:r.set(c,{item:l,count:1})}return[...r].map(([l,{item:c,count:f}])=>{const i=a.get(c.source_id)??c.source_id,u=Ze(c.code,c.message,n).summary,g=f>1?n("config.repeated",{text:u,n:xe(f,e)}):u,d=en(c.code)?n("config.backendDetail",{text:g,message:c.message}):g;return{id:l,level:c.level,tone:Ot[c.level],levelText:Te(Ht,c.level,n),sourceId:c.source_id,line:c.line,where:c.line===null?i:`${i}:${c.line}`,message:g,code:c.code,detail:c.line===null?d:n("config.atFile",{file:i,line:xe(c.line,e),message:d}),count:f}})}function ie(t){return{...Hn(t),rules:t.trim()?"keep":An}}function At(t,s,e){return s.content_sha256===e.content_sha256?null:t?"conflict":"follow"}function _t(t,s,e){return{groupUsedText:t.rules==="keep"?null:je[t.rules].groups.length?e("config.wizardNamedGroups",{names:Fe(s,je[t.rules].groups.map(n=>n.name))}):e("config.wizardGroupUsed",{name:t.group??Bn}),rows:t.subscriptions.flatMap((n,a)=>n.raw!==void 0&&!n.raw.trim()?[]:[{index:a,name:n.name,url:n.url,raw:n.raw!==void 0&&!n.name?n.raw.trim():null,nameError:n.raw===void 0&&!nn(n.name.trim())?e("config.unquotable"):void 0,error:n.url!==""&&!_n(n.url)?e("config.wizardSubscriptionHelp"):n.raw===void 0&&!Le(n.url.trim())?e("config.unquotable"):void 0,description:a===0?e("config.wizardSubscriptionHelp"):void 0,removeLabel:e("config.wizardRemove",{name:n.name||n.raw?.trim()||""})}])}}function Bt(t,s,e,n,a){if(!s&&e)return{disabled:!0,tip:e};const r=a(t==="validate"?"config.saveValidating":n?"config.saveShortcutMac":"config.saveShortcut");return{disabled:!!t||!s,tip:r}}function me({busy:t,complete:s=!0,conflict:e,invalid:n=null,changed:a},r){return t||s===null?null:s?e?r("config.saveConflict"):n??(a?null:r("config.noChanges")):r("config.incomplete")}function Ue(t,s,e,n){if(t)return null;const a=s.filter(l=>l.kind==="main"||l.kind==="include");if(a.some(l=>e(l)===void 0))return null;const r=a.find(l=>l.kind==="main");return n(r?.content!==void 0&&e(r)?"config.validateOther":"config.validateNoMain")}function It(t,s,e){return[{label:e("config.generation"),value:t,help:{title:e("config.generation"),text:e("config.generationHelp")}},[e("config.revision"),s]]}function he(t,s,e){const n=e?.id,a=e?.content;return m.useMemo(()=>{const r=t.filter(l=>l.kind==="main"||l.kind==="include");return r.some(l=>s(l)===void 0)?null:sn(r.filter(l=>s(l)),n!==void 0&&a!==void 0?{id:n,content:a}:void 0)},[t,s,n,a])}const $t=600,Wt=()=>{};function qe(t,s){const{validate:e,cancel:n}=He(Wt);m.useEffect(()=>{if(!t)return;let a=!0;const r=setTimeout(()=>{e({sources:t,mode:"full"}).then(l=>{a&&l&&s(l.diagnostics)})},$t);return()=>{a=!1,clearTimeout(r),n()}},[t,e,n,s])}function Vt(t){const s=F(),e=He(t),n=m.useMemo(()=>e.error instanceof cn&&e.error.status===422?e.error.details?.diagnostics??[]:null,[e.error]);return m.useEffect(()=>{if(e.error)if(n){const a=dn(n);A("negative",a?s("config.writeRestart",{n:a}):s("ui.writeInvalid",{n:n.filter(r=>r.level==="error").length}))}else Be(e.error,s,s("ui.writeFailed"))},[e.error,n,s]),{...e,diagnostics:n}}function Kt({go:t,query:s}){const e=F(),n=ee[ne()],a=on().data?.resources,r=rn(ye(a,"config",{whileLoading:!0})),l=Vt(r.refetch),c=m.useMemo(()=>new URLSearchParams(s),[s]),f=m.useMemo(()=>r.data?.sources??[],[r.data]),i=f.find(M=>M.kind==="main")??null,u=f.find(M=>M.id===c.get("source"))??f[0]??null,g=u?.id??null,d=M=>t("config",re(s,{source:M,line:null})),v=(M,z)=>t("config",re(s,{tab:"source",source:M,line:z===null?null:String(z)})),S=Number(c.get("line"))||null,w=m.useMemo(()=>(r.data?.diagnostics??[]).filter(M=>M.source_id===g),[r.data,g]),b=m.useMemo(()=>{const M=r.data?.diagnostics??[];return{error:M.filter(z=>z.level==="error").length,warning:M.filter(z=>z.level==="warning").length}},[r.data]),x=Gn(a,i),k=Un(x),C=ye(a,"config_validate",{whileLoading:!1})&&(a?.config_validate.modes??[]).includes("full"),N=a?.config.writable===!0,h=ce(f),y=Ae().data,D=m.useMemo(()=>_e(y),[y]),E=u?Ft(u,N,h(u),D,e):null,T=!!u&&!E,j=c.has("source")||i?.content===void 0?"source":!i.content.trim()&&x?"setup":"modules",L=an(s,k.map(M=>M.id),j),H=u?{source:u,sources:f,open:v,diagnostics:w,canValidate:C&&T,canWrite:T,readOnly:E,isComplete:h,contentOffered:a?.config.content===!0,editor:l,focusLine:S}:null,$=x&&i?{main:i,editor:l,onDone:()=>t("config",re(s,{tab:"source",source:i.id}))}:null,W=a?.config.create===!0&&a.config.writable===!0?{sources:f,contentOffered:a.config.content===!0,refetch:r.refetch,open:M=>v(M,null)}:null,V=r.data?{config:r.data,editor:l,canValidate:C,open:v}:null;return{error:r.error,reload:r.refetch,loading:r.loading&&!r.data,ready:!!r.data,metadata:r.data?It(r.data.generation_id,r.data.revision,e):[],redacted:!!r.data?.secrets_redacted,tabs:k.map(M=>({id:M.id,label:e(M.titleKey)})),tab:L,setTab:M=>t("config",ln(s,M,null)),selectedId:g??"",select:d,sourceProps:H,newSourceProps:W,wizardProps:$,modulesProps:r.data?{config:r.data,editor:l,canWrite:N,canValidate:C,open:v}:null,validateProps:V,sourceModel:u?{...Q(u,n,e),readOnly:E}:null,sourceOptions:f.map(M=>{const z=Q(M,n,e);return{id:z.id,label:z.label,desc:z.kind}}),exportSource:()=>{u?.content!==void 0&&On(q(u),u.content,"text/plain;charset=utf-8")},summaryTone:b.error?"err":b.warning?"warn":"ok",summaryText:b.error?e("config.errors",{n:b.error}):b.warning?e("config.warnings",{n:b.warning}):e("config.clean")}}function Gt({source:t,sources:s,diagnostics:e,canValidate:n,canWrite:a,readOnly:r,isComplete:l,editor:c,focusLine:f}){const i=F(),u=ee[ne()],[g,d]=m.useState(null),[v,S]=m.useState(null),w=a&&l(t)===!0,b=m.useRef(!1),k=(c.errorSource===t.id?c.diagnostics:null)??v??e,C=m.useMemo(()=>Rt(k,t.id),[k,t.id]),N=g?.text??t.content??"",h=()=>Ie(s,{id:t.id,content:N}),[y,D]=m.useState(null);Y(f,()=>D(null));const E=g!==null&&g.text!==t.content,T=E&&g.origin.content_sha256!==t.content_sha256,j=de(E,()=>{d(null),S(null)});m.useEffect(()=>c.cancel,[c.cancel,j.revision]);const L=g?.text,H=he(s,l,{id:t.id,content:N});qe(n&&L!==void 0?H:null,S);const $=(p,O=!0)=>{S(p.diagnostics);const U=p.diagnostics.find(X=>X.source_id===t.id&&X.level==="error"&&X.line!==null);return D(U?U.line:null),p.valid?O&&A("positive",i("config.valid")):A("negative",i("config.invalid",{n:p.diagnostics.filter(X=>X.level==="error").length})),p.valid},W=async()=>{if(!H)return!1;const p=await c.validate({sources:H,mode:"full"});return p?$(p):!1},V=async()=>{if(g===null||c.busy||!w||T)return;const p=await c.apply(g.origin,g.text);if(S(null),!!p){if(p.diagnostics){$({valid:!1,diagnostics:p.diagnostics},!1);return}A("positive",i("config.saved",{path:Q(t,u,i).label})),j.clear(),d(null)}},M=()=>{d(null),S(null)},z=p=>{p===t.content?M():d(O=>({text:p,origin:O?.origin??t}))},P=r?()=>{b.current||(b.current=!0,A("info",i("config.readOnlyAttempt"),{detail:r.note}))}:void 0,I=Q(t,u,i);return{writable:w,note:r?.note??i(n?"config.editNoteValidate":"config.editNote"),refused:P,shown:se(k,s,u,i),marks:C,text:N,outbounds:h,focus:y??f,dirty:E,conflict:T?i("config.changedOnDisk"):null,keep:()=>d(p=>p&&{...p,origin:t}),validate:W,save:V,cancel:M,change:z,view:I,busy:!!c.busy,validating:c.busy==="validate",saving:c.busy==="save",saveButton:T?{disabled:!0,tip:i("config.changedOnDisk")}:Bt(c.busy,w,r?.note??null,un,i),validateDisabled:!!c.busy||!H,reason:E?!w&&r?r.note:me({busy:!!c.busy,conflict:!!T,changed:!0},i):n&&!c.busy?Ue(H,s,l,i):null}}function Ut({config:t,editor:s}){const e=F(),n=ee[ne()],[a,r]=m.useState("all"),[l,c]=m.useState(null),[f,i]=m.useState(null);Y(t.generation_id,()=>{c(null),i(null)});const u=m.useMemo(()=>se(l?.diagnostics??t.diagnostics,t.sources,n,e),[l,t.diagnostics,t.sources,n,e]),g=k=>u.reduce((C,N)=>C+(N.level===k?N.count:0),0),d=g("error"),v=g("warning"),S=a==="all"?u:u.filter(k=>k.level===a),w=ce(t.sources),b=he(t.sources,w);return{level:a,setLevel:r,selected:f,setSelected:i,shown:S,validate:()=>{b&&s.validate({sources:b,mode:"full"}).then(k=>{k&&(c(k),i(null))})},summaryTone:d?"err":v?"warn":"ok",summary:d?e("config.failed",{errors:e("config.errors",{n:d}),warnings:e("config.warnings",{n:v})}):v?e("config.passedWarnings",{n:v}):e("config.passed"),lastRun:l?e("config.lastRun",{time:ze(l.validated_at,n)}):e("config.acceptedDiagnostics",{generation:t.generation_id}),validating:s.busy==="validate",blocked:!!s.busy||!b,reason:s.busy?null:Ue(b,t.sources,w,e),levels:[["all",e("config.levelAll",{n:d+v+g("info")})],["error",e("config.levelErrors",{n:d})],["warning",e("config.levelWarnings",{n:v})],["info",e("config.levelInfo",{n:g("info")})]]}}const qt=qn.define({name:"dae",languageData:{commentTokens:{line:"#"},closeBrackets:{brackets:["(","{","'",'"']}},startState:kt,token:jt}),Jt=["global","subscription","node","group","dns","routing"].map(t=>({label:t,type:"keyword"})),Qt=gn.map(t=>({label:t,type:"property",apply:t+": "})),Xt=["domain","dip","sip","dport","sport","l4proto","ipversion","pname","mac","dscp","qname","qtype","upstream"].map(t=>({label:t,type:"function",apply:t+"("})),Yt=["geosite","geoip","suffix","full","keyword","regex"].map(t=>({label:t,type:"constant",apply:t+":"})),Ne=pn.map(t=>({label:t,type:"constant"})),Zt=fn.map(t=>({label:t,type:"keyword"})),es=[{label:"fallback",type:"keyword",apply:"fallback: "},{label:"include",type:"keyword",apply:"include "}];function ns(t,s){const e=t.matchBefore(/[\w.-]*/);if(!e)return null;const n=t.state.doc.lineAt(t.pos),a=n.text.slice(0,t.pos-n.from),r=/->\s*[\w.-]*$/.test(a)||/^\s*fallback:\s*[\w.-]*$/.test(a);if(e.from===e.to&&!t.explicit&&!r)return null;const l=t.state.doc.sliceString(0,t.pos),{blocks:c,tokens:f}=Oe(l),i=f.at(-1);if(i?.to===t.pos&&(i.kind==="quoted"||i.kind==="comment"))return null;const u=c.find(d=>d.close===t.pos)?.name;let g;if(r)g=[...s().map(d=>({label:d.name,apply:d.written,type:"variable"})),...Zt];else if(/\b(domain|dip|sip|qname)\(\s*[\w.-]*$/.test(a))g=Yt;else if(u===void 0)g=Jt.map(d=>({...d,apply:(v,S,w,b)=>{const x=d.label+` { - -}`;v.dispatch({changes:{from:w,to:b,insert:x},selection:{anchor:w+d.label.length+4}})}}));else if(u==="routing"||u==="dns")g=[...Xt,...es];else if(u==="global")g=Qt;else if(u==="group")g=/\bpolicy\s*:\s*[\w.-]*$/.test(a)?Ne:[...Ne.map(d=>({...d,apply:"policy: "+d.label})),{label:"filter",type:"property",apply:"filter: "}];else return null;return{from:e.from,options:g,validFor:/^[\w.-]*$/}}function ts(t){return Jn({override:[s=>ns(s,t)]})}function ss(t,s){return s.filter(e=>e.line>=1&&e.line<=t.doc.lines).map(e=>{const n=t.doc.line(e.line),a=Math.max(0,(e.column??1)-1),r=new TextEncoder().encode(n.text);let l=0;for(let f=0;fa)break;f+=i,l+=i===4?2:1}return{from:n.from+l,to:n.to,severity:e.level,message:e.message}})}function os(t){return t.key==="Backspace"||t.key==="Delete"||t.key==="Enter"?!0:[...t.key].length===1&&!t.ctrlKey&&!t.metaKey}function rs(t){let s=!1;const e=n=>(n.state.readOnly&&t(),!1);return _.domEventHandlers({keydown:(n,a)=>os(n)&&e(a),paste:(n,a)=>e(a),cut:(n,a)=>e(a),pointerdown:n=>(s=n.pointerType==="touch",!1),click:(n,a)=>s&&e(a)})}const as=[["Completions","cm.completions"],["Find","cm.find"],["Replace","cm.replace"],["next","cm.next"],["previous","cm.previous"],["all","cm.all"],["match case","cm.matchCase"],["regexp","cm.regexp"],["by word","cm.byWord"],["replace","cm.replaceOne"],["replace all","cm.replaceAll"],["close","close"],["Go to line","cm.gotoLine"],["go","cm.go"],["current match","cm.currentMatch"],["replaced $ matches","cm.replacedMatches"],["replaced match on line $","cm.replacedOnLine"],["on line","cm.onLine"],["Selection deleted","cm.selectionDeleted"],["Control character","cm.controlCharacter"]],Me=t=>ge.phrases.of(Object.fromEntries(as.map(([s,e])=>[s,t(e)]))),is=_.theme({"&":{backgroundColor:"var(--rp-base)",color:"var(--rp-text)",border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-md)",fontSize:"var(--rp-text-sm)"},"&.cm-focused":{outline:"none",borderColor:"var(--rp-accent)",boxShadow:"0 0 0 1px var(--rp-accent)"},".cm-scroller":{fontFamily:"ui-monospace, 'SF Mono', Menlo, Consolas, 'JetBrains Mono', 'Fira Code', 'DejaVu Sans Mono', 'Liberation Mono', 'Noto Sans Mono', monospace",lineHeight:"20px",maxHeight:"70vh",fontVariantLigatures:"none",borderRadius:"calc(var(--rp-r-md) - 1px)"},".cm-content":{padding:"8px 0",caretColor:"var(--rp-text)"},".cm-line":{padding:"0 12px"},".cm-gutters":{backgroundColor:"var(--rp-base)",color:"var(--rp-muted)",border:"none"},".cm-lineNumbers .cm-gutterElement":{padding:"0 8px 0 12px",minWidth:"40px"},".cm-activeLine, .cm-focusLine":{backgroundColor:"color-mix(in srgb, var(--rp-hl-med) 60%, transparent)"},".cm-activeLineGutter":{backgroundColor:"transparent",color:"var(--rp-text)"},".cm-selectionBackground, &.cm-focused .cm-selectionBackground, ::selection":{backgroundColor:"var(--rp-hl-high)"},".cm-cursor":{borderLeftColor:"var(--rp-text)"},".cm-matchingBracket":{backgroundColor:"color-mix(in srgb, var(--rp-accent) 20%, transparent)",outline:"none"},".cm-selectionMatch":{backgroundColor:"color-mix(in srgb, var(--rp-notice) 25%, transparent)"},".cm-tooltip.cm-tooltip-lint":{backgroundColor:"var(--rp-text)",color:"var(--rp-on-text)",border:"none",borderRadius:"var(--rp-r-sm)",padding:"2px 0"},".cm-tooltip-lint .cm-diagnostic":{border:"none",padding:"2px 8px",fontSize:"var(--rp-text-xs)",lineHeight:"16px",fontFamily:"inherit"},".cm-tooltip-lint .cm-diagnosticText":{color:"inherit"},".cm-diag-line-error":{backgroundColor:"color-mix(in srgb, var(--rp-negative) 14%, transparent)"},".cm-diag-line-warning":{backgroundColor:"color-mix(in srgb, var(--rp-notice) 16%, transparent)"},".cm-diag-line-info":{backgroundColor:"color-mix(in srgb, var(--rp-foam) 14%, transparent)"},".cm-lintRange-error":{backgroundImage:"none",textDecoration:"underline wavy var(--rp-negative)",textUnderlineOffset:"3px"},".cm-lintRange-warning":{backgroundImage:"none",textDecoration:"underline wavy var(--rp-notice)",textUnderlineOffset:"3px"},".cm-lintRange-info":{backgroundImage:"none",textDecoration:"underline dotted var(--rp-foam)",textUnderlineOffset:"3px"},".cm-tooltip":{backgroundColor:"var(--rp-surface)",border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-md)",color:"var(--rp-text)"},".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]":{backgroundColor:"var(--rp-selected)",color:"var(--rp-text)"},".cm-tooltip.cm-tooltip-autocomplete > ul":{fontFamily:"ui-monospace, 'SF Mono', Menlo, Consolas, 'JetBrains Mono', 'Fira Code', 'DejaVu Sans Mono', 'Liberation Mono', 'Noto Sans Mono', monospace"},".cm-panels":{backgroundColor:"var(--rp-surface)",color:"var(--rp-text)"},".cm-panels-bottom":{borderTop:"1px solid var(--rp-hl-med)"},".cm-textfield":{border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-sm)",backgroundColor:"var(--rp-base)",color:"var(--rp-text)"},".cm-button":{border:"1px solid var(--rp-hl-high)",borderRadius:"var(--rp-r-sm)",backgroundImage:"none",backgroundColor:"var(--rp-overlay)",color:"var(--rp-text)"}}),ls=yt.define([{tag:K.comment,color:"var(--rp-code-comment)"},{tag:K.keyword,color:"var(--rp-code-keyword)",fontWeight:"700"},{tag:K.string,color:"var(--rp-code-string)"},{tag:K.number,color:"var(--rp-code-number)"},{tag:K.propertyName,color:"var(--rp-code-propertyName)"},{tag:K.variableName,color:"var(--rp-code-variableName)"},{tag:K.operator,color:"var(--rp-code-operator)"},{tag:K.punctuation,color:"var(--rp-code-punctuation)"}]),cs=ht.of((t,s)=>{const e=t.lineAt(s,-1),n=e.from>0?t.lineAt(e.from-1,-1):null;if(!n)return 0;const a=/^\s*/.exec(n.text)[0].length,r=/\{\s*(#.*)?$/.test(n.text),l=/^\s*\}/.test(e.text);return Math.max(0,a+(r?2:0)-(l?2:0))}),Je=Ke.define(),ds={error:J.line({class:"cm-diag-line cm-diag-line-error"}),warning:J.line({class:"cm-diag-line cm-diag-line-warning"}),info:J.line({class:"cm-diag-line cm-diag-line-info"})},us=Ve.define({create:()=>J.none,update(t,s){let e=t.map(s.changes);for(const n of s.effects){if(!n.is(Je))continue;const a=new mt,r={error:0,warning:1,info:2},l=new Map;for(const c of n.value){if(c.line<1||c.line>s.state.doc.lines)continue;const f=l.get(c.line);(!f||r[c.level]f-i)){const f=s.state.doc.line(c).from;a.add(f,f,ds[l.get(c).level])}e=a.finish()}return e},provide:t=>_.decorations.from(t)}),fs=[],Pe=wt.define(),Qe=Ke.define(),ps=J.line({class:"cm-focusLine"}),gs=Ve.define({create:()=>J.none,update(t,s){let e=t.map(s.changes);for(const n of s.effects)n.is(Qe)&&(e=J.set(ps.range(s.state.doc.line(n.value).from)));return e},provide:t=>_.decorations.from(t)}),Ee=t=>[ge.readOnly.of(t),_.editable.of(!t),t?gs:[bt(),vt(),xt()]];function be({value:t,onChange:s,readOnly:e=!1,marks:n=fs,focusLine:a,label:r,outbounds:l,onSave:c,onReadOnlyAttempt:f,compact:i}){const u=m.useRef(null),g=m.useRef(null),d=m.useRef(s),v=m.useRef(l),S=m.useRef(c),w=m.useRef(f);m.useEffect(()=>{d.current=s,v.current=l,S.current=c,w.current=f});const b=m.useRef(new te),x=F(),k=m.useRef(new te),C=m.useRef(new te),N=m.useRef(new te);return m.useLayoutEffect(()=>{const h=new _({parent:u.current,state:ge.create({doc:t,extensions:[Qn(),Xn(),N.current.of(Se()),Yn(),us,Zn(),et(),nt(),tt.of(" "),st(),cs,ts(()=>v.current?.()??[]),qt,ot(ls),is,rt.of([{key:"Mod-s",run:()=>(S.current?.(),!0)},{key:"Mod-/",run:at},{key:"Mod-g",run:it},...lt,...ct,...dt,...ut,...ft,pt]),b.current.of(Ee(e)),k.current.of(Me(x)),C.current.of(_.contentAttributes.of({"aria-label":r,tabindex:"0"})),rs(()=>w.current?.()),_.updateListener.of(y=>{y.docChanged&&!y.transactions.some(D=>D.annotation(Pe))&&d.current?.(y.state.doc.toString())})]})});return g.current=h,()=>{h.destroy(),g.current=null}},[]),m.useEffect(()=>{const h=g.current;h&&h.dispatch({effects:b.current.reconfigure(Ee(e))})},[e]),m.useEffect(()=>{g.current?.dispatch({effects:k.current.reconfigure(Me(x))})},[x]),m.useEffect(()=>{g.current?.dispatch({effects:C.current.reconfigure(_.contentAttributes.of({"aria-label":r,tabindex:"0"}))})},[r]),m.useEffect(()=>{const h=g.current;!h||h.state.doc.toString()===t||(h.dispatch({changes:{from:0,to:h.state.doc.length,insert:t},annotations:Pe.of(!0),effects:N.current.reconfigure([])}),h.dispatch({effects:N.current.reconfigure(Se())}))},[t]),m.useEffect(()=>{const h=g.current;if(!h)return;const y=gt(h.state,ss(h.state,n)),D=Array.isArray(y.effects)?y.effects:y.effects?[y.effects]:[];h.dispatch({...y,effects:[...D,Je.of(n)]})},[n]),m.useEffect(()=>{const h=g.current;if(!h||!a||a<1||a>h.state.doc.lines)return;const y=h.state.doc.line(a);h.dispatch({selection:{anchor:y.from},effects:[Qe.of(a),_.scrollIntoView(y.from,{y:"center"})]}),h.focus()},[a]),o.jsx("div",{className:i?"rp-editor compact":"rp-editor",ref:u})}function ve({message:t,busy:s,keep:e,discard:n}){const a=F();return o.jsx(le,{action:(e||n)&&o.jsxs("span",{className:"rp-toolbar",children:[e&&o.jsx(R,{isDisabled:s,onPress:e,children:a("config.keepChanges")}),n&&o.jsx(R,{isDisabled:s,onPress:n,children:a("config.discard")})]}),children:t})}function ms({config:t,editor:s,canWrite:e,canValidate:n,open:a}){const r=F(),l=ne(),c=ee[l],f=Ae().data,i=m.useMemo(()=>_e(f),[f]),u=m.useMemo(()=>zt(t.sources,i,l,r),[t,i,l,r]),g=ce(t.sources),[d,v]=m.useState(null),[S,w]=m.useState(null),b=d!==null&&d.text!==d.section.source.content.slice(d.section.block.from,d.section.block.to),x=m.useMemo(()=>d?Pt(d,u):null,[d,u]),k=!!x?.conflict;Y(x&&!x.conflict?x.next:null,p=>{p&&v(p)});const C=de(b,()=>{v(null),w(null)}),{clear:N}=C;m.useEffect(()=>s.cancel,[s.cancel,C.revision]);const h=m.useMemo(()=>d?Mt(d.section.source.content,d.section.block,d.text):null,[d]),y=d?.section.source.id,D=he(t.sources,g,y&&h!==null?{id:y,content:h}:void 0);qe(n&&h!==null?D:null,w);const E=(s.errorSource===y?s.diagnostics:null)??S??t.diagnostics,T=m.useMemo(()=>E.filter(p=>p.source_id===y),[E,y]),j=d?.section.id,L=m.useMemo(()=>({own:T,sectionId:j}),[T,j]),[H,$]=m.useState([]);Y(L,p=>$(d?Et(p.own,d.section.source.id,d.section.block,d.text):[]));const W=m.useMemo(()=>Ie(t.sources,y&&h!==null?{id:y,content:h}:void 0),[y,h,t]),V=()=>{s.cancel(),N(),v(null),w(null)},M=(p,O)=>{w(O),A(p?"positive":"negative",p?r("config.valid"):r("config.invalid",{n:O.filter(U=>U.level==="error").length}))},z=async()=>{if(!d||!D||h===null||s.busy)return;const p=await s.validate({sources:D,mode:"full"});p&&M(p.valid,p.diagnostics)},P=async()=>{if(!d||h===null||s.busy||!b||k)return;const p=await s.apply(d.section.source,h);if(p){if(p.diagnostics){M(!1,p.diagnostics);return}A("positive",r("config.saved",{path:Q(d.section.source,c,r).label})),N(),v(null),w(null)}};return{cards:(d&&!u.some(p=>p.id===d.section.id)?[...u,d.section]:u).map(p=>{const O=d?.section.id===p.id,U=e&&!!p.source?.writable&&!!p.block&&g(p.source)===!0;return{...p,editing:O,canEdit:U,editDisabled:b||!!s.busy,editTip:Nt(b,!!s.busy,r),editReason:U&&!O&&b?r("config.moduleEditBlocked"):null,note:p.note??(p.source&&p.block&&g(p.source)===!1?r("config.incomplete"):null),muted:!p.block,manual:p.source&&p.source.content!==void 0?()=>a(p.source.id,p.block?p.block.line+1:null):null,edit:()=>{b||s.busy||!e||!p.source?.writable||!p.block||g(p.source)!==!0||(w(null),v({section:{...p,source:p.source,block:p.block},text:p.source.content.slice(p.block.from,p.block.to)}))}}}),text:d?.text??"",change:p=>v(O=>O?{...O,text:p}:null),marks:H,diagnostics:se(T,t.sources,c,r),outbounds:()=>W,dirty:b,saveReason:me({busy:!!s.busy,conflict:!!k,changed:b},r),conflict:k?r("config.changedOnDisk"):null,keep:k&&x?.next?()=>v(x.next):null,busy:!!s.busy,saving:s.busy==="save",validating:s.busy==="validate",canValidate:n&&!!D,validate:z,save:P,cancel:V}}function hs(t){const s=F(),e=ms(t);return o.jsx("div",{className:"rp-page",children:e.cards.map(n=>o.jsxs(ue,{"aria-label":n.kind,children:[o.jsx(Z,{reason:n.editReason,children:o.jsxs("div",{className:"rp-row",children:[o.jsxs("span",{className:"rp-cluster",children:[o.jsx("h3",{className:"rp-h3 rp-code",children:n.kind}),o.jsx("span",{className:"rp-label rp-code",children:n.range}),n.editing&&e.dirty&&o.jsx(fe,{tone:"warn",children:s("config.unsaved")})]}),o.jsxs("span",{className:"rp-cluster",children:[n.href&&o.jsx(mn,{appearance:"button",href:n.href,children:s("config.moduleOpen")}),n.canEdit&&!n.editing&&o.jsx(R,{isDisabled:n.editDisabled,tip:n.editTip,onPress:n.edit,children:s("config.edit")}),n.manual&&!n.editing&&o.jsx(R,{quiet:!0,tip:s("config.moduleManualTip"),onPress:n.manual,children:s("config.moduleManual")})]})]})}),o.jsx(B,{small:!0,tone:n.muted?"muted":"info",children:n.summary}),n.note&&o.jsx(B,{small:!0,tone:"muted",children:n.note}),n.editing&&o.jsxs(o.Fragment,{children:[o.jsx(be,{label:n.range,value:e.text,onChange:e.change,readOnly:e.busy,marks:e.marks,outbounds:e.outbounds,onSave:e.dirty&&!e.busy?()=>void e.save():void 0}),e.conflict&&o.jsx(ve,{message:e.conflict,busy:e.busy,keep:e.keep}),e.diagnostics.length>0&&o.jsx("div",{className:"rp-list rp-config-diagnostics",role:"list","aria-label":s("config.diagnostics"),children:e.diagnostics.map(a=>o.jsx("div",{role:"listitem",children:o.jsx(B,{small:!0,tone:a.tone,children:a.detail})},a.id))}),o.jsx(Z,{reason:e.saveReason,children:o.jsxs("div",{className:"rp-cluster",children:[e.canValidate&&o.jsx(R,{isPending:e.validating,isDisabled:e.busy,onPress:()=>void e.validate(),children:s("config.validate")}),o.jsx(R,{accent:!0,isPending:e.saving,isDisabled:e.busy||!e.dirty||!!e.conflict,onPress:()=>void e.save(),children:s("config.save")}),o.jsx(R,{isDisabled:e.busy,onPress:e.cancel,children:s("ui.cancel")})]})})]})]},n.id))})}function bs({sources:t,contentOffered:s,refetch:e,open:n}){const a=F(),r=t.find(h=>h.kind==="main"),l=m.useMemo(()=>s&&r?.content!==void 0?hn(r.content):null,[s,r]),c=m.useMemo(()=>bn(l??[]),[l]),f=m.useMemo(()=>vn(t),[t]),[i,u]=m.useState(null),[g,d]=m.useState(null),{busy:v,create:S}=xn(e),w=wn(),b=i?.text??"",x=c.find(h=>h.pattern===i?.pattern)??null,k=x?x.prefix+b+x.suffix:b,C=b?x?yn(b,x):jn(b):null,N=async h=>{if(!b||C||v)return;const y=w.start();try{const D=await S(k);if(!D||(A("positive",a("config.newSourceCreated",{path:k})),!y()))return;h(),D.id&&n(D.id)}catch(D){y()?d(E=>({id:(E?.id??0)+1,text:$e(D,a)})):Be(D,a,a("config.newSourceFailed",{path:k}))}};return{isOpen:i!==null,show:()=>{w.next(),d(null),u({text:c.length?"":kn(l??[]),pattern:c[0]?.pattern??""})},hide:()=>{w.next(),u(null)},choices:c,choice:x,setChoice:h=>u(y=>y&&{...y,pattern:h}),text:b,setText:h=>u(y=>y&&{...y,text:h}),error:C?a(C):void 0,unmatched:!!b&&!C&&f!==null&&!f(k),problem:g,busy:v,canSubmit:!!b&&!C&&!v,submit:N}}function vs(t){const s=F(),e=bs(t);return o.jsxs(o.Fragment,{children:[o.jsxs(R,{onPress:e.show,children:[o.jsx(St,{}),s("config.newSource")]}),o.jsxs(Sn,{title:s("config.newSourceTitle"),narrow:!0,isOpen:e.isOpen,onOpenChange:n=>{n||e.hide()},footer:n=>o.jsxs(o.Fragment,{children:[o.jsx(R,{onPress:n,children:s("ui.cancel")}),o.jsx(R,{accent:!0,isDisabled:!e.canSubmit,isPending:e.busy,onPress:()=>void e.submit(n),children:s("config.newSourceCreate")})]}),children:[e.problem&&o.jsx(le,{takeFocus:!0,children:e.problem.text},e.problem.id),o.jsxs("div",{className:"rp-list",children:[o.jsx("span",{className:"rp-label",children:s(e.choice?"config.newSourceNameHelp":"config.newSourceHelp")}),e.choices.length>1&&o.jsx(pe,{label:s("config.newSourcePattern"),items:e.choices.map(n=>({id:n.pattern,label:n.pattern})),value:e.choice?.pattern??"",onChange:e.setChoice,isDisabled:e.busy}),e.choice?o.jsx(G,{isDisabled:e.busy,label:s("config.newSourceName"),value:e.text,prefix:e.choice.prefix,suffix:e.choice.suffix,placeholder:"extra",spellCheck:!1,error:e.error,onChange:e.setText}):o.jsx(G,{isDisabled:e.busy,label:s("config.newSourcePath"),value:e.text,placeholder:"config.d/extra.dae",spellCheck:!1,error:e.error,onChange:e.setText}),e.unmatched&&o.jsx(le,{tone:"informative",children:s("config.newSourceUnmatched")})]})]})]})}function xs(t){const{canValidate:s,contentOffered:e}=t,n=F(),{writable:a,note:r,refused:l,shown:c,marks:f,text:i,outbounds:u,focus:g,dirty:d,conflict:v,keep:S,validate:w,save:b,cancel:x,change:k,view:C,busy:N,validating:h,saving:y,saveButton:D,validateDisabled:E,reason:T}=Gt(t);return o.jsxs(ue,{"aria-label":C.label,children:[o.jsx(Z,{reason:T,children:o.jsxs("div",{className:"rp-row rp-source-note",children:[o.jsx("span",{className:"rp-cluster",children:d?o.jsxs(o.Fragment,{children:[o.jsx(fe,{tone:"warn",children:n("config.unsaved")}),o.jsx("span",{className:"rp-label",children:n("config.unsavedHint")})]}):C.hasContent&&o.jsx("span",{className:"rp-label",children:r})}),(s||d)&&o.jsxs("span",{className:"rp-cluster nowrap",children:[s&&o.jsx(R,{isPending:h,isDisabled:E,onPress:()=>void w(),children:n("config.validate")}),d&&o.jsxs(o.Fragment,{children:[o.jsx(R,{isDisabled:N,onPress:x,children:n("ui.cancel")}),o.jsx(R,{accent:!0,isPending:y,isDisabled:D.disabled,tip:D.tip,onPress:()=>void b(),children:n("config.save")})]})]})]})}),v&&o.jsx(ve,{message:v,busy:N,keep:S}),c.length>0&&o.jsx("div",{className:"rp-list rp-config-diagnostics",role:"list","aria-label":n("config.diagnostics"),children:c.map((j,L)=>o.jsxs("div",{className:"rp-cluster",role:"listitem",children:[o.jsx(B,{small:!0,tone:j.tone,children:j.detail}),o.jsx(R,{small:!0,quiet:!0,label:n("config.openSourceAt",{where:j.where}),onPress:()=>t.open(j.sourceId,j.line),children:n("config.openSource")})]},L))}),C.hasContent?o.jsx(be,{label:C.label,value:i,readOnly:!a||N,onChange:k,onReadOnlyAttempt:l,marks:f,focusLine:g,outbounds:u,onSave:d&&!N?()=>void b():void 0}):o.jsx(Cn,{children:n(e?"config.contentWithheld":"config.contentHidden")})]})}function ws(t){const{canValidate:s,open:e}=t,n=F(),{level:a,setLevel:r,selected:l,setSelected:c,shown:f,validate:i,summaryTone:u,summary:g,lastRun:d,validating:v,blocked:S,reason:w,levels:b}=Ut(t);return o.jsxs(o.Fragment,{children:[o.jsx(Z,{reason:s?w:null,children:o.jsxs("div",{className:"rp-toolbar",children:[o.jsx(B,{small:!0,tone:u,children:g}),o.jsx("span",{className:"rp-label",children:d}),o.jsx("span",{className:"rp-grow"}),s&&o.jsxs(R,{isPending:v,isDisabled:S,onPress:i,children:[o.jsx(Dn,{className:"rp-spin-on-press"}),n("config.revalidate")]})]})}),o.jsx("span",{className:"rp-label",children:n("config.validateNote")}),o.jsx(Nn,{label:n("config.level"),value:a,onChange:r,items:b}),o.jsx(Ct,{label:n("config.diagnostics"),rows:f,height:360,selected:l,onSelect:c,detail:x=>o.jsxs("div",{className:"rp-cluster rp-config-diagnostics",children:[o.jsx(B,{small:!0,tone:x.tone,children:x.detail}),o.jsx(R,{label:n("config.openSourceAt",{where:x.where}),onPress:()=>e(x.sourceId,x.line),children:n("config.openSource")})]}),empty:n("config.noDiagnostics"),cols:[{id:"level",label:n("config.level"),minWidth:96,grow:0,render:x=>o.jsx(B,{small:!0,tone:x.tone,children:x.levelText})},{id:"where",label:n("config.where"),minWidth:150,grow:0,render:x=>o.jsx("span",{className:"rp-code",children:x.where})},{id:"message",label:n("config.message"),minWidth:240,grow:2,isRowHeader:!0,render:x=>o.jsx(We,{children:x.message})},{id:"code",label:n("config.code"),minWidth:140,drop:1,render:x=>o.jsx(Ge,{text:x.code})}]})]})}const ys=["global","bypass","gfw","mini","standard","full"],Re={global:["config.wizardGlobal","config.wizardGlobalHelp"],bypass:["config.wizardBypass","config.wizardBypassHelp"],gfw:["config.wizardGfw","config.wizardGfwHelp"],mini:["config.wizardMini","config.wizardMiniHelp"],standard:["config.wizardStandard","config.wizardStandardHelp"],full:["config.wizardFull","config.wizardFullHelp"]};function js({main:t,editor:s,onDone:e}){const n=F(),a=ne(),r=ee[a],[l,c]=m.useState(()=>t),f=Mn(l),i=l.content??"",[u,g]=m.useState(()=>ie(i)),d=m.useMemo(()=>ke(i,ie(i)),[i]),v=m.useMemo(()=>{try{return{text:f?ke(i,u):i,error:null}}catch(P){return{text:i,error:P}}},[f,i,u]),{text:S}=v,w=!!s.busy,b=v.error!==null||f===!0&&S!==d,x=b||f===!0&&!i.trim(),[k,C]=m.useState(null),N=()=>{c(t),g(ie(t.content??"")),C(null)},h=de(b,N);m.useEffect(()=>s.cancel,[s.cancel,h.revision]);const y=At(b,l,t),D=y==="conflict";Y(y==="follow"?t:null,P=>{P&&N()});const E=In(u.subscriptions),T=!!i.trim()||$n(u),j=E&&T,L=P=>{C(null),g(I=>({...I,...P}))},H=(P,I)=>L({subscriptions:u.subscriptions.map((p,O)=>O===P?{...p,...I,raw:void 0}:p)}),$=async()=>{if(w||!j||D)return;if(v.error){A("negative",n("config.previewFailed"),{detail:$e(v.error,n)});return}const P=await s.apply(l,S);if(P){if(P.diagnostics){C(P.diagnostics),A("negative",n("ui.writeInvalid",{n:P.diagnostics.filter(I=>I.level==="error").length}));return}A("positive",n("config.saved",{path:W})),h.clear(),e()}},W=Q(t,r,n).label,V=_t(u,a,n),M=(s.errorSource===l.id?s.diagnostics:null)??k??[],z=P=>Le(P.trim())?void 0:n("config.unquotable");return{state:u,text:S,busy:w,rows:V.rows,diagnostics:se(M,[t],r,n),defaultDnsError:z(u.defaultDns),chinaDnsError:z(u.chinaDns),groupUsedText:V.groupUsedText,templateHelp:u.rules==="keep"?null:n("config.wizardPresetHelp"),networkError:T?void 0:n("config.wizardNetworkError"),patch:L,setSubscription:H,apply:$,conflict:D?n("config.changedOnDisk"):null,keep:()=>c(t),discard:N,saveDisabled:!f||!j||w||!x||D,saving:s.busy==="save",saveReason:me({busy:w,complete:f,conflict:D,invalid:E?T?null:n("config.wizardNetworkError"):n("config.wizardSubsInvalid"),changed:x},n),writeHelp:i.trim()?n("config.wizardWriteHelp",{path:W}):null,showLan:!i.trim(),templates:[...i.trim()?[{id:"keep",label:n("config.wizardKeep"),desc:n("config.wizardKeepHelp")}]:[],...ys.map(P=>({id:P,label:n(Re[P][0]),desc:n(Re[P][1])}))],add:()=>L({subscriptions:[...u.subscriptions,{name:Wn(u.subscriptions),url:""}]}),remove:P=>L({subscriptions:u.subscriptions.filter((I,p)=>p!==P)})}}function ks(t){const s=F(),{state:e,text:n,busy:a,rows:r,diagnostics:l,defaultDnsError:c,chinaDnsError:f,groupUsedText:i,templateHelp:u,networkError:g,patch:d,setSubscription:v,apply:S,conflict:w,keep:b,discard:x,saveDisabled:k,saving:C,saveReason:N,writeHelp:h,showLan:y,templates:D,add:E,remove:T}=js(t);return o.jsxs(ue,{"aria-label":s("config.wizard"),children:[o.jsx("span",{className:"rp-label",children:s("config.wizardNote")}),o.jsx("h3",{className:"rp-h3",children:s("config.wizardSubscriptions")}),o.jsxs("div",{className:"rp-list",children:[r.map(j=>o.jsxs("div",{className:j.raw===null?"rp-toolbar top rp-sub-row":"rp-toolbar top",children:[j.raw!==null?o.jsx(Ge,{text:j.raw,className:"rp-grow rp-config-raw"}):o.jsxs(o.Fragment,{children:[o.jsx(G,{isDisabled:a,label:s("config.wizardSubscriptionName"),value:j.name,width:140,error:j.nameError,onChange:L=>v(j.index,{name:L})}),o.jsx(G,{isDisabled:a,className:"rp-sub-url",label:s("config.wizardSubscription"),value:j.url,width:520,placeholder:"https://example.org/sub?token=…",error:j.error,description:j.description,onChange:L=>v(j.index,{url:L})})]}),o.jsx("span",{className:j.raw===null?"rp-field-row rp-sub-remove":void 0,children:o.jsx(R,{isDisabled:a,quiet:!0,small:!0,label:j.removeLabel,onPress:()=>T(j.index),children:o.jsx(Pn,{})})})]},j.index)),o.jsx("div",{children:o.jsx(R,{isDisabled:a,small:!0,onPress:E,children:s("config.wizardAddSubscription")})})]}),o.jsx("h3",{className:"rp-h3",children:s("config.wizardTemplate")}),o.jsxs("div",{className:"rp-toolbar top",children:[o.jsx(pe,{isDisabled:a,label:s("config.wizardTemplate"),value:e.rules,onChange:j=>d({rules:j}),items:D}),y&&o.jsx(G,{isDisabled:a,label:s("config.wizardLan"),value:e.lanInterface,width:140,placeholder:"auto",onChange:j=>d({lanInterface:j})})]}),i&&o.jsx("span",{className:"rp-label",children:i}),u&&o.jsx("span",{className:"rp-label",children:u}),y&&o.jsxs("div",{className:"rp-toolbar top",children:[o.jsx(G,{isDisabled:a,label:s("config.wizardListenerPort"),value:e.listenerPort,width:140,onChange:j=>d({listenerPort:j}),error:g}),o.jsx(G,{isDisabled:a,label:s("config.wizardDefaultDns"),value:e.defaultDns,error:c,onChange:j=>d({defaultDns:j})}),o.jsx(G,{isDisabled:a,label:s("config.wizardChinaDns"),value:e.chinaDns,error:f,onChange:j=>d({chinaDns:j})})]}),o.jsx("h3",{className:"rp-h3",children:s("config.wizardPreview")}),o.jsx(be,{label:s("config.wizardPreview"),value:n,readOnly:!0,compact:!0}),l.length>0&&o.jsx("div",{className:"rp-list rp-config-diagnostics",role:"list","aria-label":s("config.diagnostics"),children:l.map(j=>o.jsx("div",{role:"listitem",children:o.jsx(B,{small:!0,tone:j.tone,children:j.detail})},j.id))}),w&&o.jsx(ve,{message:w,busy:a,keep:b,discard:x}),o.jsx(Z,{reason:N,children:o.jsxs("div",{className:"rp-toolbar",children:[o.jsx(R,{accent:!0,isDisabled:k,isPending:C,onPress:()=>void S(),children:s("config.save")}),h&&o.jsx("span",{className:"rp-label",children:h})]})})]})}function Hs(t){const s=F(),{error:e,reload:n,loading:a,ready:r,metadata:l,redacted:c,tabs:f,tab:i,setTab:u,selectedId:g,select:d,sourceProps:v,newSourceProps:S,wizardProps:w,validateProps:b,modulesProps:x,sourceModel:k,sourceOptions:C,exportSource:N,summaryTone:h,summaryText:y}=Kt(t),D={modules:x&&o.jsx(hs,{...x}),setup:w&&o.jsx(ks,{...w}),source:o.jsxs(o.Fragment,{children:[o.jsxs("div",{className:"rp-toolbar",children:[o.jsxs("span",{className:"rp-cluster nowrap rp-source-pick",children:[o.jsx(pe,{side:!0,cut:"start",label:s("config.source"),value:g,onChange:d,items:C}),k&&o.jsxs(o.Fragment,{children:[k.readOnly&&o.jsxs("span",{className:"rp-help-row",children:[o.jsx(fe,{children:k.readOnly.label}),k.readOnly.help&&o.jsx(En,{...k.readOnly.help})]}),o.jsx(We,{className:"rp-label",text:k.loaded,children:k.facts})]})]}),(S||k?.hasContent)&&o.jsxs("span",{className:"rp-cluster nowrap",children:[S&&o.jsx(vs,{...S}),k?.hasContent&&o.jsxs(R,{onPress:N,children:[o.jsx(Rn,{}),s("config.export")]})]})]}),k?.hasContent&&o.jsx("span",{className:"rp-label",children:s("config.exportWarning")}),v&&o.jsx(xs,{...v},k.id)]}),validate:b&&o.jsx(ws,{...b})};return o.jsxs("div",{className:"rp-page",children:[o.jsx(Tn,{error:e,onRetry:n}),a&&o.jsx(zn,{}),r&&o.jsxs("div",{className:"rp-toolbar",children:[o.jsx(Ln,{row:!0,items:l}),o.jsx(B,{small:!0,tone:h,children:y}),c&&o.jsx(B,{small:!0,tone:"muted",children:s("config.redacted")})]}),r&&o.jsx(Fn,{label:s("nav.config"),value:i,onChange:u,items:f.map(E=>({...E,content:D[E.id]}))})]})}export{Hs as Config}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Connections-B3chbGPe.js b/luci-app-honk/root/etc/honk/doona/assets/Connections-B3chbGPe.js deleted file mode 100644 index fed20b9ad..000000000 --- a/luci-app-honk/root/etc/honk/doona/assets/Connections-B3chbGPe.js +++ /dev/null @@ -1,3 +0,0 @@ -import{j as s,r as w}from"./vendor-react-Bf71BWbF.js";import{aP as xn,aQ as wn,aR as fe,aS as de,u as X,aE as Je,a5 as ve,a as ye,as as te,aT as ee,aU as vn,aI as $e,aV as yn,aJ as ge,E as je,a4 as ie,aW as jn,aX as _n,Y as ue,$ as re,a1 as kn,a3 as _e,aY as ke,aZ as Xe,a_ as xe,at as Cn,a$ as Nn,b0 as Sn,b1 as Ln,ax as Ae,b2 as Mn,b3 as Ye,aK as we,aH as le,af as An,I as Te,b4 as qe,b5 as ce,B as R,b6 as Tn,b7 as Pn,b8 as Ze,b9 as Rn,a8 as ze,aa as G,ae as Dn,ac as Fn,ba as On,bb as In,bc as Bn,bd as En,be as J,f as Pe,bf as Wn,X as Hn,a9 as Un,bg as Vn,bh as Kn,a0 as Qn,ab as Gn,bi as Jn,bj as en,bk as $n,b as Re,bl as Xn,bm as Yn,A as qn,T as De,bn as me,bo as Zn,bp as zn,bq as et,aF as nt,aG as Fe,br as tt}from"./index-BNBwb-FJ.js";import{F as st}from"./FactStrip-n2q1T87k.js";import{B as ot,r as at}from"./ranked-B09X8uKl.js";import{u as lt,C as it,s as Oe,a as rt,p as Ie}from"./layout-wfdMYi2n.js";import{D as ct}from"./Table-DyWJelc_.js";import{T as dt}from"./TimeCell-DUt0i0gi.js";import{t as z,r as nn,a as ut}from"./link-CIkWI7An.js";import{w as Be}from"./labels-Bgu_ZhL8.js";import{c as Ee,d as pt,e as bt}from"./files-BxEOxSF8.js";import{D as mt}from"./DaeCode-B8yPDjSE.js";import{u as ht}from"./outbounds-DPmb26w8.js";import{u as ft}from"./flows-CMFlFH_d.js";import"./useGridSelectionCheckbox-CrCOlZv8.js";import"./Virtualizer-DipGMcji.js";import"./ListLayout-F74Z1Dpf.js";const Q=64,gt=22,Z=8,xt=28;function wt({label:e,series:t,fmt:n,onSelect:a,regions:r,height:i=260}){const o=xn(),[l,c]=wn(),{ref:b,tip:y,show:p,hide:m}=lt(),k=Math.max(1,...t.flatMap(h=>h.points.flatMap(T=>[T.x,T.y]))),{end:N,ticks:f}=rt(k),u=Math.max((c??0)-Q-xt,1),C=i-Z-gt,v=h=>Q+Oe(h,N)*u,_=h=>Z+(1-Oe(h,N))*C,S=new Map,I=t.flatMap(h=>h.points.map(T=>{const L=v(T.x),j=_(T.y),A=L+","+j,F=S.get(A)??0;return S.set(A,F+1),{point:T,color:h.color,cx:L,cy:j,nth:F,spot:A}})).map(h=>({...h,twins:S.get(h.spot)}));return s.jsx("div",{className:"rp-scatter",ref:l,children:s.jsxs("div",{className:"rp-chart-hover",ref:b,onPointerLeave:m,children:[c!==null&&s.jsxs("svg",{width:c,height:i,role:"img","aria-label":e,"aria-describedby":o,children:[f.map(h=>s.jsxs("g",{children:[s.jsx("line",{className:"grid",x1:v(h),x2:v(h),y1:Z,y2:Z+C}),s.jsx("line",{className:"grid",x1:Q,x2:Q+u,y1:_(h),y2:_(h)}),s.jsx("text",{className:"tick",x:v(h),y:i-6,textAnchor:"middle",children:n(h)}),s.jsx("text",{className:"tick",x:Q-8,y:_(h)+4,textAnchor:"end",children:n(h)})]},h)),r&&s.jsxs("g",{className:"diagonal",children:[s.jsx("line",{x1:v(0),y1:_(0),x2:v(N),y2:_(N)}),s.jsx("text",{x:Q+8,y:Z+14,children:r.above}),s.jsx("text",{x:Q+u-8,y:Z+C-8,textAnchor:"end",children:r.below})]}),I.map(({point:h,color:T,cx:L,cy:j,nth:A,twins:F})=>{const B=2*Math.PI*A/F,V=F>1?6:0;return s.jsx("circle",{className:a?"pick":void 0,cx:L+V*Math.cos(B),cy:j+V*Math.sin(B),r:5,fill:T,onClick:a?()=>a(h.id):void 0,onPointerMove:D=>p(D,[h.name,h.detail])},h.id)})]}),s.jsx(it,{tip:y})]})})}function vt({series:e}){return s.jsx("div",{className:"rp-legend",children:e.map(t=>s.jsx(fe,{swatch:t.color,label:t.label,value:String(t.points.length)},t.id))})}function yt(e){const t=new Map;let n=0;for(const o of e){if(o.upload_bytes===null||o.download_bytes===null){n++;continue}const l={id:o.id,up:Number(o.upload_bytes),down:Number(o.download_bytes),name:o.domain||o.dst||o.id},c=t.get(o.outbound);c?c.push(l):t.set(o.outbound,[l])}const a=[...t].map(([o,l])=>({outbound:o,points:l})).sort((o,l)=>de(o.outbound??"",l.outbound??""));let r,i=-1n;for(const o of e){if(o.upload_bytes===null||o.download_bytes===null)continue;const l=BigInt(o.upload_bytes)+BigInt(o.download_bytes);l>i&&(i=l,r={id:o.id,up:Number(o.upload_bytes),down:Number(o.download_bytes),name:o.domain||o.dst||o.id,outbound:o.outbound})}return{series:a,unknown:n,heaviest:r,placed:e.length-n}}const We=[0,2,3,1,4,5,6,7],jt=w.memo(function({records:t,outbounds:n,latency:a,latencyError:r,retryLatency:i,truncated:o,onSelect:l}){const c=X(),b=Je(),y=ve[ye()],p=w.useCallback(u=>te(u,y),[y]),m=w.useMemo(()=>yt(t),[t]),k=w.useMemo(()=>{const u=n.filter(v=>v!=="block"),C=v=>v==="block"?b.negative:b.cat[We[Math.max(0,u.indexOf(v))%We.length]];return m.series.map(v=>({id:v.outbound??"",label:ee(v.outbound,c),color:C(v.outbound),points:v.points.map(_=>({id:_.id,x:_.up,y:_.down,name:_.name,detail:c("conn.chart.point",{down:p(_.down),up:p(_.up)})}))}))},[m,n,b,c,p]),N=m.heaviest?[{label:c("conn.chart.busiest"),icon:s.jsx(vn,{}),tint:"c3",value:m.heaviest.name,caption:ee(m.heaviest.outbound,c)},{label:c("conn.chart.down"),value:p(m.heaviest.down),icon:s.jsx($e,{}),tint:"c1"},{label:c("conn.chart.up"),value:p(m.heaviest.up),icon:s.jsx(yn,{}),tint:"c4"}]:[],f=m.unknown?c("conn.chart.sampleUnknown",{n:t.length,unknown:m.unknown}):c("conn.chart.sample",{n:t.length});return s.jsxs("div",{className:"rp-chart-page",children:[s.jsx(st,{facts:N,lead:!0}),s.jsxs(ge,{title:c("conn.chart.title"),note:f,children:[o&&s.jsx("p",{className:"rp-note",children:c("conn.truncated")}),m.placed>0&&s.jsxs(s.Fragment,{children:[s.jsx(wt,{label:c("conn.chart.title"),series:k,fmt:p,onSelect:l,regions:{above:c("conn.chart.moreDown"),below:c("conn.chart.moreUp")}}),s.jsx(vt,{series:k}),s.jsx("p",{className:"rp-note",children:c("conn.chart.hint")})]})]}),a?s.jsx(_t,{latency:a}):r&&s.jsx(ge,{title:c("ui.nodeLatency"),children:s.jsx(je,{error:r,onRetry:i})})]})});function _t({latency:e}){const t=X(),n=Je(),a=o=>jn(o,t),r=ve[ye()],i=o=>!e.chains||o?n.cat[0]:n.muted;return s.jsx(ge,{title:t("ui.nodeLatency"),note:t("conn.latency.sample",{n:e.samples.length,missing:e.missing}),children:e.samples.length?s.jsxs(s.Fragment,{children:[s.jsx("p",{className:"rp-note",children:t("conn.latency.percentiles",{p50:a(e.p50),p90:a(e.p90)})}),e.weightedP50!==null&&s.jsx("p",{className:"rp-note",children:e.unplaced?t("conn.latency.weightedUnplaced",{p50:a(e.weightedP50),n:e.unplaced}):t("conn.latency.weighted",{p50:a(e.weightedP50)})}),s.jsx(ot,{label:t("ui.nodeLatency"),points:e.samples.map(o=>({id:o.node,value:o.value,color:i(o.connections>0),lines:[o.name,a(o.value),...o.connections?[t("conn.chart.sample",{n:o.connections})]:[]]})),fmt:a}),e.chains&&s.jsxs("div",{className:"rp-legend",children:[s.jsx(fe,{swatch:i(!0),label:t("conn.latency.inUse"),value:ie(e.used,r)}),s.jsx(fe,{swatch:i(!1),label:t("conn.latency.others"),value:ie(e.samples.length-e.used,r)})]}),s.jsx("p",{className:"rp-note",children:t("conn.latency.hint")})]}):s.jsx("p",{className:"rp-note",children:t("conn.latency.pending")})})}const He={userspace:"conn.observed.userspace",ebpf:"conn.observed.ebpf",mixed:"conn.observed.mixed"},Ue={evaluation:"conn.chainSource.evaluation",reconstructed:"conn.chainSource.reconstructed",unknown:"ui.unknown"};function kt(e,t){const n=e.chain_source?[["conn.f.chainSource",Ue[e.chain_source]?{key:Ue[e.chain_source]}:e.chain_source]]:[];return[["ui.device",e.src??"—"],["conn.f.dst",e.dst??"—"],["ui.domain",e.domain??"—"],["conn.f.ingress",Be(e.ingress)],["conn.f.domainSource",Be(e.domain_source)],...n,["ui.process",e.pname??"—"],["conn.f.observedBy",He[e.observed_by]?{key:He[e.observed_by]}:e.observed_by],["ui.upload",te(e.upload_bytes,t)],["ui.download",te(e.download_bytes,t)],["conn.f.uploadRate",xe(e.upload_bytes_per_second,t)],["conn.f.downloadRate",xe(e.download_bytes_per_second,t)],["conn.f.started",Cn(e.started_at,t)]]}const $=[{id:"dst",label:"ui.target",minWidth:200,sortable:!0},{id:"src",label:"ui.device",minWidth:128,sortable:!0,drop:5},{id:"node",label:"conn.node",minWidth:120,drop:3},{id:"rule",label:"conn.rule",minWidth:220,drop:2},{id:"state",label:"ui.state",minWidth:88,sortable:!0,drop:7},{id:"down",label:"ui.download",minWidth:96,align:"end",sortable:!0,drop:4},{id:"downRate",label:"conn.f.downloadRate",minWidth:128,align:"end",sortable:!0,drop:1},{id:"age",label:"ui.started",minWidth:132,align:"end",sortable:!0,drop:6}],Ve=_n.connectionsView,he=e=>({allCollapsed:e,exceptions:new Set}),tn=(e,t)=>e.allCollapsed!==e.exceptions.has(t);function sn(e,t){const n=new Set(e.exceptions);return n.delete(t)||n.add(t),{allCollapsed:e.allCollapsed,exceptions:n}}const Ct=(e,t)=>tn(e,t)?sn(e,t):e,on=(e,t)=>t==="source"?ue(e.src??void 0)??e.src??"—":e.outbound??"unknown",Nt=(e,t,n)=>t==="source"?e:ee(e,n),St=e=>"g:"+e,Ce=e=>e.startsWith("g:")||e.startsWith("\\")?"\\"+e:e,Lt=e=>e.startsWith("\\")?e.slice(1):e;function Mt(e,t){if(!e||t==="none")return null;const n=on(e,t);return{group:n,token:JSON.stringify([e.id,t,n])}}function Ke(e){const t={hidden:[],sort:null,group:"source"};try{const n=JSON.parse(e??"null");if(!n||typeof n!="object")return t;const a=Array.isArray(n.hidden)?n.hidden.map(o=>o==="chain"?"node":o):[],r=$.filter(o=>a.includes(o.id)).map(o=>o.id),i=n.sort;return{hidden:r.length===$.length?[]:r,sort:i&&$.some(o=>o.sortable&&o.id===i.column)&&["ascending","descending"].includes(i.direction)?{column:i.column,direction:i.direction}:null,group:n.group==="none"||n.group==="outbound"?n.group:"source"}}catch{return t}}function At(e,t,n){return e.map(a=>({item:a,key:t(a)})).sort((a,r)=>n(a.key,r.key)).map(a=>a.item)}function Tt(e,t,n){let a=e;if(t.sort){const{column:i,direction:o}=t.sort;a=At(e,c=>{switch(i){case"dst":return c.domain||c.dst;case"src":return c.src;case"state":return _e(ke,c.state,n);case"down":return Ae(c.download_bytes);case"downRate":return Ae(c.download_bytes_per_second);case"age":return c.started_at?Date.parse(c.started_at):null;default:return null}},(c,b)=>{if(c==null)return b==null?0:1;if(b==null)return-1;const y=typeof c=="string"&&typeof b=="string"?de(c,b):cb?1:0;return o==="descending"?-y:y})}if(t.group==="none")return a.map(i=>({id:Ce(i.id),connection:i}));const r=new Map;for(const i of a){const o=on(i,t.group),l=r.get(o);l?l.push(i):r.set(o,[i])}return[...r].map(([i,o])=>({id:St(i),group:i,children:o,active:o.filter(l=>l.state==="active").length,download:Nn(...o.map(l=>l.download_bytes))}))}const Qe=new WeakMap;function Pt(e,t,n,a,r,i){const o=l=>{const c=Qe.get(l);if(c&&c.locale===n&&c.names===a&&c.rulesListed===r&&c.t===i)return c.row;const b={id:Ce(l.id),target:l.domain||l.dst||"—",source:l.src??"—",node:Ln(l,i,a),path:Sn(l,i,a),rule:{expression:l.rule_expression,href:nn(l.rule_id,r)},recomputed:l.rule_source==="recomputed"?i("conn.recomputed"):null,state:_e(ke,l.state,i),download:te(l.download_bytes,n),downloadRate:xe(l.download_bytes_per_second,n),startedAt:l.started_at};return Qe.set(l,{locale:n,names:a,rulesListed:r,t:i,row:b}),b};return Tt(e,t,i).map(l=>"connection"in l?{id:l.id,connection:o(l.connection)}:{id:l.id,group:l.group,children:l.children.map(o),label:i("conn.groupCount",{name:Nt(l.group,t.group,i),n:l.children.length}),totals:{down:te(l.download,n),state:i("conn.activeCount",{n:l.active})}})}function Rt(e,t,n,a,r,i){const o=l=>{const c=l.flatMap(b=>b?[b]:[]);return at(c,12).top};return{networks:[["all",i("ui.allCount",{n:e.length})],["tcp",i("ui.tcp")],["udp",i("ui.udp")]],outbounds:[{id:"all",label:i("conn.allOutbounds")},...[...new Set(e.flatMap(l=>l.outbound?[l.outbound]:[]))].map(l=>({id:l,label:ee(l,i)}))],picks:[{title:i("ui.device"),value:z("src",n??""),items:o(e.map(l=>ue(l.src))).map(({key:l,count:c})=>({id:z("src",l),label:l,desc:ie(c,r)}))},{title:i("conn.rule"),value:z("rule",a),items:o(e.map(l=>l.rule_expression)).map(({key:l,count:c})=>({id:z("rule",l),label:l,desc:ie(c,r)}))}],visibility:t&&t.visibility!=="full"?i(t.visibility==="none"?"conn.visibilityNone":"conn.visibilityPartial"):null}}function Dt(e,t,n){const[a,r]=e.picks,i=(o,l,c,b)=>({filter:o,label:l,sections:[{title:l,items:c,value:b}]});return{active:[t.network!=="all",t.out!=="all",!!t.src,t.rule!=="all"].filter(Boolean).length,submenus:[i("network",n("ui.network"),e.networks.map(([o,l])=>({id:o,label:l})),t.network),i("out",n("ui.outbound"),e.outbounds,t.out),i("src",a.title,[{id:z("src",""),label:n("conn.allDevices")},...a.items],a.value),i("rule",r.title,[{id:z("rule","all"),label:n("conn.allRules")},...r.items],r.value)]}}const Ge={observed:["conn.state.observed","conn.stateHelp.observed"],routing:["conn.state.routing","conn.stateHelp.routing"],dialing:["conn.state.dialing","conn.stateHelp.dialing"]};function Ft(e,t){return Object.hasOwn(Ge,e)?{title:t("ui.state"),text:Object.values(Ge).map(([n,a])=>t("ui.valuePair",{label:t(n),value:t(a)}))}:null}function Ot(e,t,n,a,r){return e?{id:e.id,title:e.domain||e.dst||e.id,tone:e.state==="blocked"||e.state==="failed"?"err":e.state==="active"?"ok":"info",status:n("ui.aside",{text:_e(ke,e.state,n),note:e.network.toUpperCase()}),chain:kn(e,n,a),outbound:ee(e.outbound,n),rule:{expression:e.rule_expression,href:nn(e.rule_id,r)},fields:kt(e,t).map(([i,o])=>[n(i),typeof o=="string"?o:n(o.key,o.params)]),flowQuery:re("",{tab:"flows",...e.flow_id?{id:e.flow_id}:{connection_id:e.id}}),source:e.src?ue(e.src)??e.src:null,closable:e.state==="active"||e.state==="dialing"||e.state==="routing",stateHelp:Ft(e.state,n)}:null}function It(e,t){return[Ee(["id","target","domain","source","network","state","outbound","chain","rule","upload_bytes","download_bytes","started_at"]),...e.map(n=>Ee([n.id,n.dst,n.domain,n.src,n.network,n.state,n.outbound,Xe(n.chain,t).join(" > "),n.rule_expression,n.upload_bytes,n.download_bytes,n.started_at]))].join(` -`)+` -`}function Bt(e,t){const n=e.map(r=>r.id),a=t.bulkLimit!=null&&n.length>t.bulkLimit;return t.narrowed||t.truncated||a?{ids:n}:{ids:n,query:{type:t.network,src:t.src,all:!0}}}const Et=e=>e.target;function Wt({collection:e,view:t,collapse:n,onToggleGroup:a,loading:r,selected:i,onSelect:o,selectOnFocus:l,onSort:c}){const b=X(),[y,p]=Mn(442),m=w.useMemo(()=>{const f={dst:u=>s.jsx(le,{children:u.target}),src:u=>s.jsx(le,{className:"rp-code",children:u.source}),node:u=>s.jsx(le,{className:"rp-chain",text:u.path??void 0,children:u.node}),rule:u=>s.jsxs("span",{className:"rp-rule",children:[s.jsx(Ye,{...u.rule}),u.recomputed&&s.jsx(we,{children:u.recomputed})]}),state:u=>u.state,down:u=>u.download,downRate:u=>u.downloadRate,age:u=>s.jsx(dt,{at:u.startedAt})};return $.filter(u=>!t.hidden.includes(u.id)).map(u=>({...u,label:b(u.label),grow:1,render:f[u.id]}))},[t.hidden,b]),k=w.useMemo(()=>e.map(f=>"connection"in f?f.connection:f),[e]),N=w.useMemo(()=>({grouped:t.group!=="none",collapsed:f=>tn(n,f),onToggle:a}),[t.group,n,a]);return s.jsx("div",{ref:y,children:s.jsx(ct,{label:b("nav.connections"),rowDetail:!0,cols:m,rows:k,height:p,selected:i&&Ce(i),onSelect:o&&(f=>o(f&&Lt(f))),selectOnFocus:l,reveal:!0,empty:b("conn.empty"),loading:r,sort:t.sort&&{column:String(t.sort.column),direction:t.sort.direction},onSort:c,getTextValue:Et,stream:!0,tree:N})})}function Ht({dialog:e}){const t=X();return s.jsxs(An,{title:t("rule.add"),narrow:!0,isOpen:!!e,reason:e?.reason,onOpenChange:n=>{n||e?.close()},footer:()=>s.jsxs(s.Fragment,{children:[s.jsx(R,{onPress:()=>e?.close(),children:t("ui.cancel")}),s.jsx(R,{isDisabled:e?.disabled,isPending:e?.busy,onPress:()=>e?.applyNow(),children:t("rule.addApply")}),s.jsx(R,{accent:!0,isDisabled:e?.disabled||e?.busy,onPress:()=>e?.hold(),children:t("rule.hold")})]}),children:[e?.failure&&s.jsx(Te,{takeFocus:!0,children:e.failure.text},e.failure.id),e&&s.jsxs("div",{className:"rp-list",children:[e.failure?.lines.map((n,a)=>s.jsx("span",{className:"rp-label",children:n},a)),s.jsx(je,{error:e.loadError,onRetry:e.retry}),s.jsx("span",{className:"rp-label",children:t("rule.holdHelp")}),e.targets&&s.jsx(qe,{isDisabled:e.busy,label:t("rule.kind"),value:e.target,onChange:e.setTarget,items:e.targets}),s.jsxs("div",{className:"rp-toolbar top",children:[s.jsx(ce,{isDisabled:e.busy,label:t("ui.outbound"),value:e.outbound,onChange:e.setOutbound,items:e.outbounds}),s.jsx(ce,{isDisabled:e.busy||!e.positions.length,label:t("rule.position"),value:e.before,onChange:e.setBefore,items:e.positions})]}),e.moved&&s.jsx(Te,{tone:"informative",children:t("conn.ruleMoved")}),e.unplaceable&&s.jsx("p",{className:"rp-note",children:t("conn.ruleNoPosition")}),s.jsx(mt,{text:e.preview})]})]})}function Ut(e,t){if(!t.some(p=>p.health?.length))return null;const n=[];let a=0;for(const p of t){const m=Tn(Pn(p.health??[]));m===void 0?a++:n.push({node:p.id,name:p.name,value:m,connections:0})}n.sort((p,m)=>p.value-m.value||de(p.name,m.name));const r=new Map(n.map(p=>[p.node,p])),i=e.some(p=>p.chain?.length);let o=0;for(const p of e){const m=p.chain?.at(-1);if(m===void 0)continue;const k=r.get(m);k?k.connections++:o++}const l=n.reduce((p,m)=>p+m.connections,0);let c=0;const b=n.find(p=>(c+=p.connections)>=Math.max(1,Math.ceil(l/2))),y=n.map(p=>p.value);return{samples:n,chains:i,missing:a,unplaced:o,used:n.filter(p=>p.connections).length,p50:Ie(y,50),p90:Ie(y,90),weightedP50:l?b.value:null}}function Vt(e){const t=r=>r.flatMap(([i,o])=>{const l=Rn(i,o);return l?[{kind:i,condition:l}]:[]}),n=e.domain?t([["domain",e.domain],["domainSuffix",e.domain]]):[],a=ue(e.dst);return n.length?n:a?t([["dip",a]]):[]}function Kt(e,t,n,a){const r=c=>an(c,t),i=e.find(c=>c.rule_id===n&&r(c)),o=e.find(r),l=c=>c===e[0]?a("conn.ruleTop"):a("rule.positionBefore",{n:c.index+1});return[...i?[{rule:i,label:a("conn.ruleBeforeMatched")}]:[],...o&&o!==i?[{rule:o,label:l(o)}]:[]].map(({rule:c,label:b})=>({id:c.rule_id,label:b,desc:c.expression}))}function an(e,t){const n=e&&t.find(a=>a.id===e.source?.source_id);return!!n?.writable&&Ze(n,e)!==null}function Qt(e,t,n){if(!t)return{before:e[0]?.id,moved:!1};const a=e.find(r=>r.id===t.rule.rule_id&&(n===t.generation||r.desc===t.rule.expression));return a?{before:a.id,moved:!1}:{before:e[0]?.id,moved:!0}}function Gt({disabled:e,busy:t,failed:n,unplaceable:a},r){return e&&!t&&!n&&!a?r("ui.loading"):null}function Jt(e){const t=X(),n=ze().data?.resources,a=G(n,"rules",{whileLoading:!1})&&G(n,"config",{whileLoading:!1})&&n?.config.writable===!0,[r,i]=w.useState(null),[o,l]=w.useState(null),c=!!r,b=a?e?.rule_id??null:null,y=ft(c||!!b),p=Dn(c||!!b),m=G(n,"groups",{whileLoading:!1}),k=Fn(c&&m),N=()=>{y.refetch(),p.refetch(),m&&k.refetch()},f=On(),u=p.data?.sources??[],C=Kt(y.data?.rules??[],u,r?.matched??null,t),v=In(k.data??[]),_=!m||!!k.data,S=r?.outbound||v.find(x=>x.id===r?.current)?.id||(_?v[0].id:""),Y=y.data?.generation_id,I=x=>{const M=y.data?.rules.find(O=>O.rule_id===x);return M&&Y?{generation:Y,rule:M}:null},{before:h,moved:T}=Qt(C,r?.pin??null,Y),L=r&&!r.pin?I(h):null;L&&i({...r,pin:L});const j=r?.targets[r.target],A=x=>{r&&!f.busy&&i({...r,...x})},F=()=>{f.busy&&(f.cancel(),N()),i(null),l(null)},B=()=>{J("negative",t("rule.stale")),N()},V=()=>{const x=y.data?.rules.find(O=>O.rule_id===h),M=u.find(O=>O.id===x?.source?.source_id);return!j||!x||!M||!Ze(M,x)||y.data?.generation_id!==p.data?.generation_id?(B(),null):(T&&i({...r,pin:I(h)}),{condition:j.condition,outbound:S,must:!1,before:x,sourceId:M.id})},D=()=>{const x=V();x&&(En.add(x),J("positive",t("rule.held")),F())},E=async()=>{const x=V();if(!x)return;l(null);const M=await f.apply([{...x,id:0}]);if(M){if(!M.written){l({id:Date.now(),...M.failure});return}J(M.failure?"negative":"positive",M.failure?M.failure.text:t("rule.added")),i(null)}},P=e?Vt(e):[],K=y.error??p.error??k.error,W=!!y.data&&!!p.data&&!C.length,se=!j||!h||!_;return{canAdd:a&&P.length>0,canShow:G(n,"rules",{whileLoading:!1})&&!!e?.rule_id,canEdit:!!b&&an(y.data?.rules.find(x=>x.rule_id===b),u),openAdd:()=>{e&&i({targets:P,matched:e.rule_id,current:e.outbound,target:0,outbound:"",pin:null})},dialog:r&&{targets:r.targets.length>1?r.targets.map((x,M)=>[String(M),t(`rule.kind.${x.kind}`)]):null,target:String(r.target),setTarget:x=>A({target:Number(x)}),outbounds:v,outbound:S,setOutbound:x=>A({outbound:x}),positions:C,before:h??"",setBefore:x=>A({pin:I(x)}),preview:j?S?Bn(j.condition,S):j.condition:"",busy:f.busy,loadError:K,retry:N,moved:T,unplaceable:W,disabled:se,reason:Gt({disabled:se,busy:f.busy,failed:!!K,unplaceable:W},t),failure:o,hold:D,applyNow:()=>void E(),close:F}}}const ln=["traffic","list"],rn=e=>["id","src","network","out","rule","q"].some(t=>new URLSearchParams(e).has(t))?"list":"traffic",ne=(e,t)=>re(e,rn(e)==="list"?{tab:en(e,ln,"list"),...t}:t);function $t({go:e,query:t}){const n=X(),a=ve[ye()],[r,i]=w.useState(()=>{try{return Ke(localStorage.getItem(Ve))}catch{return Ke(null)}}),o=Pe(Yn),l=Pe(Xn),[c,b]=w.useState(()=>he(!1)),y=w.useCallback(d=>b(g=>sn(g,d)),[]),p=d=>{const g={...r,...d};g.group!==r.group&&b(he(!1)),i(g);try{localStorage.setItem(Ve,JSON.stringify(g))}catch{}},m=w.useMemo(()=>new URLSearchParams(t),[t]),[k,N]=w.useState(m.get("q")??""),f=m.get("network")??"all",u=m.get("out")??"all",C=m.get("rule")??"all",v=(d,g)=>e("connections",ne(t,{[d]:g==="all"?null:g})),_=m.get("id"),[S,Y]=w.useState(null);Wn(m.get("q"),d=>N(d??""));const I=w.useRef(t);w.useEffect(()=>{I.current=t});const h=d=>e("connections",ne(I.current,{id:d})),T=w.useDeferredValue(k),L=Hn(m.get("src")??""),j=Un(L),A=ze(),F=A.data?.resources.connections.can_close===!0,B=G(A.data?.resources,"rules",{whileLoading:!1}),V=G(A.data?.resources,"flows",{whileLoading:!1});Vn(A.data?.resources);const D=ht(),E=Kn(j.refetch),P=w.useMemo(()=>Qn(j.data),[j.data]),K=G(A.data?.resources,"nodes",{whileLoading:!1}),W=Gn(K),se=w.useMemo(()=>K&&W.data?Ut(P,W.data):null,[K,W.data,P]),x=K&&!W.data?W.error:null,M=w.useMemo(()=>[...new Set(P.map(d=>d.outbound))].sort((d,g)=>de(d??"",g??"")),[P]),O=T.trim().toLowerCase(),q=w.useMemo(()=>P.filter(d=>(f==="all"||d.network===f)&&(u==="all"||d.outbound===u)&&(C==="all"||d.rule_expression===C)&&(!O||[d.dst,d.domain,d.src,d.pname,ee(d.outbound,n),Xe(d.chain,D).join(" "),d.rule_expression].join(" ").toLowerCase().includes(O))),[P,f,u,C,O,D,n]),H=_?P.find(d=>d.id===_):void 0,[Ne,Se]=w.useState(null);!_&&Ne!==null&&Se(null);const oe=Mt(H,r.group);oe&&Ne!==oe.token&&(Se(oe.token),b(Ct(c,oe.group)));const cn=Jt(H),Le=w.useMemo(()=>Rt(P,j.data,L,C,a,n),[P,j.data,L,C,a,n]),dn=w.useMemo(()=>Ot(H,a,n,D,B),[H,a,n,D,B]),U={...Le,detail:dn},un=w.useMemo(()=>Pt(q,r,a,D,B,n),[q,r,a,D,B,n]),pn=async()=>{if(!U.detail)return;const{id:d}=U.detail;try{if(!await E.close(d))return;new URLSearchParams(I.current).get("id")===d&&h(null),J("positive",n("conn.closed",{name:U.detail.title}))}catch(g){g instanceof qn&&g.code==="state_conflict"?J("negative",n("conn.notClosable")):J("negative",n("conn.closeFailed"),{detail:Re(g,n)})}},bn=async()=>{if(S)try{const d=await E.closeAll(S);if(!d)return;h(null),J($n(d),n("conn.closedAll",{closed:d.closed,skipped:d.skipped}))}catch(d){return n("ui.valuePair",{label:n("conn.closeFailed"),value:Re(d,n)})}},pe=d=>{const g=ut(String(d),["src","rule"]);g?.kind==="src"?(N(""),e("connections",ne(t,{src:!g.value||L===g.value?null:g.value,q:null}))):g?.kind==="rule"&&v("rule",C===g.value?"all":g.value)},Me=Dt(Le,{network:f,out:u,src:L,rule:C},n),mn={network:d=>v("network",d),out:d=>v("out",d),src:pe,rule:pe},hn={active:Me.active,submenus:Me.submenus.map(({filter:d,...g})=>({...g,sections:g.sections.map(ae=>({...ae,onChange:mn[d]}))}))},be=rn(t),fn=w.useCallback(d=>e("connections",re(t,{tab:"list",id:d})),[e,t]);return{...U,tab:en(t,ln,be),setTab:d=>e("connections",Jn(t,d,be==="traffic"?be:null)),openInList:fn,view:r,updateView:p,collapse:c,toggleCollapse:y,toggleCollapseAll:()=>b(he(!c.allCollapsed)),wide:o,text:k,setText:N,network:f,out:u,sel:_,select:h,collection:un,rows:P,outboundKeys:M,latency:se,latencyError:x,retryLatency:W.refetch,setNetwork:d=>v("network",d),setOut:d=>v("out",d),pick:pe,compact:l,filterMenu:hn,columns:$.map(d=>({id:d.id,label:n(d.label)})),visibleColumns:$.filter(d=>!r.hidden.includes(d.id)).map(d=>d.id),toggleColumn:d=>{const g=String(d),ae=r.hidden.includes(g)?r.hidden.filter(gn=>gn!==g):[...r.hidden,g];ae.length<$.length&&p({hidden:ae})},filtered:f!=="all"||u!=="all"||C!=="all"||!!L||k.trim()!=="",clear:()=>{N(""),e("connections",ne(t,{network:null,out:null,rule:null,q:null,src:null}))},error:j.error,retry:j.refetch,loading:j.loading&&!j.data,truncated:!!j.data?.truncated,canClose:F,canViewFlow:V,closeAll:{confirmationText:S?.query?n(S.query.type==="all"?"conn.closeAllLive":S.query.type==="tcp"?"conn.closeAllLiveTcp":"conn.closeAllLiveUdp",L?{n:S.ids.length,src:L}:{n:S.ids.length,src:n("conn.anySource")}):n("conn.closeAllHelp",{n:S?.ids.length??0}),open:!!S,setOpen:d=>Y(d?Bt(q,{network:f,src:L,narrowed:u!=="all"||C!=="all"||!!O,truncated:!!j.data?.truncated,bulkLimit:A.data?.resources.connections.max_bulk_close}):null),isDisabled:!q.length||!!E.busy||k!==T,isPending:E.busy==="all",onConfirm:bn,onAbort:E.cancel},close:{pending:E.busy===H?.id,disabled:!!E.busy,run:()=>void pn()},ruleAction:cn,showRule:(d=!1)=>{H?.rule_id&&e("rules",re("",{tab:"list",rule:H.rule_id,edit:d?H.rule_id:null}))},showFlow:()=>{U.detail&&V&&e("rules",U.detail.flowQuery)},onlyClient:()=>{U.detail?.source&&(N(""),e("connections",ne(t,{src:U.detail.source,q:null})))},canExport:q.length>0,export:()=>pt(bt("connections","csv"),It(q,D),"text/csv;charset=utf-8"),detailTitle:U.detail?.title??"",notInSnapshot:!!_&&!H&&!!j.data}}function us(e){const t=X(),n=$t(e),a=n.detail,r=s.jsxs(s.Fragment,{children:[n.error&&s.jsx(je,{error:n.error,onRetry:n.retry}),s.jsxs("div",{className:"rp-toolbar",children:[n.compact?s.jsxs("span",{className:"rp-filter-row",children:[s.jsx(De,{search:!0,label:t("ui.filter"),value:n.text,onChange:n.setText,placeholder:t("conn.filterHint"),className:"rp-filter"}),s.jsx(me,{label:n.filterMenu.active?t("conn.filtersActive",{n:n.filterMenu.active}):t("conn.filters"),count:n.filterMenu.active,submenus:n.filterMenu.submenus,children:t("conn.filters")})]}):s.jsxs(s.Fragment,{children:[s.jsx(De,{search:!0,label:t("ui.filter"),value:n.text,onChange:n.setText,placeholder:t("conn.filterHint"),className:"rp-filter"}),s.jsx(qe,{label:t("ui.network"),value:n.network,onChange:n.setNetwork,items:n.networks}),s.jsx(ce,{label:t("ui.outbound"),side:!0,value:n.out,onChange:n.setOut,items:n.outbounds}),s.jsx(me,{quiet:!0,label:t("conn.pick"),sections:n.picks,onAction:n.pick,children:t("conn.pick")})]}),s.jsx(ce,{label:t("conn.group"),side:!0,value:n.view.group,onChange:i=>n.updateView({group:i}),items:[{id:"source",label:t("conn.byClient")},{id:"outbound",label:t("ui.outbound")},{id:"none",label:t("conn.ungrouped")}]}),n.view.group!=="none"&&s.jsx(R,{onPress:n.toggleCollapseAll,children:t(n.collapse.allCollapsed?"conn.expandAll":"conn.collapseAll")}),s.jsx(me,{label:t("conn.columns"),selectionMode:"multiple",items:n.columns,value:n.visibleColumns,onAction:n.toggleColumn,children:t("conn.columns")}),n.filtered&&s.jsx(R,{quiet:!0,onPress:n.clear,children:t("ui.clearFilters")}),n.truncated&&s.jsx(we,{tone:"warn",children:t("conn.truncated")}),n.visibility&&s.jsx(le,{text:t("conn.visibilityNote"),children:s.jsx(we,{children:n.visibility})}),s.jsx("span",{className:"rp-grow"}),n.canClose&&s.jsx(Zn,{label:t("conn.closeAll"),...n.closeAll}),s.jsxs(R,{isDisabled:!n.canExport,onPress:n.export,children:[s.jsx($e,{}),t("conn.export")]})]}),s.jsxs("div",{className:"rp-with-panel","data-open":a?"":void 0,children:[s.jsx(Wt,{collection:n.collection,loading:n.loading,selected:n.sel,onSelect:n.select,selectOnFocus:n.wide,view:n.view,collapse:n.collapse,onToggleGroup:n.toggleCollapse,onSort:i=>n.updateView({sort:i})}),s.jsx(zn,{open:!!a,title:n.detailTitle,onClose:()=>n.select(null),children:a&&s.jsxs(s.Fragment,{children:[s.jsx(et,{help:a.stateHelp,children:s.jsx(nt,{small:!0,tone:a.tone,children:a.status})}),s.jsxs("div",{className:"rp-cluster",children:[s.jsxs("div",{className:"rp-cluster",children:[n.ruleAction.canAdd&&s.jsx(R,{onPress:n.ruleAction.openAdd,children:t("rule.add")}),n.ruleAction.canShow&&s.jsx(R,{onPress:()=>n.showRule(),children:t("conn.showRule")}),n.ruleAction.canEdit&&s.jsx(R,{onPress:()=>n.showRule(!0),children:t("conn.editRule")}),n.canViewFlow&&s.jsx(R,{onPress:n.showFlow,children:t("conn.viewFlow")}),a.source&&s.jsx(R,{onPress:n.onlyClient,children:t("conn.onlyThisClient")})]}),n.canClose&&a.closable&&s.jsx(R,{negative:!0,quiet:!0,isPending:n.close.pending,isDisabled:n.close.disabled,onPress:n.close.run,children:t("conn.close")})]}),s.jsx(Fe,{items:a.fields}),s.jsx(Fe,{items:[[t("ui.outbound"),a.outbound],[t("conn.chain"),a.chain]]}),s.jsxs("div",{className:"rp-list",children:[s.jsx("span",{className:"rp-label",children:t("conn.rule")}),s.jsx(Ye,{...a.rule})]})]})})]}),n.notInSnapshot&&s.jsx("span",{className:"rp-label",children:t("conn.notInSnapshot")}),s.jsx(Ht,{dialog:n.ruleAction.dialog})]});return s.jsx("div",{className:"rp-page",children:s.jsx(tt,{keepMounted:!0,label:t("nav.connections"),value:n.tab,onChange:n.setTab,items:[{id:"traffic",label:t("conn.tab.traffic"),content:s.jsx(jt,{records:n.rows,outbounds:n.outboundKeys,latency:n.latency,latencyError:n.latencyError,retryLatency:n.retryLatency,truncated:n.truncated,onSelect:n.openInList})},{id:"list",label:t("conn.tab.list"),content:r}]})})}export{us as Connections}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Connections-EJJs6m0v.js b/luci-app-honk/root/etc/honk/doona/assets/Connections-EJJs6m0v.js new file mode 100644 index 000000000..3cfd64c2c --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/Connections-EJJs6m0v.js @@ -0,0 +1,3 @@ +import{j as o,r as x}from"./vendor-react-Bf71BWbF.js";import{aT as hn,aU as fn,aV as ue,aW as le,u as J,aI as Ue,a6 as he,a as fe,av as X,aX as K,aY as gn,aM as Ve,aZ as xn,aN as pe,E as Qe,a5 as se,a_ as wn,a$ as vn,Z as F,b0 as Q,b1 as yn,b2 as Ce,a0 as ae,b3 as Ke,a2 as jn,a4 as ge,b4 as xe,b5 as Je,b6 as me,aw as _n,b7 as kn,b8 as Cn,b9 as An,aB as Ae,ba as Nn,bb as Ge,aO as be,aL as oe,bc as Mn,bd as Ln,aa as Ye,ac as E,ag as Sn,be as Tn,bf as Rn,f as Ne,bg as Pn,Y as Fn,ab as Dn,bh as Wn,bi as In,a1 as On,ad as En,bj as Bn,bk as Ze,bl as Hn,bm as te,bn as Un,b as Vn,bo as Qn,bp as Kn,A as Jn,bq as Gn,T as Me,br as re,bs as Yn,bt as Le,B as Z,bu as Zn,bv as qn,bw as Xn,aJ as $n,aK as Se,bx as zn}from"./index-Bw0aJc9a.js";import{M as et}from"./ActionGroup-DLxTuKht.js";import{F as nt}from"./FactStrip-DtkOGBRy.js";import{B as tt,r as ot}from"./ranked-SM2ov7Tw.js";import{u as st,C as at,s as Te,a as lt,p as Re}from"./layout-BWzq8YqC.js";import{D as it}from"./Table-Km6Zv-S8.js";import{T as ct}from"./TimeCell-DKHUJpad.js";import{w as Pe}from"./labels-Bgu_ZhL8.js";import{c as Fe,d as rt,e as dt}from"./files-BxEOxSF8.js";import{u as ut,R as pt}from"./useQuickRule-BmFeKwTA.js";import{u as mt}from"./outbounds-DMhWS-9H.js";import{u as bt}from"./flows-D3eabARZ.js";import{c as qe}from"./nav-Wiib71Wo.js";import"./useGridSelectionCheckbox-COXIVEmS.js";import"./Virtualizer-DCY9HC9Z.js";import"./ListLayout-_fDlx5XY.js";import"./DaeCode-B8yPDjSE.js";const O=64,ht=22,V=8,ft=28;function gt({label:n,series:t,fmt:e,onSelect:s,regions:r,height:d=260}){const l=hn(),[a,c]=fn(),{ref:u,tip:b,show:g,hide:p}=st(),w=Math.max(1,...t.flatMap(h=>h.points.flatMap(S=>[S.x,S.y]))),{end:_,ticks:v}=lt(w),m=Math.max((c??0)-O-ft,1),C=d-V-ht,y=h=>O+Te(h,_)*m,j=h=>V+(1-Te(h,_))*C,N=new Map,G=t.flatMap(h=>h.points.map(S=>{const A=y(S.x),k=j(S.y),M=A+","+k,D=N.get(M)??0;return N.set(M,D+1),{point:S,color:h.color,cx:A,cy:k,nth:D,spot:M}})).map(h=>({...h,twins:N.get(h.spot)}));return o.jsx("div",{className:"rp-scatter",ref:a,children:o.jsxs("div",{className:"rp-chart-hover",ref:u,onPointerLeave:p,children:[c!==null&&o.jsxs("svg",{width:c,height:d,role:"img","aria-label":n,"aria-describedby":l,children:[v.map(h=>o.jsxs("g",{children:[o.jsx("line",{className:"grid",x1:y(h),x2:y(h),y1:V,y2:V+C}),o.jsx("line",{className:"grid",x1:O,x2:O+m,y1:j(h),y2:j(h)}),o.jsx("text",{className:"tick",x:y(h),y:d-6,textAnchor:"middle",children:e(h)}),o.jsx("text",{className:"tick",x:O-8,y:j(h)+4,textAnchor:"end",children:e(h)})]},h)),r&&o.jsxs("g",{className:"diagonal",children:[o.jsx("line",{x1:y(0),y1:j(0),x2:y(_),y2:j(_)}),o.jsx("text",{x:O+8,y:V+14,children:r.above}),o.jsx("text",{x:O+m-8,y:V+C-8,textAnchor:"end",children:r.below})]}),G.map(({point:h,color:S,cx:A,cy:k,nth:M,twins:D})=>{const W=2*Math.PI*M/D,Y=D>1?6:0;return o.jsx("circle",{className:s?"pick":void 0,cx:A+Y*Math.cos(W),cy:k+Y*Math.sin(W),r:5,fill:S,onClick:s?()=>s(h.id):void 0,onPointerMove:R=>g(R,[h.name,h.detail])},h.id)})]}),o.jsx(at,{tip:b})]})})}function xt({series:n}){return o.jsx("div",{className:"rp-legend",children:n.map(t=>o.jsx(ue,{swatch:t.color,label:t.label,value:String(t.points.length)},t.id))})}function wt(n,t){const e=new Map;let s=0;for(const a of n){if(a.upload_bytes===null||a.download_bytes===null){s++;continue}const c={id:a.id,up:Number(a.upload_bytes),down:Number(a.download_bytes),name:a.domain||a.dst||a.id},u=e.get(a.outbound);u?u.push(c):e.set(a.outbound,[c])}const r=[...e].map(([a,c])=>({outbound:a,points:c})).sort((a,c)=>le(t)(a.outbound??"",c.outbound??""));let d,l=-1n;for(const a of n){if(a.upload_bytes===null||a.download_bytes===null)continue;const c=BigInt(a.upload_bytes)+BigInt(a.download_bytes);c>l&&(l=c,d={id:a.id,up:Number(a.upload_bytes),down:Number(a.download_bytes),name:a.domain||a.dst||a.id,outbound:a.outbound})}return{series:r,unknown:s,heaviest:d,placed:n.length-s}}const De=[0,2,3,1,4,5,6,7],vt=x.memo(function({records:t,outbounds:e,latency:s,latencyError:r,retryLatency:d,truncated:l,onSelect:a}){const c=J(),u=Ue(),b=he[fe()],g=x.useCallback(m=>X(m,b),[b]),p=x.useMemo(()=>wt(t,b),[t,b]),w=x.useMemo(()=>{const m=e.filter(y=>y!=="block"),C=y=>y==="block"?u.negative:u.cat[De[Math.max(0,m.indexOf(y))%De.length]];return p.series.map(y=>({id:y.outbound??"",label:K(y.outbound,c),color:C(y.outbound),points:y.points.map(j=>({id:j.id,x:j.up,y:j.down,name:j.name,detail:c("conn.chart.point",{download:g(j.down),upload:g(j.up)})}))}))},[p,e,u,c,g]),_=p.heaviest?[{label:c("conn.chart.busiest"),icon:o.jsx(gn,{}),tint:"c3",value:p.heaviest.name,caption:K(p.heaviest.outbound,c)},{label:c("conn.chart.down"),value:g(p.heaviest.down),icon:o.jsx(Ve,{}),tint:"c1"},{label:c("conn.chart.up"),value:g(p.heaviest.up),icon:o.jsx(xn,{}),tint:"c4"}]:[],v=p.unknown?c("conn.chart.sampleUnknown",{n:t.length,unknown:p.unknown}):c("conn.chart.sample",{n:t.length});return o.jsxs("div",{className:"rp-chart-page",children:[o.jsx(nt,{facts:_,lead:!0}),o.jsxs(pe,{title:c("conn.chart.title"),note:v,children:[l&&o.jsx("p",{className:"rp-note",children:c("conn.truncated")}),p.placed>0&&o.jsxs(o.Fragment,{children:[o.jsx(gt,{label:c("conn.chart.title"),series:w,fmt:g,onSelect:a,regions:{above:c("conn.chart.moreDown"),below:c("conn.chart.moreUp")}}),o.jsx(xt,{series:w}),o.jsx("p",{className:"rp-note",children:c("conn.chart.hint")})]})]}),s?o.jsx(yt,{latency:s}):r&&o.jsx(pe,{title:c("ui.nodeLatency"),children:o.jsx(Qe,{error:r,onRetry:d})})]})});function yt({latency:n}){const t=J(),e=Ue(),s=l=>wn(l,t),r=he[fe()],d=l=>!n.chains||l?e.cat[0]:e.muted;return o.jsx(pe,{title:t("ui.nodeLatency"),note:t("conn.latency.sample",{n:n.samples.length,missing:n.missing}),children:n.samples.length?o.jsxs(o.Fragment,{children:[o.jsx("p",{className:"rp-note",children:t("conn.latency.percentiles",{p50:s(n.p50),p90:s(n.p90)})}),n.weightedP50!==null&&o.jsx("p",{className:"rp-note",children:n.unplaced?t("conn.latency.weightedUnplaced",{p50:s(n.weightedP50),n:n.unplaced}):t("conn.latency.weighted",{p50:s(n.weightedP50)})}),o.jsx(tt,{label:t("ui.nodeLatency"),points:n.samples.map(l=>({id:l.node,value:l.value,color:d(l.connections>0),lines:[l.name,s(l.value),...l.connections?[t("conn.chart.sample",{n:l.connections})]:[]]})),fmt:s}),n.chains&&o.jsxs("div",{className:"rp-legend",children:[o.jsx(ue,{swatch:d(!0),label:t("conn.latency.inUse"),value:se(n.used,r)}),o.jsx(ue,{swatch:d(!1),label:t("conn.latency.others"),value:se(n.samples.length-n.used,r)})]}),o.jsx("p",{className:"rp-note",children:t("conn.latency.hint")})]}):o.jsx("p",{className:"rp-note",children:t("conn.latency.pending")})})}const We={userspace:"conn.observed.userspace",ebpf:"conn.observed.ebpf",mixed:"conn.observed.mixed"},Ie={evaluation:"conn.chainSource.evaluation",reconstructed:"conn.chainSource.reconstructed",unknown:"ui.unknown"};function jt(n,t){const e=n.chain_source?[["conn.f.chainSource",Ie[n.chain_source]?{key:Ie[n.chain_source]}:n.chain_source]]:[];return[["ui.device",n.src??"—"],["conn.f.dst",n.dst??"—"],["ui.domain",n.domain??"—"],["conn.f.ingress",Pe(n.ingress)],["conn.f.domainSource",Pe(n.domain_source)],...e,["ui.process",n.pname??"—"],["conn.f.observedBy",We[n.observed_by]?{key:We[n.observed_by]}:n.observed_by],["ui.upload",X(n.upload_bytes,t)],["ui.download",X(n.download_bytes,t)],["conn.f.uploadRate",me(n.upload_bytes_per_second,t)],["conn.f.downloadRate",me(n.download_bytes_per_second,t)],["conn.f.started",_n(n.started_at,t)]]}const B=[{id:"dst",label:"ui.target",minWidth:200,sortable:!0},{id:"src",label:"ui.device",minWidth:128,sortable:!0,drop:5},{id:"node",label:"conn.node",minWidth:120,drop:3},{id:"rule",label:"conn.rule",minWidth:220,drop:2},{id:"state",label:"ui.state",minWidth:88,sortable:!0,drop:7},{id:"down",label:"ui.download",minWidth:96,align:"end",sortable:!0,drop:4},{id:"downRate",label:"conn.f.downloadRate",minWidth:128,align:"end",sortable:!0,drop:1},{id:"age",label:"ui.started",minWidth:132,align:"end",sortable:!0,drop:6}],Oe=vn.connectionsView,de=n=>({allCollapsed:n,exceptions:new Set}),Xe=(n,t)=>n.allCollapsed!==n.exceptions.has(t);function $e(n,t){const e=new Set(n.exceptions);return e.delete(t)||e.add(t),{allCollapsed:n.allCollapsed,exceptions:e}}const _t=(n,t)=>Xe(n,t)?$e(n,t):n,ze=(n,t)=>t==="source"?F(n.src??void 0)??n.src??"—":n.outbound??"unknown",kt=(n,t,e)=>t==="source"?n:K(n,e),Ct=n=>"g:"+n,we=n=>n.startsWith("g:")||n.startsWith("\\")?"\\"+n:n,At=n=>n.startsWith("\\")?n.slice(1):n;function Nt(n,t){if(!n||t==="none")return null;const e=ze(n,t);return{group:e,token:JSON.stringify([n.id,t,e])}}function Ee(n){const t={hidden:[],sort:null,group:"source"};try{const e=JSON.parse(n??"null");if(!e||typeof e!="object")return t;const s=Array.isArray(e.hidden)?e.hidden.map(l=>l==="chain"?"node":l):[],r=B.filter(l=>s.includes(l.id)).map(l=>l.id),d=e.sort;return{hidden:r.length===B.length?[]:r,sort:d&&B.some(l=>l.sortable&&l.id===d.column)&&["ascending","descending"].includes(d.direction)?{column:d.column,direction:d.direction}:null,group:e.group==="none"||e.group==="outbound"?e.group:"source"}}catch{return t}}function Mt(n,t,e){return n.map(s=>({item:s,key:t(s)})).sort((s,r)=>e(s.key,r.key)).map(s=>s.item)}function Lt(n,t,e,s){let r=n;if(t.sort){const{column:l,direction:a}=t.sort,c=le(e);r=Mt(n,b=>{switch(l){case"dst":return b.domain||b.dst;case"src":return b.src;case"state":return ge(xe,b.state,s);case"down":return Ae(b.download_bytes);case"downRate":return Ae(b.download_bytes_per_second);case"age":return b.started_at?Date.parse(b.started_at):null;default:return null}},(b,g)=>{if(b==null)return g==null?0:1;if(g==null)return-1;const p=typeof b=="string"&&typeof g=="string"?c(b,g):bg?1:0;return a==="descending"?-p:p})}if(t.group==="none")return r.map(l=>({id:we(l.id),connection:l}));const d=new Map;for(const l of r){const a=ze(l,t.group),c=d.get(a);c?c.push(l):d.set(a,[l])}return[...d].map(([l,a])=>({id:Ct(l),group:l,children:a,active:a.filter(c=>c.state==="active").length,download:kn(...a.map(c=>c.download_bytes))}))}const Be=new WeakMap;function St(n,t,e,s,r,d){const l=a=>{const c=Be.get(a);if(c&&c.locale===e&&c.names===s&&c.rulesListed===r&&c.t===d)return c.row;const u={id:we(a.id),target:a.domain||a.dst||"—",source:a.src??"—",node:An(a,d,s),path:Cn(a,d,s),rule:{expression:a.rule_expression,href:Ke(a.rule_id,r)},recomputed:a.rule_source==="recomputed"?d("conn.recomputed"):null,state:ge(xe,a.state,d),download:X(a.download_bytes,e),downloadRate:me(a.download_bytes_per_second,e),startedAt:a.started_at};return Be.set(a,{locale:e,names:s,rulesListed:r,t:d,row:u}),u};return Lt(n,t,e,d).map(a=>"connection"in a?{id:a.id,connection:l(a.connection)}:{id:a.id,group:a.group,children:a.children.map(l),label:d("conn.groupCount",{name:kt(a.group,t.group,d),n:a.children.length}),totals:{down:X(a.download,e),state:d("conn.activeCount",{n:a.active})}})}function Tt(n,t,e,s,r,d,l){const a=new Set(n.flatMap(u=>u.outbound?[u.outbound]:[]));r!=="all"&&a.add(r);const c=u=>{const b=u.flatMap(g=>g?[g]:[]);return ot(b,12).top};return{networks:[["all",l("ui.allCount",{n:n.length})],["tcp",l("ui.tcp")],["udp",l("ui.udp")]],outbounds:[{id:"all",label:l("conn.allOutbounds")},...[...a].map(u=>({id:u,label:K(u,l)}))],picks:[{title:l("ui.device"),value:Q("src",e??""),items:c(n.map(u=>F(u.src))).map(({key:u,count:b})=>({id:Q("src",u),label:u,desc:se(b,d)}))},{title:l("conn.rule"),value:Q("rule",s),items:c(n.map(u=>u.rule_expression)).map(({key:u,count:b})=>({id:Q("rule",u),label:u,desc:se(b,d)}))}],visibility:t&&t.visibility!=="full"?l(t.visibility==="none"?"conn.visibilityNone":"conn.visibilityPartial"):null}}function Rt(n,t,e){const[s,r]=n.picks,d=(l,a,c,u)=>({filter:l,label:a,sections:[{title:a,items:c,value:u}]});return{active:[t.network!=="all",t.out!=="all",!!t.src,t.rule!=="all"].filter(Boolean).length,submenus:[d("network",e("ui.network"),n.networks.map(([l,a])=>({id:l,label:a})),t.network),d("out",e("ui.outbound"),n.outbounds,t.out),d("src",s.title,[{id:Q("src",""),label:e("conn.allDevices")},...s.items],s.value),d("rule",r.title,[{id:Q("rule","all"),label:e("conn.allRules")},...r.items],r.value)]}}const He={observed:["conn.state.observed","conn.stateHelp.observed"],routing:["conn.state.routing","conn.stateHelp.routing"],dialing:["conn.state.dialing","conn.stateHelp.dialing"]};function Pt(n,t){return Object.hasOwn(He,n)?{title:t("ui.state"),text:Object.values(He).map(([e,s])=>t("ui.valuePair",{label:t(e),value:t(s)}))}:null}function Ft(n,t,e,s,r){return n?{id:n.id,title:n.domain||n.dst||n.id,tone:n.state==="blocked"||n.state==="failed"?"err":n.state==="active"?"ok":"info",status:e("ui.aside",{text:ge(xe,n.state,e),note:n.network.toUpperCase()}),chain:jn(n,e,s),outbound:K(n.outbound,e),rule:{expression:n.rule_expression,href:Ke(n.rule_id,r)},fields:jt(n,t).map(([d,l])=>[e(d),typeof l=="string"?l:e(l.key,l.params)]),flowQuery:ae("",{tab:"records",...n.flow_id?{id:n.flow_id}:{connection_id:n.id}}),traceQuery:n.domain||F(n.dst)?yn({network:n.network==="udp"?"udp":"tcp",domain:n.domain??"",dst_ip:F(n.dst),dst_port:Ce(n.dst),src_ip:F(n.src),src_port:Ce(n.src),pname:n.pname??""}):null,source:n.src?F(n.src)??n.src:null,closable:n.state==="active"||n.state==="dialing"||n.state==="routing",closeReason:n.observed_by==="ebpf"?e("conn.notClosable"):null,stateHelp:Pt(n.state,e)}:null}function Dt(n,t){return[Fe(["id","target","domain","source","network","state","outbound","chain","rule","upload_bytes","download_bytes","started_at"]),...n.map(e=>Fe([e.id,e.dst,e.domain,e.src,e.network,e.state,e.outbound,Je(e.chain,t).join(" > "),e.rule_expression,e.upload_bytes,e.download_bytes,e.started_at]))].join(` +`)+` +`}function Wt(n,t){const e=n.map(r=>r.id),s=t.bulkLimit!=null&&e.length>t.bulkLimit;return t.narrowed||t.truncated||s?{ids:e}:{ids:e,query:{type:t.network,src:t.src,all:!0}}}const It=n=>n.target;function Ot({collection:n,view:t,collapse:e,onToggleGroup:s,loading:r,selected:d,onSelect:l,selectOnFocus:a,onSort:c}){const u=J(),[b,g]=Nn(442),p=x.useMemo(()=>{const v={dst:m=>o.jsx(oe,{children:m.target}),src:m=>o.jsx(oe,{className:"rp-code",children:m.source}),node:m=>o.jsx(oe,{className:"rp-chain",text:m.path??void 0,children:m.node}),rule:m=>o.jsxs("span",{className:"rp-rule",children:[o.jsx(Ge,{...m.rule}),m.recomputed&&o.jsx(be,{children:m.recomputed})]}),state:m=>m.state,down:m=>m.download,downRate:m=>m.downloadRate,age:m=>o.jsx(ct,{at:m.startedAt})};return B.filter(m=>!t.hidden.includes(m.id)).map(m=>({...m,label:u(m.label),grow:1,render:v[m.id]}))},[t.hidden,u]),w=x.useMemo(()=>n.map(v=>"connection"in v?v.connection:v),[n]),_=x.useMemo(()=>({grouped:t.group!=="none",collapsed:v=>Xe(e,v),onToggle:s}),[t.group,e,s]);return o.jsx("div",{ref:b,children:o.jsx(it,{label:u("nav.connections"),rowDetail:!0,cols:p,rows:w,height:g,selected:d&&we(d),onSelect:l&&(v=>l(v&&At(v))),selectOnFocus:a,reveal:!0,empty:u("conn.empty"),loading:r,sort:t.sort&&{column:String(t.sort.column),direction:t.sort.direction},onSort:c,getTextValue:It,stream:!0,tree:_})})}function Et(n,t,e){if(!t.some(p=>p.health?.length))return null;const s=[];let r=0;for(const p of t){const w=Mn(Ln(p.health??[]));w===void 0?r++:s.push({node:p.id,name:p.name,value:w,connections:0})}s.sort((p,w)=>p.value-w.value||le(e)(p.name,w.name));const d=new Map(s.map(p=>[p.node,p])),l=n.some(p=>p.chain?.length);let a=0;for(const p of n){const w=p.chain?.at(-1);if(w===void 0)continue;const _=d.get(w);_?_.connections++:a++}const c=s.reduce((p,w)=>p+w.connections,0);let u=0;const b=s.find(p=>(u+=p.connections)>=Math.max(1,Math.ceil(c/2))),g=s.map(p=>p.value);return{samples:s,chains:l,missing:r,unplaced:a,used:s.filter(p=>p.connections).length,p50:Re(g,50),p90:Re(g,90),weightedP50:c?b.value:null}}const Bt=n=>({domain:n.domain??null,dip:F(n.dst)??null,sip:F(n.src)??null,outbound:n.outbound,matched:n.rule_id&&n.rule_source!=="unknown"?{id:n.rule_id,expression:n.rule_expression}:null});function Ht(n,t){const e=J(),s=Ye().data?.resources,r=ut(t),l=E(s,"rules",{whileLoading:!1})&&E(s,"config",{whileLoading:!1})&&s?.config.writable===!0?n?.rule_id??null:null,a=bt(!!l),c=Sn(!!l),u=n&&Bt(n);return{canAdd:!!u&&r.canAdd(u),addTip:u?Rn(u).length?void 0:e("conn.ruleNoTarget"):e("ui.selectRow"),canShow:E(s,"rules",{whileLoading:!1})&&!!n?.rule_id,canEdit:!!l&&Tn(a.data?.rules.find(b=>b.rule_id===l),c.data?.sources??[]),openAdd:()=>{u&&r.open(u)},dialog:r.dialog}}const en=qe().map(n=>n.id),nn=n=>["id","src","network","out","rule","q"].some(t=>new URLSearchParams(n).has(t))?"list":"traffic",q=(n,t)=>ae(n,nn(n)==="list"?{tab:Ze(n,en,"list"),...t}:t);function Ut({go:n,query:t}){const e=J(),s=he[fe()],[r,d]=x.useState(()=>{try{return Ee(localStorage.getItem(Oe))}catch{return Ee(null)}}),l=Ne(Kn),a=Ne(Qn),[c,u]=x.useState(()=>de(!1)),b=x.useCallback(i=>u(f=>$e(f,i)),[]),g=i=>{const f={...r,...i};f.group!==r.group&&u(de(!1)),d(f);try{localStorage.setItem(Oe,JSON.stringify(f))}catch{}},p=x.useMemo(()=>new URLSearchParams(t),[t]),[w,_]=x.useState(p.get("q")??""),v=p.get("network")??"all",m=p.get("out")??"all",C=p.get("rule")??"all",y=(i,f)=>n("connections",q(t,{[i]:f==="all"?null:f})),j=p.get("id"),[N,ve]=x.useState(null);Pn(p.get("q"),i=>_(i??""));const G=x.useRef(t);x.useEffect(()=>{G.current=t});const h=i=>n("connections",q(G.current,{id:i})),S=x.useDeferredValue(w),A=Fn(p.get("src")??""),k=Dn(A),M=Ye(),D=M.data?.resources.connections.can_close===!0,W=E(M.data?.resources,"rules",{whileLoading:!1}),Y=E(M.data?.resources,"flows",{whileLoading:!1});Wn(M.data?.resources);const R=mt(),I=In(k.refetch),T=x.useMemo(()=>On(k.data),[k.data]),$=E(M.data?.resources,"nodes",{whileLoading:!1}),H=En($),tn=x.useMemo(()=>$&&H.data?Et(T,H.data,s):null,[$,H.data,T,s]),on=$&&!H.data?H.error:null,sn=x.useMemo(()=>[...new Set(T.map(i=>i.outbound))].sort((i,f)=>le(s)(i??"",f??"")),[T,s]),z=S.trim().toLowerCase(),U=x.useMemo(()=>T.filter(i=>(v==="all"||i.network===v)&&(m==="all"||i.outbound===m)&&(C==="all"||i.rule_expression===C)&&(!z||[i.dst,i.domain,i.src,i.pname,K(i.outbound,e),Je(i.chain,R).join(" "),i.rule_expression].join(" ").toLowerCase().includes(z))),[T,v,m,C,z,R,e]),P=j?T.find(i=>i.id===j):void 0,[ye,je]=x.useState(null);!j&&ye!==null&&je(null);const ee=Nt(P,r.group);ee&&ye!==ee.token&&(je(ee.token),u(_t(c,ee.group)));const an=Ht(P,n),_e=x.useMemo(()=>Tt(T,k.data,A,C,m,s,e),[T,k.data,A,C,m,s,e]),ln=x.useMemo(()=>Ft(P,s,e,R,W),[P,s,e,R,W]),L={..._e,detail:ln},cn=x.useMemo(()=>St(U,r,s,R,W,e),[U,r,s,R,W,e]),rn=async()=>{if(!L.detail)return;const{id:i}=L.detail;try{if(!await I.close(i))return;new URLSearchParams(G.current).get("id")===i&&h(null),te("positive",e("conn.closed",{name:L.detail.title}))}catch(f){f instanceof Jn&&f.code==="state_conflict"?te("negative",e("conn.notClosable")):te("negative",e("conn.closeFailed"),Gn(f,e))}},dn=async()=>{if(N)try{const i=await I.closeAll(N);if(!i)return;h(null),te(Un(i),e("conn.closedAll",{closed:i.closed,skipped:i.skipped}))}catch(i){return e("ui.valuePair",{label:e("conn.closeFailed"),value:Vn(i,e)})}},ie=i=>{const f=Hn(String(i),["src","rule"]);f?.kind==="src"?(_(""),n("connections",q(t,{src:!f.value||A===f.value?null:f.value,q:null}))):f?.kind==="rule"&&y("rule",C===f.value?"all":f.value)},ke=Rt(_e,{network:v,out:m,src:A,rule:C},e),un={network:i=>y("network",i),out:i=>y("out",i),src:ie,rule:ie},pn={active:ke.active,submenus:ke.submenus.map(({filter:i,...f})=>({...f,sections:f.sections.map(ne=>({...ne,onChange:un[i]}))}))},ce=nn(t),mn=x.useCallback(i=>n("connections",ae(t,{tab:"list",id:i})),[n,t]);return{...L,tab:Ze(t,en,ce),setTab:i=>n("connections",Bn(t,i,ce==="traffic"?ce:null)),openInList:mn,view:r,updateView:g,collapse:c,toggleCollapse:b,toggleCollapseAll:()=>u(de(!c.allCollapsed)),wide:l,text:w,setText:_,network:v,out:m,sel:j,select:h,collection:cn,rows:T,outboundKeys:sn,latency:tn,latencyError:on,retryLatency:H.refetch,setNetwork:i=>y("network",i),setOut:i=>y("out",i),pick:ie,compact:a,filterMenu:pn,columns:B.map(i=>({id:i.id,label:e(i.label)})),visibleColumns:B.filter(i=>!r.hidden.includes(i.id)).map(i=>i.id),toggleColumn:i=>{const f=String(i),ne=r.hidden.includes(f)?r.hidden.filter(bn=>bn!==f):[...r.hidden,f];ne.length{_(""),n("connections",q(t,{network:null,out:null,rule:null,q:null,src:null}))},error:k.error,retry:k.refetch,loading:k.loading&&!k.data,truncated:!!k.data?.truncated,canClose:D,canViewFlow:Y,closeAll:{confirmationText:N?.query?e(N.query.type==="all"?"conn.closeAllLive":N.query.type==="tcp"?"conn.closeAllLiveTcp":"conn.closeAllLiveUdp",A?{n:N.ids.length,source:A}:{n:N.ids.length,source:e("conn.anySource")}):e("conn.closeAllHelp",{n:N?.ids.length??0}),open:!!N,setOpen:i=>ve(i?Wt(U,{network:v,src:A,narrowed:m!=="all"||C!=="all"||!!z,truncated:!!k.data?.truncated,bulkLimit:M.data?.resources.connections.max_bulk_close}):null),isDisabled:!U.length||!!I.busy||w!==S,isPending:I.busy==="all",onConfirm:dn,onAbort:I.cancel},close:{pending:I.busy===P?.id,disabled:!!I.busy,run:()=>void rn()},ruleAction:an,showRule:(i=!1)=>{P?.rule_id&&n("rules",ae("",{tab:"list",rule:P.rule_id,edit:i?P.rule_id:null}))},canTrace:E(M.data?.resources,"routing_trace",{whileLoading:!1})&&!!L.detail?.traceQuery,traceConnection:()=>{L.detail?.traceQuery&&n("rules",L.detail.traceQuery)},showFlow:()=>{L.detail&&Y&&n("flows",L.detail.flowQuery)},onlyClient:()=>{L.detail?.source&&(_(""),n("connections",q(t,{src:L.detail.source,q:null})))},canExport:U.length>0,export:()=>rt(dt("connections","csv"),Dt(U,R),"text/csv;charset=utf-8"),detailTitle:L.detail?.title??"",notInSnapshot:!!j&&!P&&!!k.data}}function io(n){const t=J(),e=Ut(n),s=e.detail,d={list:o.jsxs(o.Fragment,{children:[e.error&&o.jsx(Qe,{error:e.error,onRetry:e.retry}),o.jsxs("div",{className:"rp-toolbar",children:[e.compact?o.jsxs("span",{className:"rp-filter-row",children:[o.jsx(Me,{search:!0,label:t("ui.filter"),value:e.text,onChange:e.setText,placeholder:t("conn.filterHint"),className:"rp-filter"}),o.jsx(re,{label:e.filterMenu.active?t("conn.filtersActive",{n:e.filterMenu.active}):t("conn.filters"),count:e.filterMenu.active,submenus:e.filterMenu.submenus,children:t("conn.filters")})]}):o.jsxs(o.Fragment,{children:[o.jsx(Me,{search:!0,label:t("ui.filter"),value:e.text,onChange:e.setText,placeholder:t("conn.filterHint"),className:"rp-filter"}),o.jsx(Yn,{label:t("ui.network"),value:e.network,onChange:e.setNetwork,items:e.networks}),o.jsx(Le,{label:t("ui.outbound"),side:!0,value:e.out,onChange:e.setOut,items:e.outbounds}),o.jsx(re,{quiet:!0,label:t("conn.pick"),sections:e.picks,onAction:e.pick,children:t("conn.pick")})]}),o.jsx(Le,{label:t("conn.group"),side:!0,value:e.view.group,onChange:l=>e.updateView({group:l}),items:[{id:"source",label:t("conn.byClient")},{id:"outbound",label:t("ui.outbound")},{id:"none",label:t("conn.ungrouped")}]}),e.view.group!=="none"&&o.jsx(Z,{onPress:e.toggleCollapseAll,children:t(e.collapse.allCollapsed?"conn.expandAll":"conn.collapseAll")}),o.jsx(re,{label:t("conn.columns"),selectionMode:"multiple",items:e.columns,value:e.visibleColumns,onAction:e.toggleColumn,children:t("conn.columns")}),e.filtered&&o.jsx(Z,{quiet:!0,onPress:e.clear,children:t("ui.clearFilters")}),e.truncated&&o.jsx(be,{tone:"warn",children:t("conn.truncated")}),e.visibility&&o.jsx(oe,{text:t("conn.visibilityNote"),children:o.jsx(be,{children:e.visibility})}),o.jsx("span",{className:"rp-grow"}),o.jsx(Z,{isDisabled:!e.ruleAction.canAdd,tip:e.ruleAction.addTip,onPress:e.ruleAction.openAdd,children:t("rule.add")}),e.canClose&&o.jsx(Zn,{label:t("conn.closeAll"),...e.closeAll}),o.jsxs(Z,{isDisabled:!e.canExport,onPress:e.export,children:[o.jsx(Ve,{}),t("conn.export")]})]}),o.jsxs("div",{className:"rp-with-panel","data-open":s?"":void 0,children:[o.jsx(Ot,{collection:e.collection,loading:e.loading,selected:e.sel,onSelect:e.select,selectOnFocus:e.wide,view:e.view,collapse:e.collapse,onToggleGroup:e.toggleCollapse,onSort:l=>e.updateView({sort:l})}),o.jsx(qn,{open:!!s,title:e.detailTitle,onClose:()=>e.select(null),children:s&&o.jsxs(o.Fragment,{children:[o.jsx(Xn,{help:s.stateHelp,children:o.jsx($n,{small:!0,tone:s.tone,children:s.status})}),o.jsxs("div",{className:"rp-cluster",children:[e.ruleAction.canAdd&&o.jsx(Z,{onPress:e.ruleAction.openAdd,children:t("rule.add")}),o.jsx(et,{actions:[...e.ruleAction.canShow?[{id:"show-rule",label:t("conn.showRule"),onAction:()=>e.showRule()}]:[],...e.ruleAction.canEdit?[{id:"edit-rule",label:t("conn.editRule"),onAction:()=>e.showRule(!0)}]:[],...e.canViewFlow?[{id:"view-flow",label:t("conn.viewFlow"),onAction:e.showFlow}]:[],...e.canTrace?[{id:"trace",label:t("conn.trace"),onAction:e.traceConnection}]:[],...s.source?[{id:"only-client",label:t("conn.onlyThisClient"),onAction:e.onlyClient}]:[],...e.canClose&&s.closable?[{id:"close",label:t("conn.close"),negative:!0,isPending:e.close.pending,isDisabled:e.close.disabled||!!s.closeReason,reason:s.closeReason??void 0,onAction:e.close.run}]:[]]})]}),o.jsx(Se,{items:s.fields}),o.jsx(Se,{items:[[t("ui.outbound"),s.outbound],[t("conn.chain"),s.chain]]}),o.jsxs("div",{className:"rp-list",children:[o.jsx("span",{className:"rp-label",children:t("conn.rule")}),o.jsx(Ge,{...s.rule})]})]})})]}),e.notInSnapshot&&o.jsx("span",{className:"rp-label",children:t("conn.notInSnapshot")}),o.jsx(pt,{dialog:e.ruleAction.dialog})]}),traffic:o.jsx(vt,{records:e.rows,outbounds:e.outboundKeys,latency:e.latency,latencyError:e.latencyError,retryLatency:e.retryLatency,truncated:e.truncated,onSelect:e.openInList})};return o.jsx("div",{className:"rp-page",children:o.jsx(zn,{keepMounted:!0,label:t("nav.connections"),value:e.tab,onChange:e.setTab,items:qe().map(l=>({id:l.id,label:t(l.titleKey),content:d[l.id]}))})})}export{io as Connections}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Coverage-DhDWz2sB.js b/luci-app-honk/root/etc/honk/doona/assets/Coverage-DhDWz2sB.js new file mode 100644 index 000000000..39000b2d5 --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/Coverage-DhDWz2sB.js @@ -0,0 +1 @@ +import{aB as u,a3 as d,a4 as t,u as f,aL as m,aJ as c}from"./index-Bw0aJc9a.js";import{j as s}from"./vendor-react-Bf71BWbF.js";const g={userspace_tcp:"flow.userspaceTcp",userspace_udp:"flow.userspaceUdp",kernel_direct:"flow.kernelDirect",kernel_block:"flow.kernelBlock",dns_intercept:"flow.dnsIntercept",kernel_bypass:"flow.kernelBypass"},w={full:"flow.full",partial:"flow.partialVisibility",none:"ui.none"};function h(e,r,p){const l=Object.entries(e.coverage).filter(([,a])=>a!=="full"),o=u(e.dropped_records),n=o?r("flow.dropped",{n:o}):null;return!l.length&&!n?null:{summary:l.length?r("flow.coverageSummary",{n:l.length}):null,detail:d(p,l.map(([a,i])=>r("ui.valuePair",{label:t(g,a,r),value:t(w,i,r)}))),dropped:n}}function k({view:e}){const r=f();return s.jsxs("div",{className:"rp-cluster",role:"group","aria-label":r("flow.coverage"),children:[e.summary&&s.jsx(m,{text:e.detail,children:s.jsx(c,{small:!0,tone:"warn",children:e.summary})}),e.dropped&&s.jsx(c,{small:!0,tone:"warn",children:e.dropped})]})}export{k as C,h as c}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Dns-4ANKlqye.js b/luci-app-honk/root/etc/honk/doona/assets/Dns-4ANKlqye.js new file mode 100644 index 000000000..b12afdc8c --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/Dns-4ANKlqye.js @@ -0,0 +1,3 @@ +import{r as h,j as s}from"./vendor-react-Bf71BWbF.js";import{u as v,aT as De,bE as Re,c as Ae,bF as me,Z as qe,a4 as ke,a_ as S,aw as Ee,a5 as fe,aq as Fe,A as ge,aB as Oe,bG as xe,aa as Y,bg as E,bH as be,ac as B,a0 as W,h as ce,bk as Pe,bj as Me,a6 as V,a as I,bI as de,Y as He,f as We,bp as Ue,bJ as Be,bm as U,bq as Ve,ag as Ie,bK as Qe,W as Ke,b as $e,bL as ze,aW as Je,ak as R,j as ve,E as O,aI as Z,bM as Ge,bN as Xe,bO as Ye,bP as Ze,aN as F,aV as oe,L as ee,aP as je,aL as A,bs as es,bQ as J,T as G,bt as ye,B as _,bR as ss,aO as we,aK as se,bx as as,aJ as ue,bw as ns,bS as ts,aM as rs,bv as ls,bu as is}from"./index-Bw0aJc9a.js";import{D as Ne}from"./Table-Km6Zv-S8.js";import{T as X}from"./TimeCell-DKHUJpad.js";import{A as cs}from"./ActionGroup-DLxTuKht.js";import{q as ds,u as Ce,a as os,b as us}from"./dns-BCg5F0Tv.js";import{c as pe,d as ps,e as hs}from"./files-BxEOxSF8.js";import{d as ms}from"./nav-CdRBQuvD.js";import{u as fs,R as gs}from"./useQuickRule-BmFeKwTA.js";import{F as xs}from"./FactStrip-DtkOGBRy.js";import{r as he,B as bs}from"./ranked-SM2ov7Tw.js";import{u as vs,w as js,C as ys,p as $}from"./layout-BWzq8YqC.js";import"./useGridSelectionCheckbox-COXIVEmS.js";import"./Virtualizer-DCY9HC9Z.js";import"./ListLayout-_fDlx5XY.js";import"./DaeCode-B8yPDjSE.js";import"./flows-D3eabARZ.js";function ws({label:t,shares:n}){const a=v(),r=De(),{ref:c,tip:e,show:l,hide:o}=vs(),i=h.useMemo(()=>{const d=js(n.map(m=>m.count));return n.flatMap((m,f)=>Array.from({length:d[f]},()=>m))},[n]);return s.jsxs("div",{className:"rp-waffle rp-chart-hover",ref:c,onPointerLeave:o,children:[s.jsx("div",{className:"grid",role:"img","aria-describedby":r,"aria-label":Re(t,n,a),children:i.map((d,m)=>s.jsx("span",{style:{background:d.color},onPointerMove:f=>l(f,[d.label,d.text])},m))}),s.jsx("ul",{className:"legend",children:n.map(d=>s.jsxs("li",{children:[s.jsx("i",{className:"sw",style:{background:d.color}}),s.jsx("span",{children:d.label}),s.jsx("b",{children:d.text})]},d.id))}),s.jsx(ys,{tip:e})]})}function Ns({className:t,...n}){return s.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:20,height:20,viewBox:"0 0 20 20","aria-hidden":"true",focusable:"false",className:Ae("rp-icon",t),...n,children:[s.jsx("path",{fill:"currentColor",d:"M8.249 15.021c-.4 0-.733-.317-.748-.72l-.25-6.5c-.017-.414.307-.763.72-.779H8c.4 0 .733.317.748.72l.25 6.5c.017.414-.307.763-.72.778zM11.751 15.021h-.03c-.413-.016-.737-.365-.72-.779l.25-6.5c.015-.403.348-.72.748-.72h.03c.413.016.737.365.72.779l-.25 6.5c-.015.403-.348.72-.748.72"}),s.jsx("path",{fill:"currentColor",d:"M17 4h-3.5v-.75C13.5 2.01 12.49 1 11.25 1h-2.5C7.51 1 6.5 2.01 6.5 3.25V4H3c-.414 0-.75.336-.75.75s.336.75.75.75h.52l.422 10.342C3.99 17.052 4.98 18 6.19 18h7.62c1.211 0 2.2-.948 2.248-2.158L16.48 5.5H17c.414 0 .75-.336.75-.75S17.414 4 17 4m-9-.75c0-.413.337-.75.75-.75h2.5c.413 0 .75.337.75.75V4H8zm6.56 12.531c-.017.404-.346.719-.75.719H6.19c-.404 0-.733-.315-.75-.719L5.02 5.5h9.96z"})]})}function ae(t,n,a,r,c){return{domain:t,dip:null,sip:(c&&qe(c))??null,outbound:null,matched:null,dns:{type:n,answers:me(a),upstream:r,query:{name:t,type:n}}}}const Cs=(t,n,a)=>({domain:null,dip:t,sip:null,outbound:null,matched:null,dns:{type:a,answers:[t],upstream:null,query:{name:n,type:a}}}),Ss={forced:"dns.route.forced","dns.routing":"dns.route.rules",default:"dns.route.default"};function Se(t,n){return{fields:[[n("ui.state"),t.status],[n("ui.upstream"),t.upstream??"—"],[n("dns.routeSource"),ke(Ss,t.route.source,n)],[n("dns.routeRule"),t.route.rule??"—"],[n("ui.elapsed"),S(t.elapsed_ms,n)]],answers:(t.answers??[]).map(a=>n("dns.answer",{name:a.name,type:a.type,ttl:a.ttl,data:a.data})),cacheText:n(t.cached?"dns.hit":"dns.miss"),cacheTone:t.cached?void 0:"warn"}}function _s(t,n,a,r,c,e){const l=n?.dns_query.record_types??[],o=a==="all"?l.length>0:l.includes(a);return{types:l,choices:[...l.map(i=>({id:i,label:i})),{id:"all",label:e("dns.allTypes")}],disabled:c||!n?.dns_query.available||!o||!r.trim(),reason:!n||c?null:n.dns_query.available?o?null:e(a==="all"?"dns.noTypes":"dns.typeUnsupported"):e("dns.queryUnavailable"),showCache:!!n?.dns_cache.available,cards:t?.results.map(i=>({id:i.type,title:`${t.domain} ${i.type}`,...Se(i,e),seed:ae(t.domain,i.type,i.answers??[],i.upstream,null),answerSeeds:(i.answers??[]).map(d=>me([d]).length?{address:d.data,seed:Cs(d.data,t.domain,i.type)}:null)}))??[],tabs:ms(n).map(i=>({id:i.id,label:e(i.titleKey)}))}}function Ts(t,n,a,r,c,e){const l=a.toLowerCase(),o=n?.dns_cache,i=(t?.entries??[]).filter(d=>!l||d.domain.toLowerCase().includes(l));return{fields:[[e("dns.entries"),t?fe(t.total,c):"—"]],coverage:t?["positive","negative","persistent"].filter(d=>!t.coverage[d]).map(d=>({id:d,text:e("ui.valuePair",{label:e({positive:"dns.positive",negative:"dns.negative",persistent:"dns.persistent"}[d]),value:e(d==="persistent"?"dns.chart.memoryOnly":"dns.notCovered")})})):[],filterText:l?e("dns.cacheFilter",{domain:a}):"",confirmationText:t?e("dns.flushConfirm",{n:t.total}):e("dns.flushConfirmAll"),flushDisabled:!!r||!n?.dns_cache.available||!n.dns_cache.flush,flushReason:o&&!r&&(!o.available||!o.flush)?e("dns.flushUnsupported"):null,deleteReason:o&&!r&&i.length>0&&(!o.available||!o.delete_entry)?e("dns.deleteUnsupported"):null,empty:e(n?.dns_cache.available&&n.dns_cache.read?"dns.empty":"dns.cacheUnavailable"),rows:i.map(d=>({id:d.entry_id,domain:d.domain,type:d.type,status:d.status,expiresAt:d.expires_at,staleUntil:d.stale_until,deleteLabel:e("dns.deleteEntry",{domain:d.domain,type:d.type}),seed:ae(d.domain,d.type,[],null,null),pending:r===d.entry_id,disabled:!!r||!n?.dns_cache.available||!n.dns_cache.delete_entry}))}}function Ls(t,n,a,r){const c=t?.records.find(l=>l.id===n);if(!c)return null;const e=Se(c,r);return{id:c.id,title:c.question.name,answers:e.answers,seed:ae(c.question.name,c.question.type,c.answers,c.upstream,c.src),fields:[[r("ui.type"),c.question.type],[r("ui.device"),c.src??"—"],e.fields[0],[r("ui.cache"),e.cacheText],...e.fields.slice(1),[r("ui.time"),Ee(c.observed_at,a)]]}}function Ds(t,n,a,r=[]){const c=t?.records??[];return{choices:[{id:"all",label:a("dns.allTypes")},...[...new Set([...r,...c.map(e=>e.question.type)])].map(e=>({id:e,label:e}))],total:t?a("dns.logTotal",{n:t.total}):"",totalHelp:t?{title:a("dns.logTotal",{n:t.total}),text:a("dns.logTotalHelp")}:null,loaded:t?.next_cursor?a("dns.logLoaded",{n:c.length}):"",empty:a(n===void 0?"ui.loading":n?"dns.logEmpty":"dns.logUnavailable"),rows:c.map(e=>({id:e.id,observedAt:e.observed_at,name:e.question.name,type:e.question.type,source:e.src??"—",resultError:e.status!=="NOERROR",result:e.status!=="NOERROR"?e.status:e.answers.map(l=>l.data).join(", ")||"—",cached:e.cached,upstream:e.cached?a("dns.hit"):e.upstream??"—",elapsed:S(e.elapsed_ms,a)}))}}function Rs(t){return[pe(["id","observed_at","src","name","type","status","cached","upstream","route_source","route_rule","elapsed_ms","answers"]),...t.map(n=>pe([n.id,n.observed_at,n.src,n.question.name,n.question.type,n.status,n.cached?"true":"false",n.upstream,n.route.source,n.route.rule,n.elapsed_ms,n.answers.map(a=>a.data).join(" ")]))].join(` +`)+` +`}function As(t,n){const a=new Set(t.records.map(r=>r.id));return{...t,records:[...t.records,...n.records.filter(r=>!a.has(r.id))],next_cursor:n.next_cursor}}function qs(t,n){const a=n&&new Set(n.records.map(r=>r.id));return{data:n??t,newerWaiting:!!a&&!!t?.records.some(r=>!a.has(r.id))}}function ks(t,n,a){if(!t)return null;const{usage:r,coverage:c}=t,e=i=>{const d=Oe(i);return d===null?"—":fe(d,n)},l=r?.entry_capacity??null,o=r&&l!==null?Fe(r.entries,l):null;return{note:r?l===null?a("dns.chart.usageFacts",{entries:e(r.entries)}):void 0:a("dns.chart.cacheNote",{n:t.total}),usage:r&&l!==null&&o!==null?{pct:o,value:o>0&&o<.5?"<"+a("ui.percent",{n:1}):a("ui.percent",{n:Math.round(o)}),facts:a("dns.chart.usageFacts",{entries:a("ui.fraction",{part:e(r.entries),whole:e(l)})})}:null,coverage:a("dns.chart.coverage",{kinds:[c.positive&&a("dns.chart.positive"),c.negative&&a("dns.chart.negative")].filter(Boolean).join(a("ui.listSeparator")),persistent:a(c.persistent?"dns.chart.persistent":"dns.chart.memoryOnly")})}}function Es(t,n,a){return t?a instanceof ge&&a.status===503?"unavailable":n?"ready":a?"error":"loading":"unlisted"}function Fs({go:t,query:n}){const a=v(),r=xe(),c=Y(),e=h.useMemo(()=>new URLSearchParams(n),[n]),[l,o]=h.useState(e.get("domain")??""),[i,d]=h.useState(e.get("type")??"A");E(e.get("domain"),p=>o(p??"")),E(e.get("type"),p=>d(p??"A"));const[m,f]=h.useState(null),{busy:x,error:y,run:C}=be({rethrow:!0}),u=c.data?.resources,b=h.useMemo(()=>_s(m,u,i,l,!!x,a),[m,u,i,l,x,a]),w=b.tabs.map(p=>p.id),T=e.has("domain")||e.has("device"),q=w.includes("log")?T?"log":"stats":w.includes("query")?"query":w[0]??"query",N=async(p={domain:l,type:i})=>{try{await C("query",async g=>{const H=await ds(r.dnsQuery,p.domain.trim(),p.type==="all"?b.types:[p.type],u?.dns_query.limits?.max_types_per_request??1,g);return g.aborted||f(H),H})}catch{}},P=B(u,"dns_query",{whileLoading:!1})&&b.types.length>0,L=fs(t,{queryAgain:P?p=>{const g=b.types.includes(p.type)?p.type:"all";t("dns",W("",{tab:"query",domain:p.name.replace(/\.$/,""),type:g,run:"1"}))}:void 0}),k=e.has("run")&&u?n:null,M=h.useEffectEvent(p=>{const g=new URLSearchParams(p);t("dns",W(p,{run:null}),{replace:!0}),N({domain:g.get("domain")??"",type:g.get("type")??"A"})});return h.useEffect(()=>{k!==null&&M(k)},[k]),{...b,rule:L,domain:l,setDomain:o,type:i,setType:d,pending:x==="query",queryError:y,submit:()=>void N(),setTab:p=>t("dns",Me(n,p,u&&!T?q:null)),tab:Pe(n,b.tabs.map(p=>p.id),q),filterDomain:e.get("domain")??"",filterDevice:e.get("device")??"",cacheHref:w.includes("cache")?ce("dns",{tab:"cache"}):null,logHref:(p,g)=>ce("dns",{tab:"log",[p]:g}),logLinks:[...B(u,"dns_rules",{whileLoading:!1})?[{id:"rules",label:a("rule.dnsTitle"),onAction:()=>t("rules","tab=dns")}]:[],...u?.runtime_settings.available?[{id:"recording",label:a("ui.recordingSettings"),onAction:()=>t("settings","card=runtime")}]:[]],logEnabled:u?.dns_log.available,viewCache:()=>t("dns",W(n,{tab:"cache",domain:m?.domain??""})),clearCacheFilter:()=>t("dns",W(n,{tab:"cache",domain:null}))}}function Os(t){const n=v(),a=V[I()],r=os(!Be()),c=h.useMemo(()=>Ts(r.cache.data,r.capabilities.data?.resources,t,r.busy,a,n),[r.cache.data,r.capabilities.data,t,r.busy,a,n]),[e,l]=h.useState(null),o=c.rows.find(f=>f.id===e),{remove:i}=r,d=h.useCallback(f=>void i(f).then(x=>x&&U("positive",n("dns.deleted",{n:x.deleted})),x=>U("negative",n("dns.deleteFailed"),Ve(x,n))),[i,n]),m=async()=>{try{const f=await r.flush();f&&U("positive",n("dns.flushed",{matched:f.matched,deleted:f.deleted}))}catch(f){return n("dns.flushFailed",{error:$e(f,n)})}};return{...c,selected:o?e:null,setSelected:l,seed:o?.seed??null,error:r.cache.error,retry:r.cache.refetch,loading:(r.cache.loading||r.capabilities.loading)&&!r.cache.data,flushPending:r.busy==="flush",remove:d,flush:m,abortFlush:()=>{r.cancel(),r.cache.refetch()}}}function Ps(t){const n=Ce({},t===!0),a=Y().data?.resources,r=B(a,"config",{whileLoading:!1}),e=Ie(t===!0&&r).data?.sources,l=h.useMemo(()=>r&&e?Qe(e,"dns"):null,[r,e]);return{log:n,cacheListed:B(a,"dns_cache",{whileLoading:!1})&&a?.dns_cache.read===!0,configHref:l}}function Ms(t){const n=v(),a=V[I()],[r,c]=ze(),[e,l]=h.useState(!1),o=us(t,!c&&e);o.data&&!e&&l(!0);const i=h.useMemo(()=>ks(o.data,a,n),[o.data,a,n]);return{ref:r,card:i,state:Es(t,!!i,o.error),error:o.error,retry:o.refetch}}function Hs(t,n,a){const r=v(),c=V[I()],[e,l]=h.useState(n);E(n,l);const[o,i]=h.useState("all"),[d,m]=h.useState(a);E(a,m);const f=xe(),x=Y(),y=de(d),C=He(y),u=y.trim()!==""&&!C,[b,w]=h.useState(C);!u&&C!==b&&w(C);const T={name:de(e),type:o,src:u?b:C},q=JSON.stringify(T),N=Ce(T,t===!0),[P,L]=h.useState(null),[k,M]=h.useState(!1),p=be({scope:q});E(q,()=>L(null));const{data:g,newerWaiting:H}=h.useMemo(()=>qs(N.data,P),[N.data,P]),ne=()=>void p.run("older",async D=>{if(!g?.next_cursor)return;L(g);let le;try{le=await f.dnsLog({name:T.name.trim()||void 0,type:o==="all"?void 0:o,src:T.src,cursor:g.next_cursor,limit:N.limit},D)}catch(j){if(!(j instanceof ge)||D.aborted)throw j;const ie=j.status===503&&j.code==="snapshot_unavailable"&&j.retryAfter!==null;if(!(j.status===410&&j.code==="snapshot_expired"||j.status===400&&j.code==="invalid_request")&&!ie)throw j;ie&&await Ke(j.retryAfter,D),L(null),N.refetch(),U("info",r("dns.olderExpired"));return}D.aborted||L(As(g,le))}),te=()=>{p.cancel(),L(null);const D=N.refetch();D&&(M(!0),D.finally(()=>M(!1)))},[Q,_e]=h.useState(null),Te=We(Ue),re=x.data?.resources.dns_query.record_types,Le=h.useMemo(()=>Ds(g,t,r,re),[g,t,r,re]),K=h.useMemo(()=>Ls(g,Q,c,r),[g,Q,c,r]);return{...Le,detail:K,detailTitle:K?.title??"",name:e,newerWaiting:H,setName:l,type:o,setType:i,src:d,setSrc:m,srcError:u?r("ui.invalidIp"):void 0,selected:K?Q:null,setSelected:_e,wide:Te,error:p.error??N.error,loading:N.loading&&!g,hasOlder:!!g?.next_cursor,loadingOlder:!!p.busy,loadOlder:ne,refreshing:k,refresh:te,retry:p.error?ne:te,export:()=>ps(hs("dns-log","csv"),Rs(g?.records??[]),"text/csv;charset=utf-8")}}const Ws=["cached","answered","nxdomain","failed"],Us=t=>t.cached?"cached":t.status==="NOERROR"?"answered":t.status==="NXDOMAIN"?"nxdomain":"failed";function Bs(t,n){const a={cached:0,answered:0,nxdomain:0,failed:0},r=[];for(const i of t){const d=Us(i);a[d]++,!i.cached&&i.upstream!==null&&r.push({id:i.id,value:i.elapsed_ms,outcome:d,name:i.question.name,upstream:i.upstream})}const c=r.map(i=>i.value).sort((i,d)=>i-d),e=new Map;for(const i of r)e.set(i.upstream,[...e.get(i.upstream)??[],i]);const l=[...e].map(([i,d])=>({upstream:i,median:$(d.map(m=>m.value).sort((m,f)=>m-f),50),samples:d}));l.sort((i,d)=>d.samples.length-i.samples.length||Je(n)(i.upstream,d.upstream));const o=t.length-a.cached;return{domains:he(t.map(i=>i.question.name.replace(/\.$/,"")),8),devices:he(t.map(i=>i.src===null?null:Vs(i.src)),8),total:t.length,counts:a,uncached:o,samples:r,typical:$(c,50),slowest:$(c,95),failureRate:o?a.failed/o:null,cacheRate:t.length?a.cached/t.length:null,upstreams:l}}const Vs=t=>t.replace(/:\d+$/,""),Is=(t,n)=>!!t?.next_cursor&&n!==void 0&&t.records.lengthBs(t,o),[t,o]),d={cached:l.positive,answered:l.cat[2],nxdomain:l.notice,failed:l.negative},m=u=>e("ui.percent",{n:u===null?0:Math.round(u*100)}),f=(u,b)=>{const w=b?u/b:0;return u>0&&w<.005?"<"+e("ui.percent",{n:1}):u.995?">"+e("ui.percent",{n:99}):m(w)},x=u=>({id:u.id,value:u.value,color:d[u.outcome],lines:[u.name,S(u.value,e),e(z[u.outcome])]}),y=n??(i.total<5?s.jsx(R,{children:e("dns.chart.tooFew")}):null),C=[{label:e("dns.chart.median"),value:S(i.typical,e),icon:s.jsx(Ge,{}),tint:"c1"},{label:e("dns.chart.p95"),value:S(i.slowest,e),icon:s.jsx(Xe,{}),tint:"c4"},{label:e("dns.chart.cacheRate"),value:m(i.cacheRate),icon:s.jsx(Ye,{}),tint:"c2"},{label:e("dns.chart.failureRate"),value:m(i.failureRate),icon:s.jsx(Ze,{}),tint:"c5",tone:i.counts.failed?"negative":void 0}];return s.jsxs("div",{className:"rp-chart-page",children:[a,!y&&s.jsx(xs,{facts:C}),s.jsxs("div",{className:"rp-g21",children:[s.jsx(F,{title:e("dns.chart.speed",{n:i.samples.length}),note:y?void 0:e("dns.chart.sample",{n:i.total,uncached:i.uncached,upstream:i.samples.length}),aside:c.config&&s.jsx(ee,{appearance:"link",href:c.config,children:e("dns.openConfig")}),children:y??s.jsxs(s.Fragment,{children:[s.jsx(bs,{label:e("dns.chart.speed",{n:i.samples.length}),points:i.samples.map(x),marks:i.typical!==null&&i.slowest!==null?[{value:i.typical,label:e("dns.chart.typical",{value:S(i.typical,e)})},{value:i.slowest,label:e("dns.chart.slowest",{value:S(i.slowest,e)})}]:[],rows:i.upstreams.map(u=>({id:u.upstream,label:u.upstream,detail:e("dns.chart.upstream",{n:u.samples.length,median:S(u.median,e)}),points:u.samples.map(x),mark:u.median})),fmt:u=>S(u,e)}),s.jsxs("div",{className:"rp-legend",children:[["answered","nxdomain","failed"].map(u=>s.jsx(oe,{swatch:d[u],label:e(z[u])},u)),s.jsx(oe,{swatch:s.jsx("i",{className:"rp-median-key","aria-hidden":"true"}),label:e("dns.chart.medianKey")})]})]})}),s.jsx(F,{title:e("dns.chart.outcomes"),children:y??s.jsx(ws,{label:e("dns.chart.outcomes"),shares:Ws.map(u=>({id:u,label:e(z[u]),count:i.counts[u],color:d[u],text:e("dns.chart.share",{n:i.counts[u],share:f(i.counts[u],i.total)})}))})})]}),s.jsxs("div",{className:"rp-g21",children:[s.jsx(Js,{analysis:i,standIn:y,logHref:c.log}),s.jsx(zs,{listed:r,href:c.cache})]})]})}function zs({listed:t,href:n}){const a=v(),r=Z(),{ref:c,...e}=Ms(t);return s.jsx(F,{ref:c,title:a("dns.chart.cache"),note:e.state==="ready"?e.card?.note:void 0,aside:t&&n&&s.jsx(ee,{appearance:"link",href:n,children:a("dns.viewCache")}),children:e.state==="unlisted"?s.jsx(R,{children:a("dns.cacheUnavailable")}):e.state==="unavailable"?s.jsx(R,{children:a("dns.cacheBusy")}):e.state==="error"?s.jsx(O,{error:e.error,onRetry:e.retry}):e.card?s.jsxs(s.Fragment,{children:[e.card.usage&&s.jsxs("div",{className:"rp-form",children:[s.jsx(je,{label:a("dns.chart.usage"),value:e.card.usage.value,pct:e.card.usage.pct,color:r.accent}),s.jsx("span",{className:"rp-label",children:e.card.usage.facts})]}),s.jsx("p",{className:"rp-note",children:e.card.coverage})]}):s.jsx(ve,{})})}function Js({analysis:t,standIn:n,logHref:a}){const r=v(),c=Z(),[e,l]=h.useState("device"),o=e==="device"?t.devices:t.domains,i=o.top[0]?.count??1;return s.jsx(F,{title:r("dns.chart.ranking"),aside:!n&&s.jsx(es,{label:r("dns.chart.ranking"),value:e,onChange:l,items:[["device",r("dns.chart.byDevice")],["domain",r("dns.chart.byDomain")]]}),children:n??s.jsxs(s.Fragment,{children:[s.jsx("div",{className:"rp-list",children:o.top.map(d=>s.jsx(je,{label:d.key===null?r("dns.chart.resolver"):s.jsx(ee,{appearance:"link",href:a(e==="device"?"device":"domain",d.key),children:s.jsx(A,{children:d.key})}),value:r("dns.chart.count",{n:d.count}),pct:d.count/i*100,color:e==="device"?c.cat[0]:c.cat[3]},d.key??""))}),o.rest>0&&s.jsx("p",{className:"rp-note",children:r("dns.chart.rest",{n:o.rest})})]})})}function ga(t){const n=v(),a=Fs(t),r=s.jsxs(s.Fragment,{children:[a.queryError&&s.jsx(O,{error:a.queryError,onRetry:a.submit,message:e=>n("dns.queryFailed",{error:e})}),s.jsx("form",{className:ss(),onSubmit:e=>{e.preventDefault(),a.submit()},children:s.jsx(J,{reason:a.reason,children:s.jsxs("div",{className:"rp-toolbar",children:[s.jsx(G,{side:!0,label:n("ui.domain"),value:a.domain,onChange:a.setDomain,width:280,placeholder:"example.com"}),s.jsx(ye,{label:n("ui.type"),side:!0,value:a.type,onChange:a.setType,items:a.choices}),s.jsx(_,{accent:!0,type:"submit",isPending:a.pending,isDisabled:a.disabled,children:n("dns.query")})]})})}),a.cards.length>0&&s.jsx("div",{className:"rp-col",children:a.cards.map(e=>s.jsxs(F,{className:"rp-col",children:[s.jsxs("div",{className:"rp-row",children:[s.jsxs("div",{className:"rp-cluster",children:[s.jsx("h3",{className:"rp-h3",children:e.title}),s.jsx(we,{tone:e.cacheTone,children:e.cacheText})]}),s.jsxs("div",{className:"rp-cluster",children:[a.rule.canAdd(e.seed)&&s.jsx(_,{quiet:!0,small:!0,onPress:()=>a.rule.open(e.seed),children:n("rule.add")}),a.showCache&&s.jsx(_,{quiet:!0,small:!0,onPress:a.viewCache,children:n("dns.viewCache")})]})]}),s.jsx(se,{inline:!0,items:e.fields}),e.answers.length?s.jsx("div",{className:"rp-list",children:e.answers.map((l,o)=>{const i=e.answerSeeds[o];return s.jsxs("div",{className:"rp-cluster",children:[s.jsx("div",{className:"rp-code",children:l}),i&&a.rule.canAdd(i.seed)&&s.jsx(_,{quiet:!0,small:!0,label:n("dns.addRuleFor",{value:i.address}),onPress:()=>a.rule.open(i.seed),children:n("rule.add")})]},o)})}):s.jsx(R,{children:n("dns.noAnswers")})]},e.id))})]}),c={stats:s.jsx(Qs,{enabled:a.logEnabled,links:{cache:a.cacheHref,log:a.logHref}}),query:r,cache:s.jsx(Gs,{domain:a.filterDomain,clearFilter:a.clearCacheFilter,rule:a.rule}),log:s.jsx(Xs,{enabled:a.logEnabled,initialName:a.filterDomain,initialSrc:a.filterDevice,links:a.logLinks,rule:a.rule})};return s.jsxs("div",{className:"rp-page",children:[s.jsx(as,{keepMounted:!0,label:n("nav.dns"),items:a.tabs.map(e=>({...e,content:c[e.id]})),value:a.tab,onChange:a.setTab}),s.jsx(gs,{dialog:a.rule.dialog})]})}function Gs({domain:t,clearFilter:n,rule:a}){const r=v(),c=Os(t),{remove:e}=c,l=h.useMemo(()=>[{id:"q",label:r("ui.domain"),minWidth:192,isRowHeader:!0,render:o=>s.jsx(A,{className:"rp-code",text:o.id,children:o.domain})},{id:"t",label:r("ui.type"),minWidth:88,grow:0,drop:3,render:o=>o.type},{id:"s",label:r("ui.state"),minWidth:104,grow:0,render:o=>o.status},{id:"e",label:r("dns.expires"),minWidth:128,drop:2,render:o=>s.jsx(X,{at:o.expiresAt})},{id:"st",label:r("dns.staleUntil"),minWidth:128,drop:1,render:o=>s.jsx(X,{at:o.staleUntil})},{id:"a",label:r("ui.delete"),minWidth:80,grow:0,render:o=>s.jsx(_,{quiet:!0,icon:!0,small:!0,label:o.deleteLabel,isPending:o.pending,isDisabled:o.disabled,onPress:()=>e(o.id),children:s.jsx(Ns,{})})}],[r,e]);return s.jsxs(s.Fragment,{children:[c.error&&s.jsx(O,{error:c.error,onRetry:c.retry}),s.jsx(J,{reason:c.flushReason,children:s.jsxs("div",{className:"rp-toolbar",children:[s.jsx(se,{row:!0,items:c.fields}),c.coverage.map(o=>s.jsx(we,{tone:"warn",children:o.text},o.id)),c.filterText&&s.jsx(_,{small:!0,onPress:n,children:c.filterText}),s.jsx("span",{className:"rp-grow"}),s.jsx(_,{isDisabled:!c.seed||!a.canAdd(c.seed),tip:c.seed?void 0:r("ui.selectRow"),onPress:()=>c.seed&&a.open(c.seed),children:r("rule.add")}),s.jsx(is,{label:r("dns.flushAll"),confirmationText:c.confirmationText,isPending:c.flushPending,isDisabled:c.flushPending||c.flushDisabled,onConfirm:c.flush,onAbort:c.abortFlush})]})}),s.jsx(J,{reason:c.deleteReason,above:!0,children:s.jsx(Ne,{label:r("ui.cache"),height:442,fit:!0,rows:c.rows,selected:c.selected,onSelect:c.setSelected,loading:c.loading,empty:c.empty,cols:l})})]})}function Xs({enabled:t,initialName:n,initialSrc:a,links:r,rule:c}){const e=v(),l=Hs(t,n,a),o=l.detail?.seed,i=h.useMemo(()=>[{id:"t",label:e("ui.time"),minWidth:140,grow:0,render:d=>s.jsx(X,{at:d.observedAt})},{id:"q",label:e("ui.domain"),minWidth:200,grow:2,isRowHeader:!0,render:d=>s.jsx(A,{children:d.name})},{id:"ty",label:e("ui.type"),minWidth:88,grow:0,drop:3,render:d=>d.type},{id:"s",label:e("ui.device"),minWidth:128,drop:2,render:d=>s.jsx(A,{className:"rp-code",children:d.source})},{id:"r",label:e("dns.result"),minWidth:160,grow:2,render:d=>d.resultError?s.jsx(ue,{small:!0,tone:"err",children:d.result}):s.jsx(A,{className:"rp-code",children:d.result})},{id:"u",label:e("ui.upstream"),minWidth:128,drop:1,render:d=>d.cached?s.jsx(ue,{small:!0,tone:"ok",children:d.upstream}):s.jsx(A,{children:d.upstream})},{id:"e",label:e("ui.elapsed"),minWidth:88,grow:0,align:"end",drop:4,render:d=>d.elapsed}],[e]);return s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"rp-toolbar",children:[s.jsx(G,{search:!0,label:e("ui.domain"),value:l.name,onChange:l.setName,placeholder:e("dns.logFilterHint"),width:240}),s.jsx(ye,{label:e("ui.type"),side:!0,value:l.type,onChange:l.setType,items:l.choices}),s.jsx(G,{search:!0,label:e("ui.device"),value:l.src,onChange:l.setSrc,error:l.srcError,placeholder:"10.0.0.12",width:160}),l.total&&s.jsx(ns,{help:l.totalHelp,children:s.jsx("span",{className:"rp-label",children:l.total})}),l.loaded&&s.jsx("span",{className:"rp-label",children:l.loaded}),s.jsx("span",{className:"rp-grow"}),s.jsx(cs,{actions:[{id:"refresh",label:e("ui.refresh"),icon:s.jsx(ts,{className:"rp-spin-on-press"}),isPending:l.refreshing,onAction:l.refresh},{id:"export",label:e("dns.exportLog"),icon:s.jsx(rs,{}),isDisabled:!l.rows.length,onAction:l.export},{id:"rule",label:e("rule.add"),isDisabled:!o||!c.canAdd(o),reason:o?void 0:e("ui.selectRow"),onAction:()=>o&&c.open(o)},...r,...l.hasOlder?[{id:"older",label:e("dns.loadOlder"),isPending:l.loadingOlder,onAction:l.loadOlder}]:[]]})]}),l.error&&s.jsx(O,{error:l.error,onRetry:l.retry}),l.newerWaiting&&s.jsx("p",{className:"rp-note",children:e("dns.newerWaiting")}),s.jsxs("div",{className:"rp-with-panel","data-open":l.detail?"":void 0,children:[s.jsx(Ne,{label:e("dns.log"),rowDetail:!0,height:520,rows:l.rows,selected:l.selected,onSelect:l.setSelected,selectOnFocus:l.wide,loading:l.loading,empty:l.empty,cols:i}),s.jsx(ls,{open:!!l.detail,title:l.detailTitle,onClose:()=>l.setSelected(null),children:l.detail&&s.jsxs(s.Fragment,{children:[c.canAdd(l.detail.seed)&&s.jsx("div",{className:"rp-cluster",children:s.jsx(_,{small:!0,onPress:()=>c.open(l.detail.seed),children:e("rule.add")})}),s.jsx(se,{inline:!0,items:l.detail.fields}),l.detail.answers.length?s.jsx("div",{className:"rp-list",children:l.detail.answers.map((d,m)=>s.jsx("div",{className:"rp-code",children:d},m))}):s.jsx(R,{children:e("dns.noAnswers")})]})})]}),l.hasOlder&&s.jsx("div",{className:"rp-narrow-only",children:s.jsx("div",{className:"rp-cluster",children:s.jsx(_,{small:!0,isPending:l.loadingOlder,onPress:l.loadOlder,children:e("dns.loadOlder")})})})]})}export{ga as Dns}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Dns-CTpwVfIj.js b/luci-app-honk/root/etc/honk/doona/assets/Dns-CTpwVfIj.js deleted file mode 100644 index ba232fdfb..000000000 --- a/luci-app-honk/root/etc/honk/doona/assets/Dns-CTpwVfIj.js +++ /dev/null @@ -1,3 +0,0 @@ -import{r as p,j as a}from"./vendor-react-Bf71BWbF.js";import{u as g,aP as Te,c as _e,a3 as Se,aW as j,at as Le,a4 as ie,an as De,A as Re,ax as qe,bs as ce,a8 as I,bf as E,bt as oe,$ as ee,bj as Ae,bi as Fe,a5 as Q,a as z,bu as se,X as Ee,f as Me,bm as Oe,aa as U,bv as ke,be as P,b as ae,bw as Pe,aS as We,ai as T,j as de,E as F,aE as K,bx as He,by as Ue,bz as Be,bA as Ve,aJ as A,aR as te,aL as ue,b4 as $e,bB as B,T as V,b5 as pe,B as M,bC as Ie,aK as he,aG as G,br as Qe,aH as q,aF as ne,bq as ze,aI as Ke,bD as Ge,bp as Je,L as Xe,bo as Ye}from"./index-BNBwb-FJ.js";import{D as me}from"./Table-DyWJelc_.js";import{T as $}from"./TimeCell-DUt0i0gi.js";import{A as Ze}from"./ActionGroup-BKxDwmnT.js";import{q as es,u as fe,a as ss,s as as,b as ts}from"./dns-CvJ19DpX.js";import{c as re,d as ns,e as rs}from"./files-BxEOxSF8.js";import{d as ls}from"./nav-DuA2h3KP.js";import{b as is}from"./link-CIkWI7An.js";import{F as cs}from"./FactStrip-n2q1T87k.js";import{r as le,B as os}from"./ranked-B09X8uKl.js";import{u as ds,w as us,C as ps,p as W}from"./layout-wfdMYi2n.js";import"./useGridSelectionCheckbox-CrCOlZv8.js";import"./Virtualizer-DipGMcji.js";import"./ListLayout-F74Z1Dpf.js";function hs({label:r,shares:t}){const e=g(),s=Te(),{ref:l,tip:n,show:i,hide:c}=ds(),o=p.useMemo(()=>{const d=us(t.map(h=>h.count));return t.flatMap((h,f)=>Array.from({length:d[f]},()=>h))},[t]);return a.jsxs("div",{className:"rp-waffle rp-chart-hover",ref:l,onPointerLeave:c,children:[a.jsx("div",{className:"grid",role:"img","aria-describedby":s,"aria-label":e("ui.valuePair",{label:r,value:t.map(d=>`${d.label} ${d.text}`).join(e("ui.separator"))}),children:o.map((d,h)=>a.jsx("span",{style:{background:d.color},onPointerMove:f=>i(f,[d.label,d.text])},h))}),a.jsx("ul",{className:"legend",children:t.map(d=>a.jsxs("li",{children:[a.jsx("i",{className:"sw",style:{background:d.color}}),a.jsx("span",{children:d.label}),a.jsx("b",{children:d.text})]},d.id))}),a.jsx(ps,{tip:n})]})}function ms({className:r,...t}){return a.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:20,height:20,viewBox:"0 0 20 20","aria-hidden":"true",focusable:"false",className:_e("rp-icon",r),...t,children:[a.jsx("path",{fill:"currentColor",d:"M8.249 15.021c-.4 0-.733-.317-.748-.72l-.25-6.5c-.017-.414.307-.763.72-.779H8c.4 0 .733.317.748.72l.25 6.5c.017.414-.307.763-.72.778zM11.751 15.021h-.03c-.413-.016-.737-.365-.72-.779l.25-6.5c.015-.403.348-.72.748-.72h.03c.413.016.737.365.72.779l-.25 6.5c-.015.403-.348.72-.748.72"}),a.jsx("path",{fill:"currentColor",d:"M17 4h-3.5v-.75C13.5 2.01 12.49 1 11.25 1h-2.5C7.51 1 6.5 2.01 6.5 3.25V4H3c-.414 0-.75.336-.75.75s.336.75.75.75h.52l.422 10.342C3.99 17.052 4.98 18 6.19 18h7.62c1.211 0 2.2-.948 2.248-2.158L16.48 5.5H17c.414 0 .75-.336.75-.75S17.414 4 17 4m-9-.75c0-.413.337-.75.75-.75h2.5c.413 0 .75.337.75.75V4H8zm6.56 12.531c-.017.404-.346.719-.75.719H6.19c-.404 0-.733-.315-.75-.719L5.02 5.5h9.96z"})]})}const fs={forced:"dns.route.forced","dns.routing":"dns.route.rules",default:"dns.route.default"};function xe(r,t){return{fields:[[t("ui.state"),r.status],[t("ui.upstream"),r.upstream??"—"],[t("dns.routeSource"),Se(fs,r.route.source,t)],[t("dns.routeRule"),r.route.rule??"—"],[t("ui.elapsed"),j(r.elapsed_ms,t)]],answers:(r.answers??[]).map(e=>t("dns.answer",{name:e.name,type:e.type,ttl:e.ttl,data:e.data})),cacheText:t(r.cached?"dns.hit":"dns.miss"),cacheTone:r.cached?void 0:"warn"}}function xs(r,t,e,s,l,n){const i=t?.dns_query.record_types??[],c=e==="all"?i.length>0:i.includes(e);return{types:i,choices:[...i.map(o=>({id:o,label:o})),{id:"all",label:n("dns.allTypes")}],disabled:l||!t?.dns_query.available||!c||!s.trim(),reason:!t||l?null:t.dns_query.available?c?null:n(e==="all"?"dns.noTypes":"dns.typeUnsupported"):n("dns.queryUnavailable"),showCache:!!t?.dns_cache.available,cards:r?.results.map(o=>({id:o.type,title:`${r.domain} ${o.type}`,...xe(o,n)}))??[],tabs:ls(t).map(o=>({id:o.id,label:n(o.titleKey)}))}}function gs(r,t,e,s,l,n){const i=e.toLowerCase(),c=t?.dns_cache,o=(r?.entries??[]).filter(d=>!i||d.domain.toLowerCase().includes(i));return{fields:[[n("dns.entries"),r?ie(r.total,l):"—"]],coverage:r?["positive","negative","persistent"].filter(d=>!r.coverage[d]).map(d=>({id:d,text:n("ui.valuePair",{label:n({positive:"dns.positive",negative:"dns.negative",persistent:"dns.persistent"}[d]),value:n(d==="persistent"?"dns.chart.memoryOnly":"dns.notCovered")})})):[],filterText:i?n("dns.cacheFilter",{domain:e}):"",confirmationText:r?n("dns.flushConfirm",{n:r.total}):n("dns.flushConfirmAll"),flushDisabled:!!s||!t?.dns_cache.available||!t.dns_cache.flush,flushReason:c&&!s&&(!c.available||!c.flush)?n("dns.flushUnsupported"):null,deleteReason:c&&!s&&o.length>0&&(!c.available||!c.delete_entry)?n("dns.deleteUnsupported"):null,empty:n(t?.dns_cache.available&&t.dns_cache.read?"dns.empty":"dns.cacheUnavailable"),rows:o.map(d=>({id:d.entry_id,domain:d.domain,type:d.type,status:d.status,expiresAt:d.expires_at,staleUntil:d.stale_until,deleteLabel:n("dns.deleteEntry",{domain:d.domain,type:d.type}),pending:s===d.entry_id,disabled:!!s||!t?.dns_cache.available||!t.dns_cache.delete_entry}))}}function bs(r,t,e,s){const l=r?.records.find(i=>i.id===t);if(!l)return null;const n=xe(l,s);return{id:l.id,title:l.question.name,answers:n.answers,fields:[[s("ui.type"),l.question.type],[s("ui.device"),l.src??"—"],n.fields[0],[s("ui.cache"),n.cacheText],...n.fields.slice(1),[s("ui.time"),Le(l.observed_at,e)]]}}function vs(r,t,e,s=[]){const l=r?.records??[];return{choices:[{id:"all",label:e("dns.allTypes")},...[...new Set([...s,...l.map(n=>n.question.type)])].map(n=>({id:n,label:n}))],total:r?e("dns.logTotal",{n:r.total}):"",totalHelp:r?{title:e("dns.logTotal",{n:r.total}),text:e("dns.logTotalHelp")}:null,loaded:r?.next_cursor?e("dns.logLoaded",{n:l.length}):"",empty:e(t===void 0?"ui.loading":t?"dns.logEmpty":"dns.logUnavailable"),rows:l.map(n=>({id:n.id,observedAt:n.observed_at,name:n.question.name,type:n.question.type,source:n.src??"—",resultError:n.status!=="NOERROR",result:n.status!=="NOERROR"?n.status:n.answers.map(i=>i.data).join(", ")||"—",cached:n.cached,upstream:n.cached?e("dns.hit"):n.upstream??"—",elapsed:j(n.elapsed_ms,e)}))}}function js(r){return[re(["id","observed_at","src","name","type","status","cached","upstream","route_source","route_rule","elapsed_ms","answers"]),...r.map(t=>re([t.id,t.observed_at,t.src,t.question.name,t.question.type,t.status,t.cached?"true":"false",t.upstream,t.route.source,t.route.rule,t.elapsed_ms,t.answers.map(e=>e.data).join(" ")]))].join(` -`)+` -`}function ys(r,t){const e=new Set(r.records.map(s=>s.id));return{...r,records:[...r.records,...t.records.filter(s=>!e.has(s.id))],next_cursor:t.next_cursor}}function ws(r,t){const e=t&&new Set(t.records.map(s=>s.id));return{data:t??r,newerWaiting:!!e&&!!r?.records.some(s=>!e.has(s.id))}}function Ns(r,t,e){if(!r)return null;const{usage:s,coverage:l}=r,n=c=>{const o=qe(c);return o===null?"—":ie(o,t)},i=s?De(s.entries,s.entry_capacity):null;return{note:s?void 0:e("dns.chart.cacheNote",{n:r.total}),usage:s&&i!==null?{pct:i,value:i>0&&i<.5?"<"+e("ui.percent",{n:1}):e("ui.percent",{n:Math.round(i)}),facts:e("dns.chart.usageFacts",{entries:e("ui.fraction",{part:n(s.entries),whole:n(s.entry_capacity)})})}:null,coverage:e("dns.chart.coverage",{kinds:[l.positive&&e("dns.chart.positive"),l.negative&&e("dns.chart.negative")].filter(Boolean).join(e("ui.listSeparator")),persistent:e(l.persistent?"dns.chart.persistent":"dns.chart.memoryOnly")})}}function Cs(r,t,e){return r?e instanceof Re&&e.status===503?"unavailable":t?"ready":e?"error":"loading":"unlisted"}function Ts({go:r,query:t}){const e=g(),s=ce(),l=I(),n=p.useMemo(()=>new URLSearchParams(t),[t]),[i,c]=p.useState(n.get("domain")??""),[o,d]=p.useState(n.get("type")??"A");E(n.get("domain"),m=>c(m??"")),E(n.get("type"),m=>d(m??"A"));const[h,f]=p.useState(null),{busy:y,error:u,run:v}=oe({rethrow:!0}),x=l.data?.resources,_=p.useMemo(()=>xs(h,x,o,i,!!y,e),[h,x,o,i,y,e]),w=_.tabs.map(m=>m.id),L=w.includes("log")?n.has("domain")?"log":"stats":w.includes("query")?"query":w[0]??"query",N=async()=>{try{await v("query",async m=>{const C=await es(s.dnsQuery,i.trim(),o==="all"?_.types:[o],x?.dns_query.limits?.max_types_per_request??1,m);return m.aborted||f(C),C})}catch{}};return{..._,domain:i,setDomain:c,type:o,setType:d,pending:y==="query",queryError:u,submit:()=>void N(),setTab:m=>r("dns",Fe(t,m,x&&!n.has("domain")?L:null)),tab:Ae(t,_.tabs.map(m=>m.id),L),filterDomain:n.get("domain")??"",logEnabled:x?.dns_log.available,viewCache:()=>r("dns",ee(t,{tab:"cache",domain:h?.domain??""})),clearCacheFilter:()=>r("dns",ee(t,{tab:"cache",domain:null}))}}function _s(r){const t=g(),e=Q[z()],s=ss(!ke()),l=p.useMemo(()=>gs(s.cache.data,s.capabilities.data?.resources,r,s.busy,e,t),[s.cache.data,s.capabilities.data,r,s.busy,e,t]),{remove:n}=s,i=p.useCallback(o=>void n(o).then(d=>d&&P("positive",t("dns.deleted",{n:d.deleted})),d=>P("negative",t("dns.deleteFailed"),{detail:ae(d,t)})),[n,t]),c=async()=>{try{const o=await s.flush();o&&P("positive",t("dns.flushed",{matched:o.matched,deleted:o.deleted}))}catch(o){return t("dns.flushFailed",{error:ae(o,t)})}};return{...l,error:s.cache.error,retry:s.cache.refetch,loading:(s.cache.loading||s.capabilities.loading)&&!s.cache.data,flushPending:s.busy==="flush",remove:i,flush:c,abortFlush:()=>{s.cancel(),s.cache.refetch()}}}function Ss(r){const t=fe({},r===!0),e=I().data?.resources;return{log:t,cacheListed:U(e,"dns_cache",{whileLoading:!1})&&e?.dns_cache.read===!0}}function Ls(r){const t=g(),e=Q[z()],[s,l]=Pe(),[n,i]=p.useState(!1),c=ts(r,!l&&n);c.data&&!n&&i(!0);const o=p.useMemo(()=>Ns(c.data,e,t),[c.data,e,t]);return{ref:s,card:o,state:Cs(r,!!o,c.error),error:c.error,retry:c.refetch}}function Ds(r,t){const e=g(),s=Q[z()],[l,n]=p.useState(t);E(t,n);const[i,c]=p.useState("all"),[o,d]=p.useState(""),h=ce(),f=I(),y=se(o),u=Ee(y),v=y.trim()!==""&&!u,[x,_]=p.useState(u);!v&&u!==x&&_(u);const w={name:se(l),type:i,src:v?x:u},L=JSON.stringify(w),N=fe(w,r===!0),[m,C]=p.useState(null),[ge,J]=p.useState(!1),D=oe({scope:L});E(L,()=>C(null));const{data:b,newerWaiting:be}=p.useMemo(()=>ws(N.data,m),[N.data,m]),X=()=>void D.run("older",async S=>{if(!b?.next_cursor)return;C(b);const{page:Ne}=await as(Ce=>h.dnsLog(Ce,S),{name:w.name.trim()||void 0,type:i==="all"?void 0:i,src:w.src,cursor:b.next_cursor,limit:N.limit},S);S.aborted||C(ys(b,Ne))}),Y=()=>{D.cancel(),C(null);const S=N.refetch();S&&(J(!0),S.finally(()=>J(!1)))},[O,ve]=p.useState(null),je=Me(Oe),Z=f.data?.resources.dns_query.record_types,ye=p.useMemo(()=>vs(b,r,e,Z),[b,r,e,Z]),R=p.useMemo(()=>bs(b,O,s,e),[b,O,s,e]),k=f.data?.resources,we=U(k,"dns_rules",{whileLoading:!1})&&U(k,"config",{whileLoading:!1})&&k?.config.writable===!0;return{...ye,detail:R,detailTitle:R?.title??"",ruleHref:R&&we?is({kind:"qnameSuffix",value:R.title.replace(/\.$/,"")},"dns"):null,name:l,newerWaiting:be,setName:n,type:i,setType:c,src:o,setSrc:d,srcError:v?e("ui.invalidIp"):void 0,selected:R?O:null,setSelected:ve,wide:je,error:D.error??N.error,loading:N.loading&&!b,hasOlder:!!b?.next_cursor,loadingOlder:!!D.busy,loadOlder:X,refreshing:ge,refresh:Y,retry:D.error?X:Y,export:()=>ns(rs("dns-log","csv"),js(b?.records??[]),"text/csv;charset=utf-8")}}const Rs=["cached","answered","nxdomain","failed"],qs=r=>r.cached?"cached":r.status==="NOERROR"?"answered":r.status==="NXDOMAIN"?"nxdomain":"failed";function As(r){const t={cached:0,answered:0,nxdomain:0,failed:0},e=[];for(const c of r){const o=qs(c);t[o]++,!c.cached&&c.upstream!==null&&e.push({id:c.id,value:c.elapsed_ms,outcome:o,name:c.question.name,upstream:c.upstream})}const s=e.map(c=>c.value).sort((c,o)=>c-o),l=new Map;for(const c of e)l.set(c.upstream,[...l.get(c.upstream)??[],c]);const n=[...l].map(([c,o])=>({upstream:c,median:W(o.map(d=>d.value).sort((d,h)=>d-h),50),samples:o}));n.sort((c,o)=>o.samples.length-c.samples.length||We(c.upstream,o.upstream));const i=r.length-t.cached;return{domains:le(r.map(c=>c.question.name.replace(/\.$/,"")),8),devices:le(r.map(c=>c.src===null?null:Fs(c.src)),8),total:r.length,counts:t,uncached:i,samples:e,typical:W(s,50),slowest:W(s,95),failureRate:i?t.failed/i:null,cacheRate:r.length?t.cached/r.length:null,upstreams:n}}const Fs=r=>r.replace(/:\d+$/,""),Es=(r,t)=>!!r?.next_cursor&&t!==void 0&&r.records.lengthAs(r),[r]),c={cached:n.positive,answered:n.cat[2],nxdomain:n.notice,failed:n.negative},o=u=>l("ui.percent",{n:u===null?0:Math.round(u*100)}),d=(u,v)=>{const x=v?u/v:0;return u>0&&x<.005?"<"+l("ui.percent",{n:1}):u.995?">"+l("ui.percent",{n:99}):o(x)},h=u=>({id:u.id,value:u.value,color:c[u.outcome],lines:[u.name,j(u.value,l),l(H[u.outcome])]}),f=t??(i.total<5?a.jsx(T,{children:l("dns.chart.tooFew")}):null),y=[{label:l("dns.chart.median"),value:j(i.typical,l),icon:a.jsx(He,{}),tint:"c1"},{label:l("dns.chart.p95"),value:j(i.slowest,l),icon:a.jsx(Ue,{}),tint:"c4"},{label:l("dns.chart.cacheRate"),value:o(i.cacheRate),icon:a.jsx(Be,{}),tint:"c2"},{label:l("dns.chart.failureRate"),value:o(i.failureRate),icon:a.jsx(Ve,{}),tint:"c5",tone:i.counts.failed?"negative":void 0}];return a.jsxs("div",{className:"rp-chart-page",children:[e,!f&&a.jsx(cs,{facts:y}),a.jsxs("div",{className:"rp-g21",children:[a.jsx(A,{title:l("dns.chart.speed",{n:i.samples.length}),note:f?void 0:l("dns.chart.sample",{n:i.total,uncached:i.uncached,upstream:i.samples.length}),children:f??a.jsxs(a.Fragment,{children:[a.jsx(os,{label:l("dns.chart.speed",{n:i.samples.length}),points:i.samples.map(h),marks:i.typical!==null&&i.slowest!==null?[{value:i.typical,label:l("dns.chart.typical",{value:j(i.typical,l)})},{value:i.slowest,label:l("dns.chart.slowest",{value:j(i.slowest,l)})}]:[],rows:i.upstreams.map(u=>({id:u.upstream,label:u.upstream,detail:l("dns.chart.upstream",{n:u.samples.length,median:j(u.median,l)}),points:u.samples.map(h),mark:u.median})),fmt:u=>j(u,l)}),a.jsxs("div",{className:"rp-legend",children:[["answered","nxdomain","failed"].map(u=>a.jsx(te,{swatch:c[u],label:l(H[u])},u)),a.jsx(te,{swatch:a.jsx("i",{className:"rp-median-key","aria-hidden":"true"}),label:l("dns.chart.medianKey")})]})]})}),a.jsx(A,{title:l("dns.chart.outcomes"),children:f??a.jsx(hs,{label:l("dns.chart.outcomes"),shares:Rs.map(u=>({id:u,label:l(H[u]),count:i.counts[u],color:c[u],text:l("dns.chart.share",{n:i.counts[u],share:d(i.counts[u],i.total)})}))})})]}),a.jsxs("div",{className:"rp-g21",children:[a.jsx(Ws,{analysis:i,standIn:f}),a.jsx(Ps,{listed:s})]})]})}function Ps({listed:r}){const t=g(),e=K(),{ref:s,...l}=Ls(r);return a.jsx(A,{ref:s,title:t("dns.chart.cache"),note:l.state==="ready"?l.card?.note:void 0,children:l.state==="unlisted"?a.jsx(T,{children:t("dns.cacheUnavailable")}):l.state==="unavailable"?a.jsx(T,{children:t("dns.cacheBusy")}):l.state==="error"?a.jsx(F,{error:l.error,onRetry:l.retry}):l.card?a.jsxs(a.Fragment,{children:[l.card.usage&&a.jsxs("div",{className:"rp-form",children:[a.jsx(ue,{label:t("dns.chart.usage"),value:l.card.usage.value,pct:l.card.usage.pct,color:e.accent}),a.jsx("span",{className:"rp-label",children:l.card.usage.facts})]}),a.jsx("p",{className:"rp-note",children:l.card.coverage})]}):a.jsx(de,{})})}function Ws({analysis:r,standIn:t}){const e=g(),s=K(),[l,n]=p.useState("device"),i=l==="device"?r.devices:r.domains,c=i.top[0]?.count??1;return a.jsx(A,{title:e("dns.chart.ranking"),aside:!t&&a.jsx($e,{label:e("dns.chart.ranking"),value:l,onChange:n,items:[["device",e("dns.chart.byDevice")],["domain",e("dns.chart.byDomain")]]}),children:t??a.jsxs(a.Fragment,{children:[a.jsx("div",{className:"rp-list",children:i.top.map(o=>a.jsx(ue,{label:o.key??e("dns.chart.resolver"),value:e("dns.chart.count",{n:o.count}),pct:o.count/c*100,color:l==="device"?s.cat[0]:s.cat[3]},o.key??""))}),i.rest>0&&a.jsx("p",{className:"rp-note",children:e("dns.chart.rest",{n:i.rest})})]})})}function ta(r){const t=g(),e=Ts(r),s=a.jsxs(a.Fragment,{children:[e.queryError&&a.jsx(F,{error:e.queryError,onRetry:e.submit,message:n=>t("dns.queryFailed",{error:n})}),a.jsx("form",{className:Ie(),onSubmit:n=>{n.preventDefault(),e.submit()},children:a.jsx(B,{reason:e.reason,children:a.jsxs("div",{className:"rp-toolbar",children:[a.jsx(V,{side:!0,label:t("ui.domain"),value:e.domain,onChange:e.setDomain,width:280,placeholder:"example.com"}),a.jsx(pe,{label:t("ui.type"),side:!0,value:e.type,onChange:e.setType,items:e.choices}),a.jsx(M,{accent:!0,type:"submit",isPending:e.pending,isDisabled:e.disabled,children:t("dns.query")})]})})}),e.cards.length>0&&a.jsx("div",{className:"rp-col",children:e.cards.map(n=>a.jsxs(A,{className:"rp-col",children:[a.jsxs("div",{className:"rp-row",children:[a.jsxs("div",{className:"rp-cluster",children:[a.jsx("h3",{className:"rp-h3",children:n.title}),a.jsx(he,{tone:n.cacheTone,children:n.cacheText})]}),e.showCache&&a.jsx(M,{quiet:!0,small:!0,onPress:e.viewCache,children:t("dns.viewCache")})]}),a.jsx(G,{inline:!0,items:n.fields}),n.answers.length?a.jsx("div",{className:"rp-list",children:n.answers.map((i,c)=>a.jsx("div",{className:"rp-code",children:i},c))}):a.jsx(T,{children:t("dns.noAnswers")})]},n.id))})]}),l={stats:a.jsx(Ms,{enabled:e.logEnabled}),query:s,cache:a.jsx(Hs,{domain:e.filterDomain,clearFilter:e.clearCacheFilter}),log:a.jsx(Us,{enabled:e.logEnabled,initialName:e.filterDomain})};return a.jsx("div",{className:"rp-page",children:a.jsx(Qe,{keepMounted:!0,label:t("nav.dns"),items:e.tabs.map(n=>({...n,content:l[n.id]})),value:e.tab,onChange:e.setTab})})}function Hs({domain:r,clearFilter:t}){const e=g(),s=_s(r),{remove:l}=s,n=p.useMemo(()=>[{id:"q",label:e("ui.domain"),minWidth:192,isRowHeader:!0,render:i=>a.jsx(q,{className:"rp-code",text:i.id,children:i.domain})},{id:"t",label:e("ui.type"),minWidth:64,grow:0,drop:3,render:i=>i.type},{id:"s",label:e("ui.state"),minWidth:104,grow:0,render:i=>i.status},{id:"e",label:e("dns.expires"),minWidth:96,drop:2,render:i=>a.jsx($,{at:i.expiresAt})},{id:"st",label:e("dns.staleUntil"),minWidth:104,drop:1,render:i=>a.jsx($,{at:i.staleUntil})},{id:"a",label:e("ui.delete"),minWidth:80,grow:0,render:i=>a.jsx(M,{quiet:!0,icon:!0,small:!0,label:i.deleteLabel,isPending:i.pending,isDisabled:i.disabled,onPress:()=>l(i.id),children:a.jsx(ms,{})})}],[e,l]);return a.jsxs(a.Fragment,{children:[s.error&&a.jsx(F,{error:s.error,onRetry:s.retry}),a.jsx(B,{reason:s.flushReason,children:a.jsxs("div",{className:"rp-toolbar",children:[a.jsx(G,{row:!0,items:s.fields}),s.coverage.map(i=>a.jsx(he,{tone:"warn",children:i.text},i.id)),s.filterText&&a.jsx(M,{small:!0,onPress:t,children:s.filterText}),a.jsx("span",{className:"rp-grow"}),a.jsx(Ye,{label:e("dns.flushAll"),confirmationText:s.confirmationText,isPending:s.flushPending,isDisabled:s.flushPending||s.flushDisabled,onConfirm:s.flush,onAbort:s.abortFlush})]})}),a.jsx(B,{reason:s.deleteReason,above:!0,children:a.jsx(me,{label:e("ui.cache"),height:442,fit:!0,rows:s.rows,loading:s.loading,empty:s.empty,cols:n})})]})}function Us({enabled:r,initialName:t}){const e=g(),s=Ds(r,t),l=p.useMemo(()=>[{id:"t",label:e("ui.time"),minWidth:140,grow:0,render:n=>a.jsx($,{at:n.observedAt})},{id:"q",label:e("ui.domain"),minWidth:200,grow:2,isRowHeader:!0,render:n=>a.jsx(q,{children:n.name})},{id:"ty",label:e("ui.type"),minWidth:64,grow:0,drop:3,render:n=>n.type},{id:"s",label:e("ui.device"),minWidth:128,drop:2,render:n=>a.jsx(q,{className:"rp-code",children:n.source})},{id:"r",label:e("dns.result"),minWidth:160,grow:2,render:n=>n.resultError?a.jsx(ne,{small:!0,tone:"err",children:n.result}):a.jsx(q,{className:"rp-code",children:n.result})},{id:"u",label:e("ui.upstream"),minWidth:128,drop:1,render:n=>n.cached?a.jsx(ne,{small:!0,tone:"ok",children:n.upstream}):a.jsx(q,{children:n.upstream})},{id:"e",label:e("ui.elapsed"),minWidth:72,grow:0,align:"end",drop:4,render:n=>n.elapsed}],[e]);return a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"rp-toolbar",children:[a.jsx(V,{search:!0,label:e("ui.domain"),value:s.name,onChange:s.setName,placeholder:e("dns.logFilterHint"),width:240}),a.jsx(pe,{label:e("ui.type"),side:!0,value:s.type,onChange:s.setType,items:s.choices}),a.jsx(V,{search:!0,label:e("ui.device"),value:s.src,onChange:s.setSrc,error:s.srcError,placeholder:"10.0.0.12",width:160}),s.total&&a.jsx(ze,{help:s.totalHelp,children:a.jsx("span",{className:"rp-label",children:s.total})}),s.loaded&&a.jsx("span",{className:"rp-label",children:s.loaded}),a.jsx("span",{className:"rp-grow"}),a.jsx(Ze,{actions:[{id:"export",label:e("dns.exportLog"),icon:a.jsx(Ke,{}),isDisabled:!s.rows.length,onAction:s.export},{id:"refresh",label:e("refresh"),icon:a.jsx(Ge,{className:"rp-spin-on-press"}),isPending:s.refreshing,onAction:s.refresh},...s.hasOlder?[{id:"older",label:e("dns.loadOlder"),isPending:s.loadingOlder,onAction:s.loadOlder}]:[]]})]}),s.error&&a.jsx(F,{error:s.error,onRetry:s.retry}),s.newerWaiting&&a.jsx("p",{className:"rp-note",children:e("dns.newerWaiting")}),a.jsxs("div",{className:"rp-with-panel","data-open":s.detail?"":void 0,children:[a.jsx(me,{label:e("dns.log"),rowDetail:!0,height:520,rows:s.rows,selected:s.selected,onSelect:s.setSelected,selectOnFocus:s.wide,loading:s.loading,empty:s.empty,cols:l}),a.jsx(Je,{open:!!s.detail,title:s.detailTitle,onClose:()=>s.setSelected(null),children:s.detail&&a.jsxs(a.Fragment,{children:[s.ruleHref&&a.jsx("div",{className:"rp-cluster",children:a.jsx(Xe,{appearance:"button",small:!0,href:s.ruleHref,children:e("dns.newRule")})}),a.jsx(G,{inline:!0,items:s.detail.fields}),s.detail.answers.length?a.jsx("div",{className:"rp-list",children:s.detail.answers.map((n,i)=>a.jsx("div",{className:"rp-code",children:n},i))}):a.jsx(T,{children:e("dns.noAnswers")})]})})]})]})}export{ta as Dns}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Donut-BeIly43C.js b/luci-app-honk/root/etc/honk/doona/assets/Donut-BeIly43C.js new file mode 100644 index 000000000..65083862f --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/Donut-BeIly43C.js @@ -0,0 +1 @@ +import{r as an,j as K}from"./vendor-react-Bf71BWbF.js";import{u as cn,fx as fn}from"./index-Bw0aJc9a.js";import{u as gn,i as hn,e as pn,C as yn}from"./layout-BWzq8YqC.js";import{w as dn,c as T,a as mn}from"./array-C0P64tl-.js";const on=Math.abs,P=Math.atan2,k=Math.cos,vn=Math.max,rn=Math.min,C=Math.sin,F=Math.sqrt,S=1e-12,V=Math.PI,X=V/2,W=2*V;function xn(t){return t>1?0:t<-1?V:Math.acos(t)}function ln(t){return t>=1?X:t<=-1?-X:Math.asin(t)}function An(t){return t.innerRadius}function Mn(t){return t.outerRadius}function Rn(t){return t.startAngle}function Pn(t){return t.endAngle}function wn(t){return t&&t.padAngle}function Tn(t,h,x,w,v,A,p,n){var f=x-t,u=w-h,e=p-v,y=n-A,r=y*f-e*u;if(!(r*ro*o+N*N&&($=b,B=E),{cx:$,cy:B,x01:-e,y01:-y,x11:$*(v/M-1),y11:B*(v/M-1)}}function jn(){var t=An,h=Mn,x=T(0),w=null,v=Rn,A=Pn,p=wn,n=null,f=dn(u);function u(){var e,y,r=+t.apply(this,arguments),a=+h.apply(this,arguments),g=v.apply(this,arguments)-X,d=A.apply(this,arguments)-X,j=on(d-g),c=d>g;if(n||(n=e=f()),aS))n.moveTo(0,0);else if(j>W-S)n.moveTo(a*k(g),a*C(g)),n.arc(0,0,a,g,d,!c),r>S&&(n.moveTo(r*k(d),r*C(d)),n.arc(0,0,r,d,g,c));else{var m=g,i=d,l=g,M=d,R=j,I=j,$=p.apply(this,arguments)/2,B=$>S&&(w?+w.apply(this,arguments):F(r*r+a*a)),b=rn(on(a-r)/2,+x.apply(this,arguments)),E=b,L=b,s,o;if(B>S){var N=ln(B/r*C($)),O=ln(B/a*C($));(R-=N*2)>S?(N*=c?1:-1,l+=N,M-=N):(R=0,l=M=(g+d)/2),(I-=O*2)>S?(O*=c?1:-1,m+=O,i-=O):(I=0,m=i=(g+d)/2)}var q=a*k(m),z=a*C(m),G=r*k(M),H=r*C(M);if(b>S){var J=a*k(i),Q=a*C(i),Y=r*k(l),Z=r*C(l),D;if(jS?L>S?(s=U(Y,Z,q,z,a,L,c),o=U(J,Q,G,H,a,L,c),n.moveTo(s.cx+s.x01,s.cy+s.y01),LS)||!(R>S)?n.lineTo(G,H):E>S?(s=U(G,H,J,Q,r,-E,c),o=U(q,z,Y,Z,r,-E,c),n.lineTo(s.cx+s.x01,s.cy+s.y01),Et?1:h>=t?0:NaN}function En(t){return t}function Ln(){var t=En,h=Sn,x=null,w=T(0),v=T(W),A=T(0);function p(n){var f,u=(n=mn(n)).length,e,y,r=0,a=new Array(u),g=new Array(u),d=+w.apply(this,arguments),j=Math.min(W,Math.max(-W,v.apply(this,arguments)-d)),c,m=Math.min(Math.abs(j)/u,A.apply(this,arguments)),i=m*(j<0?-1:1),l;for(f=0;f0&&(r+=l);for(h!=null?a.sort(function(M,R){return h(g[M],g[R])}):x!=null&&a.sort(function(M,R){return x(n[M],n[R])}),f=0,y=r?(j-u*i)/r:0;f0?l*y:0)+i,g[e]={data:n[e],index:f,value:l,startAngle:d,endAngle:c,padAngle:m};return g}return p.value=function(n){return arguments.length?(t=typeof n=="function"?n:T(+n),p):t},p.sortValues=function(n){return arguments.length?(h=n,x=null,p):h},p.sort=function(n){return arguments.length?(x=n,h=null,p):x},p.startAngle=function(n){return arguments.length?(w=typeof n=="function"?n:T(+n),p):w},p.endAngle=function(n){return arguments.length?(v=typeof n=="function"?n:T(+n),p):v},p.padAngle=function(n){return arguments.length?(A=typeof n=="function"?n:T(+n),p):A},p}function $n({label:t,rows:h}){const x=cn(),[w,v]=fn(Math.round,120),{tip:A,showAt:p,hide:n}=gn(),[f,u]=an.useState(null),e=h.filter(i=>i.value!==null&&i.value>0),y=v?.width??0,r=v?.height??0,a=hn(e.map(i=>i.value)),g=Ln().sort(null).value((i,l)=>a[l])(e),d=jn().innerRadius(44).outerRadius(56).digits(3),j=i=>u(i),c=()=>{u(null),n()};an.useLayoutEffect(()=>{const i=f===null?void 0:g[f];if(!i||f===null){n();return}const l=e[f],[M,R]=d.centroid(i);p({x:Math.round((y/2+M)*1e4)/1e4,y:Math.round((r/2+R)*1e4)/1e4,width:y,bounds:{x:0,y:0,width:y,height:r},lines:[x("ui.valuePair",{label:l.name,value:x("ui.share",{bytes:l.text,percent:String(l.value)})})]})});const m=pn(e.length,j,c);return K.jsxs("div",{ref:w,style:{height:"100%",width:"100%",position:"relative"},onPointerLeave:m.onPointerLeave,children:[K.jsx(yn,{tip:A}),v&&K.jsx("svg",{className:"rp-activity-surface",width:y,height:r,viewBox:`0 0 ${y} ${r}`,style:{display:"block"},role:"application","aria-label":t,tabIndex:0,onFocus:m.onFocus,onBlur:m.onBlur,onKeyDown:m.onKeyDown,children:K.jsx("g",{transform:`translate(${y/2},${r/2})`,children:g.map((i,l)=>K.jsx("path",{d:d({...i,endAngle:Math.min(i.endAngle,i.startAngle+359.999*Math.PI/180)})??void 0,fill:e[l].color,stroke:"none",onPointerEnter:()=>j(l),onPointerLeave:m.onPointerLeave},e[l].name))})})]})}export{$n as DonutPlot}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Donut-C-REp4Mf.js b/luci-app-honk/root/etc/honk/doona/assets/Donut-C-REp4Mf.js deleted file mode 100644 index 938d52236..000000000 --- a/luci-app-honk/root/etc/honk/doona/assets/Donut-C-REp4Mf.js +++ /dev/null @@ -1 +0,0 @@ -import{r as an,j as K}from"./vendor-react-Bf71BWbF.js";import{u as cn,eQ as fn}from"./index-BNBwb-FJ.js";import{u as gn,i as hn,e as pn,C as yn}from"./layout-wfdMYi2n.js";import{w as dn,c as T,a as mn}from"./array-C0P64tl-.js";const on=Math.abs,w=Math.atan2,k=Math.cos,xn=Math.max,rn=Math.min,b=Math.sin,F=Math.sqrt,S=1e-12,V=Math.PI,X=V/2,W=2*V;function vn(t){return t>1?0:t<-1?V:Math.acos(t)}function ln(t){return t>=1?X:t<=-1?-X:Math.asin(t)}function An(t){return t.innerRadius}function Mn(t){return t.outerRadius}function Rn(t){return t.startAngle}function wn(t){return t.endAngle}function Pn(t){return t&&t.padAngle}function Tn(t,h,v,P,x,A,p,n){var f=v-t,u=P-h,e=p-x,y=n-A,r=y*f-e*u;if(!(r*ri*i+N*N&&(I=L,B=$),{cx:I,cy:B,x01:-e,y01:-y,x11:I*(x/M-1),y11:B*(x/M-1)}}function jn(){var t=An,h=Mn,v=T(0),P=null,x=Rn,A=wn,p=Pn,n=null,f=dn(u);function u(){var e,y,r=+t.apply(this,arguments),a=+h.apply(this,arguments),g=x.apply(this,arguments)-X,d=A.apply(this,arguments)-X,j=on(d-g),c=d>g;if(n||(n=e=f()),aS))n.moveTo(0,0);else if(j>W-S)n.moveTo(a*k(g),a*b(g)),n.arc(0,0,a,g,d,!c),r>S&&(n.moveTo(r*k(d),r*b(d)),n.arc(0,0,r,d,g,c));else{var m=g,o=d,l=g,M=d,R=j,D=j,I=p.apply(this,arguments)/2,B=I>S&&(P?+P.apply(this,arguments):F(r*r+a*a)),L=rn(on(a-r)/2,+v.apply(this,arguments)),$=L,E=L,s,i;if(B>S){var N=ln(B/r*b(I)),O=ln(B/a*b(I));(R-=N*2)>S?(N*=c?1:-1,l+=N,M-=N):(R=0,l=M=(g+d)/2),(D-=O*2)>S?(O*=c?1:-1,m+=O,o-=O):(D=0,m=o=(g+d)/2)}var q=a*k(m),z=a*b(m),Q=r*k(M),G=r*b(M);if(L>S){var H=a*k(o),J=a*b(o),Y=r*k(l),Z=r*b(l),C;if(jS?E>S?(s=U(Y,Z,q,z,a,E,c),i=U(H,J,Q,G,a,E,c),n.moveTo(s.cx+s.x01,s.cy+s.y01),ES)||!(R>S)?n.lineTo(Q,G):$>S?(s=U(Q,G,H,J,r,-$,c),i=U(q,z,Y,Z,r,-$,c),n.lineTo(s.cx+s.x01,s.cy+s.y01),$t?1:h>=t?0:NaN}function $n(t){return t}function En(){var t=$n,h=Sn,v=null,P=T(0),x=T(W),A=T(0);function p(n){var f,u=(n=mn(n)).length,e,y,r=0,a=new Array(u),g=new Array(u),d=+P.apply(this,arguments),j=Math.min(W,Math.max(-W,x.apply(this,arguments)-d)),c,m=Math.min(Math.abs(j)/u,A.apply(this,arguments)),o=m*(j<0?-1:1),l;for(f=0;f0&&(r+=l);for(h!=null?a.sort(function(M,R){return h(g[M],g[R])}):v!=null&&a.sort(function(M,R){return v(n[M],n[R])}),f=0,y=r?(j-u*o)/r:0;f0?l*y:0)+o,g[e]={data:n[e],index:f,value:l,startAngle:d,endAngle:c,padAngle:m};return g}return p.value=function(n){return arguments.length?(t=typeof n=="function"?n:T(+n),p):t},p.sortValues=function(n){return arguments.length?(h=n,v=null,p):h},p.sort=function(n){return arguments.length?(v=n,h=null,p):v},p.startAngle=function(n){return arguments.length?(P=typeof n=="function"?n:T(+n),p):P},p.endAngle=function(n){return arguments.length?(x=typeof n=="function"?n:T(+n),p):x},p.padAngle=function(n){return arguments.length?(A=typeof n=="function"?n:T(+n),p):A},p}function In({label:t,rows:h}){const v=cn(),[P,x]=fn(Math.round,120),{tip:A,showAt:p,hide:n}=gn(),[f,u]=an.useState(null),e=h.filter(o=>o.value!==null&&o.value>0),y=x?.width??0,r=x?.height??0,a=hn(e.map(o=>o.value)),g=En().sort(null).value((o,l)=>a[l])(e),d=jn().innerRadius(44).outerRadius(56).digits(3),j=o=>u(o),c=()=>{u(null),n()};an.useLayoutEffect(()=>{const o=f===null?void 0:g[f];if(!o||f===null){n();return}const l=e[f],[M,R]=d.centroid(o);p({x:Math.round((y/2+M)*1e4)/1e4,y:Math.round((r/2+R)*1e4)/1e4,width:y,bounds:{x:0,y:0,width:y,height:r},lines:[`${l.name}${v("ui.labelSeparator")}${v("ui.share",{bytes:l.text,percent:String(l.value)})}`]})});const m=pn(e.length,j,c);return K.jsxs("div",{ref:P,style:{height:"100%",width:"100%",position:"relative"},onPointerLeave:m.onPointerLeave,children:[K.jsx(yn,{tip:A}),x&&K.jsx("svg",{className:"rp-activity-surface",width:y,height:r,viewBox:`0 0 ${y} ${r}`,style:{display:"block"},role:"application","aria-label":t,tabIndex:0,onFocus:m.onFocus,onBlur:m.onBlur,onKeyDown:m.onKeyDown,children:K.jsx("g",{transform:`translate(${y/2},${r/2})`,children:g.map((o,l)=>K.jsx("path",{d:d({...o,endAngle:Math.min(o.endAngle,o.startAngle+359.999*Math.PI/180)})??void 0,fill:e[l].color,stroke:"none",onPointerEnter:()=>j(l),onPointerLeave:m.onPointerLeave},e[l].name))})})]})}export{In as DonutPlot}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Events-CoPt5zKa.js b/luci-app-honk/root/etc/honk/doona/assets/Events-CoPt5zKa.js new file mode 100644 index 000000000..c6323fc52 --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/Events-CoPt5zKa.js @@ -0,0 +1,2 @@ +import{r as h,j as n}from"./vendor-react-Bf71BWbF.js";import{a4 as g,eq as j,er as b,aw as y,h as v,bD as E,bG as L,u as k,a6 as T,a as N,aa as H,es as _,bg as D,et as K,eu as M,ev as R,ew as S,aL as p,bw as C,aK as F,L as O,bt as W,aJ as A,B,aM as I,E as J}from"./index-Bw0aJc9a.js";import{D as P}from"./Table-Km6Zv-S8.js";import{d as V,e as q}from"./files-BxEOxSF8.js";import"./useGridSelectionCheckbox-COXIVEmS.js";import"./Virtualizer-DCY9HC9Z.js";import"./ListLayout-_fDlx5XY.js";const w={buffer_overflow:["event.gap.overflow","event.gapHelp.overflow"],evicted:["event.gap.evicted","event.gapHelp.evicted"]};function G(e,t){const r=e.event==="flow.gap"&&Object.hasOwn(w,e.data.reason)?w[e.data.reason]:void 0;return r&&{title:t(r[0]),text:t(r[1])}}function z(e,t){const r=l=>l?[{id:"flow",label:t("event.viewFlow"),href:v("flows",{tab:"records",id:l})}]:[];switch(e.event){case"flow.updated":return r(e.data.resource_id);case"flow.gap":return[...r(e.data.resource_id),{id:"recording",label:t("ui.recordingSettings"),href:E}];case"generation.changed":return[{id:"config",label:t("event.viewConfig"),href:v("config")}];default:return[]}}const x=new WeakMap;function Q(e,t,r,l){const s=x.get(e);if(s&&s.locale===t)return s.row;const i=l?{key:"event.lostHistory"}:j(e,r),o={id:e.id,timestamp:y(e.data.observed_at,t),iso:e.data.observed_at,kind:e.event,kindText:g(b,e.event,r),summary:r(i.key,i.params),help:G(e,r),links:z(e,r)};return x.set(e,{locale:t,row:o}),o}function U(e,t,r,l,s,i,o,u,a=!1,c=()=>!1){const m=t==="without-runtime"||u.includes(t)?t:"all",f=e.filter(d=>m==="all"||(m==="without-runtime"?d.event!=="runtime.updated":d.event===m)).slice(0,s);return{kind:m,rows:f.map(d=>Q(d,i,o,c(d))),kinds:[{id:"without-runtime",label:o("event.withoutRuntime")},{id:"all",label:o("event.allKinds")},...u.map(d=>({id:d,label:g(b,d,o)}))],status:a&&l!==!1?{tone:"err",text:o("event.disconnected")}:{tone:r?"ok":l===null?"muted":"warn",text:o(l===!1?"event.unavailable":r?"event.connected":l===null?"ui.loading":"event.reconnecting")},limitText:o("event.limit",{n:s}),shown:f}}function X(e){return JSON.stringify(e,null,2)+` +`}function Y(){const e=L(),t=k(),r=T[N()],s=H().data?.resources.events.kinds,[i,o]=h.useState("without-runtime"),u=i!=="all"&&i!=="runtime.updated"&&s?.includes(i),a=_(i!=="without-runtime"&&!u),c=h.useMemo(()=>U(a.events,i,a.connected,a.available,S,r,t,s??[],!!a.error,R),[a.events,i,a.connected,a.available,a.error,r,t,s]);return D(c.kind,o),{...c,setKind:o,cursor:a.cursor,error:a.error,retry:()=>void K().then(()=>M(e)),loading:!a.error&&!a.connected&&a.available!==!1&&!a.events.length,export:()=>V(q("doona-events","json"),X(c.shown),"application/json")}}function ae(){const e=k(),t=Y(),r=h.useMemo(()=>[{id:"t",label:e("ui.time"),minWidth:200,grow:0,drop:1,render:s=>n.jsx(p,{className:"rp-code",text:s.iso,children:s.timestamp})},{id:"k",label:e("event.kind"),minWidth:168,drop:2,render:s=>n.jsx(p,{text:s.kind,children:s.kindText})},{id:"m",label:e("event.summary"),minWidth:240,isRowHeader:!0,render:s=>n.jsx(C,{fill:!0,help:s.help,children:n.jsx(p,{children:s.summary})})}],[e]),l=h.useCallback(s=>n.jsxs(n.Fragment,{children:[n.jsx(F,{inline:!0,items:[[e("ui.time"),s.timestamp],[e("event.kind"),s.kindText],[e("event.summary"),s.summary]]}),s.links.length>0&&n.jsx("div",{className:"rp-cluster",children:s.links.map(i=>n.jsx(O,{appearance:"button",small:!0,href:i.href,children:i.label},i.id))})]}),[e]);return n.jsxs("div",{className:"rp-page",children:[n.jsxs("div",{className:"rp-toolbar",children:[n.jsx(W,{label:e("event.kind"),side:!0,value:t.kind,onChange:t.setKind,items:t.kinds}),n.jsx(A,{small:!0,tone:t.status.tone,children:t.status.text}),t.cursor&&n.jsx(p,{text:t.cursor,children:n.jsx("span",{className:"rp-label",children:e("event.cursor")})}),n.jsx("span",{className:"rp-label",children:t.limitText}),n.jsx("span",{className:"rp-grow"}),n.jsxs(B,{isDisabled:!t.rows.length,onPress:t.export,children:[n.jsx(I,{}),e("event.export")]})]}),t.error&&n.jsx(J,{error:t.error,onRetry:t.retry}),n.jsx(P,{label:e("nav.events"),stream:!0,fit:!0,height:442,loading:t.loading,rows:t.rows,empty:e("event.empty"),cols:r,detail:l})]})}export{ae as Events}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Events-M5fPrUeR.js b/luci-app-honk/root/etc/honk/doona/assets/Events-M5fPrUeR.js deleted file mode 100644 index 7da716b87..000000000 --- a/luci-app-honk/root/etc/honk/doona/assets/Events-M5fPrUeR.js +++ /dev/null @@ -1,2 +0,0 @@ -import{r as v,j as n}from"./vendor-react-Bf71BWbF.js";import{a3 as b,dH as k,dI as f,at as j,bs as y,u as g,a5 as E,a as T,a8 as L,dJ as N,bf as H,dK as K,dL as M,dM as R,dN as D,aH as p,bq as _,aG as C,b5 as F,aF as I,B as O,aI as S,E as W}from"./index-BNBwb-FJ.js";import{D as A}from"./Table-DyWJelc_.js";import{d as B,e as J}from"./files-BxEOxSF8.js";import"./useGridSelectionCheckbox-CrCOlZv8.js";import"./Virtualizer-DipGMcji.js";import"./ListLayout-F74Z1Dpf.js";const h={buffer_overflow:["event.gap.overflow","event.gapHelp.overflow"],evicted:["event.gap.evicted","event.gapHelp.evicted"]};function P(e,t){const a=e.event==="flow.gap"&&Object.hasOwn(h,e.data.reason)?h[e.data.reason]:void 0;return a&&{title:t(a[0]),text:t(a[1])}}const w=new WeakMap;function V(e,t,a,l){const s=w.get(e);if(s&&s.locale===t)return s.row;const o=l?{key:"event.lostHistory"}:k(e,a),i={id:e.id,timestamp:j(e.data.observed_at,t),iso:e.data.observed_at,kind:e.event,kindText:b(f,e.event,a),summary:a(o.key,o.params),help:P(e,a)};return w.set(e,{locale:t,row:i}),i}function q(e,t,a,l,s,o,i,c,r=!1,u=()=>!1){const m=t==="without-runtime"||c.includes(t)?t:"all",x=e.filter(d=>m==="all"||(m==="without-runtime"?d.event!=="runtime.updated":d.event===m)).slice(0,s);return{kind:m,rows:x.map(d=>V(d,o,i,u(d))),kinds:[{id:"without-runtime",label:i("event.withoutRuntime")},{id:"all",label:i("event.allKinds")},...c.map(d=>({id:d,label:b(f,d,i)}))],status:r&&l!==!1?{tone:"err",text:i("event.disconnected")}:{tone:a?"ok":l===null?"muted":"warn",text:i(l===!1?"event.unavailable":a?"event.connected":l===null?"ui.loading":"event.reconnecting")},limitText:i("event.limit",{n:s}),shown:x}}function G(e){return JSON.stringify(e,null,2)+` -`}function z(){const e=y(),t=g(),a=E[T()],s=L().data?.resources.events.kinds,[o,i]=v.useState("without-runtime"),c=o!=="all"&&o!=="runtime.updated"&&s?.includes(o),r=N(o!=="without-runtime"&&!c),u=v.useMemo(()=>q(r.events,o,r.connected,r.available,D,a,t,s??[],!!r.error,R),[r.events,o,r.connected,r.available,r.error,a,t,s]);return H(u.kind,i),{...u,setKind:i,cursor:r.cursor,error:r.error,retry:()=>void K().then(()=>M(e)),loading:!r.error&&!r.connected&&r.available!==!1&&!r.events.length,export:()=>B(J("doona-events","json"),G(u.shown),"application/json")}}function te(){const e=g(),t=z(),a=v.useMemo(()=>[{id:"t",label:e("ui.time"),minWidth:200,grow:0,drop:1,render:s=>n.jsx(p,{className:"rp-code",text:s.iso,children:s.timestamp})},{id:"k",label:e("event.kind"),minWidth:168,drop:2,render:s=>n.jsx(p,{text:s.kind,children:s.kindText})},{id:"m",label:e("event.summary"),minWidth:240,isRowHeader:!0,render:s=>n.jsx(_,{fill:!0,help:s.help,children:n.jsx(p,{children:s.summary})})}],[e]),l=v.useCallback(s=>n.jsx(C,{inline:!0,items:[[e("ui.time"),s.timestamp],[e("event.kind"),s.kindText],[e("event.summary"),s.summary]]}),[e]);return n.jsxs("div",{className:"rp-page",children:[n.jsxs("div",{className:"rp-toolbar",children:[n.jsx(F,{label:e("event.kind"),side:!0,value:t.kind,onChange:t.setKind,items:t.kinds}),n.jsx(I,{small:!0,tone:t.status.tone,children:t.status.text}),t.cursor&&n.jsx(p,{text:t.cursor,children:n.jsx("span",{className:"rp-label",children:e("event.cursor")})}),n.jsx("span",{className:"rp-label",children:t.limitText}),n.jsx("span",{className:"rp-grow"}),n.jsxs(O,{isDisabled:!t.rows.length,onPress:t.export,children:[n.jsx(S,{}),e("event.export")]})]}),t.error&&n.jsx(W,{error:t.error,onRetry:t.retry}),n.jsx(A,{label:e("nav.events"),stream:!0,fit:!0,height:442,loading:t.loading,rows:t.rows,empty:e("event.empty"),cols:a,detail:l})]})}export{te as Events}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/FactStrip-n2q1T87k.js b/luci-app-honk/root/etc/honk/doona/assets/FactStrip-DtkOGBRy.js similarity index 82% rename from luci-app-honk/root/etc/honk/doona/assets/FactStrip-n2q1T87k.js rename to luci-app-honk/root/etc/honk/doona/assets/FactStrip-DtkOGBRy.js index 14d5843db..7167139ae 100644 --- a/luci-app-honk/root/etc/honk/doona/assets/FactStrip-n2q1T87k.js +++ b/luci-app-honk/root/etc/honk/doona/assets/FactStrip-DtkOGBRy.js @@ -1 +1 @@ -import{j as s}from"./vendor-react-Bf71BWbF.js";import{aH as t}from"./index-BNBwb-FJ.js";function p({facts:l,lead:r}){return l.length?s.jsx("dl",{className:"rp-strip rp-facts"+(r?" rp-facts-lead":""),style:{"--facts":l.length,"--facts-rest":l.length-1},children:l.map((e,i)=>s.jsxs("div",{className:"rp-card"+(e.tone?" "+e.tone:""),children:[s.jsxs("dt",{className:"rp-tile-head"+(e.tint?" rp-tint-"+e.tint:""),children:[e.icon,e.label]}),s.jsxs("dd",{className:"rp-tile-body",children:[r&&i===0?s.jsx(t,{className:"rp-big",cut:"start",children:e.value}):s.jsx("span",{className:"rp-big",title:e.value,children:e.value}),e.caption&&s.jsx("span",{className:"rp-fact-caption",title:e.caption,children:e.caption})]})]},e.label))}):null}export{p as F}; +import{j as s}from"./vendor-react-Bf71BWbF.js";import{aL as t}from"./index-Bw0aJc9a.js";function p({facts:l,lead:r}){return l.length?s.jsx("dl",{className:"rp-strip rp-facts"+(r?" rp-facts-lead":""),style:{"--facts":l.length,"--facts-rest":l.length-1},children:l.map((e,i)=>s.jsxs("div",{className:"rp-card"+(e.tone?" "+e.tone:""),children:[s.jsxs("dt",{className:"rp-tile-head"+(e.tint?" rp-tint-"+e.tint:""),children:[e.icon,e.label]}),s.jsxs("dd",{className:"rp-tile-body",children:[r&&i===0?s.jsx(t,{className:"rp-big",cut:"start",children:e.value}):s.jsx("span",{className:"rp-big",title:e.value,children:e.value}),e.caption&&s.jsx("span",{className:"rp-fact-caption",title:e.caption,children:e.caption})]})]},e.label))}):null}export{p as F}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Flows-CFBMKQ6x.js b/luci-app-honk/root/etc/honk/doona/assets/Flows-CFBMKQ6x.js new file mode 100644 index 000000000..4b83d0f50 --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/Flows-CFBMKQ6x.js @@ -0,0 +1 @@ +import{r as b,j as l}from"./vendor-react-Bf71BWbF.js";import{bl as we,by as xe,Z as K,b0 as ve,bz as ye,bA as je,bc as ke,bk as _e,bj as Me,a0 as T,b4 as F,a4 as $,b8 as Le,b9 as Ne,a6 as ie,aw as Te,h as Se,aX as Z,a3 as J,bB as Re,a_ as Ce,a5 as Pe,u as C,a as ce,aU as Ie,B as R,bC as Oe,c as te,aO as z,aa as Y,ac as O,ae as Fe,ad as Ee,f as He,bp as De,bD as $e,bh as We,j as q,E as A,bx as Be,aL as V,bb as Ae,b3 as Ue,bs as de,bt as Ve,aj as ne,L as se,bv as Qe,aK as ae,ak as ue,aN as Ge}from"./index-Bw0aJc9a.js";import{w as L}from"./labels-Bgu_ZhL8.js";import{c as Ke,C as Je}from"./Coverage-DhDWz2sB.js";import{g as ze}from"./policyText-CltaDVEo.js";import{f as Xe}from"./nav-CS6FFQFP.js";import{D as Ze}from"./Table-Km6Zv-S8.js";import{T as Ye}from"./TimeCell-DKHUJpad.js";import{b as fe,u as me,c as qe}from"./flows-D3eabARZ.js";import{u as et}from"./outbounds-DMhWS-9H.js";import{u as tt,R as nt}from"./useQuickRule-BmFeKwTA.js";import"./useGridSelectionCheckbox-COXIVEmS.js";import"./Virtualizer-DCY9HC9Z.js";import"./ListLayout-_fDlx5XY.js";import"./DaeCode-B8yPDjSE.js";const st=["client","rule","outbound","node"],at=e=>new Map(e.map(t=>[t.id,t.name])),X="\0";function ot(e,t){if(e.rule_id)return e.rule_generation_id!==null&&e.rule_generation_id===t?e.rule_id:e.rule_id+X+e.rule_expression}function pe(e,t,n,r){switch(t){case"client":{const a=K(e.input?.src??void 0);return{label:a??"unknown",unknown:!a}}case"rule":return e.rule_expression?{label:e.rule_expression,unknown:!1,key:ot(e,r)}:{label:"unknown",unknown:!0};case"outbound":return e.outbound?{label:e.outbound,unknown:!1}:{label:"unknown",unknown:!0};case"node":{if(xe(e.outbound))return null;const a=e.chain.at(-1)??null;return a?{label:n.get(a)??a,unknown:!1,key:a}:{label:"unknown",unknown:!0}}}}const W=(e,t)=>ve(e,t.unknown?"":t.key??t.label),ge=e=>we(e,st)?.kind,rt=new Map;function he(e,t,n){const r=ge(t);return r?e.filter(a=>{const s=pe(a,r,rt,n?.generation_id);return s!==null&&W(r,s)===t}):[]}function lt(e,t,n,r){const a=e.slice(0,e.indexOf(":")),s=e.slice(e.indexOf(":")+1);return s===""?r(null):a==="rule"?s.includes(X)?s.slice(s.indexOf(X)+1):t.find(c=>c.rule_id===s)?.expression??s:a==="node"?n.get(s)??s:a==="client"?s:r(s)}function it(e,t,n,r,a="rule"){const s=at(n),c=new Map(t.map(d=>[d.id,d])),i=new Map(t.map(d=>[d.name,d])),o=new Map(n.map(d=>[d.id,d])),m=new Map,w=new Map,f=new Map,p=new Map,v=(d,g)=>{const x=d+">"+g;let u=p.get(x);return u||p.set(x,u={source:d,target:g,count:0}),u},j=(d,g,x=!1)=>{const u=W("node",{key:d,label:g,unknown:x});let N=f.get(u);if(!N){const E=x?void 0:o.get(d),H=E&&je(E);f.set(u,N={id:u,label:g,count:0,unknown:x||void 0,latency:ke(H),unavailable:H?.state==="unavailable"})}return N},_=(d,g=!1)=>{const x=W("outbound",{label:d,unknown:g});let u=w.get(x);if(u)return u;const N=g?void 0:i.get(d),E=g?{groups:[],member:null}:ye(d,N?.selection.tcp_member_id?"tcp":"udp",i,c,o),H=E.groups.map(U=>({name:U.name,kind:U.policy.kind,policy:U.policy.native})),B=E.member,be=g?"unknown":d==="direct"||d==="block"?d:H.length?"group":"unknown";return u={id:x,label:d,count:0,unknown:g||void 0,kind:be,groups:H,node:B&&j(B,s.get(B)??B).id},w.set(x,u),u.node&&v(x,u.node),u},h=(d,g,x=!1)=>{let u=m.get(d);return u||m.set(d,u={id:d,label:g,count:0,unknown:x||void 0,outbound:null,must:!1,fallback:!1}),u};if(a==="rule")for(const d of r?.rules??[]){const g=h(W("rule",{key:d.rule_id,label:d.expression}),d.expression);g.must=d.must,g.fallback=d.kind==="fallback",d.outbound&&(g.outbound=_(d.outbound).id,v(g.id,g.outbound))}const k=[a,"outbound","node"];for(const d of e){let g;for(const x of k){const u=pe(d,x,s,r?.generation_id);if(!u)break;const N=x==="outbound"?_(u.label,u.unknown):x==="node"?j(u.key??u.label,u.label,u.unknown):h(W(x,u),u.label,u.unknown);N.count++,g&&v(g.id,N.id).count++,g=N}}for(const d of t)_(d.name);const M=new Set([...m.values()].map(d=>d.outbound)),P=new Set([...w.values()].flatMap(d=>d.groups.slice(1).map(g=>g.name))),y=[...w.values()].filter(d=>d.count||M.has(d.id)||!P.has(d.label)),S=new Set(y.map(d=>d.id));return{by:a,leaves:[...m.values()],outbounds:y,nodes:[...f.values()],links:[...p.values()].filter(d=>S.has(d.source)||S.has(d.target))}}const oe=new WeakMap;function ee(e){const t=oe.get(e);if(t)return t;const n=new Map,r=new Map,a=new Map;for(const i of e.links){for(const[o,m]of[[n,i.source],[r,i.target]]){let w=o.get(m);w||o.set(m,w=[]),w.push(i)}(!a.has(i.source)||a.get(i.source).count{const o=r.get(i)??[];if(!o.length){t.set(i,n++);return}for(const m of o)s(m);t.set(i,(t.get(o[0])+t.get(o[o.length-1]))/2)},c=new Set;for(const i of e.outbounds)c.add(a.get(i.id)??i.id);for(const i of e.nodes)c.add(i.id);for(const i of e.leaves)a.has(i.id)||c.add(i.id);for(const i of c)s(i);return{rows:n,at:t}}function dt(e,t){const n=new Set([t]),r=new Set;for(const[a,s]of[[e.outgoing,"target"],[e.incoming,"source"]]){const c=[t];for(const i of c)for(const o of a.get(i)??[])r.has(o)||(r.add(o),n.has(o[s])||(n.add(o[s]),c.push(o[s])))}return{items:n,edges:r}}const ut={not_instrumented:"flow.m.notInstrumented",started_late:"flow.m.startedLate",buffer_overflow:"flow.m.bufferOverflow",sampled:"flow.m.sampled",redacted:"flow.m.redacted",evicted:"flow.m.evicted"},ft={src:"ui.device",dst:"conn.f.dst",domain:"ui.domain",domain_source:"conn.f.domainSource",ingress:"conn.f.ingress",pname:"ui.process",network:"ui.protocol",dscp:"DSCP",mark:"fwmark",uid:"UID",pid:"PID"},re=e=>e==null?"—":{key:e?"ui.yes":"ui.no"};function mt(e){const t=n=>n==null?"—":typeof n=="object"?JSON.stringify(n):String(n);switch(e.stage){case"input":return Object.entries(e.data.values).filter(([,n])=>n!=null&&n!=="").map(([n,r])=>{const a=ft[n];return[a===void 0||!a.includes(".")?{key:"flow.f.input",params:{name:a??n}}:a,typeof r=="string"&&(n==="ingress"||n==="domain_source")?L(r):t(r)]});case"route":return[["flow.f.chain",e.data.chain],["flow.f.plane",L(e.data.plane)],["ui.rule",e.data.rules.filter(n=>n.result==="matched").map(n=>n.expression??n.rule_id).join(", ")||"—"],["ui.outbound",t(e.data.outbound)],["flow.f.must",re(e.data.must)]];case"dial_mode":return[["flow.f.dialTarget",e.data.configured+" → "+e.data.effective_target],["flow.f.verification",L(e.data.verification)]];case"dns":return[["ui.name",e.data.name],["flow.f.source",L(e.data.source)],["flow.f.cache",L(e.data.cache)],["ui.upstream",t(e.data.upstream)],["flow.f.selectedIp",t(e.data.selected_ip)]];case"outbound":return[["ui.outbound",t(e.data.routed_outbound)+" → "+t(e.data.effective_outbound)],["flow.f.selectionPath",e.data.selection_path.map(n=>n.group_id+" → "+t(n.member_name??n.member_id)).join(" / ")||"—"],["flow.f.leafNode",t(e.data.leaf_node_id)],["ui.target",t(e.data.target)],["ui.state",L(e.data.status)]];case"connection":return[["ui.state",Object.hasOwn(F,e.data.state)?{key:F[e.data.state]}:e.data.state],["flow.f.milestone",L(e.data.milestone)],["flow.f.reason",L(e.data.reason)]];case"datapath":return[["flow.f.plane",L(e.data.plane)],["flow.f.action",L(e.data.action)],["flow.f.reason",L(e.data.reason)]];case"reroute":return[["flow.f.performed",re(e.data.performed)],["flow.f.reason",L(e.data.reason)]];default:return null}}function pt(e,t,n){const r=(o,m)=>o.unknown?t("flow.mapUnknown"):m,a=[...e.leaves.map(o=>({id:o.id,stage:e.by,name:r(o,o.label),badge:o.must?"must":void 0,notes:[],count:o.count})),...e.outbounds.map(o=>({id:o.id,stage:"outbound",name:r(o,Z(o.label,t)),notes:[...o.groups.slice(1).map(m=>({text:"› "+m.name})),...o.groups.slice(-1).map(m=>({text:ze({kind:m.kind,native:m.policy},t).label})),...o.kind==="group"&&!o.node?[{text:t("flow.treeNoNode")}]:[]],count:o.count})),...e.nodes.map(o=>({id:o.id,stage:"node",name:r(o,o.label),notes:o.latency!=null?[{text:Ce(o.latency,t),tone:Re(o.latency)}]:o.unavailable?[{text:t("ui.unavailable"),tone:"err"}]:[],count:o.count}))],s=new Map(a.map(o=>[o.id,o.name])),{outgoing:c,incoming:i}=ee(e);return a.map(o=>{const m=(c.get(o.id)??[]).map(p=>s.get(p.target)),w=o.stage==="node"?(i.get(o.id)??[]).map(p=>s.get(p.source)):[],f=[o.name,...o.badge?[o.badge]:[],...o.notes.map(p=>p.text),t("flow.treeFlows",{n:o.count})];return w.length&&f.push(t("flow.treeFrom",{names:J(n,w)})),m.length&&f.push(t("flow.treeTo",{names:J(n,m)})),{...o,countText:Pe(o.count,ie[n]),label:f.join(t("ui.separator"))}})}function gt(e,t,n,r,a,s){return{tree:e,state:t?!e.leaves.length&&!e.outbounds.length?"empty":"ready":n?"error":"loading",pinLabel:r?s("flow.viewPinned",{n:a}):null}}const ht={input:"flow.stage.input",route:"flow.stage.route",dial_mode:"flow.stage.dialMode",dns:"flow.stage.dns",outbound:"flow.stage.outbound",connection:"flow.stage.connection",datapath:"flow.stage.datapath",reroute:"flow.stage.reroute"},bt={complete:"flow.status.complete",partial:"flow.status.partial",disabled:"flow.status.disabled"};function wt(e,t,n,r,a,s){return{rows:e.map(c=>({id:c.id,target:c.input?.domain||c.input?.dst||c.id,node:Ne(c,a,r),path:Le(c,a,r),expression:c.rule_expression,ruleId:c.rule_generation_id!==null&&c.rule_generation_id===n?c.rule_id:null,recomputed:c.rule_source==="recomputed",network:c.network.toUpperCase(),state:$(F,c.state,a),startedAt:c.started_at})),coverage:t?Ke(t,a,s):null,stateOptions:[{id:"all",label:a("flow.allStates")},...Object.entries(F).map(([c,i])=>({id:c,label:a(i)}))]}}function xt(e,t,n,r){if(!e)return null;const a=ie[n];return{title:e.input.domain||e.input.dst||e.id,status:$(bt,e.trace.status,t),tone:e.trace.status==="complete"?void 0:"warn",revision:t("flow.revision",{n:e.revision}),fields:[[t("ui.state"),$(F,e.state,t)],[t("ui.outbound"),Z(e.outbound,t)],...r?[[t("conn.node"),r.path??r.node]]:[],...r?.expression?[[t("conn.rule"),r.expression]]:[],...e.trace.missing.length?[[t("flow.missing"),J(n,e.trace.missing.map(s=>$(ut,s,t)))]]:[]],connectionHref:e.connection_id?Se("connections",{id:e.connection_id}):null,seed:{domain:e.input.domain,dip:K(e.input.dst??void 0)??null,sip:K(e.input.src??void 0)??null,outbound:e.outbound,matched:e.rule_id&&e.rule_source!=="unknown"?{id:e.rule_id,expression:e.rule_expression}:null},steps:[...e.trace.steps].sort((s,c)=>s.seq-c.seq).map(s=>{const c=mt(s);return{id:s.seq,stage:$(ht,s.stage,t),observed:Te(s.observed_at,a),elapsed:s.elapsed_us==null?"—":t("ui.microseconds",{n:s.elapsed_us}),fields:c?.map(([i,o])=>[typeof i=="string"?t(i):t(i.key,i.params),typeof o=="string"?o:t(o.key,o.params)])??null,raw:c?"":JSON.stringify(s.data,null,2)}})}}const I=30,vt=720,D=44,Q=36,le=56,G=[5,4,3],yt={rule:0,client:0,outbound:1,node:2};function jt(e,t){return e.leaves.length<=t?e:{...e,leaves:e.leaves.slice(0,t)}}function kt(e,t,n,r){const a=t===null?void 0:Math.max(t,vt),s=((a??0)-2*le)/G.reduce((f,p)=>f+p),c=f=>{const p=yt[f];return{left:G.slice(0,p).reduce((v,j)=>v+j*s+le,0),width:G[p]*s}},i=ct(e),o=pt(e,n,r).map(f=>({view:f,style:{top:i.at.get(f.id)*D,...c(f.stage)}})),m=new Map(e.outbounds.map(f=>[f.id,f])),w=e.links.flatMap(f=>{if(!i.at.has(f.source)||!i.at.has(f.target))return[];const p=ge(f.source)==="outbound"?"outbound":e.by,v=c(p),j=v.left+v.width,_=c(p==="outbound"?"node":"outbound").left,h=i.at.get(f.source)*D+Q/2,k=i.at.get(f.target)*D+Q/2,M=(j+_)/2;return[{link:f,id:f.source+">"+f.target,path:`M${j},${h} C${M},${h} ${M},${k} ${_},${k}`,width:Math.min(8,1.5+Math.log2(1+f.count)*1.25),dash:f.count?void 0:"4 4",kind:p==="outbound"?"node":m.get(f.target)?.kind??"group"}]});return{width:a,height:i.rows*D-(D-Q),captions:[{stage:e.by,label:n(e.by==="rule"?"flow.mapRule":"flow.stageClient"),style:c(e.by)},{stage:"outbound",label:n("flow.mapOutbound"),style:c("outbound")},{stage:"node",label:n("flow.mapNode"),style:c("node")}],placed:o,geometry:w}}function _t(e,t,n){const r=Xe(e).map(s=>({id:s.id,label:n(s.titleKey)})),a=r[0]?.id??"map";return{tabs:r,tab:_e(t,r.map(s=>s.id),a),fallback:e?a:null}}function Mt(e,t,n){return Me(T(e,t==="map"?{id:null,connection_id:null}:{by:null}),t,n)}function Lt(e,t,n){const r=C(),a=ce(),[s,c]=b.useState(I),[i,o]=b.useState(null),[m,w]=Ie(),f=b.useMemo(()=>ee(e),[e]),p=b.useMemo(()=>jt(e,s),[e,s]),v=b.useMemo(()=>kt(p,w,r,a),[p,w,r,a]),j=b.useMemo(()=>new Set(v.placed.map(y=>y.view.id)),[v.placed]),_=b.useMemo(()=>new Set([...e.leaves,...e.outbounds,...e.nodes].map(y=>y.id)),[e]),h=i&&j.has(i)?i:t&&_.has(t)?t:null,k=b.useMemo(()=>h?dt(f,h):null,[f,h]);b.useEffect(()=>{if(!t)return;const y=S=>{S.key==="Escape"&&n(null)};return document.addEventListener("keydown",y),()=>document.removeEventListener("keydown",y)},[t,n]);const M=b.useRef(t);b.useLayoutEffect(()=>{M.current=t},[t]);const P=b.useCallback(y=>n(M.current===y?null:y),[n]);return{...v,ref:m,ready:v.width!==void 0,active:k,pinned:t,pin:P,hover:o,more:e.leaves.length>s?r("flow.treeShowMore",{n:Math.min(I,e.leaves.length-s)}):null,fewer:s>I?r("flow.treeFewer",{n:I}):null,showMore:()=>c(y=>Math.min(e.leaves.length,y+I)),showFewer:()=>c(I)}}const Nt=b.memo(function({view:t,style:n,dim:r,selected:a,pin:s,hover:c}){return l.jsxs(Oe,{"aria-label":t.label,className:te("rp-tree-tile",r&&"dim"),"data-id":t.id,"data-stage":t.stage,style:n,isSelected:a,onChange:()=>s(t.id),onHoverStart:()=>c(t.id),onHoverEnd:()=>c(null),onFocus:()=>c(t.id),onBlur:()=>c(null),children:[l.jsxs("span",{className:"l",children:[t.stage==="rule"||t.stage==="client"?t.name:l.jsx("b",{children:t.name}),t.notes.map((i,o)=>l.jsx("span",{className:te("s",i.tone),children:i.text},o))]}),t.badge&&l.jsx(z,{children:t.badge}),l.jsx("span",{className:"c",children:t.countText})]})});function Tt({tree:e,pinned:t,onPin:n}){const{ref:r,...a}=Lt(e,t,n);return l.jsxs("div",{className:"rp-tree",ref:r,children:[l.jsx("div",{className:"rp-tree-captions",style:{width:a.width},children:a.captions.map(s=>l.jsx("span",{className:"rp-label",style:s.style,children:s.label},s.stage))}),l.jsxs("div",{className:"rp-tree-canvas",style:{height:a.height,width:a.width},children:[a.ready&&l.jsx("svg",{className:"rp-tree-links",width:a.width,height:a.height,"aria-hidden":!0,children:a.geometry.map(s=>l.jsx("path",{d:s.path,strokeWidth:s.width,"data-kind":s.kind,"data-state":a.active?a.active.edges.has(s.link)?"active":"dim":void 0,strokeDasharray:s.dash},s.id))}),a.ready&&a.placed.map(({view:s,style:c})=>l.jsx(Nt,{view:s,style:c,dim:!!a.active&&!a.active.items.has(s.id),selected:a.pinned===s.id,pin:a.pin,hover:a.hover},s.id))]}),a.more&&l.jsx(R,{small:!0,quiet:!0,onPress:a.showMore,children:a.more}),a.fewer&&l.jsx(R,{small:!0,quiet:!0,onPress:a.showFewer,children:a.fewer})]})}function St({go:e,query:t}){const n=C(),r=new URLSearchParams(t),a=Y().data?.resources,s=fe({},O(a,"flows",{whileLoading:!0})),c=Fe(O(a,"groups",{whileLoading:!1})),i=Ee(O(a,"nodes",{whileLoading:!1})),o=me(O(a,"rules",{whileLoading:!1})),m=r.get("by")==="client"?"client":"rule",w=b.useMemo(()=>it(s.data?.flows??[],c.data??[],i.data??[],o.data,m),[s.data,c.data,i.data,o.data,m]),f=r.get("path"),p=b.useRef(t);b.useLayoutEffect(()=>{p.current=t},[t]);const v=b.useCallback(h=>e("flows",T(p.current,{path:h})),[e]),j=b.useMemo(()=>f?he(s.data?.flows??[],f,o.data).length:0,[s.data,f,o.data]),_=[s,o,c,i].every(h=>h.data!==void 0||h.error||!h.loading);return{...gt(w,_&&!!(s.data||o.data||c.data),!!s.error,f,j,n),by:m,pinned:f,error:s.error??c.error??i.error??o.error,retry:()=>{s.refetch(),c.refetch(),i.refetch(),o.refetch()},pin:v,changeBy:h=>e("flows",T(t,{by:h==="client"?"client":null,path:null})),viewPinned:()=>e("flows",T(t,{tab:"records"}))}}function Rt({go:e,query:t}){const n=C(),r=ce(),a=He(De),s=b.useMemo(()=>new URLSearchParams(t),[t]),c=s.get("network"),i=c==="tcp"||c==="udp"?c:"all",o=s.get("state")??"",m=Object.hasOwn(F,o)?o:"all",w=s.get("connection_id")??void 0,f=Y().data?.resources,p=fe({connection_id:w,network:i,state:m},O(f,"flows",{whileLoading:!0})),v=O(f,"rules",{whileLoading:!1}),j=me(v),_=et(),h=s.get("id"),k=qe(h),M=s.get("path"),P=b.useMemo(()=>{const u=p.data?.flows??[];return M?he(u,M,j.data):u},[p.data,M,j.data]),y=j.data?.generation_id,S=b.useMemo(()=>wt(P,p.data,y,_,n,r),[P,p.data,y,_,n,r]),d=S.rows.find(u=>u.id===h),g=b.useMemo(()=>xt(k.data??void 0,n,r,d),[k.data,n,r,d]),x=tt(e);return{...S,detail:g,rule:{canAdd:!!g&&x.canAdd(g.seed),open:()=>{g&&x.open(g.seed)},dialog:x.dialog},network:i,setNetwork:u=>e("flows",T(t,{network:u==="all"?null:u})),state:m,setState:u=>e("flows",T(t,{state:u==="all"?null:u})),wide:a,id:h,rulesListed:v,error:p.error,retry:p.refetch,loading:p.loading&&!p.data,panelOpen:!!h&&(!!k.data||k.loading||!!k.error),panelTitle:g?.title??h??"",detailError:k.error,detailRetry:k.refetch,detailLoading:!k.data&&k.loading,select:u=>e("flows",T(t,{id:u}),{replace:h!==null}),pinLabel:M?n("flow.mapFilter",{label:lt(M,j.data?.rules??[],_,u=>u===null?n("flow.mapUnknown"):Z(u,n))}):null,clearPin:()=>e("flows",T(t,{path:null})),connectionLabel:w?n("flow.connectionFilter",{connectionId:w}):null,clearConnection:()=>e("flows",T(t,{connection_id:null})),recordingHref:f?.runtime_settings.available?$e:null}}function Ct({go:e,query:t}){const n=C(),r=Y(),a=_t(r.data?.resources,t,n);return We(r.data?.resources),{...a,loading:r.loading&&!r.data,error:r.error,retry:r.refetch,changeTab:s=>e("flows",Mt(t,s,a.fallback))}}function zt(e){const t=C(),n=Ct(e),r={map:l.jsx(Pt,{...e}),records:l.jsx(It,{...e})};return n.loading?l.jsx(q,{}):n.error?l.jsx(A,{error:n.error,onRetry:n.retry}):l.jsx("div",{className:"rp-page",children:l.jsx(Be,{label:t("nav.flows"),items:n.tabs.map(a=>({...a,content:r[a.id]})),value:n.tab,onChange:n.changeTab})})}function Pt(e){const t=C(),n=St(e);return l.jsxs("section",{className:"rp-col","aria-label":t("flow.map"),children:[l.jsx(A,{error:n.error,onRetry:n.retry}),l.jsxs(Ge,{title:t("flow.topology"),note:t("flow.topologyNote"),className:"rp-topology",aside:l.jsx(de,{label:t("flow.topology"),value:n.by,onChange:n.changeBy,items:[["rule",t("flow.byRule")],["client",t("flow.byClient")]]}),children:[n.state==="loading"&&l.jsx(q,{}),n.state==="empty"&&l.jsx(ue,{children:t("flow.mapEmpty")}),n.state==="ready"&&l.jsxs(l.Fragment,{children:[l.jsx("span",{className:"rp-tree-hint",children:t("flow.treePanHint")}),l.jsx(Tt,{tree:n.tree,pinned:n.pinned,onPin:n.pin})]})]}),n.pinLabel&&l.jsxs("div",{className:"rp-toolbar",children:[l.jsx(R,{small:!0,onPress:n.viewPinned,children:n.pinLabel}),l.jsx(R,{small:!0,quiet:!0,onPress:()=>n.pin(null),children:t("flow.clearMapFilter")})]})]})}function It(e){const t=C(),n=Rt(e),r=n.detail,a=b.useMemo(()=>[{id:"target",label:t("ui.target"),minWidth:128,grow:2,isRowHeader:!0,render:s=>l.jsx(V,{children:s.target})},{id:"node",label:t("conn.node"),minWidth:96,drop:2,render:s=>l.jsx(V,{className:"rp-chain",text:s.path??void 0,children:s.node})},{id:"rule",label:t("conn.rule"),minWidth:152,grow:2,drop:1,render:s=>l.jsxs("span",{className:"rp-rule",children:[l.jsx(Ae,{expression:s.expression,href:Ue(s.ruleId,n.rulesListed)}),s.recomputed&&l.jsx("small",{className:"rp-provenance",children:t("conn.recomputed")})]})},{id:"network",label:t("ui.protocol"),minWidth:64,grow:0,drop:3,render:s=>s.network},{id:"state",label:t("ui.state"),minWidth:80,grow:0,drop:5,render:s=>s.state},{id:"started",label:t("ui.started"),minWidth:80,grow:0,drop:4,render:s=>l.jsx(Ye,{at:s.startedAt})}],[t,n.rulesListed]);return l.jsxs(l.Fragment,{children:[l.jsx(A,{error:n.error,onRetry:n.retry}),l.jsxs("div",{className:"rp-toolbar",children:[l.jsx(de,{label:t("ui.network"),value:n.network,onChange:n.setNetwork,items:[["all",t("ui.all")],["tcp",t("ui.tcp")],["udp",t("ui.udp")]]}),l.jsx(Ve,{label:t("ui.state"),side:!0,value:n.state,onChange:n.setState,items:n.stateOptions}),n.pinLabel&&l.jsxs(R,{small:!0,label:t("ui.valuePair",{label:t("flow.clearMapFilter"),value:n.pinLabel}),onPress:n.clearPin,children:[n.pinLabel,l.jsx(ne,{})]}),n.connectionLabel&&l.jsxs(R,{small:!0,label:t("ui.valuePair",{label:t("flow.clearConnectionFilter"),value:n.connectionLabel}),onPress:n.clearConnection,children:[n.connectionLabel,l.jsx(ne,{})]}),n.coverage&&l.jsx(Je,{view:n.coverage}),n.recordingHref&&l.jsxs(l.Fragment,{children:[l.jsx("span",{className:"rp-grow"}),l.jsx(se,{appearance:"button",quiet:!0,small:!0,href:n.recordingHref,children:t("ui.recordingSettings")})]})]}),l.jsxs("div",{className:"rp-with-panel","data-open":n.panelOpen?"":void 0,children:[l.jsx(Ze,{label:t("flow.records"),rowDetail:!0,loading:n.loading,rows:n.rows,height:442,selected:n.id,onSelect:n.select,selectOnFocus:n.wide,empty:t("flow.empty"),cols:a}),l.jsxs(Qe,{open:n.panelOpen,title:n.panelTitle,onClose:()=>n.select(null),children:[l.jsx(A,{error:n.detailError,onRetry:n.detailRetry}),n.detailLoading&&l.jsx(q,{children:t("flow.detailLoading")}),r&&l.jsxs(l.Fragment,{children:[l.jsxs("div",{className:"rp-cluster",children:[l.jsx(z,{tone:r.tone,children:r.status}),l.jsx("span",{className:"rp-label",children:r.revision})]}),l.jsx(ae,{inline:!0,items:r.fields}),l.jsxs("div",{className:"rp-cluster",children:[r.connectionHref&&l.jsx(se,{appearance:"button",small:!0,href:r.connectionHref,children:t("flow.viewConnection")}),n.rule.canAdd&&l.jsx(R,{small:!0,onPress:n.rule.open,children:t("flow.addRule")})]}),l.jsxs("div",{className:"rp-list",children:[!r.steps.length&&l.jsx(ue,{children:t("ui.empty")}),r.steps.map(s=>l.jsxs("div",{className:"rp-col rp-step",children:[l.jsxs("div",{className:"rp-cluster",children:[l.jsx(z,{children:s.stage}),l.jsx(V,{text:s.observed,className:"rp-label",children:s.elapsed})]}),s.fields?l.jsx(ae,{inline:!0,items:s.fields}):l.jsx("pre",{className:"rp-flow-raw rp-code",children:l.jsx("code",{children:s.raw})})]},s.id))]})]})]})]}),l.jsx(nt,{dialog:n.rule.dialog})]})}export{zt as Flows}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Rules-l5FnUA9B.css b/luci-app-honk/root/etc/honk/doona/assets/Flows-l5FnUA9B.css similarity index 100% rename from luci-app-honk/root/etc/honk/doona/assets/Rules-l5FnUA9B.css rename to luci-app-honk/root/etc/honk/doona/assets/Flows-l5FnUA9B.css diff --git a/luci-app-honk/root/etc/honk/doona/assets/ListLayout-F74Z1Dpf.js b/luci-app-honk/root/etc/honk/doona/assets/ListLayout-_fDlx5XY.js similarity index 98% rename from luci-app-honk/root/etc/honk/doona/assets/ListLayout-F74Z1Dpf.js rename to luci-app-honk/root/etc/honk/doona/assets/ListLayout-_fDlx5XY.js index 446376a42..8db665464 100644 --- a/luci-app-honk/root/etc/honk/doona/assets/ListLayout-F74Z1Dpf.js +++ b/luci-app-honk/root/etc/honk/doona/assets/ListLayout-_fDlx5XY.js @@ -1 +1 @@ -import{en as v}from"./index-BNBwb-FJ.js";import{$ as R,c,a as S,b as p}from"./Virtualizer-DipGMcji.js";const f=48;class N extends R{constructor(t={}){super(),this.rowSize=t?.rowSize??t?.rowHeight??null,this.orientation=t.orientation??"vertical",this.estimatedRowSize=t?.estimatedRowSize??t?.estimatedRowHeight??null,this.headingSize=t?.headingSize??t?.headingHeight??null,this.estimatedHeadingSize=t?.estimatedHeadingSize??t?.estimatedHeadingHeight??null,this.loaderSize=t?.loaderSize??t?.loaderHeight??null,this.dropIndicatorThickness=t.dropIndicatorThickness||2,this.gap=t.gap||0,this.padding=t.padding||0,this.layoutNodes=new Map,this.rootNodes=[],this.lastCollection=null,this.invalidateEverything=!1,this.validRect=new c,this.requestedRect=new c,this.contentSize=new S}get collection(){return this.virtualizer.collection}get rowHeight(){return this.rowSize}get estimatedRowHeight(){return this.estimatedRowSize}get headingHeight(){return this.headingSize}get estimatedHeadingHeight(){return this.estimatedHeadingSize}get loaderHeight(){return this.loaderSize}getLayoutInfo(t){return this.ensureLayoutInfo(t),this.layoutNodes.get(t)?.layoutInfo||null}getVisibleLayoutInfos(t){let e=this.orientation==="horizontal"?"x":"y",i=this.orientation==="horizontal"?"width":"height";if(t[i]>1){let s=(this.rowSize??this.estimatedRowSize??f)+this.gap;t=t.copy();let o=Math.floor(t[e]/s)*s,l=t[i]+t[e]-o;t[e]=o,t[i]=Math.ceil(l/s)*s}this.layoutIfNeeded(t);let r=[],h=s=>{for(let o of s)this.isVisible(o,t)&&(r.push(o.layoutInfo),o.children&&h(o.children))};return h(this.rootNodes),r}layoutIfNeeded(t){if(this.lastCollection){this.requestedRect.containsRect(t)||(this.requestedRect=this.requestedRect.union(t),this.rootNodes=this.buildCollection());for(let e of this.virtualizer.persistedKeys)if(this.ensureLayoutInfo(e))return}}ensureLayoutInfo(t){return!this.layoutNodes.has(t)&&this.requestedRect.areaa.type!=="content"),s=h.filter(a=>a.type==="loader"),o=[],l=e?.size===0;l&&(t=0);for(let a of h){let n=(this.rowSize??this.estimatedRowSize??f)+this.gap;if(a.type==="item"&&t+nthis.requestedRect[r]){let u=h.indexOf(a);for(let y of s){let g=h.indexOf(y);t+=(g-u-1)*n;let z=this.orientation==="horizontal"?this.buildChild(y,t,this.padding,null):this.buildChild(y,this.padding,t,null);o.push(z),t=z.layoutInfo.rect[r],u=g}t+=(h.length-u-1)*n;break}}return t=Math.max(t-this.gap,0),t+=l?0:this.padding,this.contentSize=this.orientation==="horizontal"?new S(t,this.virtualizer.size.height):new S(this.virtualizer.size.width,t),o}isValid(t,e){let i=this.layoutNodes.get(t.key),r=this.orientation==="horizontal"?"x":"y";return!this.invalidateEverything&&!!i&&i.node===t&&e===i.layoutInfo.rect[r]&&i.layoutInfo.rect.intersects(this.validRect)&&i.validRect.containsRect(i.layoutInfo.rect.intersection(this.requestedRect))}buildChild(t,e,i,r){if(this.isValid(t,this.orientation==="horizontal"?e:i))return this.layoutNodes.get(t.key);let h=this.buildNode(t,e,i);return h.layoutInfo.parentKey=r??null,h.layoutInfo.allowOverflow=!0,this.layoutNodes.set(t.key,h),h}buildNode(t,e,i){switch(t.type){case"section":return this.buildSection(t,e,i);case"item":return this.buildItem(t,e,i);case"header":return this.buildSectionHeader(t,e,i);case"loader":return this.buildLoader(t,e,i);case"separator":return this.buildItem(t,e,i);default:throw new Error("Unsupported node type: "+t.type)}}buildLoader(t,e,i){let r=new c(e,i,this.padding,0),h=new p(t.type,t.key,r);return this.orientation==="horizontal"?(r.height=this.virtualizer.contentSize.height-this.padding-i,r.width=t.props.isLoading?this.loaderSize??this.rowSize??this.estimatedRowSize??f:0):(r.width=this.virtualizer.contentSize.width-this.padding-e,r.height=t.props.isLoading?this.loaderSize??this.rowSize??this.estimatedRowSize??f:0),{layoutInfo:h,validRect:r.intersection(this.requestedRect)}}buildSection(t,e,i){let r=this.virtualizer.collection,h=this.virtualizer.size.width-this.padding-e,s=this.virtualizer.size.height-this.padding-i,o=this.orientation==="horizontal"?new c(e,i,0,s):new c(e,i,h,0),l=new p(t.type,t.key,o),a=this.orientation==="horizontal"?e:i,n=this.orientation==="horizontal"?"x":"y",d=this.orientation==="horizontal"?"maxX":"maxY",u=this.orientation==="horizontal"?"width":"height",y=0,g=[];for(let z of v(t,r)){if(z.type==="content")continue;let w=(this.rowSize??this.estimatedRowSize??f)+this.gap;if(a+wthis.requestedRect[d]){a+=([...v(t,r)].length-(g.length+y))*w;break}}return a-=this.gap,o[u]=a-(this.orientation==="horizontal"?e:i),{layoutInfo:l,children:g,validRect:l.rect.intersection(this.requestedRect),node:t}}buildSectionHeader(t,e,i){let r=this.orientation==="horizontal"?"height":"width",h=this.orientation==="horizontal"?"width":"height",s=this.virtualizer.size[r]-this.padding-(this.orientation==="horizontal"?i:e),o=this.headingSize,l=!1;if(o==null){let d=this.layoutNodes.get(t.key),u=d?.layoutInfo;if(u){let y=this.virtualizer.collection.getItem(t.key),g=this.lastCollection?this.lastCollection.getItem(t.key):null;o=d.layoutInfo.rect[h],l=s!==u.rect[r]||y!==g||u.estimatedSize}else o=t.rendered?this.estimatedHeadingSize:0,l=!0}o==null&&(o=f);let a=this.orientation==="horizontal"?new c(e,i,o,s-i):new c(e,i,s-e,o),n=new p("header",t.key,a);return n.estimatedSize=l,{layoutInfo:n,children:[],validRect:n.rect.intersection(this.requestedRect),node:t}}buildItem(t,e,i){let r=this.orientation==="horizontal"?"height":"width",h=this.orientation==="horizontal"?"width":"height",s=this.virtualizer.size[r]-this.padding-(this.orientation==="horizontal"?i:e),o=this.rowSize,l=!1;if(o==null){let d=this.layoutNodes.get(t.key);d?(o=d.layoutInfo.rect[h],l=s!==d.layoutInfo.rect[r]||t!==d.node||d.layoutInfo.estimatedSize):(o=this.estimatedRowSize,l=!0)}o==null&&(o=f);let a=this.orientation==="horizontal"?new c(e,i,o,s):new c(e,i,s,o),n=new p(t.type,t.key,a);return n.estimatedSize=l,{layoutInfo:n,children:[],validRect:n.rect.intersection(this.requestedRect),node:t}}updateItemSize(t,e){let i=this.layoutNodes.get(t);if(!i)return!1;let r=this.virtualizer.collection,h=i.layoutInfo,s=this.orientation==="horizontal"?"x":"y",o=this.orientation==="horizontal"?"width":"height";if(h.estimatedSize=!1,h.rect[o]!==e[o]){let l=h.copy();l.rect[o]=e[o],i.layoutInfo=l,this.validRect[o]=Math.min(this.validRect[o],h.rect[s]-this.validRect[s]),i.node?.type==="item"&&(this.requestedRect[o]+=l.rect[o]-h.rect[o]),this.updateLayoutNode(t,h,l);let a=h.parentKey!=null?r.getItem(h.parentKey):null;for(;a;)this.updateLayoutNode(a.key,h,l),a=a.parentKey!=null?r.getItem(a.parentKey):null;return!0}return!1}updateLayoutNode(t,e,i){let r=this.layoutNodes.get(t);r&&(r.validRect=r.validRect.intersection(this.validRect),r.layoutInfo===e&&(r.layoutInfo=i))}getContentSize(){return this.contentSize}getDropTargetFromPoint(t,e,i){t+=this.virtualizer.visibleRect.x,e+=this.virtualizer.visibleRect.y;let r=new c(t,Math.max(0,e-this.gap),1,Math.max(1,this.gap*2)),h=this.getVisibleLayoutInfos(r),s=null,o=1/0;for(let d of h){if(!d.rect.intersects(r))continue;let u=Math.abs(d.rect.y-e),y=Math.abs(d.rect.maxY-e),g=Math.min(u,y);g=a.maxY-10&&i({...n,dropPosition:"after"})&&(n.dropPosition="after"):e<=a.y+a.height/2&&i({...n,dropPosition:"before"})?n.dropPosition="before":i({...n,dropPosition:"after"})&&(n.dropPosition="after"),n}getDropTargetLayoutInfo(t){let e=this.getLayoutInfo(t.key),i;if(t.dropPosition==="before")i=this.orientation==="horizontal"?new c(Math.max(0,e.rect.x-this.dropIndicatorThickness/2),e.rect.y,this.dropIndicatorThickness,e.rect.height):new c(e.rect.x,Math.max(0,e.rect.y-this.dropIndicatorThickness/2),e.rect.width,this.dropIndicatorThickness);else if(t.dropPosition==="after"){let r=this.collection.getItem(t.key);if(r){let h=r.level??0,s=this.collection.getKeyAfter(t.key);for(;s!=null;){let o=this.collection.getItem(s);if(!o||o.level<=h)break;e=this.getLayoutInfo(s)||e,s=this.collection.getKeyAfter(s)}}i=this.orientation==="horizontal"?new c(e.rect.maxX-this.dropIndicatorThickness/2,e.rect.y,this.dropIndicatorThickness,e.rect.height):new c(e.rect.x,e.rect.maxY-this.dropIndicatorThickness/2,e.rect.width,this.dropIndicatorThickness)}else i=e.rect;return new p("dropIndicator",t.key+":"+t.dropPosition,i)}}function H(I,t){const e=[];for(const i of I)t(i)&&e.push(i);return e}export{N as $}; +import{f4 as v}from"./index-Bw0aJc9a.js";import{$ as R,c,a as S,b as p}from"./Virtualizer-DCY9HC9Z.js";const f=48;class N extends R{constructor(t={}){super(),this.rowSize=t?.rowSize??t?.rowHeight??null,this.orientation=t.orientation??"vertical",this.estimatedRowSize=t?.estimatedRowSize??t?.estimatedRowHeight??null,this.headingSize=t?.headingSize??t?.headingHeight??null,this.estimatedHeadingSize=t?.estimatedHeadingSize??t?.estimatedHeadingHeight??null,this.loaderSize=t?.loaderSize??t?.loaderHeight??null,this.dropIndicatorThickness=t.dropIndicatorThickness||2,this.gap=t.gap||0,this.padding=t.padding||0,this.layoutNodes=new Map,this.rootNodes=[],this.lastCollection=null,this.invalidateEverything=!1,this.validRect=new c,this.requestedRect=new c,this.contentSize=new S}get collection(){return this.virtualizer.collection}get rowHeight(){return this.rowSize}get estimatedRowHeight(){return this.estimatedRowSize}get headingHeight(){return this.headingSize}get estimatedHeadingHeight(){return this.estimatedHeadingSize}get loaderHeight(){return this.loaderSize}getLayoutInfo(t){return this.ensureLayoutInfo(t),this.layoutNodes.get(t)?.layoutInfo||null}getVisibleLayoutInfos(t){let e=this.orientation==="horizontal"?"x":"y",i=this.orientation==="horizontal"?"width":"height";if(t[i]>1){let s=(this.rowSize??this.estimatedRowSize??f)+this.gap;t=t.copy();let o=Math.floor(t[e]/s)*s,l=t[i]+t[e]-o;t[e]=o,t[i]=Math.ceil(l/s)*s}this.layoutIfNeeded(t);let r=[],h=s=>{for(let o of s)this.isVisible(o,t)&&(r.push(o.layoutInfo),o.children&&h(o.children))};return h(this.rootNodes),r}layoutIfNeeded(t){if(this.lastCollection){this.requestedRect.containsRect(t)||(this.requestedRect=this.requestedRect.union(t),this.rootNodes=this.buildCollection());for(let e of this.virtualizer.persistedKeys)if(this.ensureLayoutInfo(e))return}}ensureLayoutInfo(t){return!this.layoutNodes.has(t)&&this.requestedRect.areaa.type!=="content"),s=h.filter(a=>a.type==="loader"),o=[],l=e?.size===0;l&&(t=0);for(let a of h){let n=(this.rowSize??this.estimatedRowSize??f)+this.gap;if(a.type==="item"&&t+nthis.requestedRect[r]){let u=h.indexOf(a);for(let y of s){let g=h.indexOf(y);t+=(g-u-1)*n;let z=this.orientation==="horizontal"?this.buildChild(y,t,this.padding,null):this.buildChild(y,this.padding,t,null);o.push(z),t=z.layoutInfo.rect[r],u=g}t+=(h.length-u-1)*n;break}}return t=Math.max(t-this.gap,0),t+=l?0:this.padding,this.contentSize=this.orientation==="horizontal"?new S(t,this.virtualizer.size.height):new S(this.virtualizer.size.width,t),o}isValid(t,e){let i=this.layoutNodes.get(t.key),r=this.orientation==="horizontal"?"x":"y";return!this.invalidateEverything&&!!i&&i.node===t&&e===i.layoutInfo.rect[r]&&i.layoutInfo.rect.intersects(this.validRect)&&i.validRect.containsRect(i.layoutInfo.rect.intersection(this.requestedRect))}buildChild(t,e,i,r){if(this.isValid(t,this.orientation==="horizontal"?e:i))return this.layoutNodes.get(t.key);let h=this.buildNode(t,e,i);return h.layoutInfo.parentKey=r??null,h.layoutInfo.allowOverflow=!0,this.layoutNodes.set(t.key,h),h}buildNode(t,e,i){switch(t.type){case"section":return this.buildSection(t,e,i);case"item":return this.buildItem(t,e,i);case"header":return this.buildSectionHeader(t,e,i);case"loader":return this.buildLoader(t,e,i);case"separator":return this.buildItem(t,e,i);default:throw new Error("Unsupported node type: "+t.type)}}buildLoader(t,e,i){let r=new c(e,i,this.padding,0),h=new p(t.type,t.key,r);return this.orientation==="horizontal"?(r.height=this.virtualizer.contentSize.height-this.padding-i,r.width=t.props.isLoading?this.loaderSize??this.rowSize??this.estimatedRowSize??f:0):(r.width=this.virtualizer.contentSize.width-this.padding-e,r.height=t.props.isLoading?this.loaderSize??this.rowSize??this.estimatedRowSize??f:0),{layoutInfo:h,validRect:r.intersection(this.requestedRect)}}buildSection(t,e,i){let r=this.virtualizer.collection,h=this.virtualizer.size.width-this.padding-e,s=this.virtualizer.size.height-this.padding-i,o=this.orientation==="horizontal"?new c(e,i,0,s):new c(e,i,h,0),l=new p(t.type,t.key,o),a=this.orientation==="horizontal"?e:i,n=this.orientation==="horizontal"?"x":"y",d=this.orientation==="horizontal"?"maxX":"maxY",u=this.orientation==="horizontal"?"width":"height",y=0,g=[];for(let z of v(t,r)){if(z.type==="content")continue;let w=(this.rowSize??this.estimatedRowSize??f)+this.gap;if(a+wthis.requestedRect[d]){a+=([...v(t,r)].length-(g.length+y))*w;break}}return a-=this.gap,o[u]=a-(this.orientation==="horizontal"?e:i),{layoutInfo:l,children:g,validRect:l.rect.intersection(this.requestedRect),node:t}}buildSectionHeader(t,e,i){let r=this.orientation==="horizontal"?"height":"width",h=this.orientation==="horizontal"?"width":"height",s=this.virtualizer.size[r]-this.padding-(this.orientation==="horizontal"?i:e),o=this.headingSize,l=!1;if(o==null){let d=this.layoutNodes.get(t.key),u=d?.layoutInfo;if(u){let y=this.virtualizer.collection.getItem(t.key),g=this.lastCollection?this.lastCollection.getItem(t.key):null;o=d.layoutInfo.rect[h],l=s!==u.rect[r]||y!==g||u.estimatedSize}else o=t.rendered?this.estimatedHeadingSize:0,l=!0}o==null&&(o=f);let a=this.orientation==="horizontal"?new c(e,i,o,s-i):new c(e,i,s-e,o),n=new p("header",t.key,a);return n.estimatedSize=l,{layoutInfo:n,children:[],validRect:n.rect.intersection(this.requestedRect),node:t}}buildItem(t,e,i){let r=this.orientation==="horizontal"?"height":"width",h=this.orientation==="horizontal"?"width":"height",s=this.virtualizer.size[r]-this.padding-(this.orientation==="horizontal"?i:e),o=this.rowSize,l=!1;if(o==null){let d=this.layoutNodes.get(t.key);d?(o=d.layoutInfo.rect[h],l=s!==d.layoutInfo.rect[r]||t!==d.node||d.layoutInfo.estimatedSize):(o=this.estimatedRowSize,l=!0)}o==null&&(o=f);let a=this.orientation==="horizontal"?new c(e,i,o,s):new c(e,i,s,o),n=new p(t.type,t.key,a);return n.estimatedSize=l,{layoutInfo:n,children:[],validRect:n.rect.intersection(this.requestedRect),node:t}}updateItemSize(t,e){let i=this.layoutNodes.get(t);if(!i)return!1;let r=this.virtualizer.collection,h=i.layoutInfo,s=this.orientation==="horizontal"?"x":"y",o=this.orientation==="horizontal"?"width":"height";if(h.estimatedSize=!1,h.rect[o]!==e[o]){let l=h.copy();l.rect[o]=e[o],i.layoutInfo=l,this.validRect[o]=Math.min(this.validRect[o],h.rect[s]-this.validRect[s]),i.node?.type==="item"&&(this.requestedRect[o]+=l.rect[o]-h.rect[o]),this.updateLayoutNode(t,h,l);let a=h.parentKey!=null?r.getItem(h.parentKey):null;for(;a;)this.updateLayoutNode(a.key,h,l),a=a.parentKey!=null?r.getItem(a.parentKey):null;return!0}return!1}updateLayoutNode(t,e,i){let r=this.layoutNodes.get(t);r&&(r.validRect=r.validRect.intersection(this.validRect),r.layoutInfo===e&&(r.layoutInfo=i))}getContentSize(){return this.contentSize}getDropTargetFromPoint(t,e,i){t+=this.virtualizer.visibleRect.x,e+=this.virtualizer.visibleRect.y;let r=new c(t,Math.max(0,e-this.gap),1,Math.max(1,this.gap*2)),h=this.getVisibleLayoutInfos(r),s=null,o=1/0;for(let d of h){if(!d.rect.intersects(r))continue;let u=Math.abs(d.rect.y-e),y=Math.abs(d.rect.maxY-e),g=Math.min(u,y);g=a.maxY-10&&i({...n,dropPosition:"after"})&&(n.dropPosition="after"):e<=a.y+a.height/2&&i({...n,dropPosition:"before"})?n.dropPosition="before":i({...n,dropPosition:"after"})&&(n.dropPosition="after"),n}getDropTargetLayoutInfo(t){let e=this.getLayoutInfo(t.key),i;if(t.dropPosition==="before")i=this.orientation==="horizontal"?new c(Math.max(0,e.rect.x-this.dropIndicatorThickness/2),e.rect.y,this.dropIndicatorThickness,e.rect.height):new c(e.rect.x,Math.max(0,e.rect.y-this.dropIndicatorThickness/2),e.rect.width,this.dropIndicatorThickness);else if(t.dropPosition==="after"){let r=this.collection.getItem(t.key);if(r){let h=r.level??0,s=this.collection.getKeyAfter(t.key);for(;s!=null;){let o=this.collection.getItem(s);if(!o||o.level<=h)break;e=this.getLayoutInfo(s)||e,s=this.collection.getKeyAfter(s)}}i=this.orientation==="horizontal"?new c(e.rect.maxX-this.dropIndicatorThickness/2,e.rect.y,this.dropIndicatorThickness,e.rect.height):new c(e.rect.x,e.rect.maxY-this.dropIndicatorThickness/2,e.rect.width,this.dropIndicatorThickness)}else i=e.rect;return new p("dropIndicator",t.key+":"+t.dropPosition,i)}}function H(I,t){const e=[];for(const i of I)t(i)&&e.push(i);return e}export{N as $}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Login-CpQFWFRI.js b/luci-app-honk/root/etc/honk/doona/assets/Login-CpQFWFRI.js new file mode 100644 index 000000000..3a5ca98db --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/Login-CpQFWFRI.js @@ -0,0 +1,2 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./LoginShowcase-hawa0qI8.js","./vendor-react-Bf71BWbF.js","./index-Bw0aJc9a.js","./index-7R3bVGRM.css"])))=>i.map(i=>d[i]); +import{u as G,a as ne,e as re,d as K,A as I,i as oe,b as ie,s as ae,r as le,w as ce,n as V,c as ue,f as de,L as U,h as me,g as ge,P as pe,S as fe,l as he,E as Z,j as we,I as xe,T as E,B as ye,k as je,_ as ke}from"./index-Bw0aJc9a.js";import{r as l,j as t}from"./vendor-react-Bf71BWbF.js";import{D as q,s as ve,d as be,a as Te,o as Se}from"./auth-DzCdgIKH.js";function Ee(s,r,o,c){return s.some(n=>n.id===r&&V(n.api)===V(o))?s.map(n=>n.id===r?{...n,token:c.trim()}:n):null}const Ne=/^[A-Za-z0-9_.-]{1,64}$/;function _e(s,r,o,c){const n={};r?Ne.test(r)||(n.username="login.badUsername"):n.username="login.usernameRequired";const u=[...o].length;return u?s==="setup"&&u<8?n.password="login.passwordShort":u>128||new TextEncoder().encode(o).length>512?n.password="login.passwordLong":s==="setup"&&o!==c&&(n.confirm="login.mismatch"):n.password="login.passwordRequired",n}function Ae(s){if(!(s instanceof I))return null;if(s.code==="invalid_credentials")return{key:"login.invalidCredentials"};if(s.code==="setup_required")return{key:"login.needsSetup",switchTo:"setup"};if(s.code==="setup_already_completed")return{key:"login.alreadySetUp",switchTo:"login"};if(s.code==="permission_denied")return{key:"login.setupPeer"};if(s.code==="rate_limited"){const r=s.retryAfter??60;return{key:"login.rateLimited",params:{n:r},wait:r}}return null}function Pe(s){return s instanceof SyntaxError?!0:s instanceof I&&(s.status===404||s.status===401&&(!s.code||s.code==="authentication_required"))}async function Ce(s,r){try{return ve(await be(s,r))}catch(o){if(!Pe(o))throw o;return!(o instanceof I)||o.status!==404||await Te(s,r)?"token":"no-api"}}function Le(s,r,o){try{const{profiles:c,activeId:n}=le(),u=Ee(c,s,r,o);if(!u)return"login.stale";ce({profiles:u,activeId:n})}catch{return"settings.saveError"}return null}async function De(s,r,o,c){let n;try{n=await Se(r,o,c)}catch(u){return Ae(u)??{error:u}}try{ae(s,r,n.token,n.expires_at)}catch{return{key:"settings.saveError"}}return null}function Re(s,r){const{kind:o,failure:c,attempt:n,ended:u,rejected:h}=s;return o==="no-api"?null:c!==null?{tone:"negative",text:typeof c=="string"?c:r(c.key,c.params),focus:!0,id:n}:u?{tone:"informative",text:r("login.sessionEnded"),focus:!1,id:0}:h&&o==="token"?{tone:"negative",text:r("login.rejected"),focus:!1,id:0}:null}const Me=s=>typeof s!="string"&&s.key==="login.rateLimited";function Ue(s,r){return Math.max(0,Math.ceil((s-r)/1e3))}function qe(s,r,o,c){const n=G(),u=ne(),[h]=l.useState(()=>re(s,r)),[a,x]=l.useState(null),[y,j]=l.useState({attempt:0,error:null});l.useEffect(()=>{const i=new AbortController;return Ce(r,i.signal).then(g=>x(g),g=>{i.signal.aborted||j(m=>({...m,error:g instanceof Error?g:new Error(String(g))}))}),()=>i.abort()},[r,y.attempt]);const[p,N]=l.useState(""),d=oe(r),[e,_]=l.useState(d?q.username:""),[f,k]=l.useState(d?q.password:""),[v,F]=l.useState(""),[A,J]=l.useState(!1),[B,H]=l.useState(!1),[P,O]=l.useState({}),[C,b]=l.useState(null),[W,X]=l.useState(0),[T,Y]=l.useState(0),[S,z]=l.useState(Date.now);l.useEffect(()=>{if(T<=S)return;const i=setTimeout(()=>z(Date.now()),(T-S)%1e3||1e3);return()=>clearTimeout(i)},[T,S]);const w=Ue(T,S),L=(i,g)=>m=>{g(m),P[i]&&O(({[i]:M,...se})=>se)},ee=()=>{if(!p.trim())return;const i=Le(s,r,p);i?b({key:i}):location.reload()},te=async i=>{const g=_e(i,e,f,v);if(O(g),Object.keys(g).length)return;H(!0);const m=await De(s,r,i,{username:e,password:f});if(!m){location.reload();return}if(H(!1),"error"in m){b(n("login.failed",{error:ie(m.error,n)}));return}if(m.wait){const M=Date.now();z(M),Y(M+m.wait*1e3)}m.switchTo&&(x(m.switchTo),F("")),b(m)},D=a==="setup"||a==="login",R=i=>P[i]?n(P[i]):void 0;return{kind:a,discoveryError:y.error,retryDiscovery:()=>j(i=>({attempt:i.attempt+1,error:null})),title:n(a==="no-api"?"login.noApiTitle":a==="setup"?"login.setupTitle":a==="token"?"login.title":"login.passwordTitle"),note:a==="no-api"?n("login.noApiNote"):a==="setup"?n("login.setupNote",{backend:o}):a==="login"?n("login.connectedTo",{backend:o}):n("login.note",{backend:o}),demoNote:d&&a==="login"?n("login.demoNote",q):null,alert:Re({kind:a,failure:C&&!w&&Me(C)?null:C,attempt:W,ended:h,rejected:c},n),busy:B,token:p,setToken:N,username:e,setUsername:L("username",_),usernameError:R("username"),password:f,setPassword:L("password",k),passwordError:R("password"),confirm:v,setConfirm:L("confirm",F),confirmError:R("confirm"),submit:()=>{B||w||a==="no-api"||(b(null),X(i=>i+1),D?te(a):ee())},canSubmit:a!=="no-api"&&!w&&(D||!!p.trim()),submitText:w?n("login.retryIn",{n:w}):n(a==="setup"?"login.create":a==="login"?"login.signIn":"login.submit"),secretType:A?"text":"password",toggle:()=>J(i=>!i),toggleText:n(D?A?"login.hidePassword":"login.showPassword":A?"settings.hideToken":"settings.showToken"),guideHref:K(u),requirementsHref:K(u,"no-native-api")}}function Q({className:s,...r}){return t.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:10,height:10,viewBox:"0 0 12 12","aria-hidden":"true",focusable:"false",className:ue("rp-icon rp-link-out",s),...r,children:t.jsx("path",{fill:"currentColor",d:"m10.08887,1h-5.51074c-.50293,0-.91113.4082-.91113.91113s.4082.91113.91113.91113h3.31055L1.35547,9.35547c-.35645.35645-.35645.93262,0,1.28906.17773.17773.41113.2666.64453.2666s.4668-.08887.64453-.2666l6.5332-6.5332v3.31055c0,.50293.4082.91113.91113.91113s.91113-.4082.91113-.91113V1.91113c0-.50293-.4082-.91113-.91113-.91113Z"})})}const Ie=l.lazy(()=>ke(()=>import("./LoginShowcase-hawa0qI8.js"),__vite__mapDeps([0,1,2,3]),import.meta.url)),$=t.jsx("div",{className:"rp-login-showcase","aria-hidden":"true"});function Oe({profileId:s,api:r,backend:o,rejected:c,lang:n,pickLang:u,dark:h,themeLabel:a,toggleScheme:x,palette:y,wordmark:j,error:p,onRetry:N}){const d=G(),e=qe(s,r,o,c),_=de("(min-width: 1024px)"),f={shown:e.secretType==="text",label:e.toggleText,onToggle:e.toggle},k=t.jsxs("div",{className:"rp-login-links",children:[t.jsx(U,{appearance:"link",href:me("settings"),children:d("login.settings")}),t.jsxs(U,{appearance:"link",href:e.guideHref,external:!0,children:[d("shell.guide"),t.jsx(Q,{})]})]});return t.jsxs("div",{className:"rp-login-page",children:[t.jsxs("div",{className:"rp-login-pane",children:[t.jsxs("header",{className:"rp-login-controls",children:[t.jsx(ge,{lang:n,pickLang:u}),t.jsx(pe,{...y}),t.jsx(fe,{dark:h,label:a,toggle:x})]}),t.jsxs("main",{className:"rp-login-column",children:[t.jsxs("div",{className:"rp-login-brand",children:[t.jsx("img",{src:he,alt:""}),t.jsx("span",{className:"rp-brand-text",children:t.jsx("span",{children:j})})]}),t.jsxs("div",{className:"rp-login-head",children:[t.jsx("h1",{className:"rp-h1",children:e.title}),e.note&&t.jsx("p",{className:"rp-login-note",children:e.note})]}),t.jsx(Z,{error:p,onRetry:N}),e.kind===null?e.discoveryError?t.jsxs(t.Fragment,{children:[t.jsx(Z,{error:e.discoveryError,onRetry:e.retryDiscovery}),k]}):t.jsx(we,{}):t.jsxs(t.Fragment,{children:[t.jsxs("form",{className:"rp-login",onSubmit:v=>{v.preventDefault(),e.submit()},children:[e.alert&&t.jsx(xe,{tone:e.alert.tone,takeFocus:e.alert.focus,children:e.alert.text},e.alert.id),e.kind==="no-api"?t.jsxs(U,{appearance:"link",href:e.requirementsHref,external:!0,children:[d("login.requirements"),t.jsx(Q,{})]}):e.kind==="token"?t.jsx(E,{label:d("login.token"),name:"token",type:e.secretType,value:e.token,autoComplete:"off",onChange:e.setToken,reveal:f}):t.jsxs(t.Fragment,{children:[t.jsx(E,{label:d("login.username"),name:"username",value:e.username,autoComplete:"username",spellCheck:"false",error:e.usernameError,onChange:e.setUsername}),t.jsx(E,{label:d("login.password"),name:"password",type:e.secretType,value:e.password,autoComplete:e.kind==="setup"?"new-password":"current-password",description:e.kind==="setup"?d("login.passwordRule"):void 0,error:e.passwordError,onChange:e.setPassword,reveal:f}),e.kind==="setup"&&t.jsx(E,{label:d("login.confirm"),name:"confirm",type:e.secretType,value:e.confirm,autoComplete:"new-password",error:e.confirmError,onChange:e.setConfirm})]}),e.kind!=="no-api"&&t.jsx(ye,{accent:!0,className:"rp-login-submit",type:"submit",isDisabled:!e.canSubmit,isPending:e.busy,children:e.submitText})]}),e.demoNote&&t.jsx("p",{className:"rp-login-note rp-login-account",children:e.demoNote}),k]})]})]}),_&&t.jsx(je,{fallback:$,children:t.jsx(l.Suspense,{fallback:$,children:t.jsx(Ie,{})})})]})}export{Oe as Login}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Login-DgzaXVol.js b/luci-app-honk/root/etc/honk/doona/assets/Login-DgzaXVol.js deleted file mode 100644 index 06b7b9b75..000000000 --- a/luci-app-honk/root/etc/honk/doona/assets/Login-DgzaXVol.js +++ /dev/null @@ -1,2 +0,0 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./LoginShowcase-CyHbTm5w.js","./vendor-react-Bf71BWbF.js","./index-BNBwb-FJ.js","./index-C8vJM6q6.css"])))=>i.map(i=>d[i]); -import{u as G,a as ne,e as re,d as K,A as q,i as oe,b as ie,s as ae,r as le,w as ce,n as V,c as ue,f as de,L as U,h as me,g as ge,P as pe,S as fe,l as he,E as Z,j as we,I as xe,T as E,B as ye,k as je,_ as ke}from"./index-BNBwb-FJ.js";import{r as l,j as t}from"./vendor-react-Bf71BWbF.js";import{D as I,s as ve,d as be,a as Te,o as Se}from"./auth-TcOYUrrj.js";function Ee(s,r,o,c){return s.some(n=>n.id===r&&V(n.api)===V(o))?s.map(n=>n.id===r?{...n,token:c.trim()}:n):null}const Ne=/^[A-Za-z0-9_.-]{1,64}$/;function Ae(s,r,o,c){const n={};r?Ne.test(r)||(n.username="login.badUsername"):n.username="login.usernameRequired";const u=[...o].length;return u?s==="setup"&&u<8?n.password="login.passwordShort":u>128||new TextEncoder().encode(o).length>512?n.password="login.passwordLong":s==="setup"&&o!==c&&(n.confirm="login.mismatch"):n.password="login.passwordRequired",n}function Pe(s){if(!(s instanceof q))return null;if(s.code==="invalid_credentials")return{key:"login.invalidCredentials"};if(s.code==="setup_required")return{key:"login.needsSetup",switchTo:"setup"};if(s.code==="setup_already_completed")return{key:"login.alreadySetUp",switchTo:"login"};if(s.code==="permission_denied")return{key:"login.setupPeer"};if(s.code==="rate_limited"){const r=s.retryAfter??60;return{key:"login.rateLimited",params:{n:r},wait:r}}return null}function _e(s){return s instanceof SyntaxError?!0:s instanceof q&&(s.status===404||s.status===401||s.status===403)}async function Ce(s,r){try{return ve(await be(s,r))}catch(o){if(!_e(o))throw o;return!(o instanceof q)||o.status!==404||await Te(s,r)?"token":"no-api"}}function Le(s,r,o){try{const{profiles:c,activeId:n}=le(),u=Ee(c,s,r,o);if(!u)return"login.stale";ce({profiles:u,activeId:n})}catch{return"settings.saveError"}return null}async function De(s,r,o,c){let n;try{n=await Se(r,o,c)}catch(u){return Pe(u)??{error:u}}try{ae(s,r,n.token,n.expires_at)}catch{return{key:"settings.saveError"}}return null}function Re(s,r){const{kind:o,failure:c,attempt:n,ended:u,rejected:h}=s;return o==="no-api"?null:c!==null?{tone:"negative",text:typeof c=="string"?c:r(c.key,c.params),focus:!0,id:n}:u?{tone:"informative",text:r("login.sessionEnded"),focus:!1,id:0}:h&&o==="token"?{tone:"negative",text:r("login.rejected"),focus:!1,id:0}:null}const Me=s=>typeof s!="string"&&s.key==="login.rateLimited";function Ue(s,r){return Math.max(0,Math.ceil((s-r)/1e3))}function Ie(s,r,o,c){const n=G(),u=ne(),[h]=l.useState(()=>re(s,r)),[a,x]=l.useState(null),[y,j]=l.useState({attempt:0,error:null});l.useEffect(()=>{const i=new AbortController;return Ce(r,i.signal).then(g=>x(g),g=>{i.signal.aborted||j(m=>({...m,error:g instanceof Error?g:new Error(String(g))}))}),()=>i.abort()},[r,y.attempt]);const[p,N]=l.useState(""),d=oe(r),[e,A]=l.useState(d?I.username:""),[f,k]=l.useState(d?I.password:""),[v,F]=l.useState(""),[P,J]=l.useState(!1),[B,H]=l.useState(!1),[_,O]=l.useState({}),[C,b]=l.useState(null),[W,X]=l.useState(0),[T,Y]=l.useState(0),[S,z]=l.useState(Date.now);l.useEffect(()=>{if(T<=S)return;const i=setTimeout(()=>z(Date.now()),(T-S)%1e3||1e3);return()=>clearTimeout(i)},[T,S]);const w=Ue(T,S),L=(i,g)=>m=>{g(m),_[i]&&O(({[i]:M,...se})=>se)},ee=()=>{if(!p.trim())return;const i=Le(s,r,p);i?b({key:i}):location.reload()},te=async i=>{const g=Ae(i,e,f,v);if(O(g),Object.keys(g).length)return;H(!0);const m=await De(s,r,i,{username:e,password:f});if(!m){location.reload();return}if(H(!1),"error"in m){b(n("login.failed",{error:ie(m.error,n)}));return}if(m.wait){const M=Date.now();z(M),Y(M+m.wait*1e3)}m.switchTo&&(x(m.switchTo),F("")),b(m)},D=a==="setup"||a==="login",R=i=>_[i]?n(_[i]):void 0;return{kind:a,discoveryError:y.error,retryDiscovery:()=>j(i=>({attempt:i.attempt+1,error:null})),title:n(a==="no-api"?"login.noApiTitle":a==="setup"?"login.setupTitle":a==="token"?"login.title":"login.passwordTitle"),note:a==="no-api"?n("login.noApiNote"):a==="setup"?n("login.setupNote",{backend:o}):a==="login"?n("login.connectedTo",{backend:o}):n("login.note",{backend:o}),demoNote:d&&a==="login"?n("login.demoNote",I):null,alert:Re({kind:a,failure:C&&!w&&Me(C)?null:C,attempt:W,ended:h,rejected:c},n),busy:B,token:p,setToken:N,username:e,setUsername:L("username",A),usernameError:R("username"),password:f,setPassword:L("password",k),passwordError:R("password"),confirm:v,setConfirm:L("confirm",F),confirmError:R("confirm"),submit:()=>{B||w||a==="no-api"||(b(null),X(i=>i+1),D?te(a):ee())},canSubmit:a!=="no-api"&&!w&&(D||!!p.trim()),submitText:w?n("login.retryIn",{n:w}):n(a==="setup"?"login.create":a==="login"?"login.signIn":"login.submit"),secretType:P?"text":"password",toggle:()=>J(i=>!i),toggleText:n(D?P?"login.hidePassword":"login.showPassword":P?"settings.hideToken":"settings.showToken"),guideHref:K(u),requirementsHref:K(u,"no-native-api")}}function Q({className:s,...r}){return t.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:10,height:10,viewBox:"0 0 12 12","aria-hidden":"true",focusable:"false",className:ue("rp-icon rp-link-out",s),...r,children:t.jsx("path",{fill:"currentColor",d:"m10.08887,1h-5.51074c-.50293,0-.91113.4082-.91113.91113s.4082.91113.91113.91113h3.31055L1.35547,9.35547c-.35645.35645-.35645.93262,0,1.28906.17773.17773.41113.2666.64453.2666s.4668-.08887.64453-.2666l6.5332-6.5332v3.31055c0,.50293.4082.91113.91113.91113s.91113-.4082.91113-.91113V1.91113c0-.50293-.4082-.91113-.91113-.91113Z"})})}const qe=l.lazy(()=>ke(()=>import("./LoginShowcase-CyHbTm5w.js"),__vite__mapDeps([0,1,2,3]),import.meta.url)),$=t.jsx("div",{className:"rp-login-showcase","aria-hidden":"true"});function Oe({profileId:s,api:r,backend:o,rejected:c,lang:n,pickLang:u,dark:h,themeLabel:a,toggleScheme:x,palette:y,wordmark:j,error:p,onRetry:N}){const d=G(),e=Ie(s,r,o,c),A=de("(min-width: 1024px)"),f={shown:e.secretType==="text",label:e.toggleText,onToggle:e.toggle},k=t.jsxs("div",{className:"rp-login-links",children:[t.jsx(U,{appearance:"link",href:me("settings"),children:d("login.settings")}),t.jsxs(U,{appearance:"link",href:e.guideHref,external:!0,children:[d("shell.guide"),t.jsx(Q,{})]})]});return t.jsxs("div",{className:"rp-login-page",children:[t.jsxs("div",{className:"rp-login-pane",children:[t.jsxs("header",{className:"rp-login-controls",children:[t.jsx(ge,{lang:n,pickLang:u}),t.jsx(pe,{...y}),t.jsx(fe,{dark:h,label:a,toggle:x})]}),t.jsxs("main",{className:"rp-login-column",children:[t.jsxs("div",{className:"rp-login-brand",children:[t.jsx("img",{src:he,alt:""}),t.jsx("span",{className:"rp-brand-text",children:t.jsx("span",{children:j})})]}),t.jsxs("div",{className:"rp-login-head",children:[t.jsx("h1",{className:"rp-h1",children:e.title}),e.note&&t.jsx("p",{className:"rp-login-note",children:e.note})]}),t.jsx(Z,{error:p,onRetry:N}),e.kind===null?e.discoveryError?t.jsxs(t.Fragment,{children:[t.jsx(Z,{error:e.discoveryError,onRetry:e.retryDiscovery}),k]}):t.jsx(we,{}):t.jsxs(t.Fragment,{children:[t.jsxs("form",{className:"rp-login",onSubmit:v=>{v.preventDefault(),e.submit()},children:[e.alert&&t.jsx(xe,{tone:e.alert.tone,takeFocus:e.alert.focus,children:e.alert.text},e.alert.id),e.kind==="no-api"?t.jsxs(U,{appearance:"link",href:e.requirementsHref,external:!0,children:[d("login.requirements"),t.jsx(Q,{})]}):e.kind==="token"?t.jsx(E,{label:d("login.token"),name:"token",type:e.secretType,value:e.token,autoComplete:"off",onChange:e.setToken,reveal:f}):t.jsxs(t.Fragment,{children:[t.jsx(E,{label:d("login.username"),name:"username",value:e.username,autoComplete:"username",spellCheck:"false",error:e.usernameError,onChange:e.setUsername}),t.jsx(E,{label:d("login.password"),name:"password",type:e.secretType,value:e.password,autoComplete:e.kind==="setup"?"new-password":"current-password",description:e.kind==="setup"?d("login.passwordRule"):void 0,error:e.passwordError,onChange:e.setPassword,reveal:f}),e.kind==="setup"&&t.jsx(E,{label:d("login.confirm"),name:"confirm",type:e.secretType,value:e.confirm,autoComplete:"new-password",error:e.confirmError,onChange:e.setConfirm})]}),e.kind!=="no-api"&&t.jsx(ye,{accent:!0,className:"rp-login-submit",type:"submit",isDisabled:!e.canSubmit,isPending:e.busy,children:e.submitText})]}),e.demoNote&&t.jsx("p",{className:"rp-login-note rp-login-account",children:e.demoNote}),k]})]})]}),A&&t.jsx(je,{fallback:$,children:t.jsx(l.Suspense,{fallback:$,children:t.jsx(qe,{})})})]})}export{Oe as Login}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/LoginShowcase-CyHbTm5w.js b/luci-app-honk/root/etc/honk/doona/assets/LoginShowcase-CyHbTm5w.js deleted file mode 100644 index 7306b7456..000000000 --- a/luci-app-honk/root/etc/honk/doona/assets/LoginShowcase-CyHbTm5w.js +++ /dev/null @@ -1 +0,0 @@ -import{j as N,r as B}from"./vendor-react-Bf71BWbF.js";import{u as W1,f as j1,aM as K1}from"./index-BNBwb-FJ.js";function N1({label:r,className:a,isDisabled:m,ref:e,canvasRef:l}){return N.jsx("button",{ref:e,type:"button",className:a,"aria-label":r,disabled:m,children:N.jsx("canvas",{ref:l})})}const U1=[["ink","M657 1228c-12-4-23-14-28-26-1-4-2-4-4-4-22 4-36 3-49-3-11-6-18-16-20-27-2-11 3-23 12-34 3-3 6-6 6-6 0 0-7-1-15-1-34-2-70-7-100-14-49-12-98-36-134-67l-5-4-12 4c-20 7-36 9-60 9-21 0-43-4-57-10-13-5-25-16-30-25-5-10-4-23 3-34 4-6 16-18 24-22l6-4-3-8c-2-5-2-9-2-12 1-6 5-15 9-18 4-5 16-13 21-14 3-1 5-2 6-2 0-1-1-6-3-12-21-73-6-145 45-212l7-10-12-2c-15-1-23-3-34-7-24-9-40-29-40-49 0-19 7-34 36-72 15-21 27-39 35-54 11-19 10-17 5-28-2-4-5-11-6-14-2-8-3-32-1-43 4-28 18-59 42-90l3-5-6-4c-11-9-20-21-23-32-2-6-2-9-2-17 1-9 1-10 4-18 6-11 15-20 29-27 14-7 24-10 47-15 1 0 3-3 7-11 19-37 51-71 88-94 12-8 32-18 44-22 10-3 29-8 33-8 1 0 5-2 8-5 11-8 25-14 39-16 12-2 49-1 63 2 21 4 34 9 45 19 8 7 10 9 15 18 4 7 4 7 13 12 34 18 63 46 86 81 10 16 20 38 26 57 4 12 8 34 10 48 2 13 2 43 0 56l-1 10 6 7c8 8 14 19 18 28 3 9 4 24 2 33-3 14-14 27-29 35-9 5-19 7-31 8l-9 1 0 8c0 4 0 15 0 25 0 16-1 31-5 47l0 3 14 0c27 0 58 5 83 14 21 9 51 25 68 39 3 2 6 5 7 5 0 1 6-2 14-6 27-14 49-17 69-11 26 8 38 34 27 64-2 5-3 9-3 10 0 0 4 1 8 3 14 7 24 19 29 34 8 22 0 45-24 73l-5 6 3 9c6 26 8 63 5 89-2 14-7 33-12 48-9 22-26 52-43 72-10 13-34 36-47 46-28 22-59 39-93 52-16 7-44 16-47 16-1 0-1 1-1 3 9 31 7 61-3 81-8 16-19 27-33 34-9 4-14 5-25 5-15 0-28-4-39-13l-6-5-7 6c-9 7-18 13-26 16-9 3-27 4-35 1z"],["paper","M582 1098c-44-2-79-6-117-16-55-14-102-41-141-81-42-43-67-93-75-148-2-14-1-43 1-56 6-30 16-57 32-82 8-12 24-33 32-42 6-7 7-7 17-10 58-18 110-56 126-92 2-5 2-9 3-16 1-14-2-21-15-33-13-14-21-24-33-39-18-26-28-35-45-43-11-5-21-7-33-7-13 0-23 2-33 7-6 3-9 3-9 3-4-6-4-28-2-42 5-23 18-49 37-73 14-18 37-39 56-53 5-4 6-4 11-4 41 1 105 13 154 28 32 9 72 25 104 42 18 9 51 27 66 37 8 5 8 5 11 13 7 16 13 37 16 56 2 11 2 41 1 54-4 39-19 74-44 104-8 9-10 14-9 20 1 5 7 10 13 12 7 2 14-1 24-11 10-11 22-29 32-48 3-5 4-7 6-7 2-1 14-1 27-1 22 0 24 0 37 2 34 8 68 24 98 48 13 11 15 12 20 12 5 0 7-1 16-7 22-14 41-21 53-18 13 3 16 15 7 32-2 5-6 11-8 15-4 8-4 14 0 19 4 5 7 6 17 7 15 1 23 5 27 14 3 6 3 15 0 22-2 6-10 18-20 30-9 11-11 15-8 24 3 10 6 33 7 52 0 26-2 47-10 70-18 53-57 101-111 135-40 25-87 43-144 54-66 14-132 19-194 17z"],["ink","M517 445c-7-2-13-6-18-12-7-7-9-14-9-25 0-7 0-8 3-15 7-13 17-21 31-22 23-1 43 18 41 40-2 19-17 33-36 35-4 0-9-1-12-1z"],["yellow","M541 220c-13-3-27-7-41-9-6-1-14-3-17-3l-5-1 2-6c3-15 13-40 23-59 20-39 43-66 64-73 11-3 56-1 74 4 7 1 13 4 17 7 3 3 3 4-1 4-5 0-17 4-24 7-35 18-62 59-79 118-2 8-4 14-4 14 0 0-4-1-9-3z"],["yellow","M446 203c-4-1-19-1-35-2-16 0-29 0-29-1 0-1 6-12 12-20 22-34 53-62 87-78 10-5 32-13 33-12 0 0-2 3-6 8-19 27-38 69-47 102-1 4-1 4-5 4-3 0-7-1-10-1z"],["yellow","M569 226c13-58 39-102 70-119 14-7 21-6 40 1 53 23 96 73 113 132 9 29 11 67 7 95-71-43-149-81-230-109z"],["yellow","M780 426c-1-2-5-19-5-19 0-1 3 0 8 0 6 0 8 0 10-2 5-4 3-6-21-21-50-32-74-46-109-63-71-36-143-57-225-67-48-6-99-5-107 1-4 3-5 5-2 7 1 2 3 2 10 3l8 0-4 4c-3 3-9 8-13 12l-9 8-4-2c-6-4-13-11-16-17-3-5-4-12-3-17 2-8 11-17 22-22 22-10 60-14 101-12 63 3 121 16 167 36 71 31 145 67 214 105 17 10 27 31 23 45-1 5-6 12-10 15-6 4-15 6-25 7-8 0-10 0-10-1z"],["yellow","M251 640c-19-4-32-16-32-29 0-10 5-19 23-43 26-34 37-50 50-75 6-12 9-17 13-20 12-11 29-13 45-7 11 5 17 10 37 36 9 13 19 25 24 30 5 5 10 10 12 13 2 3 2 5 2 10 0 5-1 8-4 12-17 29-73 61-123 71-14 3-38 4-47 2z"],["yellow","M226 1028c-12-1-24-5-31-10-12-8-13-16-2-27 5-5 19-13 30-17 7-3 11-6 11-8 0-3-1-5-8-9-7-6-10-10-10-14 0-4 1-5 4-8 2-2 6-4 9-5 3-1 5-2 5-2 1 0 4 7 8 14 15 29 28 49 49 72 4 5 7 8 7 9-1 1-21 5-29 6-13 1-31 1-43-1z"],["yellow","M663 1201c-7-4-9-12-7-24 1-7 1-8 0-10-3-4-7-4-15-1-18 7-40 10-48 7-5-2-8-6-8-11 0-7 8-16 29-30l10-7 19 0c22-1 52-4 78-7 18-3 57-9 65-11 6-2 11-1 14 1 2 3 4 7 5 20 4 39-13 70-39 68-9-1-16-5-29-17-14-12-14-12-27 1-11 11-20 18-28 21-7 3-15 3-19 0z"]],U={width:940,height:1192},K=1.4,R=52,Z=72,f1=500,V1=250,F=22,Y=22,i1=Y+2,l1=16,u1=12,X1=56,A1=17,E=9,S1=18,J=1/120,h1=1500,e1=430,C=48,q1=e1*e1/(2*h1),H1=Math.max(2.2*R,R+q1+4),B1=200,_1=B1*h1/(2*e1),Q=.84*R*U.width/U.height/2,d1=.84*R/2;function G1(r,a,m){let e=0;for(;r>=1e3&&e1?1:0))+" "+a[e]}function G(r){return G1(r,["MB","GB","TB","PB"],2)}function I1(r){return r<6?[100,150,200,300,450,650][r]:[1,1.5,2.5,4,6][(r-6)%5]*Math.pow(10,3+Math.floor((r-6)/5))}function J1(r){const a=I1(r);return a<1e3?a+" Mbps":G1(a,["Mbps","Gbps","Tbps","Pbps"],1).replace(".0 "," ")}function D1(r){const a=Math.pow(.9,r);return{speed:_1-(_1-110)*a,gap:H1+(205-H1)*a,space:B1+70*a,swing:r<6?0:34*(1-Math.pow(.8,r-5)),drift:r>=6}}function Q1(r){return(Math.floor(r*1e3/f1)+3)%4}function Y1(r,a,m={}){const e=Z*U.width/U.height,l=Math.max(X1,m.board??0),I=Math.floor(r-2*(u1+l1)-l-i1-Y-e),P=Math.max(120,m.row??0,Math.min(V1,I)),c=l+i1+P+Y+e,f=Math.min(1,(r/2-u1)/(c/2+l1)),g=-2*F,M=g-12,u=-Z,b=40,h=Math.round(a/2-(u+b+4)/2),v=Math.round(r/2),w=Math.round(v-c/2),A=w+l+i1;return{cx:v,post:w,board:l,x:A,bar:P,ground:h,top:h+g,label:h+M,head:h+u,sign:h+M-(m.cap??12)+.75,rail:h+g+(F-E)/2,start:h+b,duck:A+P+Y+e/2,reach:Math.round(c/2+l1),shrink:f,text:(r-2*u1)/f}}function Z1(r,a,m){const e=a.getContext("2d");if(!e)return{setText(){},destroy(){}};const l=matchMedia("(prefers-reduced-motion: reduce)"),I=document.documentElement,P=U1.map(([t,n])=>[t,new Path2D(n)]);let c,f="",g=g1(),M=1,u=0,b=0,h=0,v=0,w=0,A=0,S=0,y=[],H=0,V=0,_=0,p1=0,t1=0,z=!1,x=0,X=0,n1=0,$=0,q=0,o1=!0,s1=0,r1=0;const m1=performance.now();function g1(){const t=getComputedStyle(r),n=s=>t.getPropertyValue(s).trim();return f=t.fontFamily,{ink:n("--rp-mark-ink"),paper:n("--rp-mark-paper"),yellow:n("--rp-mark-yellow"),text:n("--rp-text"),sub:n("--rp-subtle"),accent:n("--rp-accent"),wall:n("--rp-negative"),base:n("--rp-base"),bar:n("--rp-positive")}}function w1(){M=(window.devicePixelRatio||1)*K,a.width=Math.round(a.clientWidth*M/K),a.height=Math.round(a.clientHeight*M/K),u=a.clientWidth/K,b=a.clientHeight/K,h=Math.round(b*.84),v=Math.round(u*.3)}function M1(t){const n=D1(_),s=40+n.gap/2+n.swing,i=h-30-n.gap/2-n.swing,d=y[y.length-1];let o=s+Math.random()*(i-s);if(d){const L=(n.gap-2*d1)/2+220*(n.space-C-2*Q)/n.speed-2*n.swing;n.drift&&Math.random()<.6&&(o=d.c0<(s+i)/2?i:s),o=Math.max(d.c0-L,Math.min(d.c0+L,o))}o=Math.max(s,Math.min(i,o));const p=n.swing*(Math.random()<.5?1:0);y.push({x:t,ox:t,gap:n.gap,c0:o,c:o,oc:o,a:p,f:p?Math.min(3,110/p):0,ph:Math.random()*6.3,done:!1})}function x1(){w=A=b*.42,S=H=_=p1=t1=x=$=0,y=[],M1(u+10)}function b1(){x=performance.now(),V=Math.max(V,H),m(G(H),G(V)),window.clearTimeout(s1),s1=window.setTimeout(()=>W(),950)}function z1(t){const n=D1(_);q+=t,A=w,S=Math.min(700,S+h1*t),w+=S*t,wv-Q&&(w-d1s.c+s.gap/2)&&b1();y[y.length-1].xs.x>-C),!x&&w+R/2-3>h&&(w=h-R/2+3,b1())}function D(t,n){e.beginPath(),n(),e.fillStyle=t,e.fill(),e.stroke()}function y1(t,n,s,i,d=!1){const o=s/U.height;e.save(),e.translate(t,n),e.rotate(i),e.scale(d?o:-o,o),e.translate(-628,-634);for(const[p,L]of P)e.fillStyle=g[p],e.fill(L,"evenodd");e.restore()}function O1(t,n,s,i,d){for(const[o,p]of[[t+10,t+5],[t+n-10,t+n-5]])D(g.paper,()=>{e.moveTo(o-2.5,s),e.lineTo(o+2.5,s),e.lineTo(p+2.5,d),e.lineTo(p-2.5,d),e.closePath()});D(g.yellow,()=>e.roundRect(t,i,n,E,2)),e.save(),e.beginPath(),e.roundRect(t,i,n,E,2),e.clip(),e.fillStyle=g.ink;for(let o=t-E;oe.roundRect(t,s,n,A1,3))}function k(t,n,s,i,d,o){e.fillStyle=i,e.font=`${d?600:500} ${d??13}px ${f}`,e.fillText(t,n,s,o)}function C1(t){return Math.round(t*M)/M}function W(t=1){if(e.setTransform(M,0,0,M,0,0),e.clearRect(0,0,u,b),!c||!u)return;const n=g;if(e.lineWidth=1.5,e.strokeStyle=n.ink,e.lineJoin="round",e.textAlign="center",!z){e.font=`600 11px ${f}`;const s=Math.ceil(e.measureText(c.status).width)+16;e.font=`600 15px ${f}`;const i=e.measureText([...c.loading][0]??"").actualBoundingBoxAscent,d=e.measureText(c.progress).width,o=Y1(u,b,{board:s,row:Math.ceil(e.measureText(c.loading+"...").width+S1+d),cap:i});e.save(),e.translate(o.cx,b/2),e.scale(o.shrink,o.shrink),e.translate(-o.cx,-b/2),e.fillStyle=n.sub,e.fillRect(o.cx-o.reach,o.ground,2*o.reach,1.5),O1(o.post,o.board,o.sign,o.rail,o.ground),D(n.paper,()=>e.roundRect(o.x,o.top,o.bar,F,F/2)),e.fillStyle=n.bar,e.beginPath(),e.roundRect(o.x+4,o.top+4,(o.bar-8)*.97,F-8,(F-8)/2),e.fill();const p=Q1(l.matches?0:(performance.now()-m1)/1e3);e.textAlign="right",k(c.progress,o.x+o.bar,o.label,n.text,15),e.textAlign="left",k(c.loading+"...".slice(0,p),o.x,o.label,n.text,15,o.bar-S1-d),e.textAlign="center",e.textBaseline="middle",k(c.status,o.post+o.board/2,o.sign+A1/2+.5,n.ink,11,o.board-16),e.textBaseline="alphabetic",y1(o.duck,o.ground-Z/2,Z,-.06,!0),l.matches||k(c.start,o.cx,o.start,n.sub,void 0,Math.min(360,o.text)),e.restore();return}e.fillStyle=n.sub,e.fillRect(0,h,u,1.5);for(const s of y){const i=C1(s.ox+(s.x-s.ox)*t),d=s.oc+(s.c-s.oc)*t,o=d-s.gap/2,p=d+s.gap/2;for(const[L,$1]of[[0,o],[p,h]]){D(n.wall,()=>e.rect(i,L-2,C,$1-L+2)),e.fillStyle=n.base;const j=!L;for(let c1=1,O=(j?o:p)+(j?-12:12);O>1&&Oe.roundRect(u/2-150,16,300,92,8)),k(c.result(G(H)),u/2,46,n.text,16),k(c.best(G(Math.max(V,H))),u/2,70,n.sub),performance.now()-x>900&&k(c.restart,u/2,94,n.sub)):(D(n.base,()=>e.roundRect(u/2-70,18,140,52,8)),k(G(H),u/2,40,n.text,16),k(J1(_),u/2,60,q-t1<1.2&&_?n.accent:n.sub)),e.strokeStyle=n.ink,y1(v,A+(w-A)*t,R,Math.max(-.35,Math.min(.5,S/900)))}function F1(t){for(X=0,$+=Math.min(.1,(t-(n1||t))/1e3),n1=t;$>=J&&!x;)z1(J),$-=J;W(x?1:$/J),T()}function T(){if(window.clearTimeout(r1),l.matches&&(z=!1),!z||x||l.matches||document.hidden||!o1){n1=0,!z&&!l.matches&&!document.hidden&&o1&&(r1=window.setTimeout(T,f1-(performance.now()-m1)%f1+5)),W();return}X||(X=requestAnimationFrame(F1))}function a1(t){l.matches||x&&!t&&performance.now()-x<900||((!z||x||t)&&(z=!0,x1()),S=-e1,T())}const T1=t=>{t.button||(t.preventDefault(),r.focus({preventScroll:!0,focusVisible:!1}),a1(!1))},k1=t=>{t.ctrlKey||t.metaKey||t.altKey||(t.key===" "||t.key==="r"||t.key==="R")&&(t.preventDefault(),t.repeat||a1(t.key!==" "))},E1=t=>{t.detail===0&&a1(!1)},R1=()=>{g=g1(),W()};r.addEventListener("pointerdown",T1),r.addEventListener("keydown",k1),r.addEventListener("click",E1),document.addEventListener("visibilitychange",T),l.addEventListener("change",T);const v1=new ResizeObserver(()=>{w1(),T()});v1.observe(a);const L1=new IntersectionObserver(t=>{o1=t[t.length-1].isIntersecting,T()});L1.observe(a);const P1=new MutationObserver(R1);return P1.observe(I,{attributes:!0,attributeFilter:["data-scheme","data-family","data-flavour"]}),w1(),x1(),T(),{setText(t){c=t,R1();const n=[t.loading,".",t.progress,t.status,t.start,t.restart,t.result(G(0)),t.best(G(0))].join("");Promise.all([500,600].map(s=>document.fonts.load(`${s} 16px ${f}`,n))).then(()=>{c===t&&W()},()=>{})},destroy(){c=void 0,cancelAnimationFrame(X),window.clearTimeout(s1),window.clearTimeout(r1),r.removeEventListener("pointerdown",T1),r.removeEventListener("keydown",k1),r.removeEventListener("click",E1),document.removeEventListener("visibilitychange",T),l.removeEventListener("change",T),v1.disconnect(),L1.disconnect(),P1.disconnect()}}}function ne(){const r=W1(),a=j1("(prefers-reduced-motion: reduce)"),m=B.useRef(null),e=B.useRef(null),l=B.useRef(null),[I,P]=B.useState(null),c=B.useMemo(()=>({loading:r("login.gameLoading"),progress:r("login.gameProgress"),status:r("login.gameStatus"),start:r("login.gameStart"),restart:r("login.gameRestart"),result:f=>r("login.gameResult",{amount:f}),best:f=>r("login.gameBest",{amount:f})}),[r]);return B.useEffect(()=>{const f=Z1(m.current,e.current,(g,M)=>P({amount:g,best:M}));return l.current=f,()=>{f.destroy(),l.current=null}},[]),B.useEffect(()=>l.current?.setText(c),[c]),N.jsxs("aside",{className:"rp-login-showcase","aria-hidden":a||void 0,children:[N.jsx(N1,{ref:m,canvasRef:e,className:"rp-login-game",label:r("login.gameLabel"),isDisabled:a}),N.jsx(K1,{"aria-live":"polite",children:I&&r("login.gameOver",I)})]})}export{ne as default}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/LoginShowcase-hawa0qI8.js b/luci-app-honk/root/etc/honk/doona/assets/LoginShowcase-hawa0qI8.js new file mode 100644 index 000000000..f6540c507 --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/LoginShowcase-hawa0qI8.js @@ -0,0 +1 @@ +import{j as U,r as I}from"./vendor-react-Bf71BWbF.js";import{fD as O1,u as K1,a as U1,f as N1,a6 as V1,aQ as X1}from"./index-Bw0aJc9a.js";function Q1({label:r,className:c,isDisabled:f,ref:e,canvasRef:l}){return U.jsx("button",{ref:e,type:"button",className:c,"aria-label":r,disabled:f,children:U.jsx("canvas",{ref:l})})}const q1=[["ink","M657 1228c-12-4-23-14-28-26-1-4-2-4-4-4-22 4-36 3-49-3-11-6-18-16-20-27-2-11 3-23 12-34 3-3 6-6 6-6 0 0-7-1-15-1-34-2-70-7-100-14-49-12-98-36-134-67l-5-4-12 4c-20 7-36 9-60 9-21 0-43-4-57-10-13-5-25-16-30-25-5-10-4-23 3-34 4-6 16-18 24-22l6-4-3-8c-2-5-2-9-2-12 1-6 5-15 9-18 4-5 16-13 21-14 3-1 5-2 6-2 0-1-1-6-3-12-21-73-6-145 45-212l7-10-12-2c-15-1-23-3-34-7-24-9-40-29-40-49 0-19 7-34 36-72 15-21 27-39 35-54 11-19 10-17 5-28-2-4-5-11-6-14-2-8-3-32-1-43 4-28 18-59 42-90l3-5-6-4c-11-9-20-21-23-32-2-6-2-9-2-17 1-9 1-10 4-18 6-11 15-20 29-27 14-7 24-10 47-15 1 0 3-3 7-11 19-37 51-71 88-94 12-8 32-18 44-22 10-3 29-8 33-8 1 0 5-2 8-5 11-8 25-14 39-16 12-2 49-1 63 2 21 4 34 9 45 19 8 7 10 9 15 18 4 7 4 7 13 12 34 18 63 46 86 81 10 16 20 38 26 57 4 12 8 34 10 48 2 13 2 43 0 56l-1 10 6 7c8 8 14 19 18 28 3 9 4 24 2 33-3 14-14 27-29 35-9 5-19 7-31 8l-9 1 0 8c0 4 0 15 0 25 0 16-1 31-5 47l0 3 14 0c27 0 58 5 83 14 21 9 51 25 68 39 3 2 6 5 7 5 0 1 6-2 14-6 27-14 49-17 69-11 26 8 38 34 27 64-2 5-3 9-3 10 0 0 4 1 8 3 14 7 24 19 29 34 8 22 0 45-24 73l-5 6 3 9c6 26 8 63 5 89-2 14-7 33-12 48-9 22-26 52-43 72-10 13-34 36-47 46-28 22-59 39-93 52-16 7-44 16-47 16-1 0-1 1-1 3 9 31 7 61-3 81-8 16-19 27-33 34-9 4-14 5-25 5-15 0-28-4-39-13l-6-5-7 6c-9 7-18 13-26 16-9 3-27 4-35 1z"],["paper","M582 1098c-44-2-79-6-117-16-55-14-102-41-141-81-42-43-67-93-75-148-2-14-1-43 1-56 6-30 16-57 32-82 8-12 24-33 32-42 6-7 7-7 17-10 58-18 110-56 126-92 2-5 2-9 3-16 1-14-2-21-15-33-13-14-21-24-33-39-18-26-28-35-45-43-11-5-21-7-33-7-13 0-23 2-33 7-6 3-9 3-9 3-4-6-4-28-2-42 5-23 18-49 37-73 14-18 37-39 56-53 5-4 6-4 11-4 41 1 105 13 154 28 32 9 72 25 104 42 18 9 51 27 66 37 8 5 8 5 11 13 7 16 13 37 16 56 2 11 2 41 1 54-4 39-19 74-44 104-8 9-10 14-9 20 1 5 7 10 13 12 7 2 14-1 24-11 10-11 22-29 32-48 3-5 4-7 6-7 2-1 14-1 27-1 22 0 24 0 37 2 34 8 68 24 98 48 13 11 15 12 20 12 5 0 7-1 16-7 22-14 41-21 53-18 13 3 16 15 7 32-2 5-6 11-8 15-4 8-4 14 0 19 4 5 7 6 17 7 15 1 23 5 27 14 3 6 3 15 0 22-2 6-10 18-20 30-9 11-11 15-8 24 3 10 6 33 7 52 0 26-2 47-10 70-18 53-57 101-111 135-40 25-87 43-144 54-66 14-132 19-194 17z"],["ink","M517 445c-7-2-13-6-18-12-7-7-9-14-9-25 0-7 0-8 3-15 7-13 17-21 31-22 23-1 43 18 41 40-2 19-17 33-36 35-4 0-9-1-12-1z"],["yellow","M541 220c-13-3-27-7-41-9-6-1-14-3-17-3l-5-1 2-6c3-15 13-40 23-59 20-39 43-66 64-73 11-3 56-1 74 4 7 1 13 4 17 7 3 3 3 4-1 4-5 0-17 4-24 7-35 18-62 59-79 118-2 8-4 14-4 14 0 0-4-1-9-3z"],["yellow","M446 203c-4-1-19-1-35-2-16 0-29 0-29-1 0-1 6-12 12-20 22-34 53-62 87-78 10-5 32-13 33-12 0 0-2 3-6 8-19 27-38 69-47 102-1 4-1 4-5 4-3 0-7-1-10-1z"],["yellow","M569 226c13-58 39-102 70-119 14-7 21-6 40 1 53 23 96 73 113 132 9 29 11 67 7 95-71-43-149-81-230-109z"],["yellow","M780 426c-1-2-5-19-5-19 0-1 3 0 8 0 6 0 8 0 10-2 5-4 3-6-21-21-50-32-74-46-109-63-71-36-143-57-225-67-48-6-99-5-107 1-4 3-5 5-2 7 1 2 3 2 10 3l8 0-4 4c-3 3-9 8-13 12l-9 8-4-2c-6-4-13-11-16-17-3-5-4-12-3-17 2-8 11-17 22-22 22-10 60-14 101-12 63 3 121 16 167 36 71 31 145 67 214 105 17 10 27 31 23 45-1 5-6 12-10 15-6 4-15 6-25 7-8 0-10 0-10-1z"],["yellow","M251 640c-19-4-32-16-32-29 0-10 5-19 23-43 26-34 37-50 50-75 6-12 9-17 13-20 12-11 29-13 45-7 11 5 17 10 37 36 9 13 19 25 24 30 5 5 10 10 12 13 2 3 2 5 2 10 0 5-1 8-4 12-17 29-73 61-123 71-14 3-38 4-47 2z"],["yellow","M226 1028c-12-1-24-5-31-10-12-8-13-16-2-27 5-5 19-13 30-17 7-3 11-6 11-8 0-3-1-5-8-9-7-6-10-10-10-14 0-4 1-5 4-8 2-2 6-4 9-5 3-1 5-2 5-2 1 0 4 7 8 14 15 29 28 49 49 72 4 5 7 8 7 9-1 1-21 5-29 6-13 1-31 1-43-1z"],["yellow","M663 1201c-7-4-9-12-7-24 1-7 1-8 0-10-3-4-7-4-15-1-18 7-40 10-48 7-5-2-8-6-8-11 0-7 8-16 29-30l10-7 19 0c22-1 52-4 78-7 18-3 57-9 65-11 6-2 11-1 14 1 2 3 4 7 5 20 4 39-13 70-39 68-9-1-16-5-29-17-14-12-14-12-27 1-11 11-20 18-28 21-7 3-15 3-19 0z"]],N={width:940,height:1192},K=1.4,v=52,Z=72,f1=500,J1=250,$=22,Y=22,i1=Y+2,l1=16,u1=12,Y1=56,A1=17,E=9,D1=18,q=1/120,h1=1500,e1=430,B=48,Z1=e1*e1/(2*h1),H1=Math.max(2.2*v,v+Z1+4),z1=200,_1=z1*h1/(2*e1),J=.84*v*N.width/N.height/2,d1=.84*v/2;function C1(r,c){let f=0;for(;r>=1e3&&f=6}}function te(r){return(Math.floor(r*1e3/f1)+3)%4}function ne(r,c,f={}){const e=Z*N.width/N.height,l=Math.max(Y1,f.board??0),S=Math.floor(r-2*(u1+l1)-l-i1-Y-e),R=Math.max(120,f.row??0,Math.min(J1,S)),a=l+i1+R+Y+e,M=Math.min(1,(r/2-u1)/(a/2+l1)),h=-2*$,w=h-12,d=-Z,y=40,m=Math.round(c/2-(d+y+4)/2),L=Math.round(r/2),g=Math.round(L-a/2),A=g+l+i1;return{cx:L,post:g,board:l,x:A,bar:R,ground:m,top:m+h,label:m+w,head:m+d,sign:m+w-(f.cap??12)+.75,rail:m+h+($-E)/2,start:m+y,duck:A+R+Y+e/2,reach:Math.round(a/2+l1),shrink:M,text:(r-2*u1)/M}}function oe(r,c,f){const e=c.getContext("2d");if(!e)return{setText(){},destroy(){}};const l=matchMedia("(prefers-reduced-motion: reduce)"),S=document.documentElement,R=q1.map(([t,n])=>[t,new Path2D(n)]);let a,M="",h=g1(),w=1,d=0,y=0,m=0,L=0,g=0,A=0,D=0,x=[],H=0,V=0,_=0,m1=0,t1=0,z=!1,b=0,X=0,n1=0,W=0,Q=0,o1=!0,s1=0,r1=0;const p1=performance.now();function g1(){const t=getComputedStyle(r),n=s=>t.getPropertyValue(s).trim();return M=t.fontFamily,{ink:n("--rp-mark-ink"),paper:n("--rp-mark-paper"),yellow:n("--rp-mark-yellow"),text:n("--rp-text"),sub:n("--rp-subtle"),accent:n("--rp-accent"),wall:n("--rp-negative"),base:n("--rp-base"),bar:n("--rp-positive")}}function w1(){w=(window.devicePixelRatio||1)*K,c.width=Math.round(c.clientWidth*w/K),c.height=Math.round(c.clientHeight*w/K),d=c.clientWidth/K,y=c.clientHeight/K,m=Math.round(y*.84),L=Math.round(d*.3)}function b1(t){const n=I1(_),s=40+n.gap/2+n.swing,i=m-30-n.gap/2-n.swing,u=x[x.length-1];let o=s+Math.random()*(i-s);if(u){const P=(n.gap-2*d1)/2+220*(n.space-B-2*J)/n.speed-2*n.swing;n.drift&&Math.random()<.6&&(o=u.c0<(s+i)/2?i:s),o=Math.max(u.c0-P,Math.min(u.c0+P,o))}o=Math.max(s,Math.min(i,o));const p=n.swing*(Math.random()<.5?1:0);x.push({x:t,ox:t,gap:n.gap,c0:o,c:o,oc:o,a:p,f:p?Math.min(3,110/p):0,ph:Math.random()*6.3,done:!1})}function M1(){g=A=y*.42,D=H=_=m1=t1=b=W=0,x=[],b1(d+10)}function y1(){b=performance.now(),V=Math.max(V,H),f(O(H,a.locale),O(V,a.locale)),window.clearTimeout(s1),s1=window.setTimeout(()=>j(),950)}function B1(t){const n=I1(_);Q+=t,A=g,D=Math.min(700,D+h1*t),g+=D*t,gL-J&&(g-d1s.c+s.gap/2)&&y1();x[x.length-1].xs.x>-B),!b&&g+v/2-3>m&&(g=m-v/2+3,y1())}function C(t,n){e.beginPath(),n(),e.fillStyle=t,e.fill(),e.stroke()}function x1(t,n,s,i,u){e.save(),e.beginPath(),e.roundRect(n,s,i,u,8),e.clip(),e.clearRect(n,s,i,u),e.restore(),C(t,()=>e.roundRect(n,s,i,u,8))}function T1(t,n,s,i,u=!1){const o=s/N.height;e.save(),e.translate(t,n),e.rotate(i),e.scale(u?o:-o,o),e.translate(-628,-634);for(const[p,P]of R)e.fillStyle=h[p],e.fill(P,"evenodd");e.restore()}function $1(t,n,s,i,u){for(const[o,p]of[[t+10,t+5],[t+n-10,t+n-5]])C(h.paper,()=>{e.moveTo(o-2.5,s),e.lineTo(o+2.5,s),e.lineTo(p+2.5,u),e.lineTo(p-2.5,u),e.closePath()});C(h.yellow,()=>e.roundRect(t,i,n,E,2)),e.save(),e.beginPath(),e.roundRect(t,i,n,E,2),e.clip(),e.fillStyle=h.ink;for(let o=t-E;oe.roundRect(t,s,n,A1,3))}function k(t,n,s,i,u,o){e.fillStyle=i,e.font=`${u?600:500} ${u??13}px ${M}`,e.fillText(t,n,s,o)}function W1(t){return Math.round(t*w)/w}function j(t=1){if(e.setTransform(w,0,0,w,0,0),e.clearRect(0,0,d,y),!a||!d)return;const n=h;if(e.lineWidth=1.5,e.strokeStyle=n.ink,e.lineJoin="round",e.textAlign="center",!z){e.font=`600 11px ${M}`;const s=Math.ceil(e.measureText(a.status).width)+16;e.font=`600 15px ${M}`;const i=e.measureText([...a.loading][0]??"").actualBoundingBoxAscent,u=e.measureText(a.progress).width,o=ne(d,y,{board:s,row:Math.ceil(e.measureText(a.loading+"...").width+D1+u),cap:i});e.save(),e.translate(o.cx,y/2),e.scale(o.shrink,o.shrink),e.translate(-o.cx,-y/2),e.fillStyle=n.sub,e.fillRect(o.cx-o.reach,o.ground,2*o.reach,1.5),$1(o.post,o.board,o.sign,o.rail,o.ground),C(n.paper,()=>e.roundRect(o.x,o.top,o.bar,$,$/2)),e.fillStyle=n.bar,e.beginPath(),e.roundRect(o.x+4,o.top+4,(o.bar-8)*.97,$-8,($-8)/2),e.fill();const p=te(l.matches?0:(performance.now()-p1)/1e3);e.textAlign="right",k(a.progress,o.x+o.bar,o.label,n.text,15),e.textAlign="left",k(a.loading+"...".slice(0,p),o.x,o.label,n.text,15,o.bar-D1-u),e.textAlign="center",e.textBaseline="middle",k(a.status,o.post+o.board/2,o.sign+A1/2+.5,n.ink,11,o.board-16),e.textBaseline="alphabetic",T1(o.duck,o.ground-Z/2,Z,-.06,!0),l.matches||k(a.start,o.cx,o.start,n.sub,void 0,Math.min(360,o.text)),e.restore();return}e.fillStyle=n.sub,e.fillRect(0,m,d,1.5);for(const s of x){const i=W1(s.ox+(s.x-s.ox)*t),u=s.oc+(s.c-s.oc)*t,o=u-s.gap/2,p=u+s.gap/2;for(const[P,F1]of[[0,o],[p,m]]){C(n.wall,()=>e.rect(i,P-2,B,F1-P+2)),e.save(),e.globalAlpha=.35,e.fillStyle=n.ink;const F=!P;for(let c1=1,G=(F?o:p)+(F?-12:12);G>1&&G900&&k(a.restart,d/2,94,n.sub)):(x1(n.base,d/2-70,18,140,52),k(O(H,a.locale),d/2,40,n.text,16),k(ee(_,a.locale),d/2,60,Q-t1<1.2&&_?n.accent:n.sub)),e.strokeStyle=n.ink,T1(L,A+(g-A)*t,v,Math.max(-.35,Math.min(.5,D/900)))}function j1(t){for(X=0,W+=Math.min(.1,(t-(n1||t))/1e3),n1=t;W>=q&&!b;)B1(q),W-=q;j(b?1:W/q),T()}function T(){if(window.clearTimeout(r1),l.matches&&(z=!1),!z||b||l.matches||document.hidden||!o1){n1=0,!z&&!l.matches&&!document.hidden&&o1&&(r1=window.setTimeout(T,f1-(performance.now()-p1)%f1+5)),j();return}X||(X=requestAnimationFrame(j1))}function a1(t){l.matches||b&&!t&&performance.now()-b<900||((!z||b||t)&&(z=!0,M1()),D=-e1,T())}const k1=t=>{t.button||(t.preventDefault(),r.focus({preventScroll:!0,focusVisible:!1}),a1(!1))},E1=t=>{t.ctrlKey||t.metaKey||t.altKey||(t.key===" "||t.key==="r"||t.key==="R")&&(t.preventDefault(),t.repeat||a1(t.key!==" "))},v1=t=>{t.detail===0&&a1(!1)},R1=()=>{h=g1(),j()};r.addEventListener("pointerdown",k1),r.addEventListener("keydown",E1),r.addEventListener("click",v1),document.addEventListener("visibilitychange",T),l.addEventListener("change",T);const L1=new ResizeObserver(()=>{w1(),T()});L1.observe(c);const P1=new IntersectionObserver(t=>{o1=t[t.length-1].isIntersecting,T()});P1.observe(c);const S1=new MutationObserver(R1);return S1.observe(S,{attributes:!0,attributeFilter:["data-scheme","data-family","data-flavour"]}),w1(),M1(),T(),{setText(t){a=t,R1();const n=[t.loading,".",t.progress,t.status,t.start,t.restart,t.result(O(0,t.locale)),t.best(O(0,t.locale))].join("");Promise.all([500,600].map(s=>document.fonts.load(`${s} 16px ${M}`,n))).then(()=>{a===t&&j()},()=>{})},destroy(){a=void 0,cancelAnimationFrame(X),window.clearTimeout(s1),window.clearTimeout(r1),r.removeEventListener("pointerdown",k1),r.removeEventListener("keydown",E1),r.removeEventListener("click",v1),document.removeEventListener("visibilitychange",T),l.removeEventListener("change",T),L1.disconnect(),P1.disconnect(),S1.disconnect()}}}function ae(){const r=K1(),c=U1(),f=N1("(prefers-reduced-motion: reduce)"),e=I.useRef(null),l=I.useRef(null),S=I.useRef(null),[R,a]=I.useState(null),M=I.useMemo(()=>({locale:V1[c],loading:r("login.gameLoading"),progress:r("login.gameProgress"),status:r("login.gameStatus"),start:r("login.gameStart"),restart:r("login.gameRestart"),result:h=>r("login.gameResult",{amount:h}),best:h=>r("login.gameBest",{amount:h})}),[r,c]);return I.useEffect(()=>{const h=oe(e.current,l.current,(w,d)=>a({amount:w,best:d}));return S.current=h,()=>{h.destroy(),S.current=null}},[]),I.useEffect(()=>S.current?.setText(M),[M]),U.jsxs("aside",{className:"rp-login-showcase","aria-hidden":f||void 0,children:[U.jsx(Q1,{ref:e,canvasRef:l,className:"rp-login-game",label:r("login.gameLabel"),isDisabled:f}),U.jsx(X1,{"aria-live":"polite",children:R&&r("login.gameOver",R)})]})}export{ae as default}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Logs-CVSaRJiC.js b/luci-app-honk/root/etc/honk/doona/assets/Logs-CVSaRJiC.js new file mode 100644 index 000000000..60af2f0f9 --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/Logs-CVSaRJiC.js @@ -0,0 +1,3 @@ +import{j as r,r as x}from"./vendor-react-Bf71BWbF.js";import{aT as P,u as L,a6 as O,a as D,aI as B,H as T,B as W,ex as H,bP as k,ey as C,aN as I,a4 as N,aw as _,aa as q,aF as J,bI as G,ez as K,dl as V,eA as z,aL as S,aJ as F,aK as U,bt as Q,T as X,cN as Y,aM as Z,E as ee}from"./index-Bw0aJc9a.js";import{F as te}from"./FactStrip-DtkOGBRy.js";import{u as se,h as ae,C as re,t as oe}from"./layout-BWzq8YqC.js";import{D as ne}from"./Table-Km6Zv-S8.js";import{A as le}from"./ActionGroup-DLxTuKht.js";import{d as ie,e as ce}from"./files-BxEOxSF8.js";import{r as ge}from"./recorder-DlDpPhd4.js";import"./useGridSelectionCheckbox-COXIVEmS.js";import"./Virtualizer-DCY9HC9Z.js";import"./ListLayout-_fDlx5XY.js";function ue({label:a,rows:t,columns:e}){const n=P(),{ref:s,tip:o,show:c,hide:p}=se();return r.jsxs("div",{className:"rp-heatmap rp-chart-hover",ref:s,onPointerLeave:p,role:"group","aria-label":a,"aria-describedby":n,style:{"--cols":e.length},children:[t.map(i=>{const g=Math.max(...i.counts);return r.jsxs("div",{className:"row",children:[r.jsx("div",{className:"head",children:i.label}),r.jsx("div",{className:"cells",children:i.counts.map((b,v)=>r.jsx("span",{className:"cell t"+ae(b,g),style:{"--tone":i.color},onPointerMove:d=>c(d,[i.titles[v]]),role:"img","aria-label":i.titles[v]},v))})]},i.id)}),e.length>0&&r.jsxs("div",{className:"row times","aria-hidden":"true",children:[r.jsx("div",{className:"head"}),r.jsxs("div",{className:"ends",children:[r.jsx("span",{children:e[0]}),e.length>2&&r.jsx("span",{children:e[Math.floor(e.length/2)]}),e.length>1&&r.jsx("span",{children:e[e.length-1]})]})]}),r.jsx(re,{tip:o})]})}const A=new WeakMap;function E(a){let t=A.get(a);return t===void 0&&A.set(a,t=Date.parse(a.ts)),t}const M=["error","warn","info","debug","trace"];function de(a,t,e,n=24){const s=e?M.indexOf(e):M.length-1,o=M.filter((u,h)=>t.includes(u)&&h<=s),c=a.map(E).filter(Number.isFinite);if(!c.length)return{rows:o.map(u=>({level:u,counts:[]})),buckets:[],width:0,busiest:null};const p=Math.min(...c),i=Math.max(...c),g=oe(p,i,n),b=g.length>1?g[1]-g[0]:Math.max(i-p,6e4),v=new Map(o.map(u=>[u,new Array(g.length).fill(0)])),d=new Array(g.length).fill(0),j=new Array(g.length).fill(0);for(const u of a){const h=E(u),w=v.get(u.level);if(!w||!Number.isFinite(h))continue;const y=Math.min(g.length-1,Math.floor((h-g[0])/b));w[y]++,d[y]++,u.level==="error"&&j[y]++}const f=u=>u.reduce((h,w,y)=>w>u[h]?y:h,0),m=j.reduce((u,h)=>u+h,0),l=f(m?j:d);return{rows:o.map(u=>({level:u,counts:v.get(u)})),buckets:g,width:b,busiest:{start:g[l],count:m?j[l]:d[l],errors:m}}}function pe({records:a,offered:t,minimum:e,setMinimum:n}){const s=L(),o=O[D()],c=B(),p=x.useMemo(()=>de(a,t,e),[a,t,e]),i=x.useMemo(()=>new Intl.DateTimeFormat(o,{hour:"2-digit",minute:"2-digit",hourCycle:"h23"}),[o]),g=x.useCallback(f=>`${i.format(f)}–${i.format(f+p.width)}`,[i,p.width]),b=x.useMemo(()=>{const f=Object.keys(T).map(m=>{const l=s(T[m]);return[m,{text:l,label:r.jsxs(W,{quiet:!0,small:!0,className:m===e?"current":void 0,label:s(m===e?"log.chart.current":"log.chart.minimum",{level:l}),onPress:()=>n(m),children:[m===e&&r.jsx(H,{}),l]})}]});return new Map(f)},[e,n,s]),v=x.useMemo(()=>{const f={error:c.negative,warn:c.notice,info:c.info,debug:c.subtle,trace:c.muted},m=p.buckets.map(g);return{columns:p.buckets.map(l=>i.format(l)),rows:p.rows.map(l=>{const{text:u,label:h}=b.get(l.level);return{id:l.level,color:f[l.level],label:h,counts:l.counts,titles:l.counts.map((w,y)=>s("log.chart.cell",{time:m[y],level:u,n:w}))}})}},[p,g,i,b,c,s]);if(!a.length)return null;const d=p.busiest,j=d?d.errors?[{label:s("log.chart.errors"),value:s("log.chart.count",{n:d.errors}),icon:r.jsx(k,{}),tone:"negative"},{label:s("log.chart.peakErrors"),icon:r.jsx(C,{}),tint:"c1",value:g(d.start),caption:s("log.chart.count",{n:d.count})}]:[{label:s("log.chart.errors"),value:s("log.chart.count",{n:0}),icon:r.jsx(k,{}),tint:"c5"},{label:s("log.chart.peak"),icon:r.jsx(C,{}),tint:"c1",value:g(d.start),caption:s("log.chart.count",{n:d.count})}]:[];return r.jsxs("div",{className:"rp-chart-page",children:[r.jsx(te,{facts:j}),r.jsx(I,{title:s("log.chart.title"),note:s("log.chart.sample",{n:a.length}),children:r.jsx(ue,{label:s("log.chart.title"),columns:v.columns,rows:v.rows})})]})}const R=["trace","debug","info","warn","error"],me={trace:"muted",debug:"neutral",info:"info",warn:"warn",error:"err"},$=new WeakMap;function he(a,t,e){const n=$.get(a);if(n&&n.locale===t)return n.row;const s={id:a.id,timestamp:_(a.ts,t),iso:a.ts,levelText:N(T,a.level,e),tone:me[a.level],target:a.target,gap:!1,message:a.message+(a.fields?" "+Object.entries(a.fields).map(([o,c])=>`${o}=${typeof c=="string"?c:JSON.stringify(c)}`).join(" "):"")};return $.set(a,{locale:t,row:s}),s}function fe(a,t,e,n,s,o=new Set,c){const p=i=>!!c&&R.indexOf(i){const g=he(i,n,s);return o.has(i)?[{...g,id:`gap ${i.id}`,timestamp:"",iso:"",levelText:"",target:"",gap:!0,message:s("log.gap")},g]:[g]}),levels:t.map(i=>({id:i,label:p(i)?s("log.levelNotRecorded",{level:N(T,i,s)}):N(T,i,s)})),recordedText:c?s("log.recorded",{level:N(T,c,s)}):null,exportBase:`${e||"engine"}-log`}}function xe(a,t,e){return e(ge(a,t,{forbidden:"log.emptyForbidden",off:"log.emptyNotRecorded",filtered:"log.emptyFiltered",empty:"log.empty"}))}function be(a,t,e,n,s,o){return t?{tone:"err",text:o("log.disconnected")}:e?{tone:"neutral",text:o(n>s?"log.pausedOverflow":"log.paused",{n:Math.min(n,s)})}:{tone:a?"ok":"warn",text:o(a?"log.connected":"log.reconnecting")}}function ve(a,t=[]){return t.includes(a)?a:t.includes("info")?"info":t[0]}function je(a,t,e){return[...a].reverse().flatMap(n=>{const s=`${n.ts} ${n.level.toUpperCase().padEnd(5)} ${n.target??"—"} ${n.message}${n.fields?" "+JSON.stringify(n.fields):""}`;return t.has(n)?[s,e("log.gap")]:[s]}).join(` +`)+` +`}const we=[];function ye({go:a}){const t=L(),e=O[D()],n=q(),s=J(),[o,c]=x.useState("info"),p=x.useCallback(y=>c(y),[]),[i,g]=x.useState(""),[b,v]=x.useState(!1),d=n.data?.resources.logs,j=d?.filters?.includes("target")??!1,f=G(j?i.trim():""),m=ve(o,d?.levels),l=K({level:m,target:f,paused:b}),u=V(n.data?.resources.runtime_settings.available??!1).data,h=u?.log?.level,w=x.useMemo(()=>fe(l.records,d?.levels??[],s.data?.engine.name,e,t,l.gaps,h),[l.records,l.gaps,d,s.data,e,t,h]);return{...w,empty:xe(u?.recording?.logs,!!f,t),status:be(l.connected,!!l.error,b,l.pending,z,t),records:l.records,offered:d?.levels??we,level:m??"",setLevel:p,filtersTarget:j,target:i,setTarget:g,paused:b,setPaused:v,error:n.error??l.error,loading:!n.error&&!l.error&&!l.connected&&!l.records.length,clear:l.clear,openRecording:n.data?.resources.runtime_settings.available?()=>a("settings","card=runtime"):null,retry:n.error?n.refetch:l.retry,export:()=>ie(ce(w.exportBase,"txt"),je(l.records,l.gaps,t),"text/plain;charset=utf-8")}}function $e({go:a}){const t=L(),e=ye({go:a}),n=x.useMemo(()=>[{id:"ts",label:t("ui.time"),minWidth:200,grow:0,drop:2,render:o=>!o.gap&&r.jsx(S,{className:"rp-code",text:o.iso,children:o.timestamp})},{id:"level",label:t("log.level"),minWidth:90,grow:0,drop:3,render:o=>!o.gap&&r.jsx(F,{small:!0,tone:o.tone,children:o.levelText})},{id:"target",label:t("log.target"),minWidth:160,grow:0,drop:1,render:o=>r.jsx("span",{className:"rp-code",children:o.target??"—"})},{id:"message",label:t("log.message"),minWidth:280,grow:3,isRowHeader:!0,render:o=>r.jsx(S,{children:o.message})}],[t]),s=x.useCallback(o=>r.jsx(U,{inline:!0,items:o.gap?[[t("log.message"),o.message]]:[[t("ui.time"),o.timestamp],[t("log.level"),o.levelText],[t("log.target"),o.target??"—"],[t("log.message"),o.message]]}),[t]);return r.jsxs("div",{className:"rp-page",children:[r.jsxs("div",{className:"rp-toolbar",children:[r.jsx(Q,{side:!0,label:t("log.level"),value:e.level,onChange:e.setLevel,items:e.levels}),e.filtersTarget&&r.jsx(X,{search:!0,label:t("log.target"),value:e.target,width:240,placeholder:t("log.targetPlaceholder"),onChange:e.setTarget}),r.jsx(Y,{isSelected:e.paused,onChange:e.setPaused,children:t("log.pause")}),r.jsx(F,{small:!0,tone:e.status.tone,children:e.status.text}),e.recordedText&&r.jsx("span",{className:"rp-label",children:e.recordedText}),r.jsx("span",{className:"rp-grow"}),r.jsx(le,{actions:[{id:"clear",label:t("log.clear"),isDisabled:!e.rows.length,onAction:e.clear},{id:"export",label:t("log.export"),icon:r.jsx(Z,{}),isDisabled:!e.rows.length,onAction:e.export},...e.openRecording?[{id:"recording",label:t("ui.recordingSettings"),onAction:e.openRecording}]:[]]})]}),r.jsx(ee,{error:e.error,onRetry:e.retry}),r.jsx(pe,{records:e.records,offered:e.offered,minimum:e.level,setMinimum:e.setLevel}),r.jsx(ne,{label:t("nav.logs"),stream:!0,rows:e.rows,height:640,loading:e.loading,empty:e.empty,cols:n,detail:s})]})}export{$e as Logs}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Logs-sKihIR9Z.js b/luci-app-honk/root/etc/honk/doona/assets/Logs-sKihIR9Z.js deleted file mode 100644 index e2312fece..000000000 --- a/luci-app-honk/root/etc/honk/doona/assets/Logs-sKihIR9Z.js +++ /dev/null @@ -1,3 +0,0 @@ -import{j as a,r as b}from"./vendor-react-Bf71BWbF.js";import{aP as P,u as M,a5 as D,a as R,aE as B,dO as T,B as W,dP as H,bA as k,dQ as C,aJ as I,a3 as N,a4 as _,at as q,a8 as G,aB as J,bu as V,dR as K,c_ as Q,dS as U,aH as S,aF as E,aG as z,b5 as X,T as Y,cA as Z,aI as ee,E as te}from"./index-BNBwb-FJ.js";import{F as se}from"./FactStrip-n2q1T87k.js";import{u as ae,h as re,C as oe,t as ne}from"./layout-wfdMYi2n.js";import{D as le}from"./Table-DyWJelc_.js";import{A as ie}from"./ActionGroup-BKxDwmnT.js";import{d as ce,e as ge}from"./files-BxEOxSF8.js";import{r as ue}from"./recorder-DlDpPhd4.js";import"./useGridSelectionCheckbox-CrCOlZv8.js";import"./Virtualizer-DipGMcji.js";import"./ListLayout-F74Z1Dpf.js";function de({label:e,rows:s,columns:r}){const n=P(),{ref:t,tip:m,show:l,hide:p}=ae();return a.jsxs("div",{className:"rp-heatmap rp-chart-hover",ref:t,onPointerLeave:p,role:"group","aria-label":e,"aria-describedby":n,style:{"--cols":r.length},children:[s.map(o=>{const c=Math.max(...o.counts);return a.jsxs("div",{className:"row",children:[a.jsx("div",{className:"head",children:o.label}),a.jsx("div",{className:"cells",children:o.counts.map((v,x)=>a.jsx("span",{className:"cell t"+re(v,c),style:{"--tone":o.color},onPointerMove:u=>l(u,[o.titles[x]]),role:"img","aria-label":o.titles[x]},x))})]},o.id)}),r.length>0&&a.jsxs("div",{className:"row times","aria-hidden":"true",children:[a.jsx("div",{className:"head"}),a.jsxs("div",{className:"ends",children:[a.jsx("span",{children:r[0]}),r.length>2&&a.jsx("span",{children:r[Math.floor(r.length/2)]}),r.length>1&&a.jsx("span",{children:r[r.length-1]})]})]}),a.jsx(oe,{tip:m})]})}const F=new WeakMap;function $(e){let s=F.get(e);return s===void 0&&F.set(e,s=Date.parse(e.ts)),s}const L=["error","warn","info","debug","trace"];function pe(e,s,r,n=24){const t=r?L.indexOf(r):L.length-1,m=L.filter((g,f)=>s.includes(g)&&f<=t),l=e.map($).filter(Number.isFinite);if(!l.length)return{rows:m.map(g=>({level:g,counts:[]})),buckets:[],width:0,busiest:null};const p=Math.min(...l),o=Math.max(...l),c=ne(p,o,n),v=c.length>1?c[1]-c[0]:Math.max(o-p,6e4),x=new Map(m.map(g=>[g,new Array(c.length).fill(0)])),u=new Array(c.length).fill(0),j=new Array(c.length).fill(0);for(const g of e){const f=$(g),y=x.get(g.level);if(!y||!Number.isFinite(f))continue;const w=Math.min(c.length-1,Math.floor((f-c[0])/v));y[w]++,u[w]++,g.level==="error"&&j[w]++}const i=g=>g.reduce((f,y,w)=>y>g[f]?w:f,0),h=j.reduce((g,f)=>g+f,0),d=i(h?j:u);return{rows:m.map(g=>({level:g,counts:x.get(g)})),buckets:c,width:v,busiest:{start:c[d],count:h?j[d]:u[d],errors:h}}}function me({records:e,offered:s,minimum:r,setMinimum:n}){const t=M(),m=D[R()],l=B(),p=b.useMemo(()=>pe(e,s,r),[e,s,r]),o=b.useMemo(()=>new Intl.DateTimeFormat(m,{hour:"2-digit",minute:"2-digit",hourCycle:"h23"}),[m]),c=b.useCallback(i=>`${o.format(i)}–${o.format(i+p.width)}`,[o,p.width]),v=b.useMemo(()=>{const i=Object.keys(T).map(h=>{const d=t(T[h]);return[h,{text:d,label:a.jsxs(W,{quiet:!0,small:!0,className:h===r?"current":void 0,label:t(h===r?"log.chart.current":"log.chart.minimum",{level:d}),onPress:()=>n(h),children:[h===r&&a.jsx(H,{}),d]})}]});return new Map(i)},[r,n,t]),x=b.useMemo(()=>{const i={error:l.negative,warn:l.notice,info:l.info,debug:l.subtle,trace:l.muted},h=p.buckets.map(c);return{columns:p.buckets.map(d=>o.format(d)),rows:p.rows.map(d=>{const{text:g,label:f}=v.get(d.level);return{id:d.level,color:i[d.level],label:f,counts:d.counts,titles:d.counts.map((y,w)=>t("log.chart.cell",{time:h[w],level:g,n:y}))}})}},[p,c,o,v,l,t]);if(!e.length)return null;const u=p.busiest,j=u?u.errors?[{label:t("log.chart.errors"),value:t("log.chart.count",{n:u.errors}),icon:a.jsx(k,{}),tone:"negative"},{label:t("log.chart.peakErrors"),icon:a.jsx(C,{}),tint:"c1",value:c(u.start),caption:t("log.chart.count",{n:u.count})}]:[{label:t("log.chart.errors"),value:t("log.chart.count",{n:0}),icon:a.jsx(k,{}),tint:"c5"},{label:t("log.chart.peak"),icon:a.jsx(C,{}),tint:"c1",value:c(u.start),caption:t("log.chart.count",{n:u.count})}]:[];return a.jsxs("div",{className:"rp-chart-page",children:[a.jsx(se,{facts:j}),a.jsx(I,{title:t("log.chart.title"),note:t("log.chart.sample",{n:e.length}),children:a.jsx(de,{label:t("log.chart.title"),columns:x.columns,rows:x.rows})})]})}const A=["trace","debug","info","warn","error"],he={trace:"muted",debug:"neutral",info:"info",warn:"warn",error:"err"},O=new WeakMap;function fe(e,s,r){const n=O.get(e);if(n&&n.locale===s)return n.row;const t={id:e.id,timestamp:q(e.ts,s),iso:e.ts,levelText:N(T,e.level,r),tone:he[e.level],target:e.target,gap:!1,message:e.message+(e.fields?" "+Object.entries(e.fields).map(([m,l])=>`${m}=${typeof l=="string"?l:JSON.stringify(l)}`).join(" "):"")};return O.set(e,{locale:s,row:t}),t}function xe(e,s,r,n,t,m=new Set,l){const p=o=>!!l&&A.indexOf(o){const c=fe(o,n,t);return m.has(o)?[{...c,id:`gap ${o.id}`,timestamp:"",iso:"",levelText:"",target:"",gap:!0,message:t("log.gap")},c]:[c]}),levels:s.map(o=>({id:o,label:p(o)?t("log.levelNotRecorded",{level:N(T,o,t)}):N(T,o,t)})),recordedText:l?t("log.recorded",{level:N(T,l,t)}):null,exportBase:`${r||"engine"}-log`}}function be(e,s,r){return r(ue(e,s,{forbidden:"log.emptyForbidden",off:"log.emptyNotRecorded",filtered:"log.emptyFiltered",empty:"log.empty"}))}function ve(e,s,r,n,t,m,l){return s?{tone:"err",text:l("log.disconnected")}:r?{tone:"neutral",text:l("log.paused",{n:n>t?`${_(t,m)}+`:n})}:{tone:e?"ok":"warn",text:l(e?"log.connected":"log.reconnecting")}}function je(e,s=[]){return s.includes(e)?e:s.includes("info")?"info":s[0]}function we(e,s,r){return[...e].reverse().flatMap(n=>{const t=`${n.ts} ${n.level.toUpperCase().padEnd(5)} ${n.target} ${n.message}${n.fields?" "+JSON.stringify(n.fields):""}`;return s.has(n)?[t,r("log.gap")]:[t]}).join(` -`)+` -`}const ye=[];function Te(){const e=M(),s=D[R()],r=G(),n=J(),[t,m]=b.useState("info"),l=b.useCallback(f=>m(f),[]),[p,o]=b.useState(""),[c,v]=b.useState(!1),x=V(p.trim()),u=r.data?.resources.logs,j=je(t,u?.levels),i=K({level:j,target:x,paused:c}),h=Q(r.data?.resources.runtime_settings.available??!1).data,d=h?.log.level,g=b.useMemo(()=>xe(i.records,u?.levels??[],n.data?.engine.name,s,e,i.gaps,d),[i.records,i.gaps,u,n.data,s,e,d]);return{...g,empty:be(h?.recording?.logs,!!x,e),status:ve(i.connected,!!i.error,c,i.pending,U,s,e),records:i.records,offered:u?.levels??ye,level:j??"",setLevel:l,target:p,setTarget:o,paused:c,setPaused:v,error:r.error??i.error,loading:!r.error&&!i.error&&!i.connected&&!i.records.length,clear:i.clear,retry:r.error?r.refetch:i.retry,export:()=>ce(ge(g.exportBase,"txt"),we(i.records,i.gaps,e),"text/plain;charset=utf-8")}}function De(){const e=M(),s=Te(),r=b.useMemo(()=>[{id:"ts",label:e("ui.time"),minWidth:200,grow:0,drop:2,render:t=>!t.gap&&a.jsx(S,{className:"rp-code",text:t.iso,children:t.timestamp})},{id:"level",label:e("log.level"),minWidth:90,grow:0,drop:3,render:t=>!t.gap&&a.jsx(E,{small:!0,tone:t.tone,children:t.levelText})},{id:"target",label:e("log.target"),minWidth:160,grow:0,drop:1,render:t=>a.jsx("span",{className:"rp-code",children:t.target})},{id:"message",label:e("log.message"),minWidth:280,grow:3,isRowHeader:!0,render:t=>a.jsx(S,{children:t.message})}],[e]),n=b.useCallback(t=>a.jsx(z,{inline:!0,items:t.gap?[[e("log.message"),t.message]]:[[e("ui.time"),t.timestamp],[e("log.level"),t.levelText],[e("log.target"),t.target],[e("log.message"),t.message]]}),[e]);return a.jsxs("div",{className:"rp-page",children:[a.jsxs("div",{className:"rp-toolbar",children:[a.jsx(X,{side:!0,label:e("log.level"),value:s.level,onChange:s.setLevel,items:s.levels}),a.jsx(Y,{search:!0,label:e("log.target"),value:s.target,width:240,placeholder:e("log.targetPlaceholder"),onChange:s.setTarget}),a.jsx(Z,{isSelected:s.paused,onChange:s.setPaused,children:e("log.pause")}),a.jsx(E,{small:!0,tone:s.status.tone,children:s.status.text}),s.recordedText&&a.jsx("span",{className:"rp-label",children:s.recordedText}),a.jsx("span",{className:"rp-grow"}),a.jsx(ie,{actions:[{id:"clear",label:e("log.clear"),isDisabled:!s.rows.length,onAction:s.clear},{id:"export",label:e("log.export"),icon:a.jsx(ee,{}),isDisabled:!s.rows.length,onAction:s.export}]})]}),a.jsx(te,{error:s.error,onRetry:s.retry}),a.jsx(me,{records:s.records,offered:s.offered,minimum:s.level,setMinimum:s.setLevel}),a.jsx(le,{label:e("nav.logs"),stream:!0,rows:s.rows,height:640,loading:s.loading,empty:s.empty,cols:r,detail:n})]})}export{De as Logs}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/NodeSearch-B91jhtS3.js b/luci-app-honk/root/etc/honk/doona/assets/NodeSearch-aCbtGtHA.js similarity index 52% rename from luci-app-honk/root/etc/honk/doona/assets/NodeSearch-B91jhtS3.js rename to luci-app-honk/root/etc/honk/doona/assets/NodeSearch-aCbtGtHA.js index 98bd54be3..7c49eaa67 100644 --- a/luci-app-honk/root/etc/honk/doona/assets/NodeSearch-B91jhtS3.js +++ b/luci-app-honk/root/etc/honk/doona/assets/NodeSearch-aCbtGtHA.js @@ -1 +1 @@ -import{j as e}from"./vendor-react-Bf71BWbF.js";import{u as s,ag as a,T as c}from"./index-BNBwb-FJ.js";import{d as i}from"./Virtualizer-DipGMcji.js";import{$ as b}from"./useFilter-jz02VVEB.js";import{$ as f}from"./ListLayout-F74Z1Dpf.js";function x({children:t}){const o=s(),{contains:r}=b({sensitivity:"base"});return e.jsxs(a,{filter:r,children:[e.jsx(c,{search:!0,label:o("policy.filter"),autoFocus:!0,className:"rp-menu-search"}),e.jsx(i,{layout:f,layoutOptions:{rowHeight:32,headingHeight:26},children:t})]})}export{x as NodeSearch}; +import{j as e}from"./vendor-react-Bf71BWbF.js";import{u as s,ai as a,T as c}from"./index-Bw0aJc9a.js";import{d as i}from"./Virtualizer-DCY9HC9Z.js";import{$ as b}from"./useFilter-Tjznm3lB.js";import{$ as f}from"./ListLayout-_fDlx5XY.js";function x({children:t}){const o=s(),{contains:r}=b({sensitivity:"base"});return e.jsxs(a,{filter:r,children:[e.jsx(c,{search:!0,label:o("policy.filter"),autoFocus:!0,className:"rp-menu-search"}),e.jsx(i,{layout:f,layoutOptions:{rowHeight:32,headingHeight:26},children:t})]})}export{x as NodeSearch}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Nodes-Cccfa5J0.js b/luci-app-honk/root/etc/honk/doona/assets/Nodes-Cccfa5J0.js new file mode 100644 index 000000000..e292947d3 --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/Nodes-Cccfa5J0.js @@ -0,0 +1,5 @@ +import{r as y,j as o}from"./vendor-react-Bf71BWbF.js";import{u as ne,aT as Fn,L as On,B as X,aW as ke,bA as Be,a6 as Pe,a as me,aa as rn,ad as ln,ac as de,ae as In,af as dn,c_ as En,aI as $n,E as cn,j as Bn,ak as Wn,a_ as ee,bM as un,bN as qn,bP as Hn,aN as Un,bB as mn,bs as Vn,a3 as ye,bQ as zn,aL as ce,aO as Qn,br as pn,aJ as Kn,bS as Jn,aj as Xn,T as K,bt as Fe,y as Me,z as Yn,q as W,Q as fn,dN as Ze,U as je,dO as xe,V as Zn,F as es,dP as hn,dQ as ns,a9 as ss,M as Se,dR as bn,ay as as,b7 as os,as as ts,at as rs,a4 as en,aw as is,av as Le,a5 as Oe,bc as ls,cK as ds,bm as G,cT as ge,de as We,b as Ne,dd as cs,bg as us,dS as ms,by as ps,dT as nn,cS as fs,dU as hs,dV as bs,cO as vs,ap as gs,aF as ks,ag as ys,cP as js,dW as xs,dX as Ns,d9 as ws,bj as Ps,bk as Ms,a0 as Ge,dY as Ss,dZ as Ts,d_ as _s,cW as Cs,cU as sn,bx as As,ah as Ls,I as Gs,cN as an,du as Ds,dt as Rs}from"./index-Bw0aJc9a.js";import{F as Fs}from"./FactStrip-DtkOGBRy.js";import{u as Os,C as Is,p as Es}from"./layout-BWzq8YqC.js";import{D as vn,c as $s}from"./Table-Km6Zv-S8.js";import{T as Bs}from"./TimeCell-DKHUJpad.js";import{M as Ws}from"./ActionGroup-DLxTuKht.js";import{A as qs}from"./AddCircle-D11CyK2n.js";import{u as Hs}from"./outbounds-DMhWS-9H.js";import{p as Us,b as Vs}from"./policyText-CltaDVEo.js";import{a as Ie}from"./setup-DLvQ_6ZI.js";import{u as zs}from"./useRefreshAll-D0DryBsY.js";import{$ as Qs}from"./useFilter-Tjznm3lB.js";import{p as Ks}from"./probe-D0Quphno.js";import{o as Js,P as Xs}from"./openGroup-Dk9B33qx.js";import{n as Ys}from"./nav-DONyavaI.js";import"./useGridSelectionCheckbox-COXIVEmS.js";import"./Virtualizer-DCY9HC9Z.js";import"./ListLayout-_fDlx5XY.js";function on({kind:e,color:a}){return o.jsx("i",{className:"rp-marker "+e,style:a?{color:a}:void 0,"aria-hidden":"true"})}function Zs({label:e,groups:a,legend:n,max:s,fmt:l,limit:t=10,showAll:r}){const b=ne(),c=Fn(),{ref:i,tip:f,show:u,hide:h}=Os(),[d,m]=y.useState(new Set),p=[0,s/4,s/2,3*s/4,s],j=w=>Math.min(100,w/s*100);return o.jsxs("div",{className:"rp-markerplot rp-chart-hover",ref:i,onPointerLeave:h,role:"group","aria-label":e,"aria-describedby":c,children:[o.jsx("ul",{className:"legend",children:n.map(w=>o.jsxs("li",{children:[o.jsx(on,{kind:w.kind}),w.label]},w.kind))}),o.jsxs("div",{className:"axis","aria-hidden":"true",children:[o.jsx("span",{}),o.jsx("div",{className:"scale",children:p.map(w=>o.jsx("span",{style:{insetInlineStart:`${j(w)}%`},children:l(w)},w))}),o.jsx("span",{})]}),a.map(w=>o.jsxs("section",{"aria-label":w.label,children:[a.length>1&&o.jsx("h4",{className:"rp-label",children:w.label}),(d.has(w.id)?w.rows:w.rows.slice(0,t)).map(g=>{const P=Object.values(g.values).filter(x=>x!==void 0),C=j(Math.min(...P)),F=j(Math.max(...P));return o.jsxs("div",{className:"row",onPointerMove:x=>u(x,[g.label,...g.details]),children:[o.jsx("span",{className:"name",children:g.href?o.jsx(On,{appearance:"link",href:g.href,children:g.label}):g.label}),o.jsxs("div",{className:"track",role:"img","aria-label":g.label+b("ui.separator")+g.description,children:[p.map(x=>o.jsx("i",{className:"grid",style:{insetInlineStart:`${j(x)}%`}},x)),F>C&&o.jsx("i",{className:"span",style:{insetInlineStart:`${C}%`,width:`${F-C}%`}}),["tick","diamond","dot"].map(x=>g.values[x]===void 0?null:o.jsx("span",{className:"at "+x+(g.values[x]>s?" over":""),style:{insetInlineStart:`${j(g.values[x])}%`},children:o.jsx(on,{kind:x,color:x==="dot"?g.tone:void 0})},x))]}),o.jsx("span",{className:"value",children:g.text})]},g.id)}),!d.has(w.id)&&w.rows.length>t&&o.jsx("div",{className:"row more",children:o.jsx(X,{quiet:!0,small:!0,onPress:()=>m(g=>new Set([...g,w.id])),children:r(w.rows.length)})}),w.notes.map(g=>o.jsx("p",{className:"rp-note note",children:g},g))]},w.id)),o.jsx(Is,{tip:f})]})}function ea(e,a,n,s){const l=ke(s),t=new Map((a??[]).map(i=>[i.id,i.name])),r=new Map,b=(i,f)=>{let u=r.get(i);return u||r.set(i,u={id:i,label:f,rows:[],missing:[]}),u};for(const i of e){const f=Be(i),u=n==="protocol"?[["protocol:"+(i.protocol??""),i.protocol??null]]:i.group_ids.length?i.group_ids.map(h=>["group:"+h,t.get(h)??h]):[["group:",null]];for(const[h,d]of u){const m=b(h,d);f?.state==="healthy"&&f.latency_ms!==null?m.rows.push({id:i.id,name:i.name,latest:f.latency_ms,moving:f.moving_avg_ms,avg10:f.avg10_ms}):m.missing.push({id:i.id,name:i.name,state:f?.state==="unavailable"?"unavailable":"unmeasured"})}}const c=[...r.values()];for(const i of c)i.rows.sort((f,u)=>f.latest-u.latest||l(f.name,u.name)),i.missing.sort((f,u)=>l(f.name,u.name));return c.sort((i,f)=>(i.label===null?1:0)-(f.label===null?1:0)||l(i.label??"",f.label??""))}function na(e){const a=e.flatMap(n=>n.rows);return{moving:a.some(n=>n.moving!==null),avg10:a.some(n=>n.avg10!==null)}}function sa(e){const a=e.flatMap(l=>l.rows.flatMap(t=>[t.latest,t.moving??t.latest])).sort((l,t)=>l-t),n=Math.max(10,(Es(a,90)??0)*1.25),s=n<=100?20:n<=500?100:n<=2e3?500:1e3;return Math.ceil(n/s)*s}function aa(){const e=Pe[me()],a=rn().data?.resources,n=ln(de(a,"nodes",{whileLoading:!0})),s=In(de(a,"groups",{whileLoading:!1})),l=dn(de(a,"providers",{whileLoading:!0})),[t,r]=y.useState("group"),b=y.useMemo(()=>ea(n.data??[],s.data,t,e),[n.data,s.data,t,e]),c=y.useMemo(()=>new Map((n.data??[]).map(i=>[i.id,En(i,l.data?.providers??[])])),[n.data,l.data]);return{nodes:n,by:t,setBy:r,view:b,hrefs:c}}const De=6;function tn(e,a,n){const s=ye(a,e.slice(0,De).map(l=>l.name));return e.length>De?n("nodes.latency.andMore",{names:s,n:e.length-De}):s}function oa(){const e=ne(),a=me(),n=$n(),{nodes:s,by:l,setBy:t,view:r,hrefs:b}=aa();if(s.error&&!s.data)return o.jsx(cn,{error:s.error,onRetry:s.refetch});if(!s.data)return o.jsx(Bn,{});if(!s.data.length)return o.jsx(Wn,{children:e("ui.empty")});const c=na(r),i=[...new Map(r.flatMap(d=>d.rows).map(d=>[d.id,d])).values()].sort((d,m)=>d.latest-m.latest),f=new Set(r.flatMap(d=>d.missing.filter(m=>m.state==="unavailable").map(m=>m.id))).size,u=i.length?[{label:e("nodes.latency.lowest"),icon:o.jsx(un,{}),tint:"c2",value:i[0].name,caption:ee(i[0].latest,e)},{label:e("nodes.latency.highest"),icon:o.jsx(qn,{}),tint:"c4",value:i[i.length-1].name,caption:ee(i[i.length-1].latest,e)},{label:e("nodes.latency.unavailable"),value:e("nodes.latency.count",{n:f}),icon:o.jsx(Hn,{}),tint:"c5",tone:f?"negative":void 0}]:[],h=d=>{const m=d.filter(j=>j.state==="unavailable"),p=d.filter(j=>j.state==="unmeasured");return[...m.length?[e("nodes.latency.unavailableList",{n:m.length,names:tn(m,a,e)})]:[],...p.length?[e("nodes.latency.unmeasuredList",{n:p.length,names:tn(p,a,e)})]:[]]};return o.jsxs("div",{className:"rp-chart-page",children:[o.jsx(Fs,{facts:u}),o.jsx(Un,{title:e("ui.nodeLatency"),note:e("nodes.latency.sample",{n:s.data.length}),aside:o.jsx(Vn,{label:e("nodes.latency.by"),value:l,onChange:d=>t(d),items:[["group",e("nodes.latency.byGroup")],["protocol",e("nodes.latency.byProtocol")]]}),children:o.jsx(Zs,{label:e("ui.nodeLatency"),max:sa(r),fmt:d=>ee(d,e),showAll:d=>e("nodes.latency.showAll",{n:d}),legend:[{kind:"dot",label:e("nodes.latency.latest")},...c.moving?[{kind:"diamond",label:e("nodes.latency.moving")}]:[],...c.avg10?[{kind:"tick",label:e("nodes.latency.avg10")}]:[]],groups:r.map(d=>({id:d.id,label:d.label??e(l==="group"?"nodes.latency.noGroup":"nodes.latency.noProtocol"),rows:d.rows.map(m=>{const p=[e("ui.valuePair",{label:e("nodes.latency.latest"),value:ee(m.latest,e)}),...c.moving?[e("ui.valuePair",{label:e("nodes.latency.moving"),value:ee(m.moving,e)})]:[],...c.avg10?[e("ui.valuePair",{label:e("nodes.latency.avg10"),value:ee(m.avg10,e)})]:[]];return{id:m.id,label:m.name,href:b.get(m.id),values:{dot:m.latest,diamond:m.moving??void 0,tick:m.avg10??void 0},text:ee(m.latest,e),tone:mn(m.latest)&&n.notice,description:p.join(e("ui.separator")),details:p}}),notes:h(d.missing)}))})})]})}function ta({model:e}){const a=ne();return o.jsxs(o.Fragment,{children:[(e.canManage||e.refreshAll)&&o.jsx(zn,{reason:e.refreshAll?.reason,children:o.jsxs("div",{className:"rp-toolbar",children:[o.jsx("span",{className:"rp-grow"}),e.refreshAll&&o.jsx(X,{small:!0,isPending:e.refreshAll.refreshing,isDisabled:e.refreshAll.disabled,onPress:()=>void e.refreshAll.run(),children:e.refreshAll.label}),e.canManage&&o.jsx(X,{small:!0,onPress:e.onAdd,children:a("nodes.addProvider")})]})}),o.jsx(vn,{label:a("nodes.providers"),loading:e.loading,rows:e.rows,height:280,fit:!0,selected:e.selected,onSelect:e.onSelect,selectOnFocus:!0,empty:a("nodes.noProviders"),cols:[{id:"name",label:a("nodes.provider"),minWidth:140,grow:2,isRowHeader:!0,render:n=>o.jsx("span",{className:"rp-chain",children:o.jsx(ce,{text:n.url,children:n.name})})},{id:"kind",label:a("nodes.kindLabel"),minWidth:150,grow:0,drop:5,render:n=>o.jsx(Qn,{children:n.kind})},{id:"count",label:a("nodes.count"),minWidth:80,grow:0,align:"end",drop:6,render:n=>n.count},{id:"usage",label:a("nodes.usage"),minWidth:200,drop:2,render:n=>n.usage},{id:"updated",label:a("nodes.updated"),minWidth:140,drop:3,render:n=>o.jsx(Bs,{at:n.updatedAt})},{id:"interval",label:a("nodes.interval"),minWidth:130,grow:0,drop:4,render:n=>n.hasInterval&&e.writable?o.jsx(ce,{text:e.sourceTip,children:o.jsx(pn,{quiet:!0,label:n.intervalLabel,value:n.intervalValue,isDisabled:e.sourceBusy,onChange:n.setInterval,items:n.intervals,children:n.interval})}):n.interval},{id:"expires",label:a("nodes.expires"),minWidth:140,drop:1,render:n=>n.expires},{id:"status",label:a("ui.state"),minWidth:96,grow:0,drop:7,render:n=>n.status?o.jsx(Kn,{small:!0,tone:n.tone,children:o.jsx(ce,{text:n.error,children:n.status})}):"—"},{id:"actions",label:a("ui.actions"),minWidth:(e.canManage?112:88)+(e.editing?40:0),grow:0,render:n=>o.jsxs("span",{className:"rp-chain",children:[n.refreshable&&o.jsx(X,{small:!0,quiet:!0,icon:!0,isPending:n.refreshing,isDisabled:n.refreshDisabled,label:n.refreshLabel,onPress:n.refresh,children:o.jsx(Jn,{className:"rp-spin-on-press"})}),(n.action||n.removable)&&o.jsx(Ws,{small:!0,quiet:!0,label:a("ui.moreActionsFor",{name:n.name}),actions:[...n.action?.kind==="edit"?[{id:"edit",label:n.editLabel,isDisabled:e.busy||e.editBusy,onAction:n.action.run}]:n.action?.kind==="open"?[{id:"open",label:a("rule.openSource"),onAction:n.action.run}]:[],...n.removable?[{id:"remove",label:n.removeLabel,negative:!0,isDisabled:e.busy,onAction:n.remove}]:[]]})]})}]})]})}const gn=y.createContext(null);function ra({row:e}){const a=y.useContext(gn);return o.jsx(X,{small:!0,quiet:!0,icon:!0,isPending:a===e.id,isDisabled:!!a,label:e.probeLabel,onPress:e.probe,children:o.jsx(un,{})})}function ia({model:e}){const a=ne(),{canManage:n,writable:s,sourceBusy:l,busy:t,across:r}=e,b=y.useMemo(()=>[{id:"name",label:a("nodes.node"),minWidth:150,grow:2,isRowHeader:!0,sortable:!0,render:c=>o.jsx("span",{className:"rp-chain",children:o.jsx(ce,{children:c.name})})},...r?[{id:"source",label:a("nodes.provider"),minWidth:140,render:c=>o.jsx(ce,{children:c.source})}]:[],{id:"protocol",label:a("nodes.protocol"),minWidth:144,grow:0,drop:2,sortable:!0,render:c=>c.protocol},{id:"latency",label:a("nodes.latency"),minWidth:96,grow:0,align:"end",sortable:!0,render:c=>o.jsx("span",{className:c.latencyClass,children:c.latency})},{id:"groups",label:a("nodes.groups"),minWidth:200,drop:1,render:c=>o.jsx(ce,{children:c.groups})},{id:"actions",label:a("ui.actions"),minWidth:(n?108:72)+(s?112:0),grow:0,render:c=>o.jsxs("span",{className:"rp-chain",children:[c.canProbe&&o.jsx(ra,{row:c}),s&&o.jsxs(pn,{quiet:!0,label:c.joinLabel,isDisabled:l,items:c.menu,onAction:c.join,children:[o.jsx(qs,{}),a("nodes.addToGroup")]}),c.removable&&o.jsx(X,{small:!0,quiet:!0,icon:!0,isDisabled:t,label:c.removeLabel,onPress:c.remove,children:o.jsx(Xn,{})})]})}],[a,r,n,s,l,t]);return o.jsxs(o.Fragment,{children:[e.writable&&e.sourceTip&&o.jsx("p",{className:"rp-note",children:e.sourceTip}),e.scope&&o.jsx("p",{className:"rp-label",children:e.scope}),o.jsxs("div",{className:"rp-toolbar",children:[o.jsx(K,{label:a("nodes.search"),search:!0,value:e.search,width:240,onChange:e.setSearch}),o.jsx(Fe,{label:a("nodes.group"),side:!0,value:e.group,onChange:e.setGroup,items:e.groups}),o.jsx(Fe,{label:a("nodes.protocol"),side:!0,value:e.protocol,onChange:e.setProtocol,items:e.protocols}),o.jsx("span",{className:"rp-label",children:e.shown}),o.jsx("span",{className:"rp-grow"}),e.canManage&&o.jsx(X,{small:!0,onPress:e.onAdd,children:a("nodes.addNode")})]}),o.jsx(gn.Provider,{value:e.probeBusy,children:o.jsx(vn,{label:e.label,loading:e.loading,rows:e.rows,height:520,empty:e.empty,sort:e.sort,onSort:e.setSort,cols:b})})]})}const J=(e,a)=>a?e.slice(a.from,a.to):"",la=(e,a)=>!!a&&(a.kind==="text"||a.kind==="quoted")&&J(e,a)!==":";function kn(e){const{blocks:a,tokens:n}=Me(e),s=[];for(const l of a.filter(t=>t.name==="subscription"))for(const t of Yn(e,l)){const r=t.block?.open??t.to,b=n.filter(g=>g.from>=t.from&&g.fromg.fromx.from>d.to))continue;const g=fn(e,d,n);if(c.length===3&&u.kind==="quoted"){const x=g.map(T=>({name:T.name,value:T.value}));s.push({...h,url:W(J(e,u)),form:"options",options:x,urlAt:{from:u.from,to:u.to}});continue}const P=g.find(x=>x.name==="url"),C=P&&n.find(x=>x.from>=P.valueFrom&&x.fromx!==P).map(x=>({name:x.name,value:x.value}));s.push({...h,url:W(J(e,C)),form:"block",options:F,urlAt:{from:C.from,to:C.to}});continue}if(u?.kind!=="quoted")continue;const m=b.slice(3),p={from:u.from,to:u.to};if(!m.length){s.push({...h,url:W(J(e,u)),form:"short",options:[],urlAt:p});continue}const j=m.at(-1);if(J(e,m[0])!=="("||J(e,j)!==")"||j.parens!==1||m.slice(1,-1).some(g=>g.parens!==1))continue;const w=e.slice(m[0].to,j.from).trim();s.push({...h,url:W(J(e,u)),form:"agent",options:[{name:"ua",value:w}],urlAt:p})}return s}function da(e,a,n){const s=kn(e),l=s.find(r=>r.tag===a);if(!l)throw new Ze("nodes.editMissing");if(n.tag!==a&&s.some(r=>r.tag===n.tag))throw new Ze("nodes.tagTaken");const t=[];if(n.url!==l.url&&t.push({...l.urlAt,text:je(n.url)}),n.tag!==a){const r=/^['"]/.test(e.slice(l.tagAt.from,l.tagAt.to));t.push({...l.tagAt,text:r||!xe(n.tag)?je(n.tag):n.tag})}return t.sort((r,b)=>b.from-r.from).reduce((r,b)=>r.slice(0,b.from)+b.text+r.slice(b.to),e)}function ca(e){const a=/^(\d+(?:\.\d+)?)(ms|s|m|h)?$/.exec(e.trim());if(!a)return null;const n={ms:1/1e3,s:1,m:60,h:3600};return Math.ceil(Number(a[1])*(n[a[2]??"s"]??1))}function we(e){if(!e)return null;try{return new URL(e).hostname||null}catch{return null}}function ua(e){const a=es(e).trim(),{tokens:n}=Me(a),s=n[0];if(!s)return null;const l=a.slice(s.from,s.to),t=n[1],r=t&&a.slice(t.from,t.to)===":"&&!a.slice(t.to).startsWith("//"),b=r?t.to:0,c=n.find(m=>m.from>=b);if(!c)return null;const i=c.kind==="quoted";let f=i?W(a.slice(c.from,c.to)):a.slice(b).trim(),u=r?W(l):null;if(!u){const m=f.indexOf(":");m!==-1&&!f.startsWith("://",m)?(u=f.slice(0,m).trim(),f=f.slice(m+1)):u=we(f)}const h=i?a.slice(c.to).trim():"",d=h.startsWith("(")&&h.endsWith(")")?W(h.slice(1,-1)):null;return h&&d===null?null:u?{tag:u,url:f,ua:d}:null}function yn(e){const{blocks:a,tokens:n}=Me(e),s=[];for(const l of a.filter(t=>t.name==="subscription"))for(let t=0;t=l.close||r.depth!==l.depth+1||r.kind==="comment")continue;const b=e.lastIndexOf(` +`,r.from-1)+1,c=/^[ \t]*$/.test(e.slice(b,r.from))?b:r.from,i=l.children.find(p=>p.from===r.from);if(i){for(;n[t+1]?.fromg.name==="url"),w=p.find(g=>g.name==="interval");s.push({from:c,to:i.to,block:i,tag:i.name,host:j?we(W(j.value)):null,interval:w?ca(W(w.value)):null,fields:p,parts:null});continue}const f=n[t+1];f&&e.slice(f.from,f.to)===":"&&!e.slice(f.to).startsWith("//")&&(t+=2);const u=n[t];if(!u||u.from>=l.close)break;if(u.kind!=="quoted")for(;n[t+1]?.from===n[t].to&&!/[(){}]/.test(e.slice(n[t+1].from,n[t+1].to));)t++;if(e[n[t+1]?.from]==="(")for(t++;n[t+1]&&!(e[n[t].from]===")"&&n[t].parens===1);)t++;let h=n[t].to,d;n[t+1]?.kind==="comment"&&n[t+1].line===n[t].line&&(d=e.slice(n[t+1].from,n[t+1].to),h=n[++t].to);const m=ua(e.slice(c,h));m&&s.push({from:c,to:h,tag:m.tag,host:we(m.url),interval:null,fields:[],parts:m,comment:d})}return s}function ma(e){return yn(e).map(({tag:a,host:n,interval:s})=>({tag:a,host:n,interval:s}))}function pa(e,a,n){const s=yn(e).find(c=>c.tag===a);if(!s||s.interval===n)return e;const l=e.slice(s.from,s.to).match(/^[ \t]*/)?.[0]??" ",t=l+(l.includes(" ")?" ":" ");if(s.parts){const c=[`${l}${Zn(a)}: {`,`${t}url: ${je(s.parts.url)}`];return s.parts.ua!==null&&c.push(`${t}ua: ${je(s.parts.ua)}`),c.push(`${t}interval: '${n}s'`,`${l}}${s.comment?" "+s.comment:""}`),e.slice(0,s.from)+c.join(` +`)+e.slice(s.to)}const r=s.fields.find(c=>c.name==="interval");if(r)return e.slice(0,r.valueFrom)+` '${n}s'`+e.slice(r.valueTo);if(!s.block)return e;const b=e.lastIndexOf(` +`,s.block.close-1)+1;return e.slice(0,b)+`${t}interval: '${n}s' +`+e.slice(b)}function fa(e,a,n,s){const l=Be(e),t=l?.state==="healthy"&&l.latency_ms!=null;return{id:e.id,name:e.name,protocol:e.protocol??"—",latency:t?ee(l.latency_ms,s):l?.state==="unavailable"?s("ui.unavailable"):"—",latencyClass:t?`ms ${mn(l.latency_ms)??""}`.trimEnd():l?.state==="unavailable"?"ms err":"ms",groups:e.group_ids.length?ye(n,e.group_ids.map(r=>a.get(r)??r)):"—",probeLabel:s("nodes.probe",{name:e.name}),joinLabel:s("nodes.joinGroup",{name:e.name}),removeLabel:s("nodes.remove",{name:e.name})}}const ha=e=>ls(Be(e)),Ee=(e,a)=>Se(e).filter(n=>bn(n).subtags.includes(a)).map(n=>n.name),ba=(e,a)=>Se(e).some(n=>bn(n).rules.some(s=>Me(s).tokens.some(l=>(l.kind==="text"||l.kind==="quoted")&&W(s.slice(l.from,l.to))===a)));function va(e,a,n){return{here:Ee(a.content??"",n),elsewhere:e.filter(s=>s.id!==a.id&&Ee(s.content??"",n).length>0||ba(s.content??"",n))}}function ga(e,a,n,s){const l=new Map;for(const p of a){if(!p.provider_id||!p.subscription_tag)continue;const j=l.get(p.provider_id)??new Set;j.add(p.subscription_tag),l.set(p.provider_id,j)}const t=p=>{const j=l.get(p);return j?.size===1?[...j][0]:void 0},r=p=>{const j=we(p.url_redacted),w=j?n.filter(g=>g.host===j):[];return w.length===1?w[0].tag:void 0},b=new Map,c=e.filter(p=>p.kind==="subscription");for(const p of c){const j=t(p.id)??r(p);j&&b.set(p.id,j)}const i=c.filter(p=>!b.has(p.id)),f=new Set(b.values()),u=n.filter(p=>!f.has(p.tag));i.length===1&&u.length===1&&b.set(i[0].id,u[0].tag);const h=e.map(p=>{const j=t(p.id);return{...p,displayName:b.get(p.id)??p.name,configTag:p.kind==="subscription"&&j&&n.filter(w=>w.tag===j).length===1?j:void 0,sourceTag:p.kind==="subscription"?p.name:void 0}}),d={builtin:0,unattributed:0};for(const p of a)p.provider_id==null&&d[hn(p)]++;const m=[];for(const p of["builtin","unattributed"]){const j=d[p];j&&m.push({id:ns(p,e),name:s(p==="builtin"?"nodes.kind.builtin":"nodes.kind.unattributed"),kind:p,url_redacted:null,node_count:j,updated_at:null,expires_at:null,traffic:null,status:"ok",last_error:null})}return{list:[...m,...h]}}function ka(e,a){return a!==null&&e.some(n=>n.id===a)?a:(e.find(n=>n.kind!=="builtin"&&n.kind!=="unattributed")??e[0])?.id??null}function ya(e,a,n){return e.filter(s=>a===void 0||(a===null?s.provider_id==null&&hn(s)==="builtin"==(n==="builtin"):s.provider_id===a))}function ja(e,a){const n=new Map(e.map(s=>[s.id,s.displayName??s.name]));return s=>n.get(ss(s,a))??"—"}function xa(e,a,n,s,l,t,r){const b=a.trim(),c=e.filter(d=>(!b||t(d.name,b))&&(!n||d.group_ids.includes(n))&&(!s||d.protocol===s)),i=l.direction==="ascending"?1:-1,f=ke(r),u=l.column==="latency"?new Map(c.map(d=>[d.id,ha(d)])):new Map,h={name:(d,m)=>f(d.name,m.name),protocol:(d,m)=>f(d.protocol??"",m.protocol??""),latency:(d,m)=>ds(u.get(d.id),u.get(m.id))||f(d.name,m.name)};return c.sort((d,m)=>i*(h[l.column]??h.name)(d,m))}const $e=[3600,21600,43200,86400];function qe(e,a,n){return e===0?n("nodes.manualOnly"):$e.includes(e)?n("nodes.everyHours",{n:e/3600}):as(String(e),a)}function jn(e,a,n){return[0,...$e,...e===null||e===0||$e.includes(e)?[]:[e]].map(s=>({id:String(s),label:qe(s,a,n)}))}function Na(e,a){const n={name:e.name.trim(),kind:"subscription",url:e.value.trim()},s=Number(e.interval);a?.update_interval!==void 0&&e.interval&&s!==a.update_interval&&(n.update_interval=s);const l=e.agent.trim();return a?.user_agent!==void 0&&l&&l!==a.user_agent&&(n.user_agent=l),a?.cache!==void 0&&e.cache!==null&&e.cache!==a.cache&&(n.cache=e.cache),n}function wa(e,a,n,s){const l={subscription:"nodes.kind.subscription",file:"nodes.kind.file",inline:"nodes.kind.inline",builtin:"nodes.kind.builtin",unattributed:"nodes.kind.unattributed"},t={ok:"nodes.status.ok",stale:"nodes.status.stale",error:"nodes.status.error"},r={ok:"ok",stale:"warn",error:"err"},b=e.kind==="builtin"||e.kind==="unattributed",c=e.traffic?os(e.traffic.upload_bytes,e.traffic.download_bytes):null,i=e.kind==="subscription"?a:void 0,f=e.displayName??e.name;return{id:e.id,name:f,url:e.url_redacted??void 0,kind:en(l,e.kind,s),count:Oe(e.node_count,n),usage:c===null?"—":e.traffic?.total_bytes?s("ui.fraction",{part:Le(c,n),whole:Le(e.traffic.total_bytes,n)}):Le(c,n),updatedAt:b?null:e.updated_at,expires:e.expires_at?is(e.expires_at,n):"—",interval:i==null?"—":qe(i,n,s),intervalValue:i==null?"":String(i),hasInterval:i!==void 0,intervalLabel:s("nodes.intervalOf",{name:f}),intervals:i===void 0?[]:jn(i,n,s),status:b?null:en(t,e.status,s),tone:r[e.status],error:e.last_error?ts(rs(e.last_error.code,e.last_error.message,s),s):void 0,refreshLabel:s("nodes.refresh",{name:f}),removeLabel:s("nodes.remove",{name:f})}}const xn=e=>/^[a-z][a-z0-9+.-]*:\/\/\S+$/i.test(e.trim());function Pa(e,a,n,s){const l=a.trim();return e!=="provider"&&e!=="node"||!l&&!n.trim()?null:l?e==="node"?xn(n)?null:s("nodes.linkInvalid"):xe(l)?Ie(n)?null:s("nodes.urlInvalid"):s("nodes.nameInvalid"):s("nodes.nameMissing")}function Ma(e){const a=ne(),n=Pe[me()],{refresh:s}=e,l=new Map(e.entries.map(r=>[r.tag,r.interval])),t=e.rows.map(r=>({...wa(r,r.configTag?l.get(r.configTag):void 0,n,a),action:e.editAction(r),editLabel:a("nodes.edit",{name:r.displayName??r.name}),refreshable:r.kind==="subscription"&&e.canRefresh,refreshing:s.busy===r.id,refreshDisabled:!!s.busy,refresh:()=>void s.refresh(r.id).then(b=>{b&&("degraded"in b?G("info",a("nodes.refreshedDegraded",{name:r.name})):G("positive",a("nodes.refreshed",{name:r.name,n:b.node_count})))},b=>We(b,a,a("nodes.refreshFailed",{name:r.name}))),removable:e.canManage&&(r.kind==="subscription"||r.kind==="file"),remove:()=>{(r.kind==="subscription"||r.kind==="file")&&e.onRemove(r)},setInterval:b=>{if(!r.configTag)return;const c=Number(b);e.source.apply(i=>pa(i,r.configTag,c)).then(i=>{i.kind==="ok"&&G("positive",a("nodes.intervalSet",{name:r.name,interval:qe(c,n,a)}));const f=ge(i,a);f&&G(f.kind,f.text,{detail:f.detail,requestId:f.requestId})})}}));return{rows:t,loading:e.loading,selected:e.selected,onSelect:e.onSelect,canManage:e.canManage,busy:e.busy,writable:e.source.writable,editing:t.some(r=>r.action!==null),sourceBusy:e.source.busy||!e.source.main,editBusy:e.source.busy,sourceTip:e.source.error?Ne(e.source.error,a):void 0,refreshAll:e.canRefresh?e.refreshAll:null,onAdd:e.onAdd}}function Sa(e){const{names:a,providers:n,source:s,query:l,reload:t,joinGroup:r,onNewGroup:b,onRemove:c,canManage:i,sourceOf:f}=e,u=ne(),h=me(),d=Pe[h],m=cs(t),[p,j]=y.useState(l??"");us(l,k=>j(k??""));const[w,g]=y.useState(""),[P,C]=y.useState(""),[F,x]=y.useState({column:"name",direction:"ascending"}),T=e.multiple&&p.trim()!=="",_=T?e.all:e.nodes,O=y.useMemo(()=>[...new Set(_.flatMap(k=>k.group_ids))].sort((k,S)=>ke(d)(a.get(k)??k,a.get(S)??S)).map(k=>({id:k,label:a.get(k)??k})),[_,a,d]),Y=y.useMemo(()=>[...new Set(_.map(k=>k.protocol??""))].filter(Boolean).sort(ke(d)).map(k=>({id:k,label:k})),[_,d]),U=O.some(k=>k.id===w)?w:"",q=Y.some(k=>k.id===P)?P:"",{contains:I}=Qs({sensitivity:"base"}),V=y.useMemo(()=>xa(_,p,U,q,F,I,d),[_,p,U,q,F,I,d]),se=y.useMemo(()=>Se(s.main?.content??"").map(k=>({...k,names:new Set(ms(k))})),[s.main?.content]),D=y.useMemo(()=>new Map(_.map(k=>[k.id,new Set(k.group_ids.map(S=>a.get(S)??S))])),[_,a]),ae=y.useMemo(()=>new Set(n.filter(k=>k.kind==="inline").map(k=>k.id)),[n]),{probe:oe,canProbe:H,busy:ue}=m,N=y.useCallback(k=>({...fa(k,a,h,u),source:f(k),canProbe:H&&!ps(k.protocol),probe:()=>void oe(k.id).then(S=>{if(!S)return;const{kind:Te,text:B}=Ks(S,k.id,k.name,u);G(Te,B)},S=>We(S,u,u("nodes.probeError",{name:k.name}))),menu:()=>[...se.filter(S=>!S.names.has(k.name)&&!D.get(k.id)?.has(S.name)).map(S=>({id:S.name,label:S.name,desc:Us(S.policy,u)})),{id:"/new",label:u("nodes.newGroup")}],join:S=>S==="/new"?b(k):r(k,S),removable:i&&typeof k.provider_id=="string"&&ae.has(k.provider_id),remove:()=>c(k)}),[a,h,f,H,oe,u,se,D,b,r,i,ae,c]),te=y.useMemo(()=>({build:N,rows:new WeakMap}),[N]),re=y.useMemo(()=>$s(te.rows,V,te.build),[te,V]);return{rows:re,probeBusy:ue,search:p,setSearch:j,group:U,setGroup:g,protocol:q,setProtocol:C,sort:F,setSort:x,groups:[{id:"",label:u("nodes.anyGroup")},...O],protocols:[{id:"",label:u("nodes.anyProtocol")},...Y],shown:u("ui.fraction",{part:Oe(re.length,d),whole:Oe(_.length,d)}),loading:e.loading,label:T?u("nav.nodes"):e.label,scope:T?u("nodes.searchAll"):e.scope,across:T,empty:u(T?"nodes.noMatch":"nodes.empty"),canManage:i,busy:e.busy,writable:s.writable,sourceBusy:s.busy||!s.main,sourceTip:s.error?Ne(s.error,u):void 0,onAdd:e.onAdd}}const Re={name:"",value:"",interval:"",agent:"",cache:null};function Ta({go:e,query:a}){const n=ne(),[s,l]=y.useState(null),[t,r]=y.useState(Re),[b,c]=y.useState(nn[0].id),[i,f]=y.useState(!0),u=y.useRef(0),h=y.useRef(null),[d,m]=y.useState(null),[p,j]=y.useState(null),w=s?.kind==="editProvider"?t.name!==s.entry.tag||t.value!==s.entry.url:!!(t.name||t.value),g=fs(!!s&&w,()=>{u.current++,l(null)}),P=y.useCallback(v=>{u.current++,r(Re),c(nn[0].id),f(!0),j(null),v.kind==="editProvider"&&r({...Re,name:v.entry.tag,value:v.entry.url}),l(v)},[]),C=me(),F=Pe[C],x=rn().data?.resources,T=dn(de(x,"providers",{whileLoading:!0})),_=ln(de(x,"nodes",{whileLoading:!0})),O=Hs(),{refetch:Y}=T,{refetch:U}=_,q=y.useCallback(()=>{Y(),U()},[Y,U]),I=hs(q),V=bs(q),se=zs(T,V),D=vs(),ae=gs(ks().data).daeText,oe=ys(de(x,"config",{whileLoading:!1})),H=y.useMemo(()=>oe.data?.sources??[],[oe.data]),ue=js(H),N=y.useMemo(()=>{const v=new Map;for(const A of H)for(const L of kn(A.content))v.set(L.tag,[...v.get(L.tag)??[],{source:A,entry:L}]);return v},[H]),te=s?.kind==="editProvider"?N.get(s.entry.tag):void 0,re=te?.length===1?te[0].source:null,k=v=>{const A=v.sourceTag?N.get(v.sourceTag):void 0;if(A?.length!==1)return null;const[{source:L,entry:E}]=A,be=(T.data?.providers??[]).filter(M=>M.kind==="subscription"&&M.name===v.name).length===1;return ae&&be&&D.writable&&L.writable&&ue(L)===!0?{kind:"edit",run:()=>P({kind:"editProvider",item:v,source:L,entry:E})}:{kind:"open",run:()=>e("config",Ge("",{tab:"source",source:L.id,line:String(E.line)}))}},S=y.useMemo(()=>ma(D.main?.content??""),[D.main?.content]),Te=y.useMemo(()=>new Set(Se(D.main?.content??"").map(v=>v.name)),[D.main?.content]),{list:B}=y.useMemo(()=>ga(T.data?.providers??[],_.data??[],S,n),[T.data,_.data,S,n]),He=y.useMemo(()=>new URLSearchParams(a),[a]),pe=ka(B,He.get("provider")),ie=B.find(v=>v.id===pe)??null,Nn=y.useMemo(()=>{const v=B.find(A=>A.id===pe);return ya(_.data??[],v?.kind==="builtin"||v?.kind==="unattributed"?null:v?.id,v?.kind)},[_.data,B,pe]),wn=y.useMemo(()=>ja(B,T.data?.providers??[]),[B,T.data]),{apply:fe}=D,_e=y.useCallback(v=>({label:n("policy.viewGroup"),onAction:()=>Js(e,v),closeOnAction:!0}),[e,n]),Ce=v=>({label:n("nodes.viewNodes"),onAction:()=>e("nodes",Ge("",{provider:v})),closeOnAction:!0}),Pn=y.useCallback((v,A)=>{fe(L=>xs(L,A,[v.name])).then(L=>{L.kind==="ok"&&G("positive",n("nodes.joined",{name:v.name,group:A}),{action:_e(A)});const E=ge(L,n);E&&G(E.kind,E.text,{detail:E.detail,requestId:E.requestId})})},[fe,n,_e]),Mn=y.useCallback(()=>P({kind:"node"}),[P]),Sn=y.useCallback(v=>P({kind:"group",item:v}),[P]),Tn=y.useCallback(v=>P({kind:"removeNode",item:v}),[P]),he=y.useRef(a);y.useLayoutEffect(()=>(he.current=a,()=>{he.current=null}),[a]);const _n=async v=>{if(!s||h.current)return;h.current=s,m(s);const A=u.current,L=he.current,E=(M,R=M,Q)=>{u.current===A?j($=>({id:($?.id??0)+1,text:M})):G("negative",R,{requestId:Q})},be=M=>E(sn(M,n),sn(M,n,!1),M.requestId);try{if(s.kind==="provider"){const M=await I.addProvider(Na(t,Z));if(!M)return;const R=t.name.trim();if(u.current===A&&(g.clear(),v()),L!==null&&he.current===L&&e("nodes",Ge(L,{provider:M.id}),{replace:!0}),x?.providers.can_refresh){const Q=()=>void V.refresh(M.id).then($=>{$&&("degraded"in $?G("info",n("nodes.refreshedDegraded",{name:R}),{action:Ce(M.id)}):G("positive",n("nodes.addedRefreshed",{name:R,n:$.node_count}),{action:Ce(M.id)}))},$=>We($,n,n("nodes.addedRefreshFailed",{name:R}),{label:n("ui.retry"),onAction:Q,closeOnAction:!0}));Q();return}G("positive",n("nodes.added",{name:R}),{action:Ce(M.id)});return}else if(s.kind==="node"){const M=await I.addNode({name:t.name.trim(),link:t.value.trim()});if(!M)return;G("positive",n("nodes.added",{name:M.name}))}else if(s.kind==="group"){const M=t.name.trim(),R=s.item.name,Q=await fe(ve=>Ss(ve,[{kind:"createGroup",group:M,policy:b},{kind:"addNode",group:M,value:R}])),$=ge(Q,n);if($&&be($),Q.kind!=="ok")return;G("positive",n("nodes.joined",{name:R,group:M}),{action:_e(M)})}else if(s.kind==="editProvider"){const M=s.entry.tag,R=t.name.trim(),Q=t.value.trim(),$=R!==M&&i;if(!re){E(n(N.get(M)?.length?"nodes.tagTaken":"nodes.editMissing"));return}const ve=await fe(Dn=>{const Ae=da(Dn,M,{tag:R,url:Q});return $?Ee(Ae,M).reduce((Rn,Ye)=>Ts(_s(Rn,Ye,[R]),Ye,[M]),Ae):Ae},re),Xe=ge(ve,n);if(Xe&&be(Xe),ve.kind!=="ok")return;Y(),G("positive",n("nodes.edited",{name:R}))}else if(s.kind==="removeProvider"){if(!await I.removeProvider(s.item.id))return;G("positive",n("nodes.removed",{name:s.item.name}))}else{if(!await I.removeNode(s.item.id))return;G("positive",n("nodes.removed",{name:s.item.name}))}u.current===A&&(g.clear(),v())}catch(M){E(Ne(M,n),Ne(M,n,!1),Cs(M))}finally{h.current=null,m(null)}},Ue=s?.kind==="removeProvider"||s?.kind==="removeNode",Cn=s===null?"":s.kind==="provider"?n("nodes.addProvider"):s.kind==="node"?n("nodes.addNode"):s.kind==="group"?n("nodes.newGroup"):s.kind==="editProvider"?n("nodes.editProviderTitle",{name:s.entry.tag}):n(s.kind==="removeProvider"?"nodes.removeProviderTitle":"nodes.removeNodeTitle",{name:s.item.name}),Ve=s?.kind==="group"?Vs(t.name.trim(),Te,n):null,Z=x?.providers.create_options,ze=/^[\x20-\x7E]{0,256}$/.test(t.agent.trim())?null:n("nodes.agentInvalid"),z=t.name.trim(),Qe=s?.kind!=="editProvider"||z===s.entry.tag||!z?null:xe(z)?N.has(z)?n("nodes.tagTaken"):null:n("nodes.nameInvalid"),Ke=Ie(t.value)&&Ns(t.value.trim()),le=s?.kind==="editProvider"&&z!==s.entry.tag?va(H,re??s.source,s.entry.tag):{here:[],elsewhere:[]},An=s?.kind==="editProvider"?!!z&&Qe===null&&Ke&&!le.elsewhere.length&&(z!==s.entry.tag||t.value.trim()!==s.entry.url):s?.kind==="provider"?xe(t.name.trim())&&Ie(t.value)&&!ze:s?.kind==="node"?t.name.trim()!==""&&xn(t.value):s?.kind==="group"?Ve===null:!0,Ln=Ma({rows:B,loading:T.loading&&!T.data,selected:pe,onSelect:v=>{if(!v)return;const A=new URLSearchParams(a);A.set("provider",v),e("nodes",A.toString(),{replace:!0})},canManage:!!x?.providers.can_manage,canRefresh:!!x?.providers.can_refresh,busy:!!I.busy,source:D,entries:S,reload:q,refresh:V,refreshAll:se,onAdd:()=>P({kind:"provider"}),onRemove:v=>P({kind:"removeProvider",item:v}),editAction:k}),Gn=Sa({nodes:Nn,all:_.data??[],sourceOf:wn,providers:T.data?.providers??[],names:O,loading:_.loading&&!_.data,label:ie?n("nodes.of",{name:ie.displayName??ie.name}):n("nav.nodes"),scope:ie&&B.length>1?n("nodes.scope",{name:ie.displayName??ie.name}):null,multiple:B.length>1,query:He.get("q"),source:D,canManage:!!x?.nodes.can_manage,busy:!!I.busy,reload:U,joinGroup:Pn,onAdd:Mn,onNewGroup:Sn,onRemove:Tn}),Je=Ys(x);return{tabs:Je.map(v=>({id:v.id,label:n(v.titleKey)})),tab:Ms(a,Je.map(v=>v.id),"list"),setTab:v=>e("nodes",Ps(a,v,"list")),providerTable:Ln,nodeTable:Gn,error:T.error??_.error,reload:q,dialog:s,setDialog:v=>{u.current++,j(null),l(v)},problem:p,form:t,setForm:v=>{h.current!==s&&r(v)},removing:Ue,dialogTitle:Cn,formValid:An,formReason:s?.kind==="editProvider"?z?Ke?null:n("nodes.urlInvalid"):n("nodes.nameMissing"):Pa(s?.kind,t.name,t.value,n),submit:_n,pending:s!==null&&d===s,submitting:d!==null,submitLabel:Ue?n("nodes.remove",{name:s.item.name}):s?.kind==="group"?n("nodes.join"):s?.kind==="editProvider"?n("policy.save"):n("nodes.add"),editNameError:z?Qe:null,editOptions:s?.kind==="editProvider"?s.entry.options:[],renameGroups:le.here.length&&!le.elsewhere.length?ye(C,le.here):null,renameBlocked:le.elsewhere.length?ye(C,le.elsewhere.map(ws)):null,renameFrom:s?.kind==="editProvider"?s.entry.tag:"",updateGroups:i,setUpdateGroups:v=>{h.current!==s&&f(v)},groupHelp:s?.kind==="group"?n("nodes.newGroupHelp",{name:s.item.name}):"",groupNameError:t.name.trim()?Ve:null,agentError:ze,options:Z&&{intervals:Z.update_interval===void 0?null:jn(Z.update_interval,F,n),interval:t.interval||String(Z.update_interval),agent:Z.user_agent,cache:Z.cache===void 0?null:t.cache??Z.cache},policy:b,setPolicy:v=>{h.current!==s&&c(v)}}}function Qa(e){const a=ne(),{tabs:n,tab:s,setTab:l,providerTable:t,nodeTable:r,error:b,reload:c,dialog:i,setDialog:f,problem:u,form:h,setForm:d,removing:m,dialogTitle:p,formValid:j,formReason:w,submit:g,pending:P,submitting:C,submitLabel:F,groupHelp:x,groupNameError:T,agentError:_,options:O,policy:Y,setPolicy:U,editNameError:q,editOptions:I,renameGroups:V,renameFrom:se,renameBlocked:D,updateGroups:ae,setUpdateGroups:oe}=Ta(e),H=o.jsxs(o.Fragment,{children:[o.jsx("p",{className:"rp-note",children:a("nodes.note")}),o.jsx(cn,{error:b,onRetry:c}),o.jsx(ta,{model:t}),o.jsx(ia,{model:r})]}),ue={list:H,latency:o.jsx(oa,{})};return o.jsxs("div",{className:"rp-page",children:[n.length>0?o.jsx(As,{keepMounted:!0,label:a("nav.nodes"),value:s,onChange:l,items:n.map(N=>({...N,content:ue[N.id]}))}):H,o.jsxs(Ls,{title:p,narrow:!0,isOpen:i!==null&&!m,reason:P?null:w,onOpenChange:N=>{N||f(null)},footer:N=>o.jsxs(o.Fragment,{children:[o.jsx(X,{onPress:N,children:a("ui.cancel")}),o.jsx(X,{accent:!0,isDisabled:!j||C,isPending:P,onPress:()=>void g(N),children:F})]}),children:[u&&o.jsx(Gs,{takeFocus:!0,children:u.text},u.id),i?.kind==="provider"&&o.jsxs("div",{className:"rp-list",children:[o.jsx("span",{className:"rp-label",children:a("nodes.addProviderHelp")}),o.jsx(K,{isDisabled:P,label:a("nodes.name"),value:h.name,placeholder:"sub-a",onChange:N=>d({...h,name:N})}),o.jsx(K,{isDisabled:P,label:a("nodes.url"),value:h.value,placeholder:"https://example.org/sub?token=…",onChange:N=>d({...h,value:N})}),O?.intervals&&o.jsx(Fe,{label:a("nodes.interval"),items:O.intervals,value:O.interval,isDisabled:P,onChange:N=>d({...h,interval:N})}),O?.agent!==void 0&&o.jsx(K,{isDisabled:P,label:a("nodes.agent"),value:h.agent,placeholder:O.agent,error:_??void 0,spellCheck:!1,onChange:N=>d({...h,agent:N})}),O?.cache!=null&&o.jsxs(o.Fragment,{children:[o.jsx(an,{isSelected:O.cache,isDisabled:P,onChange:N=>d({...h,cache:N}),children:a("nodes.cache")}),o.jsx("span",{className:"rp-label",children:a("nodes.cacheHelp")})]})]}),i?.kind==="editProvider"&&o.jsxs("div",{className:"rp-list",children:[o.jsx("span",{className:"rp-label",children:a("nodes.editProviderHelp")}),o.jsx(K,{isDisabled:P,label:a("nodes.name"),value:h.name,spellCheck:!1,error:q??void 0,onChange:N=>d({...h,name:N})}),o.jsx(K,{isDisabled:P,label:a("nodes.url"),value:h.value,spellCheck:!1,onChange:N=>d({...h,value:N})}),V&&o.jsxs(o.Fragment,{children:[o.jsx(an,{isSelected:ae,isDisabled:P,onChange:oe,children:a("nodes.renameGroups",{groups:V})}),!ae&&o.jsx("span",{className:"rp-label",children:a("nodes.renameGroupsHelp",{name:se})})]}),D&&o.jsx("span",{className:"rp-label",children:a("nodes.renameBlocked",{files:D,name:se})}),I.length>0&&o.jsxs(o.Fragment,{children:[o.jsx("span",{className:"rp-label",children:a("nodes.editOptions")}),I.map(N=>o.jsx(Ds,{label:N.name,value:N.value},N.name))]})]}),i?.kind==="group"&&o.jsxs("div",{className:"rp-list",children:[o.jsx("span",{className:"rp-label",children:x}),o.jsx(K,{isDisabled:P,label:a("nodes.name"),value:h.name,placeholder:"hk",spellCheck:!1,description:a("arrange.groupNameHint"),error:T??void 0,onChange:N=>d({...h,name:N})}),o.jsx(Xs,{value:Y,onChange:U,isDisabled:P})]}),i?.kind==="node"&&o.jsxs("div",{className:"rp-list",children:[o.jsx("span",{className:"rp-label",children:a("nodes.addNodeHelp")}),o.jsx(K,{isDisabled:P,label:a("nodes.name"),value:h.name,placeholder:"hk-03",onChange:N=>d({...h,name:N})}),o.jsx(K,{isDisabled:P,label:a("nodes.link"),value:h.value,placeholder:"vless://…",onChange:N=>d({...h,value:N})})]})]}),o.jsx(Rs,{title:p,isOpen:m,onCancel:()=>f(null),confirmLabel:F,isPending:P,isDisabled:C,error:u,onConfirm:()=>void g(()=>f(null)),children:o.jsx("p",{className:"rp-label",children:a(i?.kind==="removeProvider"?"nodes.removeProviderHelp":"nodes.removeNodeHelp")})})]})}export{Qa as Nodes}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Nodes-CnRnSpMd.js b/luci-app-honk/root/etc/honk/doona/assets/Nodes-CnRnSpMd.js deleted file mode 100644 index 27aa8310d..000000000 --- a/luci-app-honk/root/etc/honk/doona/assets/Nodes-CnRnSpMd.js +++ /dev/null @@ -1,5 +0,0 @@ -import{r as j,j as t}from"./vendor-react-Bf71BWbF.js";import{u as U,aP as Qe,B as G,cB as ve,aS as q,a8 as _e,ab as Se,aa as ee,ac as Xe,a as ie,aE as Ye,E as Te,j as Ze,ai as en,aW as H,bx as Ce,by as nn,bA as sn,aJ as an,cv as Le,b4 as tn,a2 as De,aH as ne,aK as on,bn as Re,aF as rn,bD as ln,ah as $e,T as K,b5 as me,y as Ae,O as dn,q as se,U as cn,R as ke,F as un,da as Fe,db as mn,dc as Ge,av as pn,a$ as bn,ap as vn,aq as hn,a3 as Ne,at as fn,as as ce,a4 as ae,b6 as gn,cw as xn,a5 as he,be as C,cF as pe,cV as fe,b as ge,cU as jn,bf as yn,K as We,dd as kn,cL as Nn,de as we,cE as wn,ad as Pn,df as Mn,dg as _n,cC as Sn,dh as Tn,bi as Cn,bj as Ln,di as Dn,cG as Rn,br as $n,af as An,I as Fn,cA as Gn,d2 as Wn}from"./index-BNBwb-FJ.js";import{F as En}from"./FactStrip-n2q1T87k.js";import{u as In,C as Bn,p as On}from"./layout-wfdMYi2n.js";import{D as Ee,c as Hn}from"./Table-DyWJelc_.js";import{T as qn}from"./TimeCell-DUt0i0gi.js";import{A as Un}from"./AddCircle-CIj8X2wL.js";import{u as Vn}from"./outbounds-DPmb26w8.js";import{p as zn,b as Kn}from"./policyText-CmeXgUK2.js";import{a as Ie}from"./setup-d2VGFWY1.js";import{$ as Jn}from"./useFilter-jz02VVEB.js";import{p as Qn}from"./probe-BZEn7bbG.js";import{P as Xn}from"./PolicyPicker-BmHzmXzJ.js";import"./useGridSelectionCheckbox-CrCOlZv8.js";import"./Virtualizer-DipGMcji.js";import"./ListLayout-F74Z1Dpf.js";function Pe({kind:e,color:s}){return t.jsx("i",{className:"rp-marker "+e,style:s?{color:s}:void 0,"aria-hidden":"true"})}function Yn({label:e,groups:s,legend:n,max:a,fmt:l,limit:o=10,showAll:c}){const r=U(),u=Qe(),{ref:d,tip:p,show:m,hide:h}=In(),[k,b]=j.useState(new Set),i=[0,a/4,a/2,3*a/4,a],v=g=>Math.min(100,g/a*100);return t.jsxs("div",{className:"rp-markerplot rp-chart-hover",ref:d,onPointerLeave:h,role:"group","aria-label":e,"aria-describedby":u,children:[t.jsx("ul",{className:"legend",children:n.map(g=>t.jsxs("li",{children:[t.jsx(Pe,{kind:g.kind}),g.label]},g.kind))}),t.jsxs("div",{className:"axis","aria-hidden":"true",children:[t.jsx("span",{}),t.jsx("div",{className:"scale",children:i.map(g=>t.jsx("span",{style:{insetInlineStart:`${v(g)}%`},children:l(g)},g))}),t.jsx("span",{})]}),s.map(g=>t.jsxs("section",{"aria-label":g.label,children:[s.length>1&&t.jsx("h4",{className:"rp-label",children:g.label}),(k.has(g.id)?g.rows:g.rows.slice(0,o)).map(x=>{const N=Object.values(x.values).filter(M=>M!==void 0),T=v(Math.min(...N)),D=v(Math.max(...N));return t.jsxs("div",{className:"row",onPointerMove:M=>m(M,[x.label,...x.details]),children:[t.jsx("span",{className:"name",children:x.label}),t.jsxs("div",{className:"track",role:"img","aria-label":x.label+r("ui.separator")+x.description,children:[i.map(M=>t.jsx("i",{className:"grid",style:{insetInlineStart:`${v(M)}%`}},M)),D>T&&t.jsx("i",{className:"span",style:{insetInlineStart:`${T}%`,width:`${D-T}%`}}),["tick","diamond","dot"].map(M=>x.values[M]===void 0?null:t.jsx("span",{className:"at "+M+(x.values[M]>a?" over":""),style:{insetInlineStart:`${v(x.values[M])}%`},children:t.jsx(Pe,{kind:M,color:M==="dot"?x.tone:void 0})},M))]}),t.jsx("span",{className:"value",children:x.text})]},x.id)}),!k.has(g.id)&&g.rows.length>o&&t.jsx("div",{className:"row more",children:t.jsx(G,{quiet:!0,small:!0,onPress:()=>b(x=>new Set([...x,g.id])),children:c(g.rows.length)})}),g.notes.map(x=>t.jsx("p",{className:"rp-note note",children:x},x))]},g.id)),t.jsx(Bn,{tip:p})]})}function Zn(e,s,n){const a=new Map((s??[]).map(r=>[r.id,r.name])),l=new Map,o=(r,u)=>{let d=l.get(r);return d||l.set(r,d={id:r,label:u,rows:[],missing:[]}),d};for(const r of e){const u=ve(r),d=n==="protocol"?[["protocol:"+(r.protocol??""),r.protocol??null]]:r.group_ids.length?r.group_ids.map(p=>["group:"+p,a.get(p)??p]):[["group:",null]];for(const[p,m]of d){const h=o(p,m);u?.state==="healthy"&&u.latency_ms!==null?h.rows.push({id:r.id,name:r.name,latest:u.latency_ms,moving:u.moving_avg_ms,avg10:u.avg10_ms}):h.missing.push({id:r.id,name:r.name,state:u?.state==="unavailable"?"unavailable":"unmeasured"})}}const c=[...l.values()];for(const r of c)r.rows.sort((u,d)=>u.latest-d.latest||q(u.name,d.name)),r.missing.sort((u,d)=>q(u.name,d.name));return c.sort((r,u)=>(r.label===null?1:0)-(u.label===null?1:0)||q(r.label??"",u.label??""))}function es(e){const s=e.flatMap(n=>n.rows);return{moving:s.some(n=>n.moving!==null),avg10:s.some(n=>n.avg10!==null)}}function ns(e){const s=e.flatMap(l=>l.rows.flatMap(o=>[o.latest,o.moving??o.latest])).sort((l,o)=>l-o),n=Math.max(10,(On(s,90)??0)*1.25),a=n<=100?20:n<=500?100:n<=2e3?500:1e3;return Math.ceil(n/a)*a}function ss(){const e=_e().data?.resources,s=Se(ee(e,"nodes",{whileLoading:!0})),n=Xe(ee(e,"groups",{whileLoading:!1})),[a,l]=j.useState("group"),o=j.useMemo(()=>Zn(s.data??[],n.data,a),[s.data,n.data,a]);return{nodes:s,by:a,setBy:l,view:o}}const ue=6;function as(){const e=U(),s=ie(),n=Ye(),{nodes:a,by:l,setBy:o,view:c}=ss();if(a.error&&!a.data)return t.jsx(Te,{error:a.error,onRetry:a.refetch});if(!a.data)return t.jsx(Ze,{});if(!a.data.length)return t.jsx(en,{children:e("ui.empty")});const r={ok:n.positive,warn:n.notice,err:n.negative},u=es(c),d=[...new Map(c.flatMap(b=>b.rows).map(b=>[b.id,b])).values()].sort((b,i)=>b.latest-i.latest),p=new Set(c.flatMap(b=>b.missing.filter(i=>i.state==="unavailable").map(i=>i.id))).size,m=d.length?[{label:e("nodes.latency.lowest"),icon:t.jsx(Ce,{}),tint:"c2",value:d[0].name,caption:H(d[0].latest,e)},{label:e("nodes.latency.highest"),icon:t.jsx(nn,{}),tint:"c4",value:d[d.length-1].name,caption:H(d[d.length-1].latest,e)},{label:e("nodes.latency.unavailable"),value:e("nodes.latency.count",{n:p}),icon:t.jsx(sn,{}),tint:"c5",tone:p?"negative":void 0}]:[],h=b=>{const i=De(s,b.slice(0,ue).map(v=>v.name));return b.length>ue?`${i} ${e("nodes.latency.andMore",{n:b.length-ue})}`:i},k=b=>{const i=b.filter(g=>g.state==="unavailable"),v=b.filter(g=>g.state==="unmeasured");return[...i.length?[e("nodes.latency.unavailableList",{n:i.length,names:h(i)})]:[],...v.length?[e("nodes.latency.unmeasuredList",{n:v.length,names:h(v)})]:[]]};return t.jsxs("div",{className:"rp-chart-page",children:[t.jsx(En,{facts:m}),t.jsx(an,{title:e("ui.nodeLatency"),note:e("nodes.latency.sample",{n:a.data.length}),aside:t.jsx(tn,{label:e("nodes.latency.by"),value:l,onChange:b=>o(b),items:[["group",e("nodes.latency.byGroup")],["protocol",e("nodes.latency.byProtocol")]]}),children:t.jsx(Yn,{label:e("ui.nodeLatency"),max:ns(c),fmt:b=>H(b,e),showAll:b=>e("nodes.latency.showAll",{n:b}),legend:[{kind:"dot",label:e("nodes.latency.latest")},...u.moving?[{kind:"diamond",label:e("nodes.latency.moving")}]:[],...u.avg10?[{kind:"tick",label:e("nodes.latency.avg10")}]:[]],groups:c.map(b=>({id:b.id,label:b.label??e(l==="group"?"nodes.latency.noGroup":"nodes.latency.noProtocol"),rows:b.rows.map(i=>{const v=[e("ui.valuePair",{label:e("nodes.latency.latest"),value:H(i.latest,e)}),...u.moving?[e("ui.valuePair",{label:e("nodes.latency.moving"),value:H(i.moving,e)})]:[],...u.avg10?[e("ui.valuePair",{label:e("nodes.latency.avg10"),value:H(i.avg10,e)})]:[]];return{id:i.id,label:i.name,values:{dot:i.latest,diamond:i.moving??void 0,tick:i.avg10??void 0},text:H(i.latest,e),tone:r[Le(i.latest)],description:v.join(e("ui.separator")),details:v}}),notes:k(b.missing)}))})})]})}function ts({model:e}){const s=U();return t.jsxs(t.Fragment,{children:[e.canManage&&t.jsxs("div",{className:"rp-toolbar",children:[t.jsx("span",{className:"rp-grow"}),t.jsx(G,{small:!0,onPress:e.onAdd,children:s("nodes.addProvider")})]}),t.jsx(Ee,{label:s("nodes.providers"),loading:e.loading,rows:e.rows,height:280,fit:!0,selected:e.selected,onSelect:e.onSelect,selectOnFocus:!0,empty:s("nodes.noProviders"),cols:[{id:"name",label:s("nodes.provider"),minWidth:140,grow:2,isRowHeader:!0,render:n=>t.jsx("span",{className:"rp-chain",children:t.jsx(ne,{text:n.url,children:n.name})})},{id:"kind",label:s("nodes.kindLabel"),minWidth:150,grow:0,drop:5,render:n=>t.jsx(on,{children:n.kind})},{id:"count",label:s("nodes.count"),minWidth:80,grow:0,align:"end",drop:6,render:n=>n.count},{id:"usage",label:s("nodes.usage"),minWidth:200,drop:2,render:n=>n.usage},{id:"updated",label:s("nodes.updated"),minWidth:140,drop:3,render:n=>t.jsx(qn,{at:n.updatedAt})},{id:"interval",label:s("nodes.interval"),minWidth:130,grow:0,drop:4,render:n=>n.hasInterval&&e.writable?t.jsx(ne,{text:e.sourceTip,children:t.jsx(Re,{quiet:!0,label:n.intervalLabel,value:n.intervalValue,isDisabled:e.sourceBusy,onChange:n.setInterval,items:n.intervals,children:n.interval})}):n.interval},{id:"expires",label:s("nodes.expires"),minWidth:140,drop:1,render:n=>n.expires},{id:"status",label:s("ui.state"),minWidth:96,grow:0,drop:7,render:n=>n.status?t.jsx(rn,{small:!0,tone:n.tone,children:t.jsx(ne,{text:n.error,children:n.status})}):"—"},{id:"actions",label:s("ui.actions"),minWidth:e.canManage?112:88,grow:0,render:n=>t.jsxs("span",{className:"rp-chain",children:[n.refreshable&&t.jsx(G,{small:!0,quiet:!0,icon:!0,isPending:n.refreshing,isDisabled:n.refreshDisabled,label:n.refreshLabel,onPress:n.refresh,children:t.jsx(ln,{className:"rp-spin-on-press"})}),n.removable&&t.jsx(G,{small:!0,quiet:!0,icon:!0,isDisabled:e.busy,label:n.removeLabel,onPress:n.remove,children:t.jsx($e,{})})]})}]})]})}const Be=j.createContext(null);function os({row:e}){const s=j.useContext(Be);return t.jsx(G,{small:!0,quiet:!0,icon:!0,isPending:s===e.id,isDisabled:!!s,label:e.probeLabel,onPress:e.probe,children:t.jsx(Ce,{})})}function rs({model:e}){const s=U(),{canManage:n,writable:a,sourceBusy:l,busy:o}=e,c=j.useMemo(()=>[{id:"name",label:s("nodes.node"),minWidth:150,grow:2,isRowHeader:!0,sortable:!0,render:r=>t.jsx("span",{className:"rp-chain",children:t.jsx(ne,{children:r.name})})},{id:"protocol",label:s("nodes.protocol"),minWidth:144,grow:0,drop:2,sortable:!0,render:r=>r.protocol},{id:"latency",label:s("nodes.latency"),minWidth:96,grow:0,align:"end",sortable:!0,render:r=>t.jsx("span",{className:r.latencyClass,children:r.latency})},{id:"groups",label:s("nodes.groups"),minWidth:200,drop:1,render:r=>t.jsx(ne,{children:r.groups})},{id:"actions",label:s("ui.actions"),minWidth:n?108:72,grow:0,render:r=>t.jsxs("span",{className:"rp-chain",children:[r.canProbe&&t.jsx(os,{row:r}),a&&t.jsx(Re,{quiet:!0,chevron:!1,label:r.joinLabel,isDisabled:l,items:r.menu,onAction:r.join,children:t.jsx(Un,{})}),r.removable&&t.jsx(G,{small:!0,quiet:!0,icon:!0,isDisabled:o,label:r.removeLabel,onPress:r.remove,children:t.jsx($e,{})})]})}],[s,n,a,l,o]);return t.jsxs(t.Fragment,{children:[e.writable&&e.sourceTip&&t.jsx("p",{className:"rp-note",children:e.sourceTip}),t.jsxs("div",{className:"rp-toolbar",children:[t.jsx(K,{label:s("nodes.search"),search:!0,value:e.search,width:240,onChange:e.setSearch}),t.jsx(me,{label:s("nodes.group"),side:!0,value:e.group,onChange:e.setGroup,items:e.groups}),t.jsx(me,{label:s("nodes.protocol"),side:!0,value:e.protocol,onChange:e.setProtocol,items:e.protocols}),t.jsx("span",{className:"rp-label",children:e.shown}),t.jsx("span",{className:"rp-grow"}),e.canManage&&t.jsx(G,{small:!0,onPress:e.onAdd,children:s("nodes.addNode")})]}),t.jsx(Be.Provider,{value:e.probeBusy,children:t.jsx(Ee,{label:e.label,loading:e.loading,rows:e.rows,height:520,empty:s("nodes.empty"),sort:e.sort,onSort:e.setSort,cols:c})})]})}function is(e){const s=/^(\d+(?:\.\d+)?)(ms|s|m|h)?$/.exec(e.trim());if(!s)return null;const n={ms:1/1e3,s:1,m:60,h:3600};return Math.ceil(Number(s[1])*(n[s[2]??"s"]??1))}function re(e){if(!e)return null;try{return new URL(e).hostname||null}catch{return null}}function ls(e){const s=un(e).trim(),{tokens:n}=Ae(s),a=n[0];if(!a)return null;const l=s.slice(a.from,a.to),o=n[1],c=o&&s.slice(o.from,o.to)===":"&&!s.slice(o.to).startsWith("//"),r=c?o.to:0,u=n.find(b=>b.from>=r);if(!u)return null;const d=u.kind==="quoted";let p=d?se(s.slice(u.from,u.to)):s.slice(r).trim(),m=c?se(l):null;if(!m){const b=p.indexOf(":");b!==-1&&!p.startsWith("://",b)?(m=p.slice(0,b).trim(),p=p.slice(b+1)):m=re(p)}const h=d?s.slice(u.to).trim():"",k=h.startsWith("(")&&h.endsWith(")")?se(h.slice(1,-1)):null;return h&&k===null?null:m?{tag:m,url:p,ua:k}:null}function Oe(e){const{blocks:s,tokens:n}=Ae(e),a=[];for(const l of s.filter(o=>o.name==="subscription"))for(let o=0;o=l.close||c.depth!==l.depth+1||c.kind==="comment")continue;const r=e.lastIndexOf(` -`,c.from-1)+1,u=/^[ \t]*$/.test(e.slice(r,c.from))?r:c.from,d=l.children.find(i=>i.from===c.from);if(d){for(;n[o+1]?.fromx.name==="url"),g=i.find(x=>x.name==="interval");a.push({from:u,to:d.to,block:d,tag:d.name,host:v?re(se(v.value)):null,interval:g?is(se(g.value)):null,fields:i,parts:null});continue}const p=n[o+1];p&&e.slice(p.from,p.to)===":"&&!e.slice(p.to).startsWith("//")&&(o+=2);const m=n[o];if(!m||m.from>=l.close)break;if(m.kind!=="quoted")for(;n[o+1]?.from===n[o].to&&!/[(){}]/.test(e.slice(n[o+1].from,n[o+1].to));)o++;if(e[n[o+1]?.from]==="(")for(o++;n[o+1]&&!(e[n[o].from]===")"&&n[o].parens===1);)o++;let h=n[o].to,k;n[o+1]?.kind==="comment"&&n[o+1].line===n[o].line&&(k=e.slice(n[o+1].from,n[o+1].to),h=n[++o].to);const b=ls(e.slice(u,h));b&&a.push({from:u,to:h,tag:b.tag,host:re(b.url),interval:null,fields:[],parts:b,comment:k})}return a}function ds(e){return Oe(e).map(({tag:s,host:n,interval:a})=>({tag:s,host:n,interval:a}))}function cs(e,s,n){const a=Oe(e).find(u=>u.tag===s);if(!a||a.interval===n)return e;const l=e.slice(a.from,a.to).match(/^[ \t]*/)?.[0]??" ",o=l+(l.includes(" ")?" ":" ");if(a.parts){const u=[`${l}${cn(s)}: {`,`${o}url: ${ke(a.parts.url)}`];return a.parts.ua!==null&&u.push(`${o}ua: ${ke(a.parts.ua)}`),u.push(`${o}interval: '${n}s'`,`${l}}${a.comment?" "+a.comment:""}`),e.slice(0,a.from)+u.join(` -`)+e.slice(a.to)}const c=a.fields.find(u=>u.name==="interval");if(c)return e.slice(0,c.valueFrom)+` '${n}s'`+e.slice(c.valueTo);if(!a.block)return e;const r=e.lastIndexOf(` -`,a.block.close-1)+1;return e.slice(0,r)+`${o}interval: '${n}s' -`+e.slice(r)}function us(e,s,n,a){const l=ve(e),o=l?.state==="healthy"&&l.latency_ms!=null;return{id:e.id,name:e.name,protocol:e.protocol??"—",latency:o?H(l.latency_ms,a):l?.state==="unavailable"?a("ui.unavailable"):"—",latencyClass:o?`ms ${Le(l.latency_ms)}`:l?.state==="unavailable"?"ms err":"ms",groups:e.group_ids.length?De(n,e.group_ids.map(c=>s.get(c)??c)):"—",probeLabel:a("nodes.probe",{name:e.name}),joinLabel:a("nodes.joinGroup",{name:e.name}),removeLabel:a("nodes.remove",{name:e.name})}}const ms=e=>gn(ve(e));function ps(e,s,n,a){const l=new Map;for(const i of s){if(!i.provider_id||!i.subscription_tag)continue;const v=l.get(i.provider_id)??new Set;v.add(i.subscription_tag),l.set(i.provider_id,v)}const o=i=>{const v=l.get(i);return v?.size===1?[...v][0]:void 0},c=i=>{const v=re(i.url_redacted),g=v?n.filter(x=>x.host===v):[];return g.length===1?g[0].tag:void 0},r=new Map,u=e.filter(i=>i.kind==="subscription");for(const i of u){const v=o(i.id)??c(i);v&&r.set(i.id,v)}const d=u.filter(i=>!r.has(i.id)),p=new Set(r.values()),m=n.filter(i=>!p.has(i.tag));d.length===1&&m.length===1&&r.set(d[0].id,m[0].tag);const h=e.map(i=>{const v=o(i.id);return{...i,displayName:r.get(i.id)??i.name,configTag:i.kind==="subscription"&&v&&n.filter(g=>g.tag===v).length===1?v:void 0}}),k={builtin:0,unattributed:0};for(const i of s)i.provider_id==null&&k[Fe(i)]++;const b=[];for(const i of["builtin","unattributed"]){const v=k[i];v&&b.push({id:mn(i,e),name:a(i==="builtin"?"nodes.kind.builtin":"nodes.kind.unattributed"),kind:i,url_redacted:null,node_count:v,updated_at:null,expires_at:null,traffic:null,status:"ok",last_error:null})}return{list:[...b,...h]}}function bs(e,s){return s!==null&&e.some(n=>n.id===s)?s:(e.find(n=>n.kind!=="builtin"&&n.kind!=="unattributed")??e[0])?.id??null}function vs(e,s,n){return e.filter(a=>s===void 0||(s===null?a.provider_id==null&&Fe(a)==="builtin"==(n==="builtin"):a.provider_id===s))}function hs(e,s,n,a,l,o){const c=s.trim(),r=e.filter(m=>(!c||o(m.name,c))&&(!n||m.group_ids.includes(n))&&(!a||m.protocol===a)),u=l.direction==="ascending"?1:-1,d=l.column==="latency"?new Map(r.map(m=>[m.id,ms(m)])):new Map,p={name:(m,h)=>q(m.name,h.name),protocol:(m,h)=>q(m.protocol??"",h.protocol??""),latency:(m,h)=>xn(d.get(m.id),d.get(h.id))||q(m.name,h.name)};return r.sort((m,h)=>u*(p[l.column]??p.name)(m,h))}const be=[3600,21600,43200,86400];function xe(e,s,n){return e===0?n("nodes.manualOnly"):be.includes(e)?n("nodes.everyHours",{n:e/3600}):pn(String(e),s)}function He(e,s,n){return[0,...be,...e===null||e===0||be.includes(e)?[]:[e]].map(a=>({id:String(a),label:xe(a,s,n)}))}function fs(e,s){const n={name:e.name.trim(),kind:"subscription",url:e.value.trim()},a=Number(e.interval);s?.update_interval!==void 0&&e.interval&&a!==s.update_interval&&(n.update_interval=a);const l=e.agent.trim();return s?.user_agent!==void 0&&l&&l!==s.user_agent&&(n.user_agent=l),s?.cache!==void 0&&e.cache!==null&&e.cache!==s.cache&&(n.cache=e.cache),n}function gs(e,s,n,a){const l={subscription:"nodes.kind.subscription",file:"nodes.kind.file",inline:"nodes.kind.inline",builtin:"nodes.kind.builtin",unattributed:"nodes.kind.unattributed"},o={ok:"nodes.status.ok",stale:"nodes.status.stale",error:"nodes.status.error"},c={ok:"ok",stale:"warn",error:"err"},r=e.kind==="builtin"||e.kind==="unattributed",u=e.traffic?bn(e.traffic.upload_bytes,e.traffic.download_bytes):null,d=e.kind==="subscription"?s:void 0,p=e.displayName??e.name;return{id:e.id,name:p,url:e.url_redacted??void 0,kind:Ne(l,e.kind,a),count:ae(e.node_count,n),usage:u===null?"—":e.traffic?.total_bytes?a("ui.fraction",{part:ce(u,n),whole:ce(e.traffic.total_bytes,n)}):ce(u,n),updatedAt:r?null:e.updated_at,expires:e.expires_at?fn(e.expires_at,n):"—",interval:d==null?"—":xe(d,n,a),intervalValue:d==null?"":String(d),hasInterval:d!==void 0,intervalLabel:a("nodes.intervalOf",{name:p}),intervals:d===void 0?[]:He(d,n,a),status:r?null:Ne(o,e.status,a),tone:c[e.status],error:e.last_error?vn(hn(e.last_error.code,e.last_error.message,a),a):void 0,refreshLabel:a("nodes.refresh",{name:p}),removeLabel:a("nodes.remove",{name:p})}}const qe=e=>/^[a-z][a-z0-9+.-]*:\/\/\S+$/i.test(e.trim());function xs(e,s,n,a){const l=s.trim();return e!=="provider"&&e!=="node"||!l&&!n.trim()?null:l?e==="node"?qe(n)?null:a("nodes.linkInvalid"):Ge(l)?Ie(n)?null:a("nodes.urlInvalid"):a("nodes.nameInvalid"):a("nodes.nameMissing")}function js(e){const s=U(),n=he[ie()],{refresh:a}=e,l=new Map(e.entries.map(c=>[c.tag,c.interval]));return{rows:e.rows.map(c=>({...gs(c,c.configTag?l.get(c.configTag):void 0,n,s),refreshable:c.kind==="subscription"&&e.canRefresh,refreshing:a.busy===c.id,refreshDisabled:!!a.busy,refresh:()=>void a.refresh(c.id).then(r=>{r&&("degraded"in r?C("info",s("nodes.refreshedDegraded",{name:c.name})):C("positive",s("nodes.refreshed",{name:c.name,n:ae(r.node_count,n)})))},r=>fe(r,s,s("nodes.refreshFailed",{name:c.name}))),removable:e.canManage&&(c.kind==="subscription"||c.kind==="file"),remove:()=>{(c.kind==="subscription"||c.kind==="file")&&e.onRemove(c)},setInterval:r=>{if(!c.configTag)return;const u=Number(r);e.source.apply(d=>cs(d,c.configTag,u)).then(d=>{d.kind==="ok"&&C("positive",s("nodes.intervalSet",{name:c.name,interval:xe(u,n,s)}));const p=pe(d,s);p&&C(p.kind,p.text,{detail:p.detail})})}})),loading:e.loading,selected:e.selected,onSelect:e.onSelect,canManage:e.canManage,busy:e.busy,writable:e.source.writable,sourceBusy:e.source.busy||!e.source.main,sourceTip:e.source.error?ge(e.source.error,s):void 0,onAdd:e.onAdd}}function ys(e){const{nodes:s,names:n,providers:a,source:l,query:o,reload:c,joinGroup:r,onNewGroup:u,onRemove:d,canManage:p}=e,m=U(),h=ie(),k=he[h],b=jn(c),[i,v]=j.useState(o??"");yn(o,f=>v(f??""));const[g,x]=j.useState(""),[N,T]=j.useState(""),[D,M]=j.useState({column:"name",direction:"ascending"}),W=j.useMemo(()=>[...new Set(s.flatMap(f=>f.group_ids))].sort((f,P)=>q(n.get(f)??f,n.get(P)??P)).map(f=>({id:f,label:n.get(f)??f})),[s,n]),$=j.useMemo(()=>[...new Set(s.map(f=>f.protocol??""))].filter(Boolean).sort(q).map(f=>({id:f,label:f})),[s]),S=W.some(f=>f.id===g)?g:"",E=$.some(f=>f.id===N)?N:"",{contains:L}=Jn({sensitivity:"base"}),A=j.useMemo(()=>hs(s,i,S,E,D,L),[s,i,S,E,D,L]),w=j.useMemo(()=>We(l.main?.content??"").map(f=>({...f,names:new Set(kn(f))})),[l.main?.content]),I=j.useMemo(()=>new Map(s.map(f=>[f.id,new Set(f.group_ids.map(P=>n.get(P)??P))])),[s,n]),X=j.useMemo(()=>new Set(a.filter(f=>f.kind==="inline").map(f=>f.id)),[a]),{probe:V,canProbe:J,busy:le}=b,Q=j.useCallback(f=>({...us(f,n,h,m),canProbe:J&&!Nn(f.protocol),probe:()=>void V(f.id).then(P=>{if(!P)return;const{kind:de,text:oe}=Qn(P,f.id,f.name,m);C(de,oe)},P=>fe(P,m,m("nodes.probeError",{name:f.name}))),menu:()=>[...w.filter(P=>!P.names.has(f.name)&&!I.get(f.id)?.has(P.name)).map(P=>({id:P.name,label:P.name,desc:zn(P.policy,m)})),{id:"/new",label:m("nodes.newGroup")}],join:P=>P==="/new"?u(f):r(f,P),removable:p&&typeof f.provider_id=="string"&&X.has(f.provider_id),remove:()=>d(f)}),[n,h,J,V,m,w,I,u,r,p,X,d]),Y=j.useMemo(()=>({build:Q,rows:new WeakMap}),[Q]),te=j.useMemo(()=>Hn(Y.rows,A,Y.build),[Y,A]);return{rows:te,probeBusy:le,search:i,setSearch:v,group:S,setGroup:x,protocol:E,setProtocol:T,sort:D,setSort:M,groups:[{id:"",label:m("nodes.anyGroup")},...W],protocols:[{id:"",label:m("nodes.anyProtocol")},...$],shown:m("ui.fraction",{part:ae(te.length,k),whole:ae(s.length,k)}),loading:e.loading,label:e.label,canManage:p,busy:e.busy,writable:l.writable,sourceBusy:l.busy||!l.main,sourceTip:l.error?ge(l.error,m):void 0,onAdd:e.onAdd}}const Me={name:"",value:"",interval:"",agent:"",cache:null};function ks({go:e,query:s}){const n=U(),[a,l]=j.useState(null),[o,c]=j.useState(Me),[r,u]=j.useState(we[0].id),d=j.useRef(0),p=j.useRef(null),[m,h]=j.useState(null),[k,b]=j.useState(null),i=wn(!!a&&!!(o.name||o.value),()=>{d.current++,l(null)}),v=j.useCallback(y=>{d.current++,c(Me),u(we[0].id),b(null),l(y)},[]),g=he[ie()],x=_e().data?.resources,N=Pn(ee(x,"providers",{whileLoading:!0})),T=Se(ee(x,"nodes",{whileLoading:!0})),D=Vn(),{refetch:M}=N,{refetch:W}=T,$=j.useCallback(()=>{M(),W()},[M,W]),S=Mn($),E=_n($),L=Sn(),A=j.useMemo(()=>ds(L.main?.content??""),[L.main?.content]),w=j.useMemo(()=>new Set(We(L.main?.content??"").map(y=>y.name)),[L.main?.content]),{list:I}=j.useMemo(()=>ps(N.data?.providers??[],T.data??[],A,n),[N.data,T.data,A,n]),X=j.useMemo(()=>new URLSearchParams(s),[s]),V=bs(I,X.get("provider")),J=I.find(y=>y.id===V)??null,le=j.useMemo(()=>{const y=I.find(R=>R.id===V);return vs(T.data??[],y?.kind==="builtin"||y?.kind==="unattributed"?null:y?.id,y?.kind)},[T.data,I,V]),{apply:Q}=L,Y=j.useCallback((y,R)=>{Q(z=>Tn(z,R,[y.name])).then(z=>{z.kind==="ok"&&C("positive",n("nodes.joined",{name:y.name,group:R}));const _=pe(z,n);_&&C(_.kind,_.text,{detail:_.detail})})},[Q,n]),te=j.useCallback(()=>v({kind:"node"}),[v]),f=j.useCallback(y=>v({kind:"group",item:y}),[v]),P=j.useCallback(y=>v({kind:"removeNode",item:y}),[v]),de=async y=>{if(!a||p.current)return;p.current=a,h(a);const R=d.current,z=_=>{d.current===R?b(F=>({id:(F?.id??0)+1,text:_})):C("negative",_)};try{if(a.kind==="provider"){const _=await S.addProvider(fs(o,B));if(!_)return;const F=o.name.trim();if(x?.providers.can_refresh){d.current===R&&(i.clear(),y());const Z=()=>void E.refresh(_.id).then(O=>{O&&("degraded"in O?C("info",n("nodes.refreshedDegraded",{name:F})):C("positive",n("nodes.addedRefreshed",{name:F,n:ae(O.node_count,g)})))},O=>fe(O,n,n("nodes.addedRefreshFailed",{name:F}),{label:n("ui.retry"),onAction:Z,closeOnAction:!0}));Z();return}C("positive",n("nodes.added",{name:F}))}else if(a.kind==="node"){const _=await S.addNode({name:o.name.trim(),link:o.value.trim()});if(!_)return;C("positive",n("nodes.added",{name:_.name}))}else if(a.kind==="group"){const _=o.name.trim(),F=a.item.name,Z=await Q(Je=>Dn(Je,[{kind:"createGroup",group:_,policy:r},{kind:"addNode",group:_,value:F}])),O=pe(Z,n);if(O&&z(Rn(O,n)),Z.kind!=="ok")return;C("positive",n("nodes.joined",{name:F,group:_}))}else if(a.kind==="removeProvider"){if(!await S.removeProvider(a.item.id))return;C("positive",n("nodes.removed",{name:a.item.name}))}else{if(!await S.removeNode(a.item.id))return;C("positive",n("nodes.removed",{name:a.item.name}))}d.current===R&&(i.clear(),y())}catch(_){z(ge(_,n))}finally{p.current=null,h(null)}},oe=a?.kind==="removeProvider"||a?.kind==="removeNode",Ue=a===null?"":a.kind==="provider"?n("nodes.addProvider"):a.kind==="node"?n("nodes.addNode"):a.kind==="group"?n("nodes.newGroup"):n(a.kind==="removeProvider"?"nodes.removeProviderTitle":"nodes.removeNodeTitle",{name:a.item.name}),je=a?.kind==="group"?Kn(o.name.trim(),w,n):null,B=x?.providers.create_options,ye=/^[\x20-\x7E]{0,256}$/.test(o.agent.trim())?null:n("nodes.agentInvalid"),Ve=a?.kind==="provider"?Ge(o.name.trim())&&Ie(o.value)&&!ye:a?.kind==="node"?o.name.trim()!==""&&qe(o.value):a?.kind==="group"?je===null:!0,ze=js({rows:I,loading:N.loading&&!N.data,selected:V,onSelect:y=>{if(!y)return;const R=new URLSearchParams(s);R.set("provider",y),e("nodes",R.toString(),{replace:!0})},canManage:!!x?.providers.can_manage,canRefresh:!!x?.providers.can_refresh,busy:!!S.busy,source:L,entries:A,reload:$,refresh:E,onAdd:()=>v({kind:"provider"}),onRemove:y=>v({kind:"removeProvider",item:y})}),Ke=ys({nodes:le,providers:N.data?.providers??[],names:D,loading:T.loading&&!T.data,label:J?n("nodes.of",{name:J.displayName??J.name}):n("nav.nodes"),query:X.get("q"),source:L,canManage:!!x?.nodes.can_manage,busy:!!S.busy,reload:W,joinGroup:Y,onAdd:te,onNewGroup:f,onRemove:P});return{measured:ee(x,"nodes",{whileLoading:!0}),tab:Ln(s,["list","latency"],"list"),setTab:y=>e("nodes",Cn(s,y,"list")),providerTable:ze,nodeTable:Ke,error:N.error??T.error,reload:$,dialog:a,setDialog:y=>{d.current++,b(null),l(y)},problem:k,form:o,setForm:y=>{p.current!==a&&c(y)},removing:oe,dialogTitle:Ue,formValid:Ve,formReason:xs(a?.kind,o.name,o.value,n),submit:de,pending:a!==null&&m===a,submitting:m!==null,submitLabel:oe?n("nodes.remove",{name:a.item.name}):a?.kind==="group"?n("nodes.join"):n("nodes.add"),groupHelp:a?.kind==="group"?n("nodes.newGroupHelp",{name:a.item.name}):"",groupNameError:o.name.trim()?je:null,agentError:ye,options:B&&{intervals:B.update_interval===void 0?null:He(B.update_interval,g,n),interval:o.interval||String(B.update_interval),agent:B.user_agent,cache:B.cache===void 0?null:o.cache??B.cache},policy:r,setPolicy:y=>{p.current!==a&&u(y)}}}function Is(e){const s=U(),{measured:n,tab:a,setTab:l,providerTable:o,nodeTable:c,error:r,reload:u,dialog:d,setDialog:p,problem:m,form:h,setForm:k,removing:b,dialogTitle:i,formValid:v,formReason:g,submit:x,pending:N,submitting:T,submitLabel:D,groupHelp:M,groupNameError:W,agentError:$,options:S,policy:E,setPolicy:L}=ks(e),A=t.jsxs(t.Fragment,{children:[t.jsx("p",{className:"rp-note",children:s("nodes.note")}),t.jsx(Te,{error:r,onRetry:u}),t.jsx(ts,{model:o}),t.jsx(rs,{model:c})]});return t.jsxs("div",{className:"rp-page",children:[n?t.jsx($n,{keepMounted:!0,label:s("nav.nodes"),value:a,onChange:l,items:[{id:"list",label:s("nodes.tab.list"),content:A},{id:"latency",label:s("nodes.tab.latency"),content:t.jsx(as,{})}]}):A,t.jsxs(An,{title:i,narrow:!0,isOpen:d!==null&&!b,reason:N?null:g,onOpenChange:w=>{w||p(null)},footer:w=>t.jsxs(t.Fragment,{children:[t.jsx(G,{onPress:w,children:s("ui.cancel")}),t.jsx(G,{accent:!0,isDisabled:!v||T,isPending:N,onPress:()=>void x(w),children:D})]}),children:[m&&t.jsx(Fn,{takeFocus:!0,children:m.text},m.id),d?.kind==="provider"&&t.jsxs("div",{className:"rp-list",children:[t.jsx("span",{className:"rp-label",children:s("nodes.addProviderHelp")}),t.jsx(K,{isDisabled:N,label:s("nodes.name"),value:h.name,placeholder:"sub-a",onChange:w=>k({...h,name:w})}),t.jsx(K,{isDisabled:N,label:s("nodes.url"),value:h.value,placeholder:"https://example.org/sub?token=…",onChange:w=>k({...h,value:w})}),S?.intervals&&t.jsx(me,{label:s("nodes.interval"),items:S.intervals,value:S.interval,isDisabled:N,onChange:w=>k({...h,interval:w})}),S?.agent!==void 0&&t.jsx(K,{isDisabled:N,label:s("nodes.agent"),value:h.agent,placeholder:S.agent,error:$??void 0,spellCheck:!1,onChange:w=>k({...h,agent:w})}),S?.cache!=null&&t.jsxs(t.Fragment,{children:[t.jsx(Gn,{isSelected:S.cache,isDisabled:N,onChange:w=>k({...h,cache:w}),children:s("nodes.cache")}),t.jsx("span",{className:"rp-label",children:s("nodes.cacheHelp")})]})]}),d?.kind==="group"&&t.jsxs("div",{className:"rp-list",children:[t.jsx("span",{className:"rp-label",children:M}),t.jsx(K,{isDisabled:N,label:s("nodes.name"),value:h.name,placeholder:"hk",spellCheck:!1,description:s("arrange.groupNameHint"),error:W??void 0,onChange:w=>k({...h,name:w})}),t.jsx(Xn,{value:E,onChange:L,isDisabled:N})]}),d?.kind==="node"&&t.jsxs("div",{className:"rp-list",children:[t.jsx("span",{className:"rp-label",children:s("nodes.addNodeHelp")}),t.jsx(K,{isDisabled:N,label:s("nodes.name"),value:h.name,placeholder:"hk-03",onChange:w=>k({...h,name:w})}),t.jsx(K,{isDisabled:N,label:s("nodes.link"),value:h.value,placeholder:"vless://…",onChange:w=>k({...h,value:w})})]})]}),t.jsx(Wn,{title:i,isOpen:b,onCancel:()=>p(null),confirmLabel:D,isPending:N,isDisabled:T,error:m,onConfirm:()=>void x(()=>p(null)),children:t.jsx("p",{className:"rp-label",children:s(d?.kind==="removeProvider"?"nodes.removeProviderHelp":"nodes.removeNodeHelp")})})]})}export{Is as Nodes}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Overview-CuiLM_k-.js b/luci-app-honk/root/etc/honk/doona/assets/Overview-CuiLM_k-.js deleted file mode 100644 index 2a28e6607..000000000 --- a/luci-app-honk/root/etc/honk/doona/assets/Overview-CuiLM_k-.js +++ /dev/null @@ -1 +0,0 @@ -import{r as S,j as t}from"./vendor-react-Bf71BWbF.js";import{an as K,ao as C,ap as I,aq as M,ar as $,as as x,at as B,a4 as g,au as G,av as J,aw as q,ax as z,u as O,a as Q,a5 as X,a8 as Y,ay as Z,aa as A,az as ee,aA as te,aB as ae,aC as se,aD as re,aE as oe,aF as y,E as L,L as P,aG as N,aH as F,aI as ie,aJ as w,aK as ne,ai as H,aL as le,aM as ce,j as T,aN as de,B as pe,aO as ue}from"./index-BNBwb-FJ.js";import{d as ve,e as me}from"./files-BxEOxSF8.js";import{D as he,t as V}from"./Table-DyWJelc_.js";import{A as fe}from"./ActionGroup-BKxDwmnT.js";import{D as xe}from"./DaeCode-B8yPDjSE.js";import"./useGridSelectionCheckbox-CrCOlZv8.js";import"./Virtualizer-DipGMcji.js";import"./ListLayout-F74Z1Dpf.js";const W={ebpf:"ov.v.ebpf",userspace:"ov.v.userspace",mock:"ov.v.mock",active:"ov.v.active",degraded:"ov.v.degraded",detached:"ov.v.detached",failed:"ov.v.failed",disabled:"ov.v.disabled",full:"ov.v.full",partial:"ov.v.partial",none:"ov.v.none",real:"ov.v.real",loaded:"ov.v.loaded",not_loaded:"ov.v.notLoaded",attached:"ov.v.attached",partially_attached:"ov.v.partiallyAttached",published:"ov.v.published",not_published:"ov.v.notPublished",healthy:"ov.v.healthy",ready:"ov.v.ready",error:"ov.v.error",unknown:"ov.v.unknown",ingress:"ov.v.ingress",egress:"ov.v.egress"};function E(o,s){return W[o]?s(W[o]):o}function ge(o,s,e){if(o==="degraded")return{title:e("ov.v.degraded"),text:e(s?"ov.degradedHelp.runtime":"ov.degradedHelp.datapath")};if(o==="unknown")return{title:e("ov.v.unknown"),text:e("ov.unknownHelp")}}function be(o,s,e,a,r=!1){const i=o.ebpf,n=i?.maps?.conn_state,c=(p,u)=>{const m=ge(u,r,e);return m?{label:e(p),value:E(u,e),help:m}:[e(p),E(u,e)]},d=i?.maps?.state??"unknown";return[c("ov.f.kind",o.kind),c("ov.f.state",o.state),...o.visibility==="partial"&&i?[]:[c("ov.f.visibility",o.visibility)],...i?[c("ov.f.backend",i.backend),c("ov.f.programs",i.programs),c("ov.f.hooks",i.hooks),c("ov.f.routing",i.routing.state),c("ov.f.health",i.health),...d==="partial"&&n&&!n.occupancy_known?[[e("ov.f.maps"),e("ov.mapCapacity",{capacity:g(n.capacity,a)})]]:[c("ov.f.maps",d),[e("ov.f.connState"),n?.occupancy_known&&n.occupancy!==null?e("ui.fraction",{part:g(n.occupancy,a),whole:g(n.capacity,a)}):n?e("ov.occupancyUnknown",{capacity:g(n.capacity,a)}):s]]]:[]]}const je={service:"ov.v.cgroupService",shared:"ov.v.cgroupShared"},ye={service:"ov.cgroupHelp.service",shared:"ov.cgroupHelp.shared"};function we(o,s,e,a=[],r=!1){const i=o.cgroup?.scope,n=p=>{const u=z(p??null);return u===null?"—":g(u,e)},c=[["ov.f.rss",x(o.process?.rss_bytes??null,e)],["ov.f.cgroupCurrent",x(o.cgroup?.current_bytes??null,e)],["ov.f.cgroupLimit",r&&o.cgroup?.limit_bytes===null?s("ov.noLimit"):x(o.cgroup?.limit_bytes??null,e)],["ov.f.cgroupScope",i&&i!=="unknown"?s(je[i]):"—"],["ov.f.oomHigh",n(o.cgroup?.events?.high)],["ov.f.oom",n(o.cgroup?.events?.oom)],["ov.f.oomKill",n(o.cgroup?.events?.oom_kill)],["ov.f.ebpfBytes",x(o.kernel?.ebpf_bytes??null,e)]],d=[...a,...i==="unknown"?["ov.f.cgroupScope"]:[],...o.kernel?[]:["ov.f.ebpfBytes"]];return c.filter(([p])=>!d.includes(p)).map(([p,u])=>p==="ov.f.cgroupScope"&&i&&i!=="unknown"?{label:s(p),value:u,help:{title:s(p),text:s("ui.valuePair",{label:u,value:s(ye[i])})}}:[s(p),u])}function ke(o,s,e,a){const{capabilities:r,runtime:i,version:n,memory:c,datapath:d,limits:p=[]}=o,u=i?.lifecycle.state,m=i?.generation.config_revision??i?.generation.active_id??"—",v=i?.last_reload,k=i?.process.cpu_percent,b=K(c?.cgroup?.current_bytes??null,c?.cgroup?.limit_bytes??null),h=l=>l===null?"—":g(l,e),f=(l,j)=>l?"ready":j?"loading":"unavailable";return{status:q(u,d?.state,a(s.capabilities||s.runtime?"ov.loading":"ov.unknown"),a),strip:[{label:a("ov.config"),value:G(m),full:m,help:{title:a("ov.config"),text:a("ov.configHelp")}},[a("ov.uptime"),J(i?.lifecycle.uptime_seconds??null,e)],[a("ov.cpu"),k==null?"—":a("ui.percent",{n:g(k,e,1)})],[a("ov.lastReload"),v?B(v.finished_at,e):"—"]],reload:v?{tooltip:v.operation_id,tone:v.status==="succeeded"?"ok":v.status==="failed"?"err":"warn",text:a(v.status==="succeeded"?"ov.succeeded":v.status==="failed"?"ov.failed":"ov.running")}:null,engine:{state:f(!!n,s.version),fields:n?[[a("ov.f.engine"),n.engine.name+" "+n.engine.version],[a("ov.f.api"),a("ui.apiVersion",{name:n.api.name,major:n.api.major,status:n.api.status})],[a("ov.f.build"),[n.build?.revision,n.build?.target].filter(Boolean).join(a("ui.separator"))||"—"],[a("ov.f.instance"),i?.instance_id??"—"],[a("ov.f.started"),B(i?.lifecycle.started_at??null,e)],[a("ov.f.activated"),B(i?.generation.activated_at??null,e)]]:[],profiles:r?.profiles.map(l=>({id:l,text:a(l==="base"?"ov.profileBase":"ov.profileFull")}))??[]},counters:{state:f(!!i,s.capabilities||s.runtime),fields:i?[[a("ov.f.tcp"),h(i.traffic.connections.tcp)],[a("ov.f.udp"),h(i.traffic.connections.udp)],[a("ov.f.total"),h(i.traffic.connections.total)],[a("ui.upload"),x(i.traffic.bytes.upload,e)],[a("ui.download"),x(i.traffic.bytes.download,e)],{label:a("ov.f.rateWindow"),value:i.traffic.rates?a("ui.seconds",{n:g(i.traffic.rates.window_seconds,e,1)}):"—",help:{title:a("ov.f.rateWindow"),text:a("ov.rateWindowHelp")}}]:[],since:i?a("ov.countersSince",{t:B(i.traffic.counter_since,e),scope:a(i.traffic.scope==="visible"?"ov.scopeVisible":"ov.scopeAll")}):""},memory:{state:f(!!c,s.capabilities||s.memory),fields:c?we(c,a,e,b===null?[]:["ov.f.cgroupCurrent","ov.f.cgroupLimit"],!!r?.resources.runtime_memory.metrics?.includes("cgroup.limit_bytes")):[],bar:b===null?null:{label:a("ov.f.cgroupPercent"),value:a("ui.fraction",{part:x(c?.cgroup?.current_bytes??null,e),whole:x(c?.cgroup?.limit_bytes??null,e)}),pct:b,tone:$(b)}},datapath:{state:f(!!d,s.capabilities||s.datapath),fields:d?be(d,a("ov.unknown"),a,e,u==="degraded"):[],showAttachments:!!d?.ebpf,attachments:(d?.ebpf?.attachments??[]).map((l,j)=>({id:String(j),name:l.name,interface:l.interface,direction:E(l.direction,a),state:E(l.state,a)})),errors:d?.errors.map(l=>({tooltip:l.code,text:I(M(l.code,l.message,a),a)}))??[],warning:d?.ebpf?.last_error&&!d.errors.some(l=>l.message===d.ebpf?.last_error)?a("ui.backendMessage",{message:d.ebpf.last_error}):null,degradations:i?.degradations?.map(l=>({id:l.component,tooltip:l.code,text:I(M(l.code,l.message,a),a)}))??[]},resources:{state:f(!!r,s.capabilities),rows:r?Object.keys(C).filter(l=>!p.some(j=>j.items.some(_=>_.id===l))).map(l=>({id:l,label:a(C[l]),text:a("ov.available")})):[]},limits:p,canExport:!!i}}function _e(o,s){return JSON.stringify({exported_at:s,...o},null,2)}const R={limits:"overview-limits",datapath:"overview-datapath"};function Le(o=""){const s=O(),e=Q(),a=X[e],r=Y(),i=r.data?.resources,n=Z(A(i,"runtime",{whileLoading:!1})),c=ee(A(i,"datapath",{whileLoading:!1})),d=te(A(i,"runtime_memory",{whileLoading:!1})),p=ae(),u=se(n.data,r.data,n.refetch),m=S.useMemo(()=>({capabilities:r.data,runtime:n.data,version:p.data,memory:d.data,datapath:c.data}),[r.data,n.data,p.data,d.data,c.data]),v=S.useMemo(()=>r.data?re(r.data,p.data,s,e):[],[r.data,p.data,s,e]),k=v.length>0,b=!!c.data;S.useEffect(()=>{const _=new URLSearchParams(o).get("card");(_==="limits"&&k||_==="datapath"&&b)&&document.getElementById(R[_])?.scrollIntoView({block:"start"})},[o,k,b]);const h=S.useMemo(()=>ke({...m,limits:v},{capabilities:r.loading,runtime:n.loading,version:p.loading,memory:d.loading,datapath:c.loading},a,s),[m,v,r.loading,n.loading,p.loading,d.loading,c.loading,a,s]),f=oe(),l={err:f.love,warn:f.gold,ok:f.cat[0]},j={...h.memory,bar:h.memory.bar?{...h.memory.bar,color:l[h.memory.bar.tone]}:null};return{...h,memory:j,errors:{capabilities:r.error,runtime:n.error,version:p.error,memory:d.error,datapath:c.error},retry:{capabilities:r.refetch,runtime:n.refetch,version:p.refetch,memory:d.refetch,datapath:c.refetch},actions:u.actions,export:()=>ve(me("doona-state","json"),_e(m,new Date().toISOString()),"application/json")}}function D({cells:o,extra:s=0}){return t.jsxs("div",{className:"rp-body-wait",children:[t.jsx("div",{className:"rp-kv","aria-hidden":"true",children:Array.from({length:o},(e,a)=>t.jsxs("div",{children:[t.jsx("span",{className:"k",children:" "}),t.jsx("span",{className:"v",children:" "})]},a))}),s>0&&t.jsx("div",{"aria-hidden":"true",style:{height:s}}),t.jsx(T,{})]})}function U({link:o}){return t.jsxs(P,{appearance:"link",external:o.external,href:o.href,children:[o.text,o.external&&t.jsx("span",{"aria-hidden":"true",children:"↗"})]})}function Ne({help:o}){return t.jsx(de,{title:o.label,placement:"bottom end",trigger:t.jsxs(pe,{quiet:!0,children:[t.jsx(ue,{}),o.label]}),children:()=>t.jsxs(t.Fragment,{children:[t.jsx("p",{className:"rp-limit-help",children:o.text}),o.snippet&&t.jsx(xe,{as:"pre",className:"rp-limit-snippet",text:o.snippet}),o.link&&t.jsx(U,{link:o.link})]})})}const He=2+V.headingHeight+2*V.rowHeight;function Me({query:o}){const s=O(),e=Le(o),a=t.jsx(y,{tone:e.status.tone,children:e.status.text});return t.jsxs("div",{className:"rp-page",children:[t.jsx(L,{error:e.errors.capabilities,onRetry:e.retry.capabilities}),t.jsxs("div",{className:"rp-between",children:[t.jsxs("div",{className:"rp-cluster",children:[e.status.href?t.jsx(P,{appearance:"link",href:e.status.href,children:a}):a,t.jsx(N,{row:!0,items:e.strip}),e.reload&&t.jsx(F,{text:e.reload.tooltip,children:t.jsx(y,{small:!0,tone:e.reload.tone,children:e.reload.text})})]}),t.jsx("div",{className:"rp-cluster",children:t.jsx(fe,{actions:[{id:"export",label:s("ov.export"),icon:t.jsx(ie,{}),isDisabled:!e.canExport,onAction:e.export},...e.actions]})})]}),t.jsxs("div",{className:"rp-g3",children:[t.jsxs(w,{title:s("ov.engine"),children:[t.jsx(L,{error:e.errors.version,onRetry:e.retry.version}),e.engine.state==="ready"?t.jsxs(t.Fragment,{children:[t.jsx(N,{items:e.engine.fields}),e.engine.profiles.length>0&&t.jsx("div",{className:"rp-cluster",children:e.engine.profiles.map(r=>t.jsx(ne,{children:r.text},r.id))})]}):e.engine.state==="loading"?t.jsx(D,{cells:6,extra:e.engine.profiles.length>0?20:0}):e.errors.version?null:t.jsx(H,{children:s("ov.unavailable")})]}),t.jsxs(w,{title:s("ov.counters"),children:[t.jsx(L,{error:e.errors.runtime,onRetry:e.retry.runtime}),e.counters.state==="ready"?t.jsxs(t.Fragment,{children:[t.jsx(N,{items:e.counters.fields}),t.jsx("span",{className:"rp-label",children:e.counters.since})]}):e.counters.state==="loading"?t.jsx(D,{cells:6,extra:16}):e.errors.runtime?null:t.jsx(H,{children:s("ov.unavailable")})]}),t.jsxs(w,{title:s("ov.memory"),children:[t.jsx(L,{error:e.errors.memory,onRetry:e.retry.memory}),e.memory.state==="ready"?t.jsxs(t.Fragment,{children:[e.memory.bar&&t.jsx(le,{label:e.memory.bar.label,value:e.memory.bar.value,pct:e.memory.bar.pct,color:e.memory.bar.color}),t.jsx(N,{items:e.memory.fields})]}):e.memory.state==="loading"?t.jsx(D,{cells:8}):e.errors.memory?null:t.jsx(H,{children:s("ov.unavailable")})]})]}),t.jsxs("div",{className:"rp-g21 rp-overview-lower",children:[t.jsxs(w,{title:s("ov.datapath"),titleId:R.datapath,help:{title:s("ov.datapath"),text:s("ov.datapathHelp")},children:[t.jsx(L,{error:e.errors.datapath,onRetry:e.retry.datapath}),e.datapath.state==="ready"?t.jsxs(t.Fragment,{children:[t.jsx(N,{items:e.datapath.fields}),e.datapath.showAttachments&&t.jsx(he,{label:s("ov.attachments"),height:250,rows:e.datapath.attachments,empty:s("ov.noAttachments"),cols:[{id:"n",label:s("ov.name"),minWidth:128,isRowHeader:!0,render:r=>r.name},{id:"i",label:s("ov.interface"),minWidth:88,drop:2,render:r=>r.interface},{id:"d",label:s("ov.direction"),minWidth:80,grow:0,drop:1,render:r=>r.direction},{id:"s",label:s("ov.state"),minWidth:88,grow:0,render:r=>r.state}]})]}):e.datapath.state==="loading"?t.jsx(D,{cells:10,extra:He}):e.errors.datapath?null:t.jsx(H,{children:s("ov.unavailable")}),(e.datapath.errors.length>0||e.datapath.warning||e.datapath.degradations.length>0)&&t.jsxs("div",{className:"rp-cluster",children:[e.datapath.errors.map((r,i)=>t.jsx(F,{text:r.tooltip,children:t.jsx(y,{small:!0,tone:"err",children:r.text})},i)),e.datapath.warning&&t.jsx(y,{small:!0,tone:"warn",children:e.datapath.warning}),e.datapath.degradations.map(r=>t.jsx(F,{text:r.tooltip,children:t.jsx(y,{small:!0,tone:"warn",children:r.text})},r.id))]})]}),t.jsx(w,{title:s("ov.resources"),children:e.resources.state==="ready"?t.jsx("div",{className:"rp-capabilities",children:e.resources.rows.map(r=>t.jsxs("div",{className:"rp-capability",children:[t.jsx(y,{tone:"ok",children:r.label}),t.jsx(ce,{children:r.text})]},r.id))}):e.resources.state==="loading"?t.jsx(T,{}):e.errors.capabilities?null:t.jsx(H,{children:s("ov.unavailable")})})]}),e.limits.length>0&&t.jsx(w,{title:s("ov.lim.title"),titleId:R.limits,children:t.jsx("ul",{className:"rp-limits",children:e.limits.map(r=>t.jsxs("li",{className:"rp-limit",children:[t.jsxs("div",{className:"rp-limit-text",children:[t.jsx("span",{children:r.headline}),r.features&&t.jsx("span",{className:"rp-note",children:r.features})]}),r.help?t.jsx(Ne,{help:r.help}):r.link&&t.jsx(U,{link:r.link})]},r.cause))})})]})}export{Me as Overview}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Overview-D8AoxOgR.js b/luci-app-honk/root/etc/honk/doona/assets/Overview-D8AoxOgR.js new file mode 100644 index 000000000..3efafc207 --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/Overview-D8AoxOgR.js @@ -0,0 +1 @@ +import{r as B,j as t}from"./vendor-react-Bf71BWbF.js";import{ap as K,aq as $,ar as I,as as P,at as M,au as G,av as b,aw as D,ax as J,ay as z,az as Q,aA as X,h as u,a5 as _,aB as Y,u as T,a as Z,a6 as ee,aa as te,aC as ae,ac as R,aD as se,aE as re,aF as oe,aG as ie,aH as ne,aI as ce,aJ as w,E as N,L as V,aK as H,aL as A,aM as le,aN as k,aO as de,ak as S,aP as pe,aQ as ue,j as U,aR as ve,B as me,aS as he}from"./index-Bw0aJc9a.js";import{d as fe,e as ge}from"./files-BxEOxSF8.js";import{D as xe,t as O}from"./Table-Km6Zv-S8.js";import{A as be}from"./ActionGroup-DLxTuKht.js";import{D as ye}from"./DaeCode-B8yPDjSE.js";import"./useGridSelectionCheckbox-COXIVEmS.js";import"./Virtualizer-DCY9HC9Z.js";import"./ListLayout-_fDlx5XY.js";const je={connections:u("connections",{tab:"list"}),flows:u("flows",{tab:"records"}),routing_trace:u("rules",{tab:"trace"}),dns_query:u("dns",{tab:"query"}),dns_cache:u("dns",{tab:"cache"}),dns_log:u("dns",{tab:"log"}),events:u("events"),probes:u("nodes",{tab:"latency"}),traffic_history:u("activity"),memory_history:u("activity"),runtime_outbounds:u("activity"),logs:u("logs"),providers:u("nodes"),rules:u("rules",{tab:"list"}),config:u("config"),config_validate:u("config",{tab:"validate"}),runtime_settings:u("settings",{card:"runtime"}),geodata:u("settings",{card:"geodata"})},W={ebpf:"ov.v.ebpf",userspace:"ov.v.userspace",mock:"ov.v.mock",active:"ov.v.active",degraded:"ov.v.degraded",detached:"ov.v.detached",failed:"ov.v.failed",disabled:"ov.v.disabled",full:"ov.v.full",partial:"ov.v.partial",none:"ov.v.none",real:"ov.v.real",loaded:"ov.v.loaded",not_loaded:"ov.v.notLoaded",attached:"ov.v.attached",partially_attached:"ov.v.partiallyAttached",published:"ov.v.published",not_published:"ov.v.notPublished",healthy:"ov.v.healthy",ready:"ov.v.ready",error:"ov.v.error",unknown:"ov.v.unknown",ingress:"ov.v.ingress",egress:"ov.v.egress"};function F(o,s){return W[o]?s(W[o]):o}function we(o,s,e){if(o==="degraded")return{title:e("ov.v.degraded"),text:e(s?"ov.degradedHelp.runtime":"ov.degradedHelp.datapath")};if(o==="unknown")return{title:e("ov.v.unknown"),text:e("ov.unknownHelp")}}function ke(o,s,e,a){if(o!=="unknown"||!s.length)return;const r=new Intl.ListFormat(a,{type:"conjunction"}).format(s);return{title:e("ov.v.notVerified"),text:e("ov.notVerifiedHelp",{hooks:r})}}function _e(o,s,e,a,r=!1,i=[]){const c=o.ebpf,d=c?.maps?.conn_state,l=(f,h)=>{const v=we(h,r,e);return v?{label:e(f),value:F(h,e),help:v}:[e(f),F(h,e)]},p=c?.maps?.state??"unknown",m=c&&ke(c.hooks,i,e,a);return[l("ov.f.kind",o.kind),l("ov.f.state",o.state),...o.visibility==="partial"&&c?[]:[l("ov.f.visibility",o.visibility)],...c?[l("ov.f.backend",c.backend),l("ov.f.programs",c.programs),m?{label:e("ov.f.hooks"),value:e("ov.v.notVerified"),help:m}:l("ov.f.hooks",c.hooks),l("ov.f.routing",c.routing.state),l("ov.f.health",c.health),...p==="partial"&&d&&!d.occupancy_known?[[e("ov.f.maps"),e("ov.mapCapacity",{capacity:_(d.capacity,a)})]]:[l("ov.f.maps",p),[e("ov.f.connState"),d?.occupancy_known&&d.occupancy!==null?e("ui.fraction",{part:_(d.occupancy,a),whole:_(d.capacity,a)}):d?e("ov.occupancyUnknown",{capacity:_(d.capacity,a)}):s]]]:[]]}const Le={service:"ov.v.cgroupService",shared:"ov.v.cgroupShared"},Ne={service:"ov.cgroupHelp.service",shared:"ov.cgroupHelp.shared"};function He(o,s,e,a=[],r=!1){const i=o.cgroup?.scope,c=p=>{const m=Y(p??null);return m===null?"—":_(m,e)},d=[["ov.f.rss",b(o.process?.rss_bytes??null,e)],["ov.f.cgroupCurrent",b(o.cgroup?.current_bytes??null,e)],["ov.f.cgroupLimit",r&&o.cgroup?.limit_bytes===null?s("ov.noLimit"):b(o.cgroup?.limit_bytes??null,e)],["ov.f.cgroupScope",i&&i!=="unknown"?s(Le[i]):"—"],["ov.f.oomHigh",c(o.cgroup?.events?.high)],["ov.f.oom",c(o.cgroup?.events?.oom)],["ov.f.oomKill",c(o.cgroup?.events?.oom_kill)],["ov.f.ebpfBytes",b(o.kernel?.ebpf_bytes??null,e)]],l=[...a,...i==="unknown"?["ov.f.cgroupScope"]:[],...o.kernel?[]:["ov.f.ebpfBytes"]];return d.filter(([p])=>!l.includes(p)).map(([p,m])=>p==="ov.f.cgroupScope"&&i&&i!=="unknown"?{label:s(p),value:m,help:{title:s(p),text:s("ui.valuePair",{label:m,value:s(Ne[i])})}}:[s(p),m])}function Se(o,s,e,a){const{capabilities:r,runtime:i,version:c,memory:d,datapath:l,limits:p=[]}=o,m=K(c).uncheckedHooks,f=i?.lifecycle.state,h=i?.generation.config_revision??"—",v=i?.last_reload,y=$(d?.cgroup?.current_bytes??null,d?.cgroup?.limit_bytes??null),g=n=>n===null?"—":_(n,e),x=(n,j)=>n?"ready":j?"loading":"unavailable";return{status:X(f,l?.state,a(s.capabilities||s.runtime?"ov.loading":"ov.unknown"),a),strip:[{label:a("ov.config"),value:J(h),full:h,help:{title:a("ov.config"),text:a("config.revisionHelp")}},[a("ov.uptime"),z(i?.lifecycle.uptime_seconds??null,e)],[a("ov.cpu"),Q(i?.process.cpu_percent,a)],[a("ov.lastReload"),v?D(v.finished_at,e):"—"]],reload:v?{tooltip:v.operation_id,tone:v.status==="succeeded"?"ok":v.status==="failed"?"err":"warn",text:a(v.status==="succeeded"?"ov.succeeded":v.status==="failed"?"ov.failed":"ov.running")}:null,engine:{state:x(!!c,s.version),fields:c?[[a("ov.f.engine"),c.engine.name+" "+c.engine.version],[a("ov.f.api"),a("ui.apiVersion",{name:c.api.name,major:c.api.major,status:c.api.status})],[a("ov.f.build"),[c.build?.revision,c.build?.target].filter(Boolean).join(a("ui.separator"))||"—"],[a("ov.f.instance"),i?.instance_id??"—"],[a("ov.f.started"),D(i?.lifecycle.started_at??null,e)],[a("ov.f.activated"),D(i?.generation.activated_at??null,e)]]:[],profiles:r?.profiles.map(n=>({id:n,text:a(n==="base"?"ov.profileBase":"ov.profileFull")}))??[]},counters:{state:x(!!i,s.capabilities||s.runtime),fields:i?[[a("ov.f.tcp"),g(i.traffic.connections.tcp)],[a("ov.f.udp"),g(i.traffic.connections.udp)],[a("ov.f.total"),g(i.traffic.connections.total)],[a("ui.upload"),b(i.traffic.bytes.upload,e)],[a("ui.download"),b(i.traffic.bytes.download,e)],{label:a("ov.f.rateWindow"),value:i.traffic.rates?a("ui.seconds",{n:i.traffic.rates.window_seconds},"n",{n:1}):"—",help:{title:a("ov.f.rateWindow"),text:a("ov.rateWindowHelp")}}]:[],since:i?a("ov.countersSince",{time:D(i.traffic.counter_since,e),scope:a(i.traffic.scope==="visible"?"ov.scopeVisible":"ov.scopeAll")}):""},memory:{state:x(!!d,s.capabilities||s.memory),fields:d?He(d,a,e,y===null?[]:["ov.f.cgroupCurrent","ov.f.cgroupLimit"],!!r?.resources.runtime_memory.metrics?.includes("cgroup.limit_bytes")):[],bar:y===null?null:{label:a("ov.f.cgroupPercent"),value:a("ui.fraction",{part:b(d?.cgroup?.current_bytes??null,e),whole:b(d?.cgroup?.limit_bytes??null,e)}),pct:y,tone:G(y)}},datapath:{state:x(!!l,s.capabilities||s.datapath),fields:l?_e(l,a("ov.unknown"),a,e,f==="degraded",m):[],showAttachments:!!l?.ebpf,attachments:(l?.ebpf?.attachments??[]).map((n,j)=>({id:String(j),name:n.name,interface:n.kind==="interface"?n.interface??"—":a("ui.valuePair",{label:a(n.kind==="cgroup"?"ov.kind.cgroup":"ov.kind.other"),value:(n.kind==="cgroup"?n.cgroup:n.hook)??"—"}),direction:n.direction?F(n.direction,a):"—",state:F(n.state,a)})),errors:l?.errors.map(n=>({tooltip:n.code,text:P(M(n.code,n.message,a),a)}))??[],warning:l?.ebpf?.last_error&&!l.errors.some(n=>n.message===l.ebpf?.last_error)?a("ui.backendMessage",{message:l.ebpf.last_error}):null,degradations:i?.degradations?.map(n=>({id:n.component,tooltip:n.code,text:P(M(n.code,n.message,a),a)}))??[]},resources:{state:x(!!r,s.capabilities),rows:r?Object.keys(I).filter(n=>!p.some(j=>j.items.some(L=>L.id===n))).map(n=>({id:n,label:a(I[n]),text:a("ov.available"),href:je[n]})):[]},limits:p,canExport:!!i}}function Be(o,s){return JSON.stringify({exported_at:s,...o},null,2)}const C={limits:"overview-limits",datapath:"overview-datapath"};function De(o=""){const s=T(),e=Z(),a=ee[e],r=te(),i=r.data?.resources,c=ae(R(i,"runtime",{whileLoading:!1})),d=se(R(i,"datapath",{whileLoading:!1})),l=re(R(i,"runtime_memory",{whileLoading:!1})),p=oe(),m=ie(c.data,r.data,c.refetch),f=B.useMemo(()=>({capabilities:r.data,runtime:c.data,version:p.data,memory:l.data,datapath:d.data}),[r.data,c.data,p.data,l.data,d.data]),h=B.useMemo(()=>r.data?ne(r.data,p.data,s,e):[],[r.data,p.data,s,e]),v=h.length>0,y=!!d.data;B.useEffect(()=>{const L=new URLSearchParams(o).get("card");(L==="limits"&&v||L==="datapath"&&y)&&document.getElementById(C[L])?.scrollIntoView({block:"start"})},[o,v,y]);const g=B.useMemo(()=>Se({...f,limits:h},{capabilities:r.loading,runtime:c.loading,version:p.loading,memory:l.loading,datapath:d.loading},a,s),[f,h,r.loading,c.loading,p.loading,l.loading,d.loading,a,s]),x=ce(),n={err:x.love,warn:x.gold,ok:x.cat[0]},j={...g.memory,bar:g.memory.bar?{...g.memory.bar,color:n[g.memory.bar.tone]}:null};return{...g,memory:j,errors:{capabilities:r.error,runtime:c.error,version:p.error,memory:l.error,datapath:d.error},retry:{capabilities:r.refetch,runtime:c.refetch,version:p.refetch,memory:l.refetch,datapath:d.refetch},actions:m.actions,export:()=>fe(ge("doona-state","json"),Be(f,new Date().toISOString()),"application/json")}}function E({cells:o,extra:s=0}){return t.jsxs("div",{className:"rp-body-wait",children:[t.jsx("div",{className:"rp-kv","aria-hidden":"true",children:Array.from({length:o},(e,a)=>t.jsxs("div",{children:[t.jsx("span",{className:"k",children:" "}),t.jsx("span",{className:"v",children:" "})]},a))}),s>0&&t.jsx("div",{"aria-hidden":"true",style:{height:s}}),t.jsx(U,{})]})}function q({link:o}){return t.jsxs(V,{appearance:"link",external:o.external,href:o.href,children:[o.text,o.external&&t.jsx("span",{"aria-hidden":"true",children:"↗"})]})}function Ee({help:o}){return t.jsx(ve,{title:o.label,placement:"bottom end",trigger:t.jsxs(me,{quiet:!0,children:[t.jsx(he,{}),o.label]}),children:()=>t.jsxs(t.Fragment,{children:[t.jsx("p",{className:"rp-limit-help",children:o.text}),o.snippet&&t.jsx(ye,{as:"pre",className:"rp-limit-snippet",text:o.snippet}),o.link&&t.jsx(q,{link:o.link})]})})}const Fe=2+O.headingHeight+2*O.rowHeight;function Te({query:o}){const s=T(),e=De(o),a=t.jsx(w,{tone:e.status.tone,children:e.status.text});return t.jsxs("div",{className:"rp-page",children:[t.jsx(N,{error:e.errors.capabilities,onRetry:e.retry.capabilities}),t.jsxs("div",{className:"rp-between",children:[t.jsxs("div",{className:"rp-cluster",children:[e.status.href?t.jsx(V,{appearance:"link",href:e.status.href,children:a}):a,t.jsx(H,{row:!0,items:e.strip}),e.reload&&t.jsx(A,{text:e.reload.tooltip,children:t.jsx(w,{small:!0,tone:e.reload.tone,children:e.reload.text})})]}),t.jsx("div",{className:"rp-cluster",children:t.jsx(be,{actions:[{id:"export",label:s("ov.export"),icon:t.jsx(le,{}),isDisabled:!e.canExport,onAction:e.export},...e.actions]})})]}),t.jsxs("div",{className:"rp-g3",children:[t.jsxs(k,{title:s("ov.engine"),children:[t.jsx(N,{error:e.errors.version,onRetry:e.retry.version}),e.engine.state==="ready"?t.jsxs(t.Fragment,{children:[t.jsx(H,{items:e.engine.fields}),e.engine.profiles.length>0&&t.jsx("div",{className:"rp-cluster",children:e.engine.profiles.map(r=>t.jsx(de,{children:r.text},r.id))})]}):e.engine.state==="loading"?t.jsx(E,{cells:6,extra:e.engine.profiles.length>0?20:0}):e.errors.version?null:t.jsx(S,{children:s("ov.unavailable")})]}),t.jsxs(k,{title:s("ov.counters"),children:[t.jsx(N,{error:e.errors.runtime,onRetry:e.retry.runtime}),e.counters.state==="ready"?t.jsxs(t.Fragment,{children:[t.jsx(H,{items:e.counters.fields}),t.jsx("span",{className:"rp-label",children:e.counters.since})]}):e.counters.state==="loading"?t.jsx(E,{cells:6,extra:16}):e.errors.runtime?null:t.jsx(S,{children:s("ov.unavailable")})]}),t.jsxs(k,{title:s("ov.memory"),children:[t.jsx(N,{error:e.errors.memory,onRetry:e.retry.memory}),e.memory.state==="ready"?t.jsxs(t.Fragment,{children:[e.memory.bar&&t.jsx(pe,{label:e.memory.bar.label,value:e.memory.bar.value,pct:e.memory.bar.pct,color:e.memory.bar.color}),t.jsx(H,{items:e.memory.fields})]}):e.memory.state==="loading"?t.jsx(E,{cells:8}):e.errors.memory?null:t.jsx(S,{children:s("ov.unavailable")})]})]}),t.jsxs("div",{className:"rp-g21 rp-overview-lower",children:[t.jsxs(k,{title:s("ov.datapath"),titleId:C.datapath,help:{title:s("ov.datapath"),text:s("ov.datapathHelp")},children:[t.jsx(N,{error:e.errors.datapath,onRetry:e.retry.datapath}),e.datapath.state==="ready"?t.jsxs(t.Fragment,{children:[t.jsx(H,{items:e.datapath.fields}),e.datapath.showAttachments&&t.jsx(xe,{label:s("ov.attachments"),height:250,rows:e.datapath.attachments,empty:s("ov.noAttachments"),cols:[{id:"n",label:s("ov.name"),minWidth:128,isRowHeader:!0,render:r=>r.name},{id:"i",label:s("ov.interface"),minWidth:88,drop:2,render:r=>r.interface},{id:"d",label:s("ov.direction"),minWidth:80,grow:0,drop:1,render:r=>r.direction},{id:"s",label:s("ov.state"),minWidth:88,grow:0,render:r=>r.state}]})]}):e.datapath.state==="loading"?t.jsx(E,{cells:10,extra:Fe}):e.errors.datapath?null:t.jsx(S,{children:s("ov.unavailable")}),(e.datapath.errors.length>0||e.datapath.warning||e.datapath.degradations.length>0)&&t.jsxs("div",{className:"rp-cluster",children:[e.datapath.errors.map((r,i)=>t.jsx(A,{text:r.tooltip,children:t.jsx(w,{small:!0,tone:"err",children:r.text})},i)),e.datapath.warning&&t.jsx(w,{small:!0,tone:"warn",children:e.datapath.warning}),e.datapath.degradations.map(r=>t.jsx(A,{text:r.tooltip,children:t.jsx(w,{small:!0,tone:"warn",children:r.text})},r.id))]})]}),t.jsx(k,{title:s("ov.resources"),children:e.resources.state==="ready"?t.jsx("div",{className:"rp-capabilities",children:e.resources.rows.map(r=>t.jsxs("div",{className:"rp-capability",children:[t.jsx(w,{tone:"ok",children:t.jsx(V,{appearance:"link",href:r.href,children:r.label})}),t.jsx(ue,{children:r.text})]},r.id))}):e.resources.state==="loading"?t.jsx(U,{}):e.errors.capabilities?null:t.jsx(S,{children:s("ov.unavailable")})})]}),e.limits.length>0&&t.jsx(k,{title:s("ov.lim.title"),titleId:C.limits,children:t.jsx("ul",{className:"rp-limits",children:e.limits.map(r=>t.jsxs("li",{className:"rp-limit",children:[t.jsxs("div",{className:"rp-limit-text",children:[t.jsx("span",{children:r.headline}),r.features&&t.jsx("span",{className:"rp-note",children:r.features})]}),r.help?t.jsx(Ee,{help:r.help}):r.link&&t.jsx(q,{link:r.link})]},r.cause))})})]})}export{Te as Overview}; diff --git a/luci-app-honk/root/etc/honk/doona/assets/Policies-Dgwc4tfn.js b/luci-app-honk/root/etc/honk/doona/assets/Policies-Dgwc4tfn.js new file mode 100644 index 000000000..87ce48b87 --- /dev/null +++ b/luci-app-honk/root/etc/honk/doona/assets/Policies-Dgwc4tfn.js @@ -0,0 +1,2 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./Arrange-BwxzZLbt.js","./vendor-react-Bf71BWbF.js","./index-Bw0aJc9a.js","./index-7R3bVGRM.css","./Virtualizer-DCY9HC9Z.js","./ListLayout-_fDlx5XY.js","./DaeCode-B8yPDjSE.js","./policyText-CltaDVEo.js","./openGroup-Dk9B33qx.js","./useFilter-Tjznm3lB.js","./ActionGroup-DLxTuKht.js","./useGridSelectionCheckbox-COXIVEmS.js","./nav-BASDWt23.js","./Arrange-Dd3j3leY.css"])))=>i.map(i=>d[i]); +import{bT as it,bU as ot,bV as rt,bW as pe,bX as te,bY as Ie,bZ as nt,b_ as at,b$ as lt,c0 as st,c1 as je,c2 as re,c3 as ne,c4 as me,c5 as G,c6 as W,c7 as q,c8 as ee,c9 as ct,ca as ae,cb as Ke,cc as dt,cd as ut,ce as He,cf as pt,cg as de,ch as fe,ci as Oe,cj as ue,ck as ft,cl as ke,cm as Se,cn as he,co as be,cp as Fe,cq as ht,cr as bt,cs as mt,ct as Be,cu as gt,cv as yt,cw as le,cx as vt,cy as xt,cz as $t,cA as kt,cB as wt,cC as Pt,cD as It,cE as St,cF as Et,cG as Dt,cH as Mt,cI as jt,M as Ct,b as ce,cJ as Nt,a4 as _t,bc as Ge,bB as Tt,a_ as Lt,K as zt,cK as At,aW as Rt,a5 as Kt,u as B,a6 as Ht,a as Ot,ak as we,bC as Ft,cL as ge,c as ye,T as Ee,br as Bt,cM as Gt,cN as Ue,ah as Ve,I as Ut,B as Y,aj as Vt,bd as Wt,aa as qt,ae as Yt,ac as ve,ad as Xt,bA as Jt,cO as Qt,ag as Zt,cP as ei,bj as ti,bk as ii,cQ as oi,bL as ri,cR as We,cS as qe,R as ni,bm as U,cT as ai,cU as li,bg as si,cV as ci,cW as di,A as ui,E as Ye,cX as pi,bx as fi,j as Xe,aN as hi,bQ as bi,aO as mi,aJ as se,bw as gi,cY as yi,aK as vi,bs as xi,cZ as $i,_ as ki}from"./index-Bw0aJc9a.js";import{r as f,$ as S,j as c}from"./vendor-react-Bf71BWbF.js";import{M as wi}from"./ActionGroup-DLxTuKht.js";import{$ as Pi,a as Ii,b as Si,c as Ei,d as Di}from"./useGridSelectionCheckbox-COXIVEmS.js";import{$ as Mi,a as F,b as xe,c as J,d as ji}from"./Virtualizer-DCY9HC9Z.js";import{$ as Ci}from"./useFilter-Tjznm3lB.js";import{g as Ni,a as _i}from"./policyText-CltaDVEo.js";import{P as Ti,o as Li}from"./openGroup-Dk9B33qx.js";import{p as Je}from"./nav-BASDWt23.js";const De=new WeakMap;function Pe(i,t){let{id:e}=De.get(i)??{};if(!e)throw new Error("Unknown list");return`${e}-${zi(t)}`}function zi(i){return typeof i=="string"?i.replace(/\s*/g,""):""+i}function Ai(i,t,e){let{isVirtualized:o,keyboardDelegate:r,layoutDelegate:n,onAction:s,disallowTypeAhead:l,linkBehavior:a="action",keyboardNavigationBehavior:p="arrow",escapeKeyBehavior:d="clearSelection",shouldSelectOnPressUp:v}=i;!i["aria-label"]&&!i["aria-labelledby"]&&console.warn("An aria-label or aria-labelledby prop is required for accessibility.");let{listProps:h}=it({selectionManager:t.selectionManager,collection:t.collection,disabledKeys:t.disabledKeys,ref:e,keyboardDelegate:r,layoutDelegate:n,isVirtualized:o,selectOnFocus:t.selectionManager.selectionBehavior==="replace",shouldFocusWrap:i.shouldFocusWrap,linkBehavior:a,disallowTypeAhead:l,autoFocus:i.autoFocus,escapeKeyBehavior:d,UNSTABLE_focusOnEntry:i.UNSTABLE_focusOnEntry}),g=ot(i.id);De.set(t,{id:g,onAction:s,linkBehavior:a,keyboardNavigationBehavior:p,shouldSelectOnPressUp:v});let x=Pi({selectionManager:t.selectionManager,hasItemActions:!!s}),P=rt(e,{isDisabled:t.collection.size!==0}),m=pe(i,{labelable:!0}),b=te(m,{role:"grid",id:g,"aria-multiselectable":t.selectionManager.selectionMode==="multiple"?"true":void 0},t.collection.size===0?{tabIndex:P?-1:0}:h,x);return o&&(b["aria-rowcount"]=t.collection.size,b["aria-colcount"]=1),Ii({},t),{gridProps:b}}const Ce={expand:{ltr:"ArrowRight",rtl:"ArrowLeft"},collapse:{ltr:"ArrowLeft",rtl:"ArrowRight"}};function Ri(i,t,e){let{node:o,isVirtualized:r,focusMode:n="row",allowsArrowNavigation:s}=i,{direction:l}=Ie(),{onAction:a,linkBehavior:p,keyboardNavigationBehavior:d,shouldSelectOnPressUp:v}=De.get(t),h=nt(),g=f.useRef(null),x=()=>{if(e.current!==null){if(n==="child"){if(je(e.current)&&e.current!==re(ne(e.current)))return;let D=me(e.current,{tabbable:!0}).firstChild();if(D){G(D),W(D,{containingElement:q(D)});return}}(g.current!=null&&o.key!==g.current||!je(e.current))&&G(e.current)}},P={},m=i.hasChildItems,b=t.selectionManager.isLink(o.key);if(o!=null&&"expandedKeys"in t){let u=t.collection.getChildren?.(o.key);m=m||[...u??[]].length>1,a==null&&!b&&t.selectionManager.selectionMode==="none"&&m&&(a=()=>t.toggleKey(o.key));let D=m?t.expandedKeys.has(o.key):void 0,w=1,j=o.index;if(o.level>=0&&o?.parentKey!=null){let C=t.collection.getItem(o.parentKey);if(C){let z=Ki(C,t.collection);w=[...z].filter(R=>R.type==="item").length,j>0&&z[0].type!=="item"&&(j-=1)}}else w=[...t.collection].filter(C=>C.level===0&&C.type==="item").length;P={"aria-expanded":D,"aria-level":o.level+1,"aria-posinset":j+1,"aria-setsize":w}}let{itemProps:$,...I}=at({selectionManager:t.selectionManager,key:o.key,ref:e,isVirtualized:r,shouldSelectOnPressUp:i.shouldSelectOnPressUp||v,onAction:a||o.props?.onAction?lt(o.props?.onAction,a?()=>a(o.key):void 0):void 0,focus:x,linkBehavior:p}),M=u=>{let D=re(ne(e.current));if(!ae(u.currentTarget,ee(u))||!e.current||!D)return;let w=me(e.current);if(w.currentNode=D,!Ne(u,t,o,m,l,D,e.current,s))switch(u.key){case"ArrowLeft":if(d==="arrow"){let j=l==="rtl"?w.nextNode():w.previousNode();if(j)u.preventDefault(),u.stopPropagation(),G(j),W(j,{containingElement:q(e.current)});else if(u.preventDefault(),u.stopPropagation(),l==="rtl")G(e.current),W(e.current,{containingElement:q(e.current)});else{w.currentNode=e.current;let C=_e(w);C&&(G(C),W(C,{containingElement:q(e.current)}))}}break;case"ArrowRight":if(d==="arrow"){let j=l==="rtl"?w.previousNode():w.nextNode();if(j)u.preventDefault(),u.stopPropagation(),G(j),W(j,{containingElement:q(e.current)});else if(u.preventDefault(),u.stopPropagation(),l==="ltr")G(e.current),W(e.current,{containingElement:q(e.current)});else{w.currentNode=e.current;let C=_e(w);C&&(G(C),W(C,{containingElement:q(e.current)}))}}break;case"ArrowUp":case"ArrowDown":!u.altKey&&ae(e.current,ee(u))&&(u.stopPropagation(),u.preventDefault(),e.current.parentElement?.dispatchEvent(new KeyboardEvent(u.nativeEvent.type,u.nativeEvent)));break}},E=u=>{if(g.current=o.key,ee(u)!==e.current){ct()||t.selectionManager.setFocusedKey(o.key);return}n==="child"&&u.relatedTarget&&ae(e.current,u.relatedTarget)||requestAnimationFrame(()=>{n==="child"&&re(ne(e.current))===e.current&&x()})},N=u=>{let D=re(ne(e.current));if(!(!ae(u.currentTarget,ee(u))||!e.current||!D)){if(d==="tab"){if(ee(u)!==e.current&&u.key!=="Tab"){u.stopPropagation();return}if(Ne(u,t,o,m,l,D,e.current,s))return}switch(u.key){case"Tab":if(d==="tab"){let w=me(e.current,{tabbable:!0});w.currentNode=D,(u.shiftKey?w.previousNode():w.nextNode())&&u.stopPropagation()}}}},L=st(o.props),_=I.hasAction?L:{},T=te($,_,{role:"row",onKeyDownCapture:d==="arrow"||s?M:void 0,onFocus:E,"aria-label":o["aria-label"]||o.textValue||void 0,"aria-selected":t.selectionManager.canSelectItem(o.key)?t.selectionManager.isSelected(o.key):void 0,"aria-disabled":t.selectionManager.isDisabled(o.key)||void 0,"aria-labelledby":h&&(o["aria-label"]||o.textValue)?`${Pe(t,o.key)} ${h}`:void 0,id:Pe(t,o.key)});n==="child"&&s&&d==="tab"&&(T.tabIndex=-1);let k=T.onKeyDown;if(T.onKeyDown=u=>{N(u),u.isPropagationStopped()||k?.(u)},r){let{collection:u}=t,D=[...u];T["aria-rowindex"]=D.find(w=>w.type==="section")?[...u.getKeys()].filter(w=>u.getItem(w)?.type!=="section").findIndex(w=>w===o.key)+1:o.index+1}let y={role:"gridcell","aria-colindex":1};return{rowProps:{...te(T,P)},gridCellProps:y,descriptionProps:{id:h},...I}}function Ne(i,t,e,o,r,n,s,l){if(!("expandedKeys"in t)||!l&&n!==s)return!1;if(i.key===Ce.expand[r]&&t.selectionManager.focusedKey===e.key&&o&&!t.expandedKeys.has(e.key))return t.toggleKey(e.key),i.stopPropagation(),!0;if(i.key===Ce.collapse[r]&&t.selectionManager.focusedKey===e.key){if(o&&t.expandedKeys.has(e.key))return t.toggleKey(e.key),i.stopPropagation(),!0;if(!t.expandedKeys.has(e.key)&&e.parentKey&&t.collection.getItem(e.parentKey)?.type==="item")return t.selectionManager.setFocusedKey(e.parentKey),i.stopPropagation(),!0}return!1}function _e(i){let t=null,e=null;do e=i.lastChild(),e&&(t=e);while(e);return t}function Ki(i,t){let e=t.getChildren?.(i.key),o=e?Array.from(e):[],r=o.length>0?o[0]:null,n=[];for(;r;)n.push(r),r=r.nextKey!=null?t.getItem(r.nextKey):null;return n}function Hi(i,t){let{key:e}=i;const{checkboxProps:o}=Si(i,t);return{checkboxProps:{...o,"aria-labelledby":`${o.id} ${Pe(t,e)}`}}}const Oi=f.createContext(null),Fi=f.forwardRef(function(t,e){return[t,e]=Ke(t,e,Oi),S.createElement(dt,{content:S.createElement(ut,t)},o=>S.createElement(Bi,{props:t,collection:o,gridListRef:e}))});function Bi({props:i,collection:t,gridListRef:e}){[i,e]=Ke(i,e,Be);let{shouldUseVirtualFocus:o,filter:r,disallowTypeAhead:n,UNSTABLE_focusOnEntry:s,...l}=i,{dragAndDropHooks:a,keyboardNavigationBehavior:p="arrow",layout:d="stack",orientation:v="vertical"}=i,{CollectionRoot:h,isVirtualized:g,layoutDelegate:x,dropTargetDelegate:P}=f.useContext(ue),m=vt({...l,collection:t,children:void 0,layoutDelegate:x}),b=xt(m,r),$=$t({usage:"search",sensitivity:"base"}),{disabledBehavior:I,disabledKeys:M}=b.selectionManager,{direction:E}=Ie(),N=f.useMemo(()=>new kt({collection:b.collection,collator:$,ref:e,disabledKeys:M,disabledBehavior:I,layoutDelegate:x,layout:d,orientation:v,direction:E}),[b.collection,e,d,v,M,I,x,$,E]),{gridProps:L}=Ai({...l,keyboardDelegate:N,keyboardNavigationBehavior:d==="grid"?"tab":p,isVirtualized:g,shouldSelectOnPressUp:i.shouldSelectOnPressUp,disallowTypeAhead:n,UNSTABLE_focusOnEntry:s},b,e),_=b.selectionManager,T=!!a?.useDraggableCollectionState,k=!!a?.useDroppableCollectionState;f.useRef(T),f.useRef(k),f.useEffect(()=>{},[T,k]);let y,u,D,w=!1,j=null,C=f.useRef(null);if(T&&a){y=a.useDraggableCollectionState({collection:b.collection,selectionManager:_,preview:a.renderDragPreview?C:void 0}),a.useDraggableCollection({},y,e);let V=a.DragPreview;j=a.renderDragPreview?S.createElement(V,{ref:C},a.renderDragPreview):null}if(k&&a){u=a.useDroppableCollectionState({collection:b.collection,selectionManager:_});let V=a.dropTargetDelegate||P||new a.ListDropTargetDelegate(t,e,{layout:d,direction:E,orientation:v});D=a.useDroppableCollection({keyboardDelegate:N,dropTargetDelegate:V},u,e),w=u.isDropTarget({type:"root"})}let{focusProps:z,isFocused:R,isFocusVisible:K}=ke(),O=b.collection.size===0,H={isDropTarget:w,orientation:v,isEmpty:O,isFocused:R,isFocusVisible:K,layout:d,state:b},Q=he({...i,children:void 0,defaultClassName:"react-aria-GridList",values:H}),ie=null,oe=null;if(O&&i.renderEmptyState){let V=i.renderEmptyState(H);ie=S.createElement("div",{role:"row","aria-rowindex":1,style:{display:"contents"}},S.createElement("div",{role:"gridcell",style:{display:"contents"}},V))}let Z=pe(i,{global:!0});return S.createElement(wt,null,S.createElement(be.div,{...te(Z,Q,L,z,D?.collectionProps,oe),ref:e,slot:i.slot||void 0,onScroll:i.onScroll,"data-drop-target":w||void 0,"data-empty":O||void 0,"data-focused":R||void 0,"data-focus-visible":K||void 0,"data-layout":d,"data-orientation":v},S.createElement(Fe,{values:[[de,b],[fe,{dragAndDropHooks:a,dragState:y,dropState:u}],[Pt,{render:Ui}]]},k&&S.createElement(qi,null),S.createElement(It,null,S.createElement(h,{collection:b.collection,scrollRef:e,persistedKeys:Et(_,a,u),renderDropIndicator:St(a,u)}))),ie,j))}const Gi=He(pt,function(t,e,o){let r=f.useContext(de),{dragAndDropHooks:n,dragState:s,dropState:l}=f.useContext(fe),a=Oe(e),{isVirtualized:p}=f.useContext(ue),d=s&&!(s.isDisabled||s.selectionManager.isDisabled(o.key)),{rowProps:v,gridCellProps:h,descriptionProps:g,...x}=Ri({node:o,shouldSelectOnPressUp:!!s,isVirtualized:p,focusMode:t.focusMode,allowsArrowNavigation:t.allowsArrowNavigation},r,a),{hoverProps:P,isHovered:m}=ft({isDisabled:!x.allowsSelection&&!x.hasAction&&!d,onHoverStart:o.props.onHoverStart,onHoverChange:o.props.onHoverChange,onHoverEnd:o.props.onHoverEnd}),{isFocusVisible:b,focusProps:$}=ke(),{isFocusVisible:I,focusProps:M}=ke({within:!0}),{checkboxProps:E}=Hi({key:o.key},r),N=r.selectionManager.disabledBehavior==="all"&&x.isDisabled?{isDisabled:!0}:{},L=null;s&&n&&(L=n.useDraggableItem({key:o.key,hasDragButton:!0},s));let _=null,T=f.useRef(null),{visuallyHiddenProps:k}=Se();l&&n&&(_=n.useDropIndicator({target:{type:"item",key:o.key,dropPosition:"on"}},l,T));let y=s&&s.isDragging(o.key),u=he({...t,id:void 0,children:o.rendered,defaultClassName:"react-aria-GridListItem",values:{...x,isHovered:m,isFocusVisible:b,isFocusVisibleWithin:I,selectionMode:r.selectionManager.selectionMode,selectionBehavior:r.selectionManager.selectionBehavior,allowsDragging:!!s,isDragging:y,isDropTarget:_?.isDropTarget,id:o.key,state:r}}),D=f.useRef(null);f.useEffect(()=>{s&&!D.current&&console.warn('Draggable items in a GridList must contain a