local-operator-ui 0.36.6 → 0.36.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/main/index.js +739 -27
- package/out/preload/index.js +40 -0
- package/out/renderer/assets/{_basePickBy-B0B_HryP.js → _basePickBy-D11ygq2l.js} +1 -1
- package/out/renderer/assets/{_baseUniq-BC6WfZEZ.js → _baseUniq-_Pf0yG1r.js} +1 -1
- package/out/renderer/assets/{agent-details-page-CIKeI8ax.js → agent-details-page-LU973LFV.js} +2 -2
- package/out/renderer/assets/{agent-hub-page-NKE7fJK1.js → agent-hub-page-DegTVxlE.js} +2 -2
- package/out/renderer/assets/{agents-page-BIRTx9kB.js → agents-page-B6Y-wB7u.js} +3 -3
- package/out/renderer/assets/{arc-DyL52bz_.js → arc-BedtwWh_.js} +1 -1
- package/out/renderer/assets/{architectureDiagram-IEHRJDOE-OQsI3Nan.js → architectureDiagram-IEHRJDOE-DyIP0L4b.js} +1 -1
- package/out/renderer/assets/{arrow-up-BpuHf_sB.js → arrow-up-BD8jieeb.js} +1 -1
- package/out/renderer/assets/{blockDiagram-JOT3LUYC-CS1fz58m.js → blockDiagram-JOT3LUYC-w5b-ZzdW.js} +1 -1
- package/out/renderer/assets/{book-open-BiI_r4jM.js → book-open-DxzLWerU.js} +1 -1
- package/out/renderer/assets/browser-page-Bm5bblrV.js +1 -0
- package/out/renderer/assets/{browser-webauthn-prompt-ja8N1ehh.js → browser-webauthn-prompt-CbE9FFZv.js} +1 -1
- package/out/renderer/assets/{building-2-Dar5h3t0.js → building-2-DtOQfBQY.js} +1 -1
- package/out/renderer/assets/{c4Diagram-VJAJSXHY-C6RZIvJP.js → c4Diagram-VJAJSXHY-CnSFoHWb.js} +1 -1
- package/out/renderer/assets/channel-BJPW3C83.js +1 -0
- package/out/renderer/assets/{chunk-4BMEZGHF-Cpn-cLXo.js → chunk-4BMEZGHF-CY0scau5.js} +1 -1
- package/out/renderer/assets/{chunk-A2AXSNBT-S8Vffyme.js → chunk-A2AXSNBT-B_cWmZiK.js} +1 -1
- package/out/renderer/assets/{chunk-AEK57VVT-K1GcoFUy.js → chunk-AEK57VVT-BRm1a_Ub.js} +1 -1
- package/out/renderer/assets/{chunk-D6G4REZN-CyqTe7_6.js → chunk-D6G4REZN-CmZT-cQT.js} +1 -1
- package/out/renderer/assets/{chunk-RZ5BOZE2-QWUc1JND.js → chunk-RZ5BOZE2-Cwg1etHt.js} +1 -1
- package/out/renderer/assets/{chunk-XZIHB7SX-v3MFY8Qn.js → chunk-XZIHB7SX-a-OtMrnF.js} +1 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-BjlJ_E71.js +1 -0
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-BjlJ_E71.js +1 -0
- package/out/renderer/assets/clone-BuzQaJVT.js +1 -0
- package/out/renderer/assets/{console-mirror-BfM9Le8Y.js → console-mirror-wrjuOlK5.js} +1 -1
- package/out/renderer/assets/{consoleCapture-mqMk3W7y.js → consoleCapture-CGsX86Ez.js} +1 -1
- package/out/renderer/assets/{conversation-input-sync-BD8ZrQRq.js → conversation-input-sync-qFePp_gf.js} +276 -276
- package/out/renderer/assets/{dagre-OKDRZEBW-D1-V7-Tj.js → dagre-OKDRZEBW-ujAbOxN1.js} +1 -1
- package/out/renderer/assets/{diagram-SSKATNLV-D7jQdHV1.js → diagram-SSKATNLV-BGt8bOqa.js} +1 -1
- package/out/renderer/assets/{diagram-VNBRO52H-DB_YZ9C8.js → diagram-VNBRO52H-DGmIp--B.js} +1 -1
- package/out/renderer/assets/{erDiagram-Q7BY3M3F-Blv-3W3v.js → erDiagram-Q7BY3M3F-Czgf2xtG.js} +1 -1
- package/out/renderer/assets/{error-boundary-Bpk2r3Ma.js → error-boundary-CIO9VaTx.js} +2 -2
- package/out/renderer/assets/{flowDiagram-4HSFHLVR-BTShSZPF.js → flowDiagram-4HSFHLVR-BSuzI5ul.js} +1 -1
- package/out/renderer/assets/{ganttDiagram-APWFNJXF-_SXfULy-.js → ganttDiagram-APWFNJXF-DjjvFPP9.js} +1 -1
- package/out/renderer/assets/{gitGraphDiagram-7IBYFJ6S-9E7LTj7S.js → gitGraphDiagram-7IBYFJ6S-qgMylPGx.js} +1 -1
- package/out/renderer/assets/{graph-BhaFec28.js → graph-C_PIARec.js} +1 -1
- package/out/renderer/assets/{hash-CrDnkZ9w.js → hash-BTR-wmLC.js} +1 -1
- package/out/renderer/assets/index-B5ZsvNme.js +7 -0
- package/out/renderer/assets/index-B9Z9fABA.js +1 -0
- package/out/renderer/assets/index-BSn66J9q.js +57 -0
- package/out/renderer/assets/index-BzHpKJoz.css +1 -0
- package/out/renderer/assets/index-U5qrTe4P.js +824 -0
- package/out/renderer/assets/{infoDiagram-PH2N3AL5-CCsEuNFb.js → infoDiagram-PH2N3AL5-CXhZsMAw.js} +1 -1
- package/out/renderer/assets/{installer-CJRb2tgb.js → installer-DsBvKWJk.js} +1 -1
- package/out/renderer/assets/{journeyDiagram-U35MCT3I-LXUs-hfi.js → journeyDiagram-U35MCT3I-BfRBfFPi.js} +1 -1
- package/out/renderer/assets/{kanban-definition-NDS4AKOZ-GLYV-Ku1.js → kanban-definition-NDS4AKOZ-BjBPm0Wp.js} +1 -1
- package/out/renderer/assets/{layout-erSNWSH-.js → layout-CxH8v5Lh.js} +1 -1
- package/out/renderer/assets/{legacy-agents-page-CtFhdgCi.js → legacy-agents-page-CiirOdbB.js} +7 -7
- package/out/renderer/assets/{library-page-C6-aUarQ.js → library-page-CH3E7s4_.js} +3 -3
- package/out/renderer/assets/{mermaid.core-BGROKqtx.js → mermaid.core-Bx5BMQp8.js} +5 -5
- package/out/renderer/assets/mesh-page-DXuH0pWs.js +1 -0
- package/out/renderer/assets/{mindmap-definition-ALO5MXBD-C1KlK3C5.js → mindmap-definition-ALO5MXBD-Cnp-gOUf.js} +1 -1
- package/out/renderer/assets/{mini-Dnf6EgXd.js → mini-Cxcx9-Gz.js} +1 -1
- package/out/renderer/assets/{notebook-pen-CTurnI5u.js → notebook-pen-pmBcBtK5.js} +1 -1
- package/out/renderer/assets/{org-access-DTXfQgW5.js → org-access-BBS-iiGY.js} +1 -1
- package/out/renderer/assets/{org-surface-gate-CDaexKo1.js → org-surface-gate-B9JbfoNw.js} +1 -1
- package/out/renderer/assets/{page-header-Does21Km.js → page-header-D3rux4P9.js} +1 -1
- package/out/renderer/assets/{pieDiagram-IB7DONF6-DaaMC8-4.js → pieDiagram-IB7DONF6-BXGlHMJD.js} +1 -1
- package/out/renderer/assets/{projects-page-Bw0c4vc_.js → projects-page-DjaYWghP.js} +17 -17
- package/out/renderer/assets/publication-validation-Dent7Wyb.js +1 -0
- package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-BVFqf3uw.js → quadrantDiagram-7GDLP6J5-DTE1LofJ.js} +1 -1
- package/out/renderer/assets/{radar-MK3ICKWK-BbBjm1y3.js → radar-MK3ICKWK-C5aiTbpi.js} +1 -1
- package/out/renderer/assets/{radient-auth-buttons-BeDvFHK7.js → radient-auth-buttons-CD4FRlt9.js} +1 -1
- package/out/renderer/assets/{requirementDiagram-KVF5MWMF-luASPwgm.js → requirementDiagram-KVF5MWMF-B-kbiFxO.js} +1 -1
- package/out/renderer/assets/{sankeyDiagram-QLVOVGJD-DJ-Xk1mH.js → sankeyDiagram-QLVOVGJD-8mSg8Gx1.js} +1 -1
- package/out/renderer/assets/{schedules-page-D7XfeTME.js → schedules-page-M0NGG3zh.js} +1 -1
- package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-C9vBEHGW.js → sequenceDiagram-X6HHIX6F-Ctz7PqiC.js} +1 -1
- package/out/renderer/assets/settings-page-Cy2SAtSh.js +287 -0
- package/out/renderer/assets/{smartart-DCxfy3Tv.js → smartart-DmOeXeJs.js} +1 -1
- package/out/renderer/assets/{stateDiagram-DGXRK772-DCbA594R.js → stateDiagram-DGXRK772-x8oSqtIw.js} +1 -1
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-CUVgaWvm.js +1 -0
- package/out/renderer/assets/{tags-input-chips-BSg2kzIn.js → tags-input-chips-BAP2XNbQ.js} +1 -1
- package/out/renderer/assets/team-bridge-page-CYehSZqj.js +11 -0
- package/out/renderer/assets/{timeline-definition-BDJGKUSR-AlhVX480.js → timeline-definition-BDJGKUSR-DZ5836tF.js} +1 -1
- package/out/renderer/assets/ui-preferences-store-oc99NgQT.js +1 -0
- package/out/renderer/assets/{use-download-agent-mutation-DmirSifx.js → use-download-agent-mutation-Bgwi0JGB.js} +4 -4
- package/out/renderer/assets/{use-session-snapshot-DQQ3D8W6.js → use-session-snapshot-DQs7iPEs.js} +1 -1
- package/out/renderer/assets/{xychartDiagram-VJFVF3MP-djayCUFZ.js → xychartDiagram-VJFVF3MP-CQNe5VvP.js} +1 -1
- package/out/renderer/console-capture.html +5 -5
- package/out/renderer/index.html +7 -7
- package/out/renderer/installer.html +4 -4
- package/out/renderer/mini.html +7 -7
- package/package.json +3 -3
- package/out/renderer/assets/browser-page-CvUjgYjV.js +0 -1
- package/out/renderer/assets/channel-Ca9itbEI.js +0 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-BDSTmyjZ.js +0 -1
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-BDSTmyjZ.js +0 -1
- package/out/renderer/assets/clone-OIhREtCX.js +0 -1
- package/out/renderer/assets/index-BgwxrPpP.css +0 -1
- package/out/renderer/assets/index-BuM037wD.js +0 -824
- package/out/renderer/assets/index-ByYW6G08.js +0 -57
- package/out/renderer/assets/index-ClCIwVJj.js +0 -7
- package/out/renderer/assets/index-Shz25Z8Y.js +0 -1
- package/out/renderer/assets/mesh-page-CzSDWDfu.js +0 -1
- package/out/renderer/assets/publication-validation-MxGQJEQj.js +0 -1
- package/out/renderer/assets/settings-page-BubJ0gmV.js +0 -287
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-P9yjg6o0.js +0 -1
- package/out/renderer/assets/team-bridge-page-DshgiIxJ.js +0 -1
- package/out/renderer/assets/ui-preferences-store-CAt3Nng3.js +0 -1
- package/out/renderer/assets/use-memberships-query-fzcoT-92.js +0 -1
package/out/main/index.js
CHANGED
|
@@ -2384,6 +2384,28 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
2384
2384
|
conversation_id: id$1,
|
|
2385
2385
|
action: zod.z.enum(["archive", "unarchive", "join", "leave"])
|
|
2386
2386
|
}).strict(),
|
|
2387
|
+
/*
|
|
2388
|
+
* Self-join and the notification preference are their own ops rather than
|
|
2389
|
+
* `lifecycle` actions: the tenant is part of the request (a merge-view row
|
|
2390
|
+
* can name a channel the caller has not joined, and the default tenant
|
|
2391
|
+
* would be the wrong organization), and `notify` is a value, not an
|
|
2392
|
+
* action. The join route is the conversation domain's existing
|
|
2393
|
+
* `POST .../join`; the tenant travels in its body for the same reason the
|
|
2394
|
+
* create/send/read bodies carry one. The notify op rides the READ route's
|
|
2395
|
+
* `notify` field (agent-server #148's shape): it sends no `seq`, so the
|
|
2396
|
+
* cursor cannot move as a side effect of choosing a notification level.
|
|
2397
|
+
*/
|
|
2398
|
+
zod.z.object({
|
|
2399
|
+
op: zod.z.literal("team_bridge.conversations.join"),
|
|
2400
|
+
conversation_id: id$1,
|
|
2401
|
+
tenant_id: id$1.optional()
|
|
2402
|
+
}).strict(),
|
|
2403
|
+
zod.z.object({
|
|
2404
|
+
op: zod.z.literal("team_bridge.conversations.notify"),
|
|
2405
|
+
conversation_id: id$1,
|
|
2406
|
+
tenant_id: id$1.optional(),
|
|
2407
|
+
notify: zod.z.enum(["all", "mention", "mute"])
|
|
2408
|
+
}).strict(),
|
|
2387
2409
|
zod.z.object({
|
|
2388
2410
|
op: zod.z.literal("team_bridge.conversations.members.add"),
|
|
2389
2411
|
conversation_id: id$1,
|
|
@@ -4861,6 +4883,23 @@ function desktopEndpoint(request) {
|
|
|
4861
4883
|
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/${request.action}`,
|
|
4862
4884
|
method: "POST"
|
|
4863
4885
|
};
|
|
4886
|
+
case "team_bridge.conversations.join":
|
|
4887
|
+
return {
|
|
4888
|
+
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/join`,
|
|
4889
|
+
method: "POST",
|
|
4890
|
+
...request.tenant_id ? { body: { tenant_id: request.tenant_id } } : {}
|
|
4891
|
+
};
|
|
4892
|
+
case "team_bridge.conversations.notify":
|
|
4893
|
+
return {
|
|
4894
|
+
/* The read route's notify field (agent-server #148); no `seq`, so
|
|
4895
|
+
this write cannot advance the cursor. */
|
|
4896
|
+
path: `/v1/desktop/team-bridge/conversations/${encodeURIComponent(request.conversation_id)}/read`,
|
|
4897
|
+
method: "POST",
|
|
4898
|
+
body: {
|
|
4899
|
+
...request.tenant_id ? { tenant_id: request.tenant_id } : {},
|
|
4900
|
+
notify: request.notify
|
|
4901
|
+
}
|
|
4902
|
+
};
|
|
4864
4903
|
case "team_bridge.conversations.members.add": {
|
|
4865
4904
|
const query = new URLSearchParams();
|
|
4866
4905
|
if (request.tenant_id) query.set("tenant_id", request.tenant_id);
|
|
@@ -9070,7 +9109,7 @@ const DESKTOP_STREAM_DETAIL = {
|
|
|
9070
9109
|
refusedWithoutStatus: "The event stream was refused."
|
|
9071
9110
|
};
|
|
9072
9111
|
const SESSION_ID$1 = /^[a-f0-9]{12}$/;
|
|
9073
|
-
const SAFE_ID = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
9112
|
+
const SAFE_ID$1 = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
9074
9113
|
function transportFailureDetail(error) {
|
|
9075
9114
|
if (error instanceof Error && error.name === "AbortError") {
|
|
9076
9115
|
return DESKTOP_STREAM_DETAIL.ended;
|
|
@@ -9117,7 +9156,7 @@ class DesktopStreamRelay {
|
|
|
9117
9156
|
if (!SESSION_ID$1.test(args.sessionId)) {
|
|
9118
9157
|
throw new Error("Invalid session for streaming.");
|
|
9119
9158
|
}
|
|
9120
|
-
if (args.epoch !== void 0 && !SAFE_ID.test(args.epoch)) {
|
|
9159
|
+
if (args.epoch !== void 0 && !SAFE_ID$1.test(args.epoch)) {
|
|
9121
9160
|
throw new Error("Invalid stream epoch.");
|
|
9122
9161
|
}
|
|
9123
9162
|
if (args.afterSeq !== void 0 && (!Number.isInteger(args.afterSeq) || args.afterSeq < 0)) {
|
|
@@ -29452,15 +29491,31 @@ class ApprovalStore {
|
|
|
29452
29491
|
);
|
|
29453
29492
|
}
|
|
29454
29493
|
}
|
|
29494
|
+
function browserWindowForeground(window) {
|
|
29495
|
+
return !window.isDestroyed() && window.isVisible() && window.isFocused();
|
|
29496
|
+
}
|
|
29455
29497
|
function browserChromeOwnsChord(facts) {
|
|
29456
|
-
return facts.logicalFocus && facts.chromeVisible &&
|
|
29498
|
+
return facts.logicalFocus && facts.chromeVisible && browserWindowForeground(facts.window);
|
|
29499
|
+
}
|
|
29500
|
+
function browserPageOwnsChord(facts) {
|
|
29501
|
+
const active = facts.activeTab;
|
|
29502
|
+
return Boolean(
|
|
29503
|
+
active?.presented && browserWindowForeground(facts.window) && (facts.focusedContents() === active.webContentsId || facts.focusedViewTabId === active.tabId)
|
|
29504
|
+
);
|
|
29457
29505
|
}
|
|
29458
29506
|
function runBrowserMenuAction(intent, target2, owner, route) {
|
|
29507
|
+
if (target2 && target2 !== owner) {
|
|
29508
|
+
if (intent === "reload") target2.webContents?.reload();
|
|
29509
|
+
else if (intent === "hard-reload")
|
|
29510
|
+
target2.webContents?.reloadIgnoringCache();
|
|
29511
|
+
else if (intent === "close-tab") target2.close();
|
|
29512
|
+
return;
|
|
29513
|
+
}
|
|
29514
|
+
if (route(intent)) return;
|
|
29459
29515
|
if (!target2) return;
|
|
29460
|
-
if (target2 === owner && route(intent)) return;
|
|
29461
29516
|
if (intent === "reload") target2.webContents?.reload();
|
|
29462
29517
|
else if (intent === "hard-reload") target2.webContents?.reloadIgnoringCache();
|
|
29463
|
-
else target2.close();
|
|
29518
|
+
else if (intent === "close-tab") target2.close();
|
|
29464
29519
|
}
|
|
29465
29520
|
function createBrowserChordRouter(options) {
|
|
29466
29521
|
function dispatch(intent, origin) {
|
|
@@ -33524,7 +33579,26 @@ const enUiChatTags = {
|
|
|
33524
33579
|
"ui.chat.tags.move_undone": "Tag move undone",
|
|
33525
33580
|
"ui.chat.tags.move_title": "Move “{title}”",
|
|
33526
33581
|
"ui.chat.tags.move_description": "Choose a tag to make it primary, or Untagged to remove all tags.",
|
|
33527
|
-
"ui.chat.tags.move_failed": "Tags were not moved. Try again."
|
|
33582
|
+
"ui.chat.tags.move_failed": "Tags were not moved. Try again.",
|
|
33583
|
+
"ui.chat.tags.selection_count": "{count} of 8",
|
|
33584
|
+
"ui.chat.tags.registry_count": "{count} of 32",
|
|
33585
|
+
"ui.chat.tags.create_name": "Create “{name}”",
|
|
33586
|
+
"ui.chat.tags.create_helper": "Saved for all conversations",
|
|
33587
|
+
"ui.chat.tags.selection_limit": "Choose up to 8 tags",
|
|
33588
|
+
"ui.chat.tags.registry_limit": "You can have up to 32 tags",
|
|
33589
|
+
"ui.chat.tags.name_long": "Use 1–24 characters",
|
|
33590
|
+
"ui.chat.tags.name_reserved": "“Untagged” is reserved",
|
|
33591
|
+
"ui.chat.tags.create_failed": "Tag was not created. Try again.",
|
|
33592
|
+
"ui.chat.tags.remove_named": "Remove {name}",
|
|
33593
|
+
"ui.chat.tags.reorder_filtered": "Clear search to reorder tags",
|
|
33594
|
+
"ui.chat.tags.created_name": "Created “{name}”",
|
|
33595
|
+
"ui.chat.tags.selection_status": "{count} selected. Group under {name}.",
|
|
33596
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# conversation} other {# conversations}}",
|
|
33597
|
+
"ui.chat.tags.create_pending": "Saving tag…",
|
|
33598
|
+
"ui.chat.tags.remote": "Tags cannot be changed on a remote conversation.",
|
|
33599
|
+
"ui.chat.tags.renamed_name": "Renamed to “{name}”",
|
|
33600
|
+
"ui.chat.tags.staged_added": "Added “{name}” to draft",
|
|
33601
|
+
"ui.chat.tags.registry_changed": "Some tags changed elsewhere. Review your selection."
|
|
33528
33602
|
};
|
|
33529
33603
|
const enUiChatTranscriptCopy = {
|
|
33530
33604
|
"ui.chat.transcript_copy.menu.copy_text": "Copy text",
|
|
@@ -33534,7 +33608,8 @@ const enUiChatTranscriptCopy = {
|
|
|
33534
33608
|
"ui.chat.transcript_copy.toast.copied_selection": "Copied selection",
|
|
33535
33609
|
"ui.chat.transcript_copy.row.your_message": "Your message",
|
|
33536
33610
|
"ui.chat.transcript_copy.row.agent_message": "Agent message",
|
|
33537
|
-
"ui.chat.transcript_copy.selection.copy": "Copy selection"
|
|
33611
|
+
"ui.chat.transcript_copy.selection.copy": "Copy selection",
|
|
33612
|
+
"ui.chat.transcript_copy.selection.toolbar": "Selection actions"
|
|
33538
33613
|
};
|
|
33539
33614
|
const enUiCodeReview = {
|
|
33540
33615
|
"ui.code_review.activity.close": "closed",
|
|
@@ -34514,6 +34589,8 @@ const enUiMesh = {
|
|
|
34514
34589
|
"ui.mesh.mesh_drop.turn_in_flight": "{conversation} has a turn in flight, so it is not moved — the refusal changes nothing.",
|
|
34515
34590
|
"ui.mesh.mesh_drop.that_device_is_no_longer_in_any": "That device is no longer in any network this tab can read.",
|
|
34516
34591
|
"ui.mesh.mesh_drop.owner_no_answer": "{device} is not answering{reason}, so it could not hand this conversation over.",
|
|
34592
|
+
"ui.mesh.mesh_drop.reach_refusal": "{device}: {reach}{reason}, so nothing was moved.",
|
|
34593
|
+
"ui.mesh.mesh_drop.owner_reach_refusal": "{device}: {reach}{reason}, so it could not hand this conversation over.",
|
|
34517
34594
|
"ui.mesh.mesh_drop.recall_first": "This conversation is on {owner}. It has to travel through this device: recall it here first.",
|
|
34518
34595
|
"ui.mesh.mesh_drop.on_owner": "on {owner}",
|
|
34519
34596
|
"ui.mesh.mesh_drop.this_device": "this device",
|
|
@@ -34528,8 +34605,10 @@ const enUiMesh = {
|
|
|
34528
34605
|
"ui.mesh.mesh_graph.no_sessions_reported": "no sessions reported",
|
|
34529
34606
|
"ui.mesh.mesh_graph.network_count": "{count, plural, one {{count, number, ::group-off} network} other {{count, number, ::group-off} networks}}",
|
|
34530
34607
|
"ui.mesh.mesh_graph.device_count": "{count, plural, one {{count, number, ::group-off} device} other {{count, number, ::group-off} devices}}",
|
|
34608
|
+
"ui.mesh.mesh_graph.handshake_refused_count": "{count, plural, other {{count, number, ::group-off} handshake refused}}",
|
|
34531
34609
|
"ui.mesh.mesh_graph.suspected_count": "{count, plural, other {{count, number, ::group-off} of them suspected}}",
|
|
34532
34610
|
"ui.mesh.mesh_graph.reached_count": "{count, plural, other {{count, number, ::group-off} reached}}",
|
|
34611
|
+
"ui.mesh.mesh_graph.relay_down_count": "{count, plural, other {{count, number, ::group-off} relay down}}",
|
|
34533
34612
|
"ui.mesh.mesh_graph.no_answer_count": "{count, plural, other {{count, number, ::group-off} no answer}}",
|
|
34534
34613
|
"ui.mesh.mesh_graph.not_asked_count": "{count, plural, other {{count, number, ::group-off} not asked}}",
|
|
34535
34614
|
"ui.mesh.mesh_graph.unknown_count": "{count, plural, other {{count, number, ::group-off} unknown}}",
|
|
@@ -34569,6 +34648,20 @@ const enUiMesh = {
|
|
|
34569
34648
|
"ui.mesh.mesh_page.bring_copy_back": "Bring the copy back from {device}",
|
|
34570
34649
|
"ui.mesh.mesh_page.the_move_could_not_be_sent_nothing": "The move could not be sent. Nothing here changed; the list has been read again.",
|
|
34571
34650
|
"ui.mesh.mesh_reach.reached": "reached",
|
|
34651
|
+
"ui.mesh.mesh_reach.relay_not_running": "relay not running",
|
|
34652
|
+
"ui.mesh.mesh_reach.handshake_refused": "handshake refused",
|
|
34653
|
+
"ui.mesh.mesh_reach.address_unreachable": "address unreachable",
|
|
34654
|
+
"ui.mesh.mesh_reach.no_endpoint": "no address to dial",
|
|
34655
|
+
"ui.mesh.mesh_reach.not_a_member": "not a member",
|
|
34656
|
+
"ui.mesh.mesh_reach.attempt_bad_address": "bad address",
|
|
34657
|
+
"ui.mesh.mesh_reach.attempt_could_not_connect": "could not connect",
|
|
34658
|
+
"ui.mesh.mesh_reach.addresses_tried": "addresses tried",
|
|
34659
|
+
"ui.mesh.mesh_reach.attempt_answered": "answered",
|
|
34660
|
+
"ui.mesh.mesh_reach.attempt_nothing_listening": "nothing listening",
|
|
34661
|
+
"ui.mesh.mesh_reach.attempt_no_answer": "no answer",
|
|
34662
|
+
"ui.mesh.mesh_reach.attempt_not_tried": "not tried",
|
|
34663
|
+
"ui.mesh.mesh_reach.peer_relay_not_running": "the peer's relay is not running",
|
|
34664
|
+
"ui.mesh.mesh_reach.peer_closed_handshake": "the peer answered but closed the handshake",
|
|
34572
34665
|
"ui.mesh.mesh_reach.no_answer": "no answer",
|
|
34573
34666
|
"ui.mesh.mesh_reach.not_asked": "not asked",
|
|
34574
34667
|
"ui.mesh.mesh_reach.unknown": "unknown",
|
|
@@ -34583,6 +34676,9 @@ const enUiMesh = {
|
|
|
34583
34676
|
"ui.mesh.mesh_actions.the_device": "the device",
|
|
34584
34677
|
"ui.mesh.mesh_approvals.decision_could_not_be_answered": "The decision could not be answered.",
|
|
34585
34678
|
"ui.mesh.mesh_node.memberships": "· {count, plural, one {{count, number, ::group-off} networks} other {{count, number, ::group-off} networks}}",
|
|
34679
|
+
"ui.mesh.mesh_graph.address_unreachable_count": "{count, plural, other {{count, number, ::group-off} address unreachable}}",
|
|
34680
|
+
"ui.mesh.mesh_graph.no_endpoint_count": "{count, plural, other {{count, number, ::group-off} no address to dial}}",
|
|
34681
|
+
"ui.mesh.mesh_graph.not_a_member_count": "{count, plural, other {{count, number, ::group-off} not a member}}",
|
|
34586
34682
|
"ui.mesh.mesh_graph.conversation_unit": "{count, plural, one {conversation} other {conversations}}",
|
|
34587
34683
|
"ui.mesh.mesh_approvals_tray.failed_count": "{count, plural, other {{count, number, ::group-off} failed}}",
|
|
34588
34684
|
"ui.mesh.mesh_list.sort_conversations": "Conversations",
|
|
@@ -34594,7 +34690,8 @@ const enUiMesh = {
|
|
|
34594
34690
|
"ui.mesh.approval.approved_pending_apply": "Approved; waiting to apply",
|
|
34595
34691
|
"ui.mesh.approval.approved_apply_hint": "Approval is recorded. Open Details for the server-provided apply step.",
|
|
34596
34692
|
"ui.mesh.approval.approved_details_missing": "Approval is recorded. The apply step is unavailable in this app.",
|
|
34597
|
-
"ui.mesh.approval.request_window": "Request window: {remaining}"
|
|
34693
|
+
"ui.mesh.approval.request_window": "Request window: {remaining}",
|
|
34694
|
+
"ui.mesh.mesh_reach.handshake_refused_hint": "Check that this device is still a member of the network and that the epoch matches; a removed device or a changed epoch refuses the handshake."
|
|
34598
34695
|
};
|
|
34599
34696
|
const enUiOnboarding = {
|
|
34600
34697
|
"ui.onboarding.connect.intro": "Local Operator needs an AI account to work. Radient is the easiest: one browser sign-in and nothing to paste. Already pay for ChatGPT or Claude? Sign in with that instead. Anything else is under More providers.",
|
|
@@ -36190,7 +36287,23 @@ const enUiTeamBridge = {
|
|
|
36190
36287
|
"ui.teamBridge.scope.unknown": "Unknown organization",
|
|
36191
36288
|
"ui.teamBridge.scope.thread_unknown": "This conversation's organization is not available.",
|
|
36192
36289
|
"ui.teamBridge.scope.create_needs_org": "Choose an organization to start a conversation.",
|
|
36193
|
-
"ui.teamBridge.group.more_unread": "{count, plural, one {More destinations, # unread message} other {More destinations, # unread messages}}"
|
|
36290
|
+
"ui.teamBridge.group.more_unread": "{count, plural, one {More destinations, # unread message} other {More destinations, # unread messages}}",
|
|
36291
|
+
"ui.teamBridge.preview.chip": "Preview",
|
|
36292
|
+
"ui.teamBridge.preview.banner": "You’re previewing this channel. Join to see its history and get notifications.",
|
|
36293
|
+
"ui.teamBridge.preview.join": "Join",
|
|
36294
|
+
"ui.teamBridge.preview.join_error": "You could not join this channel. Try again.",
|
|
36295
|
+
"ui.teamBridge.menu.label": "Conversation options",
|
|
36296
|
+
"ui.teamBridge.menu.mute": "Mute conversation",
|
|
36297
|
+
"ui.teamBridge.menu.unmute": "Unmute conversation",
|
|
36298
|
+
"ui.teamBridge.notify.label": "Notification preferences",
|
|
36299
|
+
"ui.teamBridge.notify.all": "All messages",
|
|
36300
|
+
"ui.teamBridge.notify.mention": "Mentions",
|
|
36301
|
+
"ui.teamBridge.notify.mute": "Mute",
|
|
36302
|
+
"ui.teamBridge.notify.muted": "Muted",
|
|
36303
|
+
"ui.teamBridge.notify.error": "Your notification preference was not saved. Try again.",
|
|
36304
|
+
"ui.teamBridge.notify.title": "{conversation} ({organization})",
|
|
36305
|
+
"ui.teamBridge.notify.body": "{sender} sent a message",
|
|
36306
|
+
"ui.teamBridge.notify.body_fallback": "New message"
|
|
36194
36307
|
};
|
|
36195
36308
|
const esUiAgentMessages = {
|
|
36196
36309
|
"ui.agentMessages.dialog.title": "Mensajes de agentes en Radient",
|
|
@@ -36870,7 +36983,26 @@ const esUiChatTags = {
|
|
|
36870
36983
|
"ui.chat.tags.move_undone": "Movimiento de etiquetas deshecho",
|
|
36871
36984
|
"ui.chat.tags.move_title": "Mover «{title}»",
|
|
36872
36985
|
"ui.chat.tags.move_description": "Elige una etiqueta para hacerla principal, o Sin etiqueta para eliminar todas las etiquetas.",
|
|
36873
|
-
"ui.chat.tags.move_failed": "No se han movido las etiquetas. Inténtalo de nuevo."
|
|
36986
|
+
"ui.chat.tags.move_failed": "No se han movido las etiquetas. Inténtalo de nuevo.",
|
|
36987
|
+
"ui.chat.tags.selection_count": "{count} de 8",
|
|
36988
|
+
"ui.chat.tags.registry_count": "{count} de 32",
|
|
36989
|
+
"ui.chat.tags.create_name": "Crear «{name}»",
|
|
36990
|
+
"ui.chat.tags.create_helper": "Se guarda para todas las conversaciones",
|
|
36991
|
+
"ui.chat.tags.selection_limit": "Elige hasta 8 etiquetas",
|
|
36992
|
+
"ui.chat.tags.registry_limit": "Puedes tener hasta 32 etiquetas",
|
|
36993
|
+
"ui.chat.tags.name_long": "Usa entre 1 y 24 caracteres",
|
|
36994
|
+
"ui.chat.tags.name_reserved": "«Untagged» es un nombre reservado",
|
|
36995
|
+
"ui.chat.tags.create_failed": "No se ha creado la etiqueta. Inténtalo de nuevo.",
|
|
36996
|
+
"ui.chat.tags.remove_named": "Quitar {name}",
|
|
36997
|
+
"ui.chat.tags.reorder_filtered": "Borra la búsqueda para reordenar las etiquetas",
|
|
36998
|
+
"ui.chat.tags.created_name": "Se ha creado «{name}»",
|
|
36999
|
+
"ui.chat.tags.selection_status": "Selección: {count}. Agrupar en {name}.",
|
|
37000
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# conversación} many {# de conversaciones} other {# conversaciones}}",
|
|
37001
|
+
"ui.chat.tags.create_pending": "Guardando etiqueta…",
|
|
37002
|
+
"ui.chat.tags.remote": "No se pueden cambiar las etiquetas de una conversación remota.",
|
|
37003
|
+
"ui.chat.tags.renamed_name": "Se ha cambiado el nombre a «{name}»",
|
|
37004
|
+
"ui.chat.tags.staged_added": "Se ha añadido «{name}» al borrador",
|
|
37005
|
+
"ui.chat.tags.registry_changed": "Algunas etiquetas han cambiado en otro lugar. Revisa la selección."
|
|
36874
37006
|
};
|
|
36875
37007
|
const esUiCodeReview = {
|
|
36876
37008
|
"ui.code_review.activity.close": "cerraste",
|
|
@@ -37696,6 +37828,8 @@ const esUiMesh = {
|
|
|
37696
37828
|
"ui.mesh.mesh_drop.turn_in_flight": "{conversation} tiene un turno en curso, así que no se mueve: el rechazo no cambia nada.",
|
|
37697
37829
|
"ui.mesh.mesh_drop.that_device_is_no_longer_in_any": "Ese dispositivo ya no está en ninguna red que esta pestaña pueda leer.",
|
|
37698
37830
|
"ui.mesh.mesh_drop.owner_no_answer": "{device} no responde{reason}, así que no pudo entregar esta conversación.",
|
|
37831
|
+
"ui.mesh.mesh_drop.reach_refusal": "{device}: {reach}{reason}, así que no se movió nada.",
|
|
37832
|
+
"ui.mesh.mesh_drop.owner_reach_refusal": "{device}: {reach}{reason}, así que no pudo entregar esta conversación.",
|
|
37699
37833
|
"ui.mesh.mesh_drop.recall_first": "Esta conversación está en {owner}. Tiene que pasar por este dispositivo: tráela aquí primero.",
|
|
37700
37834
|
"ui.mesh.mesh_drop.on_owner": "en {owner}",
|
|
37701
37835
|
"ui.mesh.mesh_drop.this_device": "este dispositivo",
|
|
@@ -37710,8 +37844,10 @@ const esUiMesh = {
|
|
|
37710
37844
|
"ui.mesh.mesh_graph.no_sessions_reported": "sin sesiones informadas",
|
|
37711
37845
|
"ui.mesh.mesh_graph.network_count": "{count, plural, one {{count, number, ::group-off} red} many {{count, number, ::group-off} de redes} other {{count, number, ::group-off} redes}}",
|
|
37712
37846
|
"ui.mesh.mesh_graph.device_count": "{count, plural, one {{count, number, ::group-off} dispositivo} many {{count, number, ::group-off} de dispositivos} other {{count, number, ::group-off} dispositivos}}",
|
|
37847
|
+
"ui.mesh.mesh_graph.handshake_refused_count": "{count, plural, one {{count, number, ::group-off} handshake rechazado} many {{count, number, ::group-off} de handshakes rechazados} other {{count, number, ::group-off} handshakes rechazados}}",
|
|
37713
37848
|
"ui.mesh.mesh_graph.suspected_count": "{count, plural, other {{count, number, ::group-off} de ellos sospechosos}}",
|
|
37714
37849
|
"ui.mesh.mesh_graph.reached_count": "{count, plural, other {{count, number, ::group-off} alcanzados}}",
|
|
37850
|
+
"ui.mesh.mesh_graph.relay_down_count": "{count, plural, one {{count, number, ::group-off} relé caído} many {{count, number, ::group-off} de relés caídos} other {{count, number, ::group-off} relés caídos}}",
|
|
37715
37851
|
"ui.mesh.mesh_graph.no_answer_count": "{count, plural, other {{count, number, ::group-off} sin respuesta}}",
|
|
37716
37852
|
"ui.mesh.mesh_graph.not_asked_count": "{count, plural, other {{count, number, ::group-off} sin preguntar}}",
|
|
37717
37853
|
"ui.mesh.mesh_graph.unknown_count": "{count, plural, other {{count, number, ::group-off} desconocidos}}",
|
|
@@ -37751,6 +37887,20 @@ const esUiMesh = {
|
|
|
37751
37887
|
"ui.mesh.mesh_page.bring_copy_back": "Traer la copia de vuelta desde {device}",
|
|
37752
37888
|
"ui.mesh.mesh_page.the_move_could_not_be_sent_nothing": "No se pudo enviar el movimiento. Aquí no cambió nada; la lista se ha vuelto a leer.",
|
|
37753
37889
|
"ui.mesh.mesh_reach.reached": "alcanzado",
|
|
37890
|
+
"ui.mesh.mesh_reach.relay_not_running": "relé caído",
|
|
37891
|
+
"ui.mesh.mesh_reach.handshake_refused": "handshake rechazado",
|
|
37892
|
+
"ui.mesh.mesh_reach.address_unreachable": "dirección inaccesible",
|
|
37893
|
+
"ui.mesh.mesh_reach.no_endpoint": "sin dirección de conexión",
|
|
37894
|
+
"ui.mesh.mesh_reach.not_a_member": "no es miembro",
|
|
37895
|
+
"ui.mesh.mesh_reach.attempt_bad_address": "dirección inválida",
|
|
37896
|
+
"ui.mesh.mesh_reach.attempt_could_not_connect": "no se pudo conectar",
|
|
37897
|
+
"ui.mesh.mesh_reach.addresses_tried": "Direcciones probadas",
|
|
37898
|
+
"ui.mesh.mesh_reach.attempt_answered": "respondió",
|
|
37899
|
+
"ui.mesh.mesh_reach.attempt_nothing_listening": "ningún servicio escucha",
|
|
37900
|
+
"ui.mesh.mesh_reach.attempt_no_answer": "sin respuesta",
|
|
37901
|
+
"ui.mesh.mesh_reach.attempt_not_tried": "sin intentar",
|
|
37902
|
+
"ui.mesh.mesh_reach.peer_relay_not_running": "el relé del par no está en ejecución",
|
|
37903
|
+
"ui.mesh.mesh_reach.peer_closed_handshake": "el par respondió, pero cerró el handshake",
|
|
37754
37904
|
"ui.mesh.mesh_reach.no_answer": "sin respuesta",
|
|
37755
37905
|
"ui.mesh.mesh_reach.not_asked": "sin preguntar",
|
|
37756
37906
|
"ui.mesh.mesh_reach.unknown": "desconocido",
|
|
@@ -37765,6 +37915,9 @@ const esUiMesh = {
|
|
|
37765
37915
|
"ui.mesh.mesh_actions.the_device": "el dispositivo",
|
|
37766
37916
|
"ui.mesh.mesh_approvals.decision_could_not_be_answered": "No se pudo responder a la decisión.",
|
|
37767
37917
|
"ui.mesh.mesh_node.memberships": "· {count, plural, one {{count, number, ::group-off} red} many {{count, number, ::group-off} de redes} other {{count, number, ::group-off} redes}}",
|
|
37918
|
+
"ui.mesh.mesh_graph.address_unreachable_count": "{count, plural, other {{count, number, ::group-off} con dirección inaccesible}}",
|
|
37919
|
+
"ui.mesh.mesh_graph.no_endpoint_count": "{count, plural, other {{count, number, ::group-off} sin dirección de conexión}}",
|
|
37920
|
+
"ui.mesh.mesh_graph.not_a_member_count": "{count, plural, other {{count, number, ::group-off} sin membresía}}",
|
|
37768
37921
|
"ui.mesh.mesh_graph.conversation_unit": "{count, plural, one {conversación} other {conversaciones}}",
|
|
37769
37922
|
"ui.mesh.mesh_approvals_tray.failed_count": "{count, plural, other {{count, number, ::group-off} fallidas}}",
|
|
37770
37923
|
"ui.mesh.mesh_list.sort_conversations": "Conversaciones",
|
|
@@ -37776,7 +37929,8 @@ const esUiMesh = {
|
|
|
37776
37929
|
"ui.mesh.approval.approved_pending_apply": "Aprobado; pendiente de aplicar",
|
|
37777
37930
|
"ui.mesh.approval.approved_apply_hint": "La aprobación está registrada. Abre Detalles para ver el paso de aplicación proporcionado por el servidor.",
|
|
37778
37931
|
"ui.mesh.approval.approved_details_missing": "La aprobación está registrada. El paso de aplicación no está disponible en esta app.",
|
|
37779
|
-
"ui.mesh.approval.request_window": "Ventana de la solicitud: {remaining}"
|
|
37932
|
+
"ui.mesh.approval.request_window": "Ventana de la solicitud: {remaining}",
|
|
37933
|
+
"ui.mesh.mesh_reach.handshake_refused_hint": "Comprueba que este dispositivo siga siendo miembro de la red y que la época coincida; un dispositivo eliminado o una época distinta rechazan el handshake."
|
|
37780
37934
|
};
|
|
37781
37935
|
const esUiOnboarding = {
|
|
37782
37936
|
"ui.onboarding.connect.intro": "Local Operator necesita una cuenta de IA para funcionar. Radient es la opción más sencilla: inicia sesión en el navegador, sin copiar ni pegar nada. ¿Ya pagas por ChatGPT o Claude? Puedes usar esa cuenta. Abre la lista de proveedores de abajo para ver las demás opciones.",
|
|
@@ -39988,7 +40142,26 @@ const frUiChatTags = {
|
|
|
39988
40142
|
"ui.chat.tags.move_undone": "Déplacement des étiquettes annulé",
|
|
39989
40143
|
"ui.chat.tags.move_title": "Déplacer « {title} »",
|
|
39990
40144
|
"ui.chat.tags.move_description": "Choisissez une étiquette principale, ou Sans étiquette pour retirer toutes les étiquettes.",
|
|
39991
|
-
"ui.chat.tags.move_failed": "Les étiquettes n’ont pas été déplacées. Réessayez."
|
|
40145
|
+
"ui.chat.tags.move_failed": "Les étiquettes n’ont pas été déplacées. Réessayez.",
|
|
40146
|
+
"ui.chat.tags.selection_count": "{count} sur 8",
|
|
40147
|
+
"ui.chat.tags.registry_count": "{count} sur 32",
|
|
40148
|
+
"ui.chat.tags.create_name": "Créer « {name} »",
|
|
40149
|
+
"ui.chat.tags.create_helper": "Enregistré pour toutes les conversations",
|
|
40150
|
+
"ui.chat.tags.selection_limit": "Choisissez jusqu’à 8 étiquettes",
|
|
40151
|
+
"ui.chat.tags.registry_limit": "Vous pouvez avoir jusqu’à 32 étiquettes",
|
|
40152
|
+
"ui.chat.tags.name_long": "Utilisez de 1 à 24 caractères",
|
|
40153
|
+
"ui.chat.tags.name_reserved": "« Untagged » est un nom réservé",
|
|
40154
|
+
"ui.chat.tags.create_failed": "L’étiquette n’a pas été créée. Réessayez.",
|
|
40155
|
+
"ui.chat.tags.remove_named": "Retirer {name}",
|
|
40156
|
+
"ui.chat.tags.reorder_filtered": "Effacez la recherche pour réordonner les étiquettes",
|
|
40157
|
+
"ui.chat.tags.created_name": "« {name} » a été créée",
|
|
40158
|
+
"ui.chat.tags.selection_status": "{count} sélectionnées. Regrouper sous {name}.",
|
|
40159
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# conversation} many {# de conversations} other {# conversations}}",
|
|
40160
|
+
"ui.chat.tags.create_pending": "Enregistrement de l’étiquette…",
|
|
40161
|
+
"ui.chat.tags.remote": "Les étiquettes d’une conversation distante ne peuvent pas être modifiées.",
|
|
40162
|
+
"ui.chat.tags.renamed_name": "Renommée « {name} »",
|
|
40163
|
+
"ui.chat.tags.staged_added": "« {name} » a été ajoutée au brouillon",
|
|
40164
|
+
"ui.chat.tags.registry_changed": "Des étiquettes ont été modifiées ailleurs. Vérifiez votre sélection."
|
|
39992
40165
|
};
|
|
39993
40166
|
const frUiCodeReview = {
|
|
39994
40167
|
"ui.code_review.activity.close": "avez fermé",
|
|
@@ -40814,6 +40987,8 @@ const frUiMesh = {
|
|
|
40814
40987
|
"ui.mesh.mesh_drop.turn_in_flight": "{conversation} a un tour en cours, il n’est donc pas déplacé — le refus ne change rien.",
|
|
40815
40988
|
"ui.mesh.mesh_drop.that_device_is_no_longer_in_any": "Cet appareil n’est plus dans aucun réseau que cet onglet peut lire.",
|
|
40816
40989
|
"ui.mesh.mesh_drop.owner_no_answer": "{device} ne répond pas{reason}, il n’a donc pas pu céder cette conversation.",
|
|
40990
|
+
"ui.mesh.mesh_drop.reach_refusal": "{device} : {reach}{reason}, rien n’a donc été déplacé.",
|
|
40991
|
+
"ui.mesh.mesh_drop.owner_reach_refusal": "{device} : {reach}{reason}, il n’a donc pas pu céder cette conversation.",
|
|
40817
40992
|
"ui.mesh.mesh_drop.recall_first": "Cette conversation est sur {owner}. Elle doit passer par cet appareil : rapatriez-la ici d’abord.",
|
|
40818
40993
|
"ui.mesh.mesh_drop.on_owner": "sur {owner}",
|
|
40819
40994
|
"ui.mesh.mesh_drop.this_device": "cet appareil",
|
|
@@ -40828,8 +41003,10 @@ const frUiMesh = {
|
|
|
40828
41003
|
"ui.mesh.mesh_graph.no_sessions_reported": "aucune session signalée",
|
|
40829
41004
|
"ui.mesh.mesh_graph.network_count": "{count, plural, one {{count, number, ::group-off} réseau} many {{count, number, ::group-off} de réseaux} other {{count, number, ::group-off} réseaux}}",
|
|
40830
41005
|
"ui.mesh.mesh_graph.device_count": "{count, plural, one {{count, number, ::group-off} appareil} many {{count, number, ::group-off} d’appareils} other {{count, number, ::group-off} appareils}}",
|
|
41006
|
+
"ui.mesh.mesh_graph.handshake_refused_count": "{count, plural, one {{count, number, ::group-off} poignée de main refusée} many {{count, number, ::group-off} de poignées de main refusées} other {{count, number, ::group-off} poignées de main refusées}}",
|
|
40831
41007
|
"ui.mesh.mesh_graph.suspected_count": "{count, plural, one {{count, number, ::group-off} d’entre eux suspecté} many {{count, number, ::group-off} d’entre eux suspectés} other {{count, number, ::group-off} d’entre eux suspectés}}",
|
|
40832
41008
|
"ui.mesh.mesh_graph.reached_count": "{count, plural, one {{count, number, ::group-off} joint} many {{count, number, ::group-off} joints} other {{count, number, ::group-off} joints}}",
|
|
41009
|
+
"ui.mesh.mesh_graph.relay_down_count": "{count, plural, one {{count, number, ::group-off} relais arrêté} many {{count, number, ::group-off} de relais arrêtés} other {{count, number, ::group-off} relais arrêtés}}",
|
|
40833
41010
|
"ui.mesh.mesh_graph.no_answer_count": "{count, plural, one {{count, number, ::group-off} sans réponse} many {{count, number, ::group-off} sans réponse} other {{count, number, ::group-off} sans réponse}}",
|
|
40834
41011
|
"ui.mesh.mesh_graph.not_asked_count": "{count, plural, one {{count, number, ::group-off} non interrogé} many {{count, number, ::group-off} non interrogés} other {{count, number, ::group-off} non interrogés}}",
|
|
40835
41012
|
"ui.mesh.mesh_graph.unknown_count": "{count, plural, one {{count, number, ::group-off} inconnu} many {{count, number, ::group-off} inconnus} other {{count, number, ::group-off} inconnus}}",
|
|
@@ -40869,6 +41046,20 @@ const frUiMesh = {
|
|
|
40869
41046
|
"ui.mesh.mesh_page.bring_copy_back": "Rapatrier la copie depuis {device}",
|
|
40870
41047
|
"ui.mesh.mesh_page.the_move_could_not_be_sent_nothing": "Le déplacement n’a pas pu être envoyé. Rien n’a changé ici ; la liste a été relue.",
|
|
40871
41048
|
"ui.mesh.mesh_reach.reached": "joint",
|
|
41049
|
+
"ui.mesh.mesh_reach.relay_not_running": "relais arrêté",
|
|
41050
|
+
"ui.mesh.mesh_reach.handshake_refused": "poignée de main refusée",
|
|
41051
|
+
"ui.mesh.mesh_reach.address_unreachable": "adresse injoignable",
|
|
41052
|
+
"ui.mesh.mesh_reach.no_endpoint": "aucune adresse à contacter",
|
|
41053
|
+
"ui.mesh.mesh_reach.not_a_member": "non membre",
|
|
41054
|
+
"ui.mesh.mesh_reach.attempt_bad_address": "adresse invalide",
|
|
41055
|
+
"ui.mesh.mesh_reach.attempt_could_not_connect": "connexion impossible",
|
|
41056
|
+
"ui.mesh.mesh_reach.addresses_tried": "Adresses essayées",
|
|
41057
|
+
"ui.mesh.mesh_reach.attempt_answered": "a répondu",
|
|
41058
|
+
"ui.mesh.mesh_reach.attempt_nothing_listening": "rien n’écoute",
|
|
41059
|
+
"ui.mesh.mesh_reach.attempt_no_answer": "sans réponse",
|
|
41060
|
+
"ui.mesh.mesh_reach.attempt_not_tried": "non essayée",
|
|
41061
|
+
"ui.mesh.mesh_reach.peer_relay_not_running": "Le relais du pair est arrêté",
|
|
41062
|
+
"ui.mesh.mesh_reach.peer_closed_handshake": "Le pair a répondu mais a fermé la poignée de main",
|
|
40872
41063
|
"ui.mesh.mesh_reach.no_answer": "sans réponse",
|
|
40873
41064
|
"ui.mesh.mesh_reach.not_asked": "non interrogé",
|
|
40874
41065
|
"ui.mesh.mesh_reach.unknown": "inconnu",
|
|
@@ -40883,6 +41074,9 @@ const frUiMesh = {
|
|
|
40883
41074
|
"ui.mesh.mesh_actions.the_device": "l’appareil",
|
|
40884
41075
|
"ui.mesh.mesh_approvals.decision_could_not_be_answered": "La décision n’a pas pu recevoir de réponse.",
|
|
40885
41076
|
"ui.mesh.mesh_node.memberships": "· {count, plural, one {{count, number, ::group-off} réseau} many {{count, number, ::group-off} de réseaux} other {{count, number, ::group-off} réseaux}}",
|
|
41077
|
+
"ui.mesh.mesh_graph.address_unreachable_count": "{count, plural, one {{count, number, ::group-off} adresse injoignable} many {{count, number, ::group-off} d’adresses injoignables} other {{count, number, ::group-off} adresses injoignables}}",
|
|
41078
|
+
"ui.mesh.mesh_graph.no_endpoint_count": "{count, plural, one {{count, number, ::group-off} sans adresse à contacter} many {{count, number, ::group-off} sans adresse à contacter} other {{count, number, ::group-off} sans adresse à contacter}}",
|
|
41079
|
+
"ui.mesh.mesh_graph.not_a_member_count": "{count, plural, one {{count, number, ::group-off} non membre} many {{count, number, ::group-off} de non membres} other {{count, number, ::group-off} non membres}}",
|
|
40886
41080
|
"ui.mesh.mesh_graph.conversation_unit": "{count, plural, one {conversation} many {conversations} other {conversations}}",
|
|
40887
41081
|
"ui.mesh.mesh_approvals_tray.failed_count": "{count, plural, one {{count, number, ::group-off} en échec} many {{count, number, ::group-off} en échec} other {{count, number, ::group-off} en échec}}",
|
|
40888
41082
|
"ui.mesh.mesh_list.sort_conversations": "Conversations",
|
|
@@ -40894,7 +41088,8 @@ const frUiMesh = {
|
|
|
40894
41088
|
"ui.mesh.approval.approved_pending_apply": "Approuvée ; en attente d’application",
|
|
40895
41089
|
"ui.mesh.approval.approved_apply_hint": "L’approbation est enregistrée. Ouvrez Détails pour l’étape d’application fournie par le serveur.",
|
|
40896
41090
|
"ui.mesh.approval.approved_details_missing": "L’approbation est enregistrée. L’étape d’application est indisponible dans cette application.",
|
|
40897
|
-
"ui.mesh.approval.request_window": "Fenêtre de la demande : {remaining}"
|
|
41091
|
+
"ui.mesh.approval.request_window": "Fenêtre de la demande : {remaining}",
|
|
41092
|
+
"ui.mesh.mesh_reach.handshake_refused_hint": "Vérifiez que cet appareil est toujours membre du réseau et que son époque d’appartenance correspond à celle du réseau ; un appareil supprimé ou une époque modifiée entraîne le refus de la poignée de main."
|
|
40898
41093
|
};
|
|
40899
41094
|
const frUiOnboarding = {
|
|
40900
41095
|
"ui.onboarding.connect.intro": "Local Operator a besoin d’un compte IA pour fonctionner. Radient est le plus simple : une connexion dans le navigateur, rien à coller. Vous payez déjà pour ChatGPT ou Claude ? Connectez-vous avec ce compte. Les autres options sont regroupées plus bas.",
|
|
@@ -43193,7 +43388,26 @@ const hiUiChatTags = {
|
|
|
43193
43388
|
"ui.chat.tags.move_undone": "टैग का ले जाना पूर्ववत किया गया",
|
|
43194
43389
|
"ui.chat.tags.move_title": "“{title}” ले जाएँ",
|
|
43195
43390
|
"ui.chat.tags.move_description": "किसी टैग को प्राथमिक बनाने के लिए उसे चुनें, या सभी टैग हटाने के लिए “बिना टैग” चुनें।",
|
|
43196
|
-
"ui.chat.tags.move_failed": "टैग नहीं ले जाए गए। फिर कोशिश करें।"
|
|
43391
|
+
"ui.chat.tags.move_failed": "टैग नहीं ले जाए गए। फिर कोशिश करें।",
|
|
43392
|
+
"ui.chat.tags.selection_count": "8 में से {count}",
|
|
43393
|
+
"ui.chat.tags.registry_count": "32 में से {count}",
|
|
43394
|
+
"ui.chat.tags.create_name": "“{name}” बनाएँ",
|
|
43395
|
+
"ui.chat.tags.create_helper": "सभी बातचीतों के लिए सहेजा जाता है",
|
|
43396
|
+
"ui.chat.tags.selection_limit": "अधिकतम 8 टैग चुनें",
|
|
43397
|
+
"ui.chat.tags.registry_limit": "आप अधिकतम 32 टैग रख सकते हैं",
|
|
43398
|
+
"ui.chat.tags.name_long": "1–24 अक्षर इस्तेमाल करें",
|
|
43399
|
+
"ui.chat.tags.name_reserved": "“Untagged” नाम आरक्षित है",
|
|
43400
|
+
"ui.chat.tags.create_failed": "टैग नहीं बनाया गया। फिर कोशिश करें।",
|
|
43401
|
+
"ui.chat.tags.remove_named": "{name} हटाएँ",
|
|
43402
|
+
"ui.chat.tags.reorder_filtered": "टैग का क्रम बदलने के लिए खोज साफ़ करें",
|
|
43403
|
+
"ui.chat.tags.created_name": "“{name}” बनाया गया",
|
|
43404
|
+
"ui.chat.tags.selection_status": "{count, plural, =1 {# चुना गया} other {# चुने गए}}। {name} के तहत समूह बनाएँ।",
|
|
43405
|
+
"ui.chat.tags.tag_usage": "{count} बातचीत",
|
|
43406
|
+
"ui.chat.tags.create_pending": "टैग सहेजा जा रहा है…",
|
|
43407
|
+
"ui.chat.tags.remote": "दूरस्थ बातचीत के टैग नहीं बदले जा सकते।",
|
|
43408
|
+
"ui.chat.tags.renamed_name": "नाम बदलकर “{name}” किया गया",
|
|
43409
|
+
"ui.chat.tags.staged_added": "“{name}” मसौदे में जोड़ा गया",
|
|
43410
|
+
"ui.chat.tags.registry_changed": "कुछ टैग कहीं और बदले गए। अपना चयन जाँचें।"
|
|
43197
43411
|
};
|
|
43198
43412
|
const hiUiCodeReview = {
|
|
43199
43413
|
"ui.code_review.activity.close": "बंद किया",
|
|
@@ -44153,6 +44367,8 @@ const hiUiMesh = {
|
|
|
44153
44367
|
"ui.mesh.mesh_drop.turn_in_flight": "{conversation} में टर्न चल रहा है, इसलिए उसे नहीं ले जाया जाता — मना होने से कुछ नहीं बदलता।",
|
|
44154
44368
|
"ui.mesh.mesh_drop.that_device_is_no_longer_in_any": "वह डिवाइस अब इस टैब को दिखने वाले किसी नेटवर्क में नहीं है।",
|
|
44155
44369
|
"ui.mesh.mesh_drop.owner_no_answer": "{device} जवाब नहीं दे रहा है{reason}, इसलिए यह बातचीत सौंप नहीं सका।",
|
|
44370
|
+
"ui.mesh.mesh_drop.reach_refusal": "{device}: {reach}{reason}, इसलिए कुछ नहीं ले जाया गया।",
|
|
44371
|
+
"ui.mesh.mesh_drop.owner_reach_refusal": "{device}: {reach}{reason}, इसलिए यह बातचीत सौंप नहीं सका।",
|
|
44156
44372
|
"ui.mesh.mesh_drop.recall_first": "यह बातचीत {owner} पर है। इसे इस डिवाइस से होकर आना होगा: पहले यहाँ वापस लाएँ।",
|
|
44157
44373
|
"ui.mesh.mesh_drop.on_owner": "{owner} पर",
|
|
44158
44374
|
"ui.mesh.mesh_drop.this_device": "यह डिवाइस",
|
|
@@ -44167,8 +44383,10 @@ const hiUiMesh = {
|
|
|
44167
44383
|
"ui.mesh.mesh_graph.no_sessions_reported": "सत्रों की जानकारी नहीं मिली",
|
|
44168
44384
|
"ui.mesh.mesh_graph.network_count": "{count, plural, one {{count, number, ::group-off} नेटवर्क} other {{count, number, ::group-off} नेटवर्क}}",
|
|
44169
44385
|
"ui.mesh.mesh_graph.device_count": "{count, plural, one {{count, number, ::group-off} डिवाइस} other {{count, number, ::group-off} डिवाइस}}",
|
|
44386
|
+
"ui.mesh.mesh_graph.handshake_refused_count": "{count, plural, one {{count, number, ::group-off} में हैंडशेक अस्वीकृत} other {{count, number, ::group-off} में हैंडशेक अस्वीकृत}}",
|
|
44170
44387
|
"ui.mesh.mesh_graph.suspected_count": "{count, plural, other {इनमें से {count, number, ::group-off} संदिग्ध}}",
|
|
44171
44388
|
"ui.mesh.mesh_graph.reached_count": "{count, plural, other {{count, number, ::group-off} से संपर्क हुआ}}",
|
|
44389
|
+
"ui.mesh.mesh_graph.relay_down_count": "{count, plural, one {{count, number, ::group-off} में रिले नहीं चल रहा} other {{count, number, ::group-off} में रिले नहीं चल रहा}}",
|
|
44172
44390
|
"ui.mesh.mesh_graph.no_answer_count": "{count, plural, other {{count, number, ::group-off} से जवाब नहीं}}",
|
|
44173
44391
|
"ui.mesh.mesh_graph.not_asked_count": "{count, plural, other {{count, number, ::group-off} से पूछा नहीं}}",
|
|
44174
44392
|
"ui.mesh.mesh_graph.unknown_count": "{count, plural, other {{count, number, ::group-off} अज्ञात}}",
|
|
@@ -44208,6 +44426,20 @@ const hiUiMesh = {
|
|
|
44208
44426
|
"ui.mesh.mesh_page.bring_copy_back": "{device} से कॉपी वापस लाएँ",
|
|
44209
44427
|
"ui.mesh.mesh_page.the_move_could_not_be_sent_nothing": "ले जाने का अनुरोध भेजा नहीं जा सका। यहाँ कुछ नहीं बदला; सूची फिर पढ़ी गई है।",
|
|
44210
44428
|
"ui.mesh.mesh_reach.reached": "संपर्क हुआ",
|
|
44429
|
+
"ui.mesh.mesh_reach.relay_not_running": "रिले नहीं चल रहा",
|
|
44430
|
+
"ui.mesh.mesh_reach.handshake_refused": "हैंडशेक अस्वीकृत",
|
|
44431
|
+
"ui.mesh.mesh_reach.address_unreachable": "पता अगम्य",
|
|
44432
|
+
"ui.mesh.mesh_reach.no_endpoint": "डायल करने योग्य पता नहीं",
|
|
44433
|
+
"ui.mesh.mesh_reach.not_a_member": "सदस्य नहीं",
|
|
44434
|
+
"ui.mesh.mesh_reach.attempt_bad_address": "अमान्य पता",
|
|
44435
|
+
"ui.mesh.mesh_reach.attempt_could_not_connect": "कनेक्ट नहीं हो सका",
|
|
44436
|
+
"ui.mesh.mesh_reach.addresses_tried": "आज़माए गए पते",
|
|
44437
|
+
"ui.mesh.mesh_reach.attempt_answered": "जवाब मिला",
|
|
44438
|
+
"ui.mesh.mesh_reach.attempt_nothing_listening": "कोई नहीं सुन रहा",
|
|
44439
|
+
"ui.mesh.mesh_reach.attempt_no_answer": "जवाब नहीं",
|
|
44440
|
+
"ui.mesh.mesh_reach.attempt_not_tried": "कोशिश नहीं हुई",
|
|
44441
|
+
"ui.mesh.mesh_reach.peer_relay_not_running": "पीयर का रिले नहीं चल रहा",
|
|
44442
|
+
"ui.mesh.mesh_reach.peer_closed_handshake": "पीयर ने जवाब दिया, पर हैंडशेक बंद कर दिया",
|
|
44211
44443
|
"ui.mesh.mesh_reach.no_answer": "जवाब नहीं",
|
|
44212
44444
|
"ui.mesh.mesh_reach.not_asked": "पूछा नहीं",
|
|
44213
44445
|
"ui.mesh.mesh_reach.unknown": "अज्ञात",
|
|
@@ -44222,6 +44454,9 @@ const hiUiMesh = {
|
|
|
44222
44454
|
"ui.mesh.mesh_actions.the_device": "डिवाइस",
|
|
44223
44455
|
"ui.mesh.mesh_approvals.decision_could_not_be_answered": "फ़ैसले का जवाब नहीं दिया जा सका।",
|
|
44224
44456
|
"ui.mesh.mesh_node.memberships": "· {count, plural, one {{count, number, ::group-off} नेटवर्क} other {{count, number, ::group-off} नेटवर्क}}",
|
|
44457
|
+
"ui.mesh.mesh_graph.address_unreachable_count": "{count, plural, one {{count, number, ::group-off} में पता अगम्य} other {{count, number, ::group-off} में पता अगम्य}}",
|
|
44458
|
+
"ui.mesh.mesh_graph.no_endpoint_count": "{count, plural, one {{count, number, ::group-off} में डायल करने योग्य पता नहीं} other {{count, number, ::group-off} में डायल करने योग्य पता नहीं}}",
|
|
44459
|
+
"ui.mesh.mesh_graph.not_a_member_count": "{count, plural, one {{count, number, ::group-off} में सदस्यता नहीं} other {{count, number, ::group-off} में सदस्यता नहीं}}",
|
|
44225
44460
|
"ui.mesh.mesh_graph.conversation_unit": "{count, plural, one {बातचीत} other {बातचीतें}}",
|
|
44226
44461
|
"ui.mesh.mesh_approvals_tray.failed_count": "{count, plural, other {{count, number, ::group-off} विफल}}",
|
|
44227
44462
|
"ui.mesh.mesh_list.sort_conversations": "बातचीतें",
|
|
@@ -44233,7 +44468,8 @@ const hiUiMesh = {
|
|
|
44233
44468
|
"ui.mesh.approval.approved_pending_apply": "स्वीकृत; लागू होने का इंतज़ार",
|
|
44234
44469
|
"ui.mesh.approval.approved_apply_hint": "स्वीकृति दर्ज है। सर्वर का बताया लागू करने का चरण देखने के लिए विवरण खोलें।",
|
|
44235
44470
|
"ui.mesh.approval.approved_details_missing": "स्वीकृति दर्ज है। लागू करने का चरण इस ऐप में उपलब्ध नहीं है।",
|
|
44236
|
-
"ui.mesh.approval.request_window": "अनुरोध की समय-सीमा: {remaining}"
|
|
44471
|
+
"ui.mesh.approval.request_window": "अनुरोध की समय-सीमा: {remaining}",
|
|
44472
|
+
"ui.mesh.mesh_reach.handshake_refused_hint": "जाँचें कि यह डिवाइस अभी भी नेटवर्क का सदस्य है और epoch मेल खाता है; हटाया गया डिवाइस या बदला हुआ epoch हैंडशेक अस्वीकार कर देता है।"
|
|
44237
44473
|
};
|
|
44238
44474
|
const hiUiOnboarding = {
|
|
44239
44475
|
"ui.onboarding.connect.intro": "Local Operator को काम करने के लिए AI खाते की ज़रूरत है। Radient सबसे आसान है: ब्राउज़र में एक बार साइन इन करें, कुछ पेस्ट नहीं करना पड़ता। पहले से ChatGPT या Claude के लिए भुगतान करते हैं? उसी खाते से साइन इन करें। दूसरे विकल्प देखने के लिए नीचे प्रोवाइडरों की सूची खोलें।",
|
|
@@ -46446,7 +46682,26 @@ const ruUiChatTags = {
|
|
|
46446
46682
|
"ui.chat.tags.move_undone": "Перемещение тега отменено",
|
|
46447
46683
|
"ui.chat.tags.move_title": "Переместить «{title}»",
|
|
46448
46684
|
"ui.chat.tags.move_description": "Выберите основной тег или «Без тега», чтобы удалить все теги.",
|
|
46449
|
-
"ui.chat.tags.move_failed": "Не удалось переместить теги. Попробуйте ещё раз."
|
|
46685
|
+
"ui.chat.tags.move_failed": "Не удалось переместить теги. Попробуйте ещё раз.",
|
|
46686
|
+
"ui.chat.tags.selection_count": "{count} из 8",
|
|
46687
|
+
"ui.chat.tags.registry_count": "{count} из 32",
|
|
46688
|
+
"ui.chat.tags.create_name": "Создать «{name}»",
|
|
46689
|
+
"ui.chat.tags.create_helper": "Сохраняется для всех разговоров",
|
|
46690
|
+
"ui.chat.tags.selection_limit": "Выберите не более 8 тегов",
|
|
46691
|
+
"ui.chat.tags.registry_limit": "Можно создать не более 32 тегов",
|
|
46692
|
+
"ui.chat.tags.name_long": "Используйте от 1 до 24 символов",
|
|
46693
|
+
"ui.chat.tags.name_reserved": "Имя «Untagged» зарезервировано",
|
|
46694
|
+
"ui.chat.tags.create_failed": "Тег не создан. Попробуйте ещё раз.",
|
|
46695
|
+
"ui.chat.tags.remove_named": "Убрать {name}",
|
|
46696
|
+
"ui.chat.tags.reorder_filtered": "Очистите поиск, чтобы изменить порядок тегов",
|
|
46697
|
+
"ui.chat.tags.created_name": "Создан тег «{name}»",
|
|
46698
|
+
"ui.chat.tags.selection_status": "Выбрано: {count}. Основной тег: {name}.",
|
|
46699
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# разговор} few {# разговора} many {# разговоров} other {# разговора}}",
|
|
46700
|
+
"ui.chat.tags.create_pending": "Сохранение тега…",
|
|
46701
|
+
"ui.chat.tags.remote": "Нельзя изменить теги удалённого разговора.",
|
|
46702
|
+
"ui.chat.tags.renamed_name": "Новое имя: «{name}»",
|
|
46703
|
+
"ui.chat.tags.staged_added": "Тег «{name}» добавлен в черновик",
|
|
46704
|
+
"ui.chat.tags.registry_changed": "Некоторые теги изменены в другом месте. Проверьте выбор."
|
|
46450
46705
|
};
|
|
46451
46706
|
const ruUiCodeReview = {
|
|
46452
46707
|
"ui.code_review.activity.close": "закрыли",
|
|
@@ -47281,6 +47536,8 @@ const ruUiMesh = {
|
|
|
47281
47536
|
"ui.mesh.mesh_drop.on_owner": "на {owner}",
|
|
47282
47537
|
"ui.mesh.mesh_drop.on_this_device": "на этом устройстве",
|
|
47283
47538
|
"ui.mesh.mesh_drop.owner_no_answer": "{device} не отвечает{reason}, поэтому не смог передать этот разговор.",
|
|
47539
|
+
"ui.mesh.mesh_drop.owner_reach_refusal": "{device}: {reach}{reason}, поэтому не удалось передать этот разговор.",
|
|
47540
|
+
"ui.mesh.mesh_drop.reach_refusal": "{device}: {reach}{reason}, поэтому ничего не перемещено.",
|
|
47284
47541
|
"ui.mesh.mesh_drop.recall_first": "Этот разговор находится на {owner}. Он должен пройти через это устройство: сначала верните его сюда.",
|
|
47285
47542
|
"ui.mesh.mesh_drop.recall_it": "Вернуть",
|
|
47286
47543
|
"ui.mesh.mesh_drop.running_now": "{conversation} сейчас выполняется {where}.",
|
|
@@ -47289,17 +47546,22 @@ const ruUiMesh = {
|
|
|
47289
47546
|
"ui.mesh.mesh_drop.this_conversation": "Этот разговор",
|
|
47290
47547
|
"ui.mesh.mesh_drop.this_device": "это устройство",
|
|
47291
47548
|
"ui.mesh.mesh_drop.turn_in_flight": "В {conversation} выполняется ход, поэтому разговор не перемещается — отказ ничего не меняет.",
|
|
47549
|
+
"ui.mesh.mesh_graph.address_unreachable_count": "{count, plural, one {адрес недоступен: {count, number, ::group-off}} few {адрес недоступен: {count, number, ::group-off}} many {адрес недоступен: {count, number, ::group-off}} other {адрес недоступен: {count, number, ::group-off}}}",
|
|
47292
47550
|
"ui.mesh.mesh_graph.conversation_unit": "{count, plural, one {разговор} few {разговора} many {разговоров} other {разговора}}",
|
|
47293
47551
|
"ui.mesh.mesh_graph.conversations_not_reported": "разговоры не сообщены",
|
|
47294
47552
|
"ui.mesh.mesh_graph.device_count": "{count, plural, one {{count, number, ::group-off} устройство} few {{count, number, ::group-off} устройства} many {{count, number, ::group-off} устройств} other {{count, number, ::group-off} устройства}}",
|
|
47553
|
+
"ui.mesh.mesh_graph.handshake_refused_count": "{count, plural, one {рукопожатие отклонено: {count, number, ::group-off}} few {рукопожатие отклонено: {count, number, ::group-off}} many {рукопожатие отклонено: {count, number, ::group-off}} other {рукопожатие отклонено: {count, number, ::group-off}}}",
|
|
47295
47554
|
"ui.mesh.mesh_graph.identity_suspect": "личность под вопросом",
|
|
47296
47555
|
"ui.mesh.mesh_graph.just_now": "только что",
|
|
47297
47556
|
"ui.mesh.mesh_graph.last_status_frame": "последний кадр статуса {age}",
|
|
47298
47557
|
"ui.mesh.mesh_graph.network_count": "{count, plural, one {{count, number, ::group-off} сеть} few {{count, number, ::group-off} сети} many {{count, number, ::group-off} сетей} other {{count, number, ::group-off} сети}}",
|
|
47299
47558
|
"ui.mesh.mesh_graph.no_answer_count": "{count, plural, one {нет ответа: {count, number, ::group-off}} few {нет ответа: {count, number, ::group-off}} many {нет ответа: {count, number, ::group-off}} other {нет ответа: {count, number, ::group-off}}}",
|
|
47559
|
+
"ui.mesh.mesh_graph.no_endpoint_count": "{count, plural, one {нет адреса для подключения: {count, number, ::group-off}} few {нет адреса для подключения: {count, number, ::group-off}} many {нет адреса для подключения: {count, number, ::group-off}} other {нет адреса для подключения: {count, number, ::group-off}}}",
|
|
47300
47560
|
"ui.mesh.mesh_graph.no_sessions_reported": "сессии не сообщены",
|
|
47561
|
+
"ui.mesh.mesh_graph.not_a_member_count": "{count, plural, one {не участник сети: {count, number, ::group-off}} few {не участник сети: {count, number, ::group-off}} many {не участник сети: {count, number, ::group-off}} other {не участник сети: {count, number, ::group-off}}}",
|
|
47301
47562
|
"ui.mesh.mesh_graph.not_asked_count": "{count, plural, one {не опрошено: {count, number, ::group-off}} few {не опрошено: {count, number, ::group-off}} many {не опрошено: {count, number, ::group-off}} other {не опрошено: {count, number, ::group-off}}}",
|
|
47302
47563
|
"ui.mesh.mesh_graph.reached_count": "{count, plural, one {доступно: {count, number, ::group-off}} few {доступно: {count, number, ::group-off}} many {доступно: {count, number, ::group-off}} other {доступно: {count, number, ::group-off}}}",
|
|
47564
|
+
"ui.mesh.mesh_graph.relay_down_count": "{count, plural, one {ретранслятор не работает: {count, number, ::group-off}} few {ретранслятор не работает: {count, number, ::group-off}} many {ретранслятор не работает: {count, number, ::group-off}} other {ретранслятор не работает: {count, number, ::group-off}}}",
|
|
47303
47565
|
"ui.mesh.mesh_graph.revoked_membership": "членство отозвано",
|
|
47304
47566
|
"ui.mesh.mesh_graph.self_conversations": "это устройство · {conversations}",
|
|
47305
47567
|
"ui.mesh.mesh_graph.self_identity": "это устройство — {device}",
|
|
@@ -47342,9 +47604,24 @@ const ruUiMesh = {
|
|
|
47342
47604
|
"ui.mesh.mesh_page.the_copy_here_is_gone": "; копии здесь больше нет",
|
|
47343
47605
|
"ui.mesh.mesh_page.the_move_could_not_be_sent_nothing": "Не удалось отправить перемещение. Здесь ничего не изменилось; список прочитан заново.",
|
|
47344
47606
|
"ui.mesh.mesh_page.this_device_is_not_in_any_network": "Это устройство не состоит ни в одной сети, поэтому рисовать нечего. Создайте сеть на этом компьютере:",
|
|
47607
|
+
"ui.mesh.mesh_reach.address_unreachable": "адрес недоступен",
|
|
47608
|
+
"ui.mesh.mesh_reach.addresses_tried": "Попытки подключения",
|
|
47609
|
+
"ui.mesh.mesh_reach.attempt_answered": "ответил",
|
|
47610
|
+
"ui.mesh.mesh_reach.attempt_bad_address": "некорректный адрес",
|
|
47611
|
+
"ui.mesh.mesh_reach.attempt_could_not_connect": "не удалось подключиться",
|
|
47612
|
+
"ui.mesh.mesh_reach.attempt_no_answer": "нет ответа",
|
|
47613
|
+
"ui.mesh.mesh_reach.attempt_not_tried": "не проверялся",
|
|
47614
|
+
"ui.mesh.mesh_reach.attempt_nothing_listening": "никто не слушает",
|
|
47615
|
+
"ui.mesh.mesh_reach.handshake_refused": "рукопожатие отклонено",
|
|
47616
|
+
"ui.mesh.mesh_reach.handshake_refused_hint": "Проверьте, что это устройство всё ещё состоит в сети и что эпоха совпадает; устройство, удалённое из сети, или изменившаяся эпоха приводят к отказу в рукопожатии.",
|
|
47345
47617
|
"ui.mesh.mesh_reach.no_answer": "нет ответа",
|
|
47618
|
+
"ui.mesh.mesh_reach.no_endpoint": "нет адреса для подключения",
|
|
47619
|
+
"ui.mesh.mesh_reach.not_a_member": "не участник сети",
|
|
47346
47620
|
"ui.mesh.mesh_reach.not_asked": "не опрошено",
|
|
47621
|
+
"ui.mesh.mesh_reach.peer_closed_handshake": "другое устройство ответило, но прервало рукопожатие",
|
|
47622
|
+
"ui.mesh.mesh_reach.peer_relay_not_running": "ретранслятор другого устройства не работает",
|
|
47347
47623
|
"ui.mesh.mesh_reach.reached": "доступно",
|
|
47624
|
+
"ui.mesh.mesh_reach.relay_not_running": "ретранслятор не работает",
|
|
47348
47625
|
"ui.mesh.mesh_reach.unknown": "неизвестно",
|
|
47349
47626
|
"ui.mesh.mesh_scope.declared": "объявлено",
|
|
47350
47627
|
"ui.mesh.mesh_scope.same_prefix": "тот же префикс",
|
|
@@ -49651,7 +49928,26 @@ const urUiChatTags = {
|
|
|
49651
49928
|
"ui.chat.tags.move_undone": "ٹیگ کی منتقلی واپس کر دی گئی",
|
|
49652
49929
|
"ui.chat.tags.move_title": "“{title}” منتقل کریں",
|
|
49653
49930
|
"ui.chat.tags.move_description": "کسی ٹیگ کو بنیادی بنانے کے لیے اسے منتخب کریں، یا تمام ٹیگز ہٹانے کے لیے “بغیر ٹیگ” منتخب کریں۔",
|
|
49654
|
-
"ui.chat.tags.move_failed": "ٹیگز منتقل نہیں ہوئے۔ دوبارہ کوشش کریں۔"
|
|
49931
|
+
"ui.chat.tags.move_failed": "ٹیگز منتقل نہیں ہوئے۔ دوبارہ کوشش کریں۔",
|
|
49932
|
+
"ui.chat.tags.selection_count": "8 میں سے {count}",
|
|
49933
|
+
"ui.chat.tags.registry_count": "32 میں سے {count}",
|
|
49934
|
+
"ui.chat.tags.create_name": "“{name}” بنائیں",
|
|
49935
|
+
"ui.chat.tags.create_helper": "تمام گفتگوؤں کے لیے محفوظ",
|
|
49936
|
+
"ui.chat.tags.selection_limit": "زیادہ سے زیادہ 8 ٹیگز منتخب کریں",
|
|
49937
|
+
"ui.chat.tags.registry_limit": "آپ زیادہ سے زیادہ 32 ٹیگز رکھ سکتے ہیں",
|
|
49938
|
+
"ui.chat.tags.name_long": "1–24 حروف استعمال کریں",
|
|
49939
|
+
"ui.chat.tags.name_reserved": "“Untagged” نام مخصوص ہے",
|
|
49940
|
+
"ui.chat.tags.create_failed": "ٹیگ نہیں بنا۔ دوبارہ کوشش کریں۔",
|
|
49941
|
+
"ui.chat.tags.remove_named": "{name} ہٹائیں",
|
|
49942
|
+
"ui.chat.tags.reorder_filtered": "ٹیگز کی ترتیب بدلنے کے لیے تلاش صاف کریں",
|
|
49943
|
+
"ui.chat.tags.created_name": "“{name}” بنا دیا گیا",
|
|
49944
|
+
"ui.chat.tags.selection_status": "منتخب: {count}۔ {name} کے گروہ میں رکھیں۔",
|
|
49945
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# گفتگو} other {# گفتگوئیں}}",
|
|
49946
|
+
"ui.chat.tags.create_pending": "ٹیگ محفوظ ہو رہا ہے…",
|
|
49947
|
+
"ui.chat.tags.remote": "ریموٹ گفتگو کے ٹیگز تبدیل نہیں کیے جا سکتے۔",
|
|
49948
|
+
"ui.chat.tags.renamed_name": "نام بدل کر “{name}” کر دیا گیا",
|
|
49949
|
+
"ui.chat.tags.staged_added": "“{name}” مسودے میں شامل کر دیا گیا",
|
|
49950
|
+
"ui.chat.tags.registry_changed": "کچھ ٹیگز کہیں اور تبدیل ہو گئے ہیں۔ اپنے انتخاب کا جائزہ لیں۔"
|
|
49655
49951
|
};
|
|
49656
49952
|
const urUiCodeReview = {
|
|
49657
49953
|
"ui.code_review.activity.close": "بند کیا",
|
|
@@ -50631,6 +50927,8 @@ const urUiMesh = {
|
|
|
50631
50927
|
"ui.mesh.mesh_drop.turn_in_flight": "{conversation} کی ایک باری جاری ہے، اس لیے اسے منتقل نہیں کیا گیا — اس انکار سے کچھ نہیں بدلتا۔",
|
|
50632
50928
|
"ui.mesh.mesh_drop.that_device_is_no_longer_in_any": "وہ ڈیوائس اب کسی ایسے نیٹ ورک میں نہیں جسے یہ ٹیب پڑھ سکے۔",
|
|
50633
50929
|
"ui.mesh.mesh_drop.owner_no_answer": "{device} جواب نہیں دے رہی{reason}، اس لیے یہ گفتگو حوالے نہیں کر سکی۔",
|
|
50930
|
+
"ui.mesh.mesh_drop.reach_refusal": "{device}: {reach}{reason}، اس لیے کچھ منتقل نہیں ہوا۔",
|
|
50931
|
+
"ui.mesh.mesh_drop.owner_reach_refusal": "{device}: {reach}{reason}، اس لیے یہ گفتگو حوالے نہیں کر سکی۔",
|
|
50634
50932
|
"ui.mesh.mesh_drop.recall_first": "یہ گفتگو {owner} پر ہے۔ اسے اس ڈیوائس سے گزرنا ہو گا؛ پہلے اسے یہاں واپس لائیں۔",
|
|
50635
50933
|
"ui.mesh.mesh_drop.on_owner": "{owner} پر",
|
|
50636
50934
|
"ui.mesh.mesh_drop.this_device": "یہ ڈیوائس",
|
|
@@ -50645,8 +50943,10 @@ const urUiMesh = {
|
|
|
50645
50943
|
"ui.mesh.mesh_graph.no_sessions_reported": "سیشن کی اطلاع نہیں ملی",
|
|
50646
50944
|
"ui.mesh.mesh_graph.network_count": "{count, plural, one {{count, number, ::group-off} نیٹ ورک} other {{count, number, ::group-off} نیٹ ورک}}",
|
|
50647
50945
|
"ui.mesh.mesh_graph.device_count": "{count, plural, one {{count, number, ::group-off} ڈیوائس} other {{count, number, ::group-off} ڈیوائسز}}",
|
|
50946
|
+
"ui.mesh.mesh_graph.handshake_refused_count": "{count, plural, one {{count, number, ::group-off} کا ہینڈ شیک مسترد ہوا} other {{count, number, ::group-off} کے ہینڈ شیک مسترد ہوئے}}",
|
|
50648
50947
|
"ui.mesh.mesh_graph.suspected_count": "{count, plural, other {ان میں سے {count, number, ::group-off} مشکوک}}",
|
|
50649
50948
|
"ui.mesh.mesh_graph.reached_count": "{count, plural, other {{count, number, ::group-off} سے رابطہ ہوا}}",
|
|
50949
|
+
"ui.mesh.mesh_graph.relay_down_count": "{count, plural, one {{count, number, ::group-off} کا ریلے بند ہے} other {{count, number, ::group-off} کے ریلے بند ہیں}}",
|
|
50650
50950
|
"ui.mesh.mesh_graph.no_answer_count": "{count, plural, other {{count, number, ::group-off} سے جواب نہیں ملا}}",
|
|
50651
50951
|
"ui.mesh.mesh_graph.not_asked_count": "{count, plural, other {{count, number, ::group-off} سے پوچھا نہیں گیا}}",
|
|
50652
50952
|
"ui.mesh.mesh_graph.unknown_count": "{count, plural, other {{count, number, ::group-off} نامعلوم}}",
|
|
@@ -50686,6 +50986,20 @@ const urUiMesh = {
|
|
|
50686
50986
|
"ui.mesh.mesh_page.bring_copy_back": "{device} سے نقل واپس لائیں",
|
|
50687
50987
|
"ui.mesh.mesh_page.the_move_could_not_be_sent_nothing": "منتقلی کی درخواست بھیجی نہیں جا سکی۔ یہاں کچھ نہیں بدلا؛ فہرست دوبارہ پڑھ لی گئی ہے۔",
|
|
50688
50988
|
"ui.mesh.mesh_reach.reached": "رابطہ ہوا",
|
|
50989
|
+
"ui.mesh.mesh_reach.relay_not_running": "ریلے نہیں چل رہا",
|
|
50990
|
+
"ui.mesh.mesh_reach.handshake_refused": "ہینڈ شیک مسترد ہوا",
|
|
50991
|
+
"ui.mesh.mesh_reach.address_unreachable": "پتہ ناقابل رسائی",
|
|
50992
|
+
"ui.mesh.mesh_reach.no_endpoint": "ڈائل کرنے کے لیے کوئی پتہ نہیں",
|
|
50993
|
+
"ui.mesh.mesh_reach.not_a_member": "رکن نہیں",
|
|
50994
|
+
"ui.mesh.mesh_reach.attempt_bad_address": "غلط پتہ",
|
|
50995
|
+
"ui.mesh.mesh_reach.attempt_could_not_connect": "رابطہ نہیں ہو سکا",
|
|
50996
|
+
"ui.mesh.mesh_reach.addresses_tried": "آزمائے گئے پتے",
|
|
50997
|
+
"ui.mesh.mesh_reach.attempt_answered": "جواب ملا",
|
|
50998
|
+
"ui.mesh.mesh_reach.attempt_nothing_listening": "کچھ نہیں سن رہا",
|
|
50999
|
+
"ui.mesh.mesh_reach.attempt_no_answer": "جواب نہیں ملا",
|
|
51000
|
+
"ui.mesh.mesh_reach.attempt_not_tried": "آزمایا نہیں گیا",
|
|
51001
|
+
"ui.mesh.mesh_reach.peer_relay_not_running": "دوسرے سرے کا ریلے نہیں چل رہا",
|
|
51002
|
+
"ui.mesh.mesh_reach.peer_closed_handshake": "دوسرے سرے نے جواب دیا مگر ہینڈ شیک بند کر دیا",
|
|
50689
51003
|
"ui.mesh.mesh_reach.no_answer": "جواب نہیں ملا",
|
|
50690
51004
|
"ui.mesh.mesh_reach.not_asked": "پوچھا نہیں گیا",
|
|
50691
51005
|
"ui.mesh.mesh_reach.unknown": "نامعلوم",
|
|
@@ -50700,6 +51014,9 @@ const urUiMesh = {
|
|
|
50700
51014
|
"ui.mesh.mesh_actions.the_device": "ڈیوائس",
|
|
50701
51015
|
"ui.mesh.mesh_approvals.decision_could_not_be_answered": "فیصلے کا جواب نہیں دیا جا سکا۔",
|
|
50702
51016
|
"ui.mesh.mesh_node.memberships": "· {count, plural, one {{count, number, ::group-off} نیٹ ورک} other {{count, number, ::group-off} نیٹ ورک}}",
|
|
51017
|
+
"ui.mesh.mesh_graph.address_unreachable_count": "{count, plural, one {{count, number, ::group-off} کا پتہ ناقابل رسائی} other {{count, number, ::group-off} کے پتے ناقابل رسائی}}",
|
|
51018
|
+
"ui.mesh.mesh_graph.no_endpoint_count": "{count, plural, one {{count, number, ::group-off} کے پاس ڈائل کرنے کے لیے کوئی پتہ نہیں} other {{count, number, ::group-off} کے پاس ڈائل کرنے کے لیے کوئی پتہ نہیں}}",
|
|
51019
|
+
"ui.mesh.mesh_graph.not_a_member_count": "{count, plural, one {{count, number, ::group-off} رکن نہیں} other {{count, number, ::group-off} رکن نہیں}}",
|
|
50703
51020
|
"ui.mesh.mesh_graph.conversation_unit": "{count, plural, one {گفتگو} other {گفتگوئیں}}",
|
|
50704
51021
|
"ui.mesh.mesh_approvals_tray.failed_count": "{count, plural, other {{count, number, ::group-off} ناکام}}",
|
|
50705
51022
|
"ui.mesh.mesh_list.sort_conversations": "گفتگوئیں",
|
|
@@ -50711,7 +51028,8 @@ const urUiMesh = {
|
|
|
50711
51028
|
"ui.mesh.approval.approved_pending_apply": "منظور شدہ؛ اطلاق کا انتظار ہے",
|
|
50712
51029
|
"ui.mesh.approval.approved_apply_hint": "منظوری درج ہے۔ سرور کے فراہم کردہ اطلاق کے قدم کے لیے تفصیلات کھولیں۔",
|
|
50713
51030
|
"ui.mesh.approval.approved_details_missing": "منظوری درج ہے۔ اطلاق کا قدم اس ایپ میں دستیاب نہیں ہے۔",
|
|
50714
|
-
"ui.mesh.approval.request_window": "درخواست کی مہلت: {remaining}"
|
|
51031
|
+
"ui.mesh.approval.request_window": "درخواست کی مہلت: {remaining}",
|
|
51032
|
+
"ui.mesh.mesh_reach.handshake_refused_hint": "جانچ لیں کہ یہ ڈیوائس اب بھی نیٹ ورک کی رکن ہے اور دور میل کھاتا ہے؛ ہٹایا گیا ڈیوائس یا بدلا ہوا دور ہینڈ شیک مسترد کر دیتا ہے۔"
|
|
50715
51033
|
};
|
|
50716
51034
|
const urUiOnboarding = {
|
|
50717
51035
|
"ui.onboarding.connect.intro": "Local Operator کو کام کے لیے AI اکاؤنٹ چاہیے۔ Radient سب سے آسان ہے؛ براؤزر میں ایک بار سائن ان کریں، کچھ چسپاں نہیں کرنا پڑتا۔ پہلے ہی ChatGPT یا Claude کی ادائیگی کرتے ہیں؟ اسی سے سائن ان کریں۔ دیگر انتخاب مزید فراہم کنندگان میں ہیں۔",
|
|
@@ -52924,7 +53242,26 @@ const viUiChatTags = {
|
|
|
52924
53242
|
"ui.chat.tags.move_undone": "Đã hoàn tác thao tác chuyển nhãn",
|
|
52925
53243
|
"ui.chat.tags.move_title": "Chuyển “{title}”",
|
|
52926
53244
|
"ui.chat.tags.move_description": "Chọn một nhãn làm nhãn chính, hoặc chọn Chưa gắn nhãn để gỡ hết nhãn.",
|
|
52927
|
-
"ui.chat.tags.move_failed": "Chưa chuyển được nhãn. Hãy thử lại."
|
|
53245
|
+
"ui.chat.tags.move_failed": "Chưa chuyển được nhãn. Hãy thử lại.",
|
|
53246
|
+
"ui.chat.tags.selection_count": "{count} trên 8",
|
|
53247
|
+
"ui.chat.tags.registry_count": "{count} trên 32",
|
|
53248
|
+
"ui.chat.tags.create_name": "Tạo “{name}”",
|
|
53249
|
+
"ui.chat.tags.create_helper": "Được lưu cho mọi cuộc trò chuyện",
|
|
53250
|
+
"ui.chat.tags.selection_limit": "Chọn tối đa 8 nhãn",
|
|
53251
|
+
"ui.chat.tags.registry_limit": "Bạn có thể có tối đa 32 nhãn",
|
|
53252
|
+
"ui.chat.tags.name_long": "Dùng từ 1 đến 24 ký tự",
|
|
53253
|
+
"ui.chat.tags.name_reserved": "“Untagged” là tên dành riêng",
|
|
53254
|
+
"ui.chat.tags.create_failed": "Chưa tạo được nhãn. Hãy thử lại.",
|
|
53255
|
+
"ui.chat.tags.remove_named": "Bỏ {name}",
|
|
53256
|
+
"ui.chat.tags.reorder_filtered": "Xóa tìm kiếm để sắp xếp lại nhãn",
|
|
53257
|
+
"ui.chat.tags.created_name": "Đã tạo “{name}”",
|
|
53258
|
+
"ui.chat.tags.selection_status": "Đã chọn {count}. Nhóm vào {name}.",
|
|
53259
|
+
"ui.chat.tags.tag_usage": "{count} cuộc trò chuyện",
|
|
53260
|
+
"ui.chat.tags.create_pending": "Đang lưu nhãn…",
|
|
53261
|
+
"ui.chat.tags.remote": "Không thể thay đổi nhãn của cuộc trò chuyện từ xa.",
|
|
53262
|
+
"ui.chat.tags.renamed_name": "Đã đổi tên thành “{name}”",
|
|
53263
|
+
"ui.chat.tags.staged_added": "Đã thêm “{name}” vào bản nháp",
|
|
53264
|
+
"ui.chat.tags.registry_changed": "Một số nhãn đã thay đổi ở nơi khác. Hãy kiểm tra lựa chọn."
|
|
52928
53265
|
};
|
|
52929
53266
|
const viUiCodeReview = {
|
|
52930
53267
|
"ui.code_review.activity.close": "đã đóng",
|
|
@@ -53750,6 +54087,8 @@ const viUiMesh = {
|
|
|
53750
54087
|
"ui.mesh.mesh_drop.turn_in_flight": "{conversation} có lượt đang chạy nên không được chuyển — việc từ chối không thay đổi gì.",
|
|
53751
54088
|
"ui.mesh.mesh_drop.that_device_is_no_longer_in_any": "Thiết bị đó không còn thuộc mạng nào mà tab này có thể đọc.",
|
|
53752
54089
|
"ui.mesh.mesh_drop.owner_no_answer": "{device} không phản hồi{reason}, nên không thể bàn giao cuộc trò chuyện này.",
|
|
54090
|
+
"ui.mesh.mesh_drop.reach_refusal": "{device}: {reach}{reason}, nên chưa có gì được chuyển.",
|
|
54091
|
+
"ui.mesh.mesh_drop.owner_reach_refusal": "{device}: {reach}{reason}, nên không thể bàn giao cuộc trò chuyện này.",
|
|
53753
54092
|
"ui.mesh.mesh_drop.recall_first": "Cuộc trò chuyện này nằm trên {owner}. Nó phải đi qua thiết bị này: hãy lấy về đây trước.",
|
|
53754
54093
|
"ui.mesh.mesh_drop.on_owner": "trên {owner}",
|
|
53755
54094
|
"ui.mesh.mesh_drop.this_device": "thiết bị này",
|
|
@@ -53764,8 +54103,10 @@ const viUiMesh = {
|
|
|
53764
54103
|
"ui.mesh.mesh_graph.no_sessions_reported": "chưa báo cáo phiên nào",
|
|
53765
54104
|
"ui.mesh.mesh_graph.network_count": "{count, plural, other {{count, number, ::group-off} mạng}}",
|
|
53766
54105
|
"ui.mesh.mesh_graph.device_count": "{count, plural, other {{count, number, ::group-off} thiết bị}}",
|
|
54106
|
+
"ui.mesh.mesh_graph.handshake_refused_count": "{count, plural, other {{count, number, ::group-off} bắt tay bị từ chối}}",
|
|
53767
54107
|
"ui.mesh.mesh_graph.suspected_count": "{count, plural, other {{count, number, ::group-off} trong số đó đáng ngờ}}",
|
|
53768
54108
|
"ui.mesh.mesh_graph.reached_count": "{count, plural, other {{count, number, ::group-off} đã kết nối}}",
|
|
54109
|
+
"ui.mesh.mesh_graph.relay_down_count": "{count, plural, other {{count, number, ::group-off} dịch vụ chuyển tiếp không chạy}}",
|
|
53769
54110
|
"ui.mesh.mesh_graph.no_answer_count": "{count, plural, other {{count, number, ::group-off} không phản hồi}}",
|
|
53770
54111
|
"ui.mesh.mesh_graph.not_asked_count": "{count, plural, other {{count, number, ::group-off} chưa được hỏi}}",
|
|
53771
54112
|
"ui.mesh.mesh_graph.unknown_count": "{count, plural, other {{count, number, ::group-off} chưa rõ}}",
|
|
@@ -53805,6 +54146,20 @@ const viUiMesh = {
|
|
|
53805
54146
|
"ui.mesh.mesh_page.bring_copy_back": "Lấy bản sao về từ {device}",
|
|
53806
54147
|
"ui.mesh.mesh_page.the_move_could_not_be_sent_nothing": "Không thể gửi yêu cầu chuyển. Không có gì ở đây thay đổi; danh sách đã được đọc lại.",
|
|
53807
54148
|
"ui.mesh.mesh_reach.reached": "đã kết nối",
|
|
54149
|
+
"ui.mesh.mesh_reach.relay_not_running": "dịch vụ chuyển tiếp không chạy",
|
|
54150
|
+
"ui.mesh.mesh_reach.handshake_refused": "bắt tay bị từ chối",
|
|
54151
|
+
"ui.mesh.mesh_reach.address_unreachable": "địa chỉ không thể truy cập",
|
|
54152
|
+
"ui.mesh.mesh_reach.no_endpoint": "không có địa chỉ để kết nối",
|
|
54153
|
+
"ui.mesh.mesh_reach.not_a_member": "không phải thành viên",
|
|
54154
|
+
"ui.mesh.mesh_reach.attempt_bad_address": "địa chỉ không hợp lệ",
|
|
54155
|
+
"ui.mesh.mesh_reach.attempt_could_not_connect": "không kết nối được",
|
|
54156
|
+
"ui.mesh.mesh_reach.addresses_tried": "Địa chỉ đã thử",
|
|
54157
|
+
"ui.mesh.mesh_reach.attempt_answered": "đã phản hồi",
|
|
54158
|
+
"ui.mesh.mesh_reach.attempt_nothing_listening": "không có dịch vụ nào lắng nghe",
|
|
54159
|
+
"ui.mesh.mesh_reach.attempt_no_answer": "không phản hồi",
|
|
54160
|
+
"ui.mesh.mesh_reach.attempt_not_tried": "chưa thử",
|
|
54161
|
+
"ui.mesh.mesh_reach.peer_relay_not_running": "Dịch vụ chuyển tiếp của thiết bị ngang hàng không chạy",
|
|
54162
|
+
"ui.mesh.mesh_reach.peer_closed_handshake": "Thiết bị ngang hàng đã phản hồi nhưng đóng phiên bắt tay",
|
|
53808
54163
|
"ui.mesh.mesh_reach.no_answer": "không phản hồi",
|
|
53809
54164
|
"ui.mesh.mesh_reach.not_asked": "chưa được hỏi",
|
|
53810
54165
|
"ui.mesh.mesh_reach.unknown": "chưa rõ",
|
|
@@ -53819,6 +54174,9 @@ const viUiMesh = {
|
|
|
53819
54174
|
"ui.mesh.mesh_actions.the_device": "thiết bị",
|
|
53820
54175
|
"ui.mesh.mesh_approvals.decision_could_not_be_answered": "Không thể gửi quyết định.",
|
|
53821
54176
|
"ui.mesh.mesh_node.memberships": "· {count, plural, other {{count, number, ::group-off} mạng}}",
|
|
54177
|
+
"ui.mesh.mesh_graph.address_unreachable_count": "{count, plural, other {{count, number, ::group-off} địa chỉ không thể truy cập}}",
|
|
54178
|
+
"ui.mesh.mesh_graph.no_endpoint_count": "{count, plural, other {{count, number, ::group-off} không có địa chỉ để kết nối}}",
|
|
54179
|
+
"ui.mesh.mesh_graph.not_a_member_count": "{count, plural, other {{count, number, ::group-off} không phải thành viên}}",
|
|
53822
54180
|
"ui.mesh.mesh_graph.conversation_unit": "{count, plural, other {cuộc trò chuyện}}",
|
|
53823
54181
|
"ui.mesh.mesh_approvals_tray.failed_count": "{count, plural, other {{count, number, ::group-off} thất bại}}",
|
|
53824
54182
|
"ui.mesh.mesh_list.sort_conversations": "Cuộc trò chuyện",
|
|
@@ -53830,7 +54188,8 @@ const viUiMesh = {
|
|
|
53830
54188
|
"ui.mesh.approval.approved_pending_apply": "Đã phê duyệt; chờ áp dụng",
|
|
53831
54189
|
"ui.mesh.approval.approved_apply_hint": "Đã ghi nhận phê duyệt. Mở Chi tiết để xem bước áp dụng do máy chủ cung cấp.",
|
|
53832
54190
|
"ui.mesh.approval.approved_details_missing": "Đã ghi nhận phê duyệt. Bước áp dụng không có trong ứng dụng này.",
|
|
53833
|
-
"ui.mesh.approval.request_window": "Thời hạn yêu cầu: {remaining}"
|
|
54191
|
+
"ui.mesh.approval.request_window": "Thời hạn yêu cầu: {remaining}",
|
|
54192
|
+
"ui.mesh.mesh_reach.handshake_refused_hint": "Hãy kiểm tra xem thiết bị này còn là thành viên của mạng không và phiên bản thành viên có khớp không; thiết bị đã bị gỡ khỏi mạng hoặc phiên bản thành viên đã thay đổi đều khiến bắt tay bị từ chối."
|
|
53834
54193
|
};
|
|
53835
54194
|
const viUiOnboarding = {
|
|
53836
54195
|
"ui.onboarding.connect.intro": "Local Operator cần tài khoản AI để hoạt động. Radient đơn giản nhất: đăng nhập một lần qua trình duyệt, không cần dán gì. Bạn đã trả phí cho ChatGPT hoặc Claude? Hãy đăng nhập bằng tài khoản đó. Mở danh sách nhà cung cấp bên dưới để xem các lựa chọn khác.",
|
|
@@ -55852,7 +56211,26 @@ const zhCNUiChatTags = {
|
|
|
55852
56211
|
"ui.chat.tags.move_undone": "已撤销标签移动",
|
|
55853
56212
|
"ui.chat.tags.move_title": "移动“{title}”",
|
|
55854
56213
|
"ui.chat.tags.move_description": "选择一个标签将其设为主标签,或选择“无标签”以移除所有标签。",
|
|
55855
|
-
"ui.chat.tags.move_failed": "标签未移动。请重试。"
|
|
56214
|
+
"ui.chat.tags.move_failed": "标签未移动。请重试。",
|
|
56215
|
+
"ui.chat.tags.selection_count": "已选 {count}/8",
|
|
56216
|
+
"ui.chat.tags.registry_count": "{count}/32",
|
|
56217
|
+
"ui.chat.tags.create_name": "创建“{name}”",
|
|
56218
|
+
"ui.chat.tags.create_helper": "保存后可用于所有对话",
|
|
56219
|
+
"ui.chat.tags.selection_limit": "最多选择 8 个标签",
|
|
56220
|
+
"ui.chat.tags.registry_limit": "最多可有 32 个标签",
|
|
56221
|
+
"ui.chat.tags.name_long": "请使用 1–24 个字符",
|
|
56222
|
+
"ui.chat.tags.name_reserved": "“Untagged”是保留名称",
|
|
56223
|
+
"ui.chat.tags.create_failed": "未能创建标签。请重试。",
|
|
56224
|
+
"ui.chat.tags.remove_named": "移除{name}",
|
|
56225
|
+
"ui.chat.tags.reorder_filtered": "清空搜索以调整标签顺序",
|
|
56226
|
+
"ui.chat.tags.created_name": "已创建“{name}”",
|
|
56227
|
+
"ui.chat.tags.selection_status": "已选择 {count} 个,归入{name}。",
|
|
56228
|
+
"ui.chat.tags.tag_usage": "{count} 个对话",
|
|
56229
|
+
"ui.chat.tags.create_pending": "正在保存标签…",
|
|
56230
|
+
"ui.chat.tags.remote": "无法更改远程对话的标签。",
|
|
56231
|
+
"ui.chat.tags.renamed_name": "已重命名为“{name}”",
|
|
56232
|
+
"ui.chat.tags.staged_added": "已将“{name}”加入草稿",
|
|
56233
|
+
"ui.chat.tags.registry_changed": "部分标签已在别处更改。请检查所选标签。"
|
|
55856
56234
|
};
|
|
55857
56235
|
const zhCNUiCodeReview = {
|
|
55858
56236
|
"ui.code_review.activity.close": "已关闭",
|
|
@@ -56678,6 +57056,8 @@ const zhCNUiMesh = {
|
|
|
56678
57056
|
"ui.mesh.mesh_drop.turn_in_flight": "{conversation}有一轮尚未执行完毕,因此未移动;拒绝移动未造成任何变更。",
|
|
56679
57057
|
"ui.mesh.mesh_drop.that_device_is_no_longer_in_any": "该设备已不属于此标签页可读取的任何网络。",
|
|
56680
57058
|
"ui.mesh.mesh_drop.owner_no_answer": "{device}未响应{reason},无法移交此对话。",
|
|
57059
|
+
"ui.mesh.mesh_drop.reach_refusal": "{device}:{reach}{reason},因此未移动对话。",
|
|
57060
|
+
"ui.mesh.mesh_drop.owner_reach_refusal": "{device}:{reach}{reason},因此无法移交此对话。",
|
|
56681
57061
|
"ui.mesh.mesh_drop.recall_first": "此对话位于{owner}。转移必须经过此设备,请先将其移回此处。",
|
|
56682
57062
|
"ui.mesh.mesh_drop.on_owner": "{owner}上",
|
|
56683
57063
|
"ui.mesh.mesh_drop.this_device": "此设备",
|
|
@@ -56692,8 +57072,10 @@ const zhCNUiMesh = {
|
|
|
56692
57072
|
"ui.mesh.mesh_graph.no_sessions_reported": "未报告会话信息",
|
|
56693
57073
|
"ui.mesh.mesh_graph.network_count": "{count, plural, other {{count, number, ::group-off}个网络}}",
|
|
56694
57074
|
"ui.mesh.mesh_graph.device_count": "{count, plural, other {{count, number, ::group-off}台设备}}",
|
|
57075
|
+
"ui.mesh.mesh_graph.handshake_refused_count": "{count, plural, other {{count, number, ::group-off}台握手被拒绝}}",
|
|
56695
57076
|
"ui.mesh.mesh_graph.suspected_count": "{count, plural, other {其中{count, number, ::group-off}台身份存疑}}",
|
|
56696
57077
|
"ui.mesh.mesh_graph.reached_count": "{count, plural, other {{count, number, ::group-off}台可达}}",
|
|
57078
|
+
"ui.mesh.mesh_graph.relay_down_count": "{count, plural, other {{count, number, ::group-off}台中继未运行}}",
|
|
56697
57079
|
"ui.mesh.mesh_graph.no_answer_count": "{count, plural, other {{count, number, ::group-off}台未响应}}",
|
|
56698
57080
|
"ui.mesh.mesh_graph.not_asked_count": "{count, plural, other {{count, number, ::group-off}台未查询}}",
|
|
56699
57081
|
"ui.mesh.mesh_graph.unknown_count": "{count, plural, other {{count, number, ::group-off}台状态未知}}",
|
|
@@ -56733,6 +57115,20 @@ const zhCNUiMesh = {
|
|
|
56733
57115
|
"ui.mesh.mesh_page.bring_copy_back": "从{device}移回副本",
|
|
56734
57116
|
"ui.mesh.mesh_page.the_move_could_not_be_sent_nothing": "无法发送移动请求。此处未发生任何变更,已重新读取列表。",
|
|
56735
57117
|
"ui.mesh.mesh_reach.reached": "可达",
|
|
57118
|
+
"ui.mesh.mesh_reach.relay_not_running": "中继未运行",
|
|
57119
|
+
"ui.mesh.mesh_reach.handshake_refused": "握手被拒绝",
|
|
57120
|
+
"ui.mesh.mesh_reach.address_unreachable": "地址不可达",
|
|
57121
|
+
"ui.mesh.mesh_reach.no_endpoint": "无地址可拨",
|
|
57122
|
+
"ui.mesh.mesh_reach.not_a_member": "非成员",
|
|
57123
|
+
"ui.mesh.mesh_reach.attempt_bad_address": "地址无效",
|
|
57124
|
+
"ui.mesh.mesh_reach.attempt_could_not_connect": "无法连接",
|
|
57125
|
+
"ui.mesh.mesh_reach.addresses_tried": "已尝试的地址",
|
|
57126
|
+
"ui.mesh.mesh_reach.attempt_answered": "已响应",
|
|
57127
|
+
"ui.mesh.mesh_reach.attempt_nothing_listening": "无服务监听",
|
|
57128
|
+
"ui.mesh.mesh_reach.attempt_no_answer": "未响应",
|
|
57129
|
+
"ui.mesh.mesh_reach.attempt_not_tried": "未尝试",
|
|
57130
|
+
"ui.mesh.mesh_reach.peer_relay_not_running": "对端中继未运行",
|
|
57131
|
+
"ui.mesh.mesh_reach.peer_closed_handshake": "对端已响应,但关闭了握手",
|
|
56736
57132
|
"ui.mesh.mesh_reach.no_answer": "未响应",
|
|
56737
57133
|
"ui.mesh.mesh_reach.not_asked": "未查询",
|
|
56738
57134
|
"ui.mesh.mesh_reach.unknown": "未知",
|
|
@@ -56747,6 +57143,9 @@ const zhCNUiMesh = {
|
|
|
56747
57143
|
"ui.mesh.mesh_actions.the_device": "该设备",
|
|
56748
57144
|
"ui.mesh.mesh_approvals.decision_could_not_be_answered": "无法提交审批决定。",
|
|
56749
57145
|
"ui.mesh.mesh_node.memberships": "· {count, plural, other {{count, number, ::group-off}个网络}}",
|
|
57146
|
+
"ui.mesh.mesh_graph.address_unreachable_count": "{count, plural, other {{count, number, ::group-off}台地址不可达}}",
|
|
57147
|
+
"ui.mesh.mesh_graph.no_endpoint_count": "{count, plural, other {{count, number, ::group-off}台无地址可拨}}",
|
|
57148
|
+
"ui.mesh.mesh_graph.not_a_member_count": "{count, plural, other {{count, number, ::group-off}台非成员}}",
|
|
56750
57149
|
"ui.mesh.mesh_graph.conversation_unit": "{count, plural, other {个对话}}",
|
|
56751
57150
|
"ui.mesh.mesh_approvals_tray.failed_count": "{count, plural, other {{count, number, ::group-off}项失败}}",
|
|
56752
57151
|
"ui.mesh.mesh_list.sort_conversations": "对话",
|
|
@@ -56758,7 +57157,8 @@ const zhCNUiMesh = {
|
|
|
56758
57157
|
"ui.mesh.approval.approved_pending_apply": "已批准,待执行生效步骤",
|
|
56759
57158
|
"ui.mesh.approval.approved_apply_hint": "审批已记录。请打开“详情”,查看服务器提供的生效步骤。",
|
|
56760
57159
|
"ui.mesh.approval.approved_details_missing": "审批已记录。此应用无法提供生效步骤。",
|
|
56761
|
-
"ui.mesh.approval.request_window": "请求有效期:{remaining}"
|
|
57160
|
+
"ui.mesh.approval.request_window": "请求有效期:{remaining}",
|
|
57161
|
+
"ui.mesh.mesh_reach.handshake_refused_hint": "请检查此设备是否仍是网络成员、成员版本是否一致;设备被移除或成员版本变化都会使握手被拒绝。"
|
|
56762
57162
|
};
|
|
56763
57163
|
const zhCNUiOnboarding = {
|
|
56764
57164
|
"ui.onboarding.connect.intro": "Local Operator需要AI账户才能工作。Radient最方便:在浏览器中登录一次即可,无需粘贴任何内容。已订阅ChatGPT或Claude?也可以直接用该账户登录。要使用其他提供商,展开下方的提供商列表。",
|
|
@@ -62342,6 +62742,15 @@ class BrowserHost {
|
|
|
62342
62742
|
}
|
|
62343
62743
|
/** Main owns this short-lived UI focus fact; it conveys no page capability. */
|
|
62344
62744
|
chordFocus = false;
|
|
62745
|
+
/**
|
|
62746
|
+
* The tab whose native view last reported focus. Tracked from each view's own
|
|
62747
|
+
* `focus`/`blur` events because `webContents.getFocusedWebContents()` can
|
|
62748
|
+
* answer null while a `WebContentsView` holds focus (measured on Electron
|
|
62749
|
+
* 44.3.0 in a window that is not itself activated). Like `chordFocus`, this
|
|
62750
|
+
* is an input-ownership fact and carries no page capability; `ownsPage`
|
|
62751
|
+
* refuses it unless the tab is the active, presented one.
|
|
62752
|
+
*/
|
|
62753
|
+
focusedPageTabId = null;
|
|
62345
62754
|
onChordFocusChanged;
|
|
62346
62755
|
/** An explicit tab id fences queued chrome intents: a switch between key
|
|
62347
62756
|
* delivery and IPC must never search/zoom the newly active tab instead. */
|
|
@@ -62364,6 +62773,16 @@ class BrowserHost {
|
|
|
62364
62773
|
this.chordFocus = focused;
|
|
62365
62774
|
this.onChordFocusChanged?.(focused);
|
|
62366
62775
|
}
|
|
62776
|
+
/** One view gained or lost native focus. Only the id that lost it may clear
|
|
62777
|
+
* the fact: a departing view's blur must not erase a successor's focus. */
|
|
62778
|
+
setPageFocused(tabId, focused) {
|
|
62779
|
+
if (focused) this.focusedPageTabId = tabId;
|
|
62780
|
+
else if (this.focusedPageTabId === tabId) this.focusedPageTabId = null;
|
|
62781
|
+
}
|
|
62782
|
+
/** The window's own renderer gained focus (the user clicked chrome/chat). */
|
|
62783
|
+
clearPageFocus() {
|
|
62784
|
+
this.focusedPageTabId = null;
|
|
62785
|
+
}
|
|
62367
62786
|
/** Only user URLs survive a close, never a capability, page state or nonce.
|
|
62368
62787
|
* Conversation attribution is retained only to find the appropriate scope. */
|
|
62369
62788
|
closedUserTabs = [];
|
|
@@ -62382,6 +62801,7 @@ class BrowserHost {
|
|
|
62382
62801
|
clearChordState() {
|
|
62383
62802
|
this.pageControls.clear();
|
|
62384
62803
|
this.setChordFocus(false);
|
|
62804
|
+
this.clearPageFocus();
|
|
62385
62805
|
this.closedUserTabs = [];
|
|
62386
62806
|
}
|
|
62387
62807
|
/**
|
|
@@ -62772,12 +63192,14 @@ class BrowserHost {
|
|
|
62772
63192
|
* area and reports it, and main applies it to the active tab only. */
|
|
62773
63193
|
setContentRect(rect) {
|
|
62774
63194
|
this.registry.setContentRect(rect);
|
|
63195
|
+
if (rect === null) this.clearPageFocus();
|
|
62775
63196
|
return this.chromeState();
|
|
62776
63197
|
}
|
|
62777
63198
|
/** Full-window overlays hide the view: a native view paints above all DOM, so
|
|
62778
63199
|
* an overlay is invisible unless the view goes away (design 11.3). */
|
|
62779
63200
|
setViewVisible(visible) {
|
|
62780
63201
|
this.registry.setViewVisible(visible);
|
|
63202
|
+
if (!visible) this.clearPageFocus();
|
|
62781
63203
|
return this.chromeState();
|
|
62782
63204
|
}
|
|
62783
63205
|
/** Hand a user tab to a session, minting the capability. The RENDERER never
|
|
@@ -66041,6 +66463,8 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66041
66463
|
return view;
|
|
66042
66464
|
}, wireView = function(view, tabId) {
|
|
66043
66465
|
const contents = view.webContents;
|
|
66466
|
+
contents.on("focus", () => host.setPageFocused(tabId, true));
|
|
66467
|
+
contents.on("blur", () => host.setPageFocused(tabId, false));
|
|
66044
66468
|
const popupChildren = /* @__PURE__ */ new Set();
|
|
66045
66469
|
contents.setWindowOpenHandler((details) => {
|
|
66046
66470
|
const decision = decidePopup(
|
|
@@ -66202,6 +66626,7 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66202
66626
|
if (token) approvals.forgetDocument(token);
|
|
66203
66627
|
registry.forget(tabId);
|
|
66204
66628
|
}
|
|
66629
|
+
host.setPageFocused(tabId, false);
|
|
66205
66630
|
host.clearLoadFailure(tabId);
|
|
66206
66631
|
releaseTab(tabId, contents.id);
|
|
66207
66632
|
});
|
|
@@ -66477,9 +66902,18 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66477
66902
|
ownsChrome,
|
|
66478
66903
|
ownsPage: () => {
|
|
66479
66904
|
const record = registry.activeTab;
|
|
66480
|
-
return
|
|
66481
|
-
record
|
|
66482
|
-
|
|
66905
|
+
return browserPageOwnsChord({
|
|
66906
|
+
activeTab: record ? {
|
|
66907
|
+
tabId: record.tabId,
|
|
66908
|
+
webContentsId: record.view.webContents.id,
|
|
66909
|
+
presented: record.presented
|
|
66910
|
+
} : null,
|
|
66911
|
+
// Read lazily after the window/presented floor: a startup or test host
|
|
66912
|
+
// may carry a webContents slice without the getter.
|
|
66913
|
+
focusedContents: () => electron.webContents.getFocusedWebContents()?.id ?? null,
|
|
66914
|
+
focusedViewTabId: host.focusedPageTabId,
|
|
66915
|
+
window: options.window
|
|
66916
|
+
});
|
|
66483
66917
|
},
|
|
66484
66918
|
reload: (hard) => {
|
|
66485
66919
|
host.reloadActive(hard);
|
|
@@ -66511,6 +66945,9 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66511
66945
|
const resetChordFocus = () => {
|
|
66512
66946
|
host.setChordFocus(false);
|
|
66513
66947
|
};
|
|
66948
|
+
const resetPageFocus = () => {
|
|
66949
|
+
host.clearPageFocus();
|
|
66950
|
+
};
|
|
66514
66951
|
const resetMenuShortcutSuppression = () => {
|
|
66515
66952
|
if (!options.window.webContents.isDestroyed())
|
|
66516
66953
|
options.window.webContents.setIgnoreMenuShortcuts(false);
|
|
@@ -66519,6 +66956,7 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66519
66956
|
if (!focused) resetMenuShortcutSuppression();
|
|
66520
66957
|
};
|
|
66521
66958
|
options.window.webContents.on("before-input-event", onChromeInput);
|
|
66959
|
+
options.window.webContents.on("focus", resetPageFocus);
|
|
66522
66960
|
options.window.on("blur", resetMenuShortcutSuppression);
|
|
66523
66961
|
options.window.on("closed", resetChordFocus);
|
|
66524
66962
|
const resetOnNavigation = (details) => {
|
|
@@ -66532,6 +66970,7 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66532
66970
|
"before-input-event",
|
|
66533
66971
|
onChromeInput
|
|
66534
66972
|
);
|
|
66973
|
+
options.window.webContents.removeListener("focus", resetPageFocus);
|
|
66535
66974
|
options.window.removeListener("blur", resetMenuShortcutSuppression);
|
|
66536
66975
|
options.window.removeListener("closed", resetChordFocus);
|
|
66537
66976
|
options.window.webContents.removeListener(
|
|
@@ -66823,7 +67262,7 @@ function isAdmittedSender(event, admitted) {
|
|
|
66823
67262
|
(candidate) => candidate.window !== null && !candidate.window.isDestroyed() && event.sender === candidate.window.webContents && event.senderFrame === candidate.window.webContents.mainFrame && trustedDesktopFrame(event.senderFrame.url, candidate.url)
|
|
66824
67263
|
);
|
|
66825
67264
|
}
|
|
66826
|
-
function registerDesktopIPC(window, expectedUrl, request, streams, media, notifier, noteLeftSession, onKeymapSettingEdited, additionalWindows, supplementMounts2) {
|
|
67265
|
+
function registerDesktopIPC(window, expectedUrl, request, streams, media, notifier, noteLeftSession, onKeymapSettingEdited, additionalWindows, supplementMounts2, teamBridgeNotifier) {
|
|
66827
67266
|
const opened = /* @__PURE__ */ new Map();
|
|
66828
67267
|
function authorize(event) {
|
|
66829
67268
|
const admitted = [
|
|
@@ -66887,6 +67326,16 @@ function registerDesktopIPC(window, expectedUrl, request, streams, media, notifi
|
|
|
66887
67326
|
noteLeftSession?.(args.sessionId);
|
|
66888
67327
|
});
|
|
66889
67328
|
}
|
|
67329
|
+
if (teamBridgeNotifier) {
|
|
67330
|
+
electron.ipcMain.handle("team-bridge:notify", (event, input) => {
|
|
67331
|
+
authorize(event);
|
|
67332
|
+
return teamBridgeNotifier.notify(input);
|
|
67333
|
+
});
|
|
67334
|
+
electron.ipcMain.handle("team-bridge:pending-open", (event) => {
|
|
67335
|
+
authorize(event);
|
|
67336
|
+
return teamBridgeNotifier.takePendingOpen();
|
|
67337
|
+
});
|
|
67338
|
+
}
|
|
66890
67339
|
if (media) {
|
|
66891
67340
|
electron.ipcMain.handle("desktop-media", (event, input, bytes) => {
|
|
66892
67341
|
authorize(event);
|
|
@@ -68844,6 +69293,227 @@ function installSupplementProtocol(fetchDocument, log2) {
|
|
|
68844
69293
|
});
|
|
68845
69294
|
});
|
|
68846
69295
|
}
|
|
69296
|
+
const TEAM_BRIDGE_NOTIFY_MAX_TITLE = 320;
|
|
69297
|
+
const TEAM_BRIDGE_NOTIFY_MAX_BODY = 200;
|
|
69298
|
+
const MAX_SEQ = Number.MAX_SAFE_INTEGER;
|
|
69299
|
+
const SAFE_ID = /^[A-Za-z0-9_.:-]{1,128}$/;
|
|
69300
|
+
function hasUnsafeText(value) {
|
|
69301
|
+
for (const character of value) {
|
|
69302
|
+
const code = character.codePointAt(0) ?? 0;
|
|
69303
|
+
if (character === "<" || character === ">" || code < 32 || code === 127) {
|
|
69304
|
+
return true;
|
|
69305
|
+
}
|
|
69306
|
+
}
|
|
69307
|
+
return false;
|
|
69308
|
+
}
|
|
69309
|
+
function cleanId(value) {
|
|
69310
|
+
return typeof value === "string" && SAFE_ID.test(value) ? value : null;
|
|
69311
|
+
}
|
|
69312
|
+
function cleanText(value, max) {
|
|
69313
|
+
if (typeof value !== "string") return null;
|
|
69314
|
+
const trimmed = value.trim();
|
|
69315
|
+
if (trimmed.length === 0 || trimmed.length > max) return null;
|
|
69316
|
+
if (hasUnsafeText(trimmed)) return null;
|
|
69317
|
+
return trimmed;
|
|
69318
|
+
}
|
|
69319
|
+
function parseTeamBridgeNotifyRequest(value) {
|
|
69320
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
69321
|
+
return null;
|
|
69322
|
+
}
|
|
69323
|
+
const input = value;
|
|
69324
|
+
const conversationId = cleanId(input.conversationId);
|
|
69325
|
+
const tenantId = cleanId(input.tenantId);
|
|
69326
|
+
const title = cleanText(input.title, TEAM_BRIDGE_NOTIFY_MAX_TITLE);
|
|
69327
|
+
const body = cleanText(input.body, TEAM_BRIDGE_NOTIFY_MAX_BODY);
|
|
69328
|
+
const seq2 = input.seq;
|
|
69329
|
+
if (conversationId === null || tenantId === null || title === null || body === null || typeof seq2 !== "number" || !Number.isSafeInteger(seq2) || seq2 < 0 || seq2 > MAX_SEQ) {
|
|
69330
|
+
return null;
|
|
69331
|
+
}
|
|
69332
|
+
return { conversationId, tenantId, title, body, seq: seq2 };
|
|
69333
|
+
}
|
|
69334
|
+
function teamBridgeWindowIsQuiet(window) {
|
|
69335
|
+
if (!window) return false;
|
|
69336
|
+
return !window.isDestroyed() && window.isVisible() && !window.isMinimized() && window.isFocused();
|
|
69337
|
+
}
|
|
69338
|
+
class TeamBridgeNotifier {
|
|
69339
|
+
constructor(options) {
|
|
69340
|
+
this.options = options;
|
|
69341
|
+
this.createBanner = options.createBanner ?? ((bannerOptions) => new electron.Notification(bannerOptions));
|
|
69342
|
+
this.canNotify = options.canNotify ?? (() => electron.Notification.isSupported());
|
|
69343
|
+
}
|
|
69344
|
+
/** The live banner per conversation, so a new seq REPLACES it. */
|
|
69345
|
+
banners = /* @__PURE__ */ new Map();
|
|
69346
|
+
/** The banners this process must keep reachable for their clicks to fire. */
|
|
69347
|
+
lifetime = new NotificationLifetime();
|
|
69348
|
+
pendingOpen = null;
|
|
69349
|
+
createBanner;
|
|
69350
|
+
canNotify;
|
|
69351
|
+
/**
|
|
69352
|
+
* Validate, dedupe and deliver one banner.
|
|
69353
|
+
*
|
|
69354
|
+
* REFUSAL IS AN ERROR, not a quiet `false`: a malformed payload is a bug in
|
|
69355
|
+
* the caller, and the IPC handler should reject rather than let the renderer
|
|
69356
|
+
* believe it raised something. A well-formed payload that is suppressed
|
|
69357
|
+
* (quiet, muted by focus, duplicate, unsupported) answers `shown: false`.
|
|
69358
|
+
*/
|
|
69359
|
+
notify(input) {
|
|
69360
|
+
const request = parseTeamBridgeNotifyRequest(input);
|
|
69361
|
+
if (request === null) {
|
|
69362
|
+
throw new Error("Invalid Team Bridge notification payload.");
|
|
69363
|
+
}
|
|
69364
|
+
if (this.options.show === "never") return { shown: false };
|
|
69365
|
+
if (!this.canNotify()) return { shown: false };
|
|
69366
|
+
if (teamBridgeWindowIsQuiet(this.options.window())) {
|
|
69367
|
+
return { shown: false };
|
|
69368
|
+
}
|
|
69369
|
+
const previous = this.options.store.notifiedSeq(request.conversationId);
|
|
69370
|
+
if (previous !== void 0 && request.seq <= previous) {
|
|
69371
|
+
return { shown: false };
|
|
69372
|
+
}
|
|
69373
|
+
this.replace(request.conversationId);
|
|
69374
|
+
const notification = this.createBanner({
|
|
69375
|
+
title: request.title,
|
|
69376
|
+
body: request.body,
|
|
69377
|
+
silent: false,
|
|
69378
|
+
...this.options.icon ? { icon: this.options.icon } : {}
|
|
69379
|
+
});
|
|
69380
|
+
this.lifetime.retain(notification, () => {
|
|
69381
|
+
this.banners.delete(request.conversationId);
|
|
69382
|
+
this.open(request);
|
|
69383
|
+
});
|
|
69384
|
+
notification.once("close", () => {
|
|
69385
|
+
if (this.banners.get(request.conversationId) === notification) {
|
|
69386
|
+
this.banners.delete(request.conversationId);
|
|
69387
|
+
}
|
|
69388
|
+
});
|
|
69389
|
+
notification.show();
|
|
69390
|
+
this.banners.set(request.conversationId, notification);
|
|
69391
|
+
this.options.store.record(request.conversationId, request.seq);
|
|
69392
|
+
return { shown: true };
|
|
69393
|
+
}
|
|
69394
|
+
/**
|
|
69395
|
+
* The target a click parked for the renderer.
|
|
69396
|
+
*
|
|
69397
|
+
* Consumed exactly once: the renderer asks for it on mount and on every
|
|
69398
|
+
* `team-bridge:open` signal, and a later pull gets `null` rather than
|
|
69399
|
+
* replaying a conversation the user has already seen. The value was built
|
|
69400
|
+
* from an already-validated notification payload, so this read does not
|
|
69401
|
+
* re-parse ids.
|
|
69402
|
+
*/
|
|
69403
|
+
takePendingOpen() {
|
|
69404
|
+
const pending = this.pendingOpen;
|
|
69405
|
+
this.pendingOpen = null;
|
|
69406
|
+
return pending;
|
|
69407
|
+
}
|
|
69408
|
+
replace(conversationId) {
|
|
69409
|
+
const previous = this.banners.get(conversationId);
|
|
69410
|
+
if (!previous) return;
|
|
69411
|
+
this.banners.delete(conversationId);
|
|
69412
|
+
previous.close?.();
|
|
69413
|
+
}
|
|
69414
|
+
open(request) {
|
|
69415
|
+
const target2 = {
|
|
69416
|
+
conversationId: request.conversationId,
|
|
69417
|
+
tenantId: request.tenantId
|
|
69418
|
+
};
|
|
69419
|
+
this.pendingOpen = target2;
|
|
69420
|
+
const window = this.options.window();
|
|
69421
|
+
if (window && !window.isDestroyed()) {
|
|
69422
|
+
this.options.host.signalOpen();
|
|
69423
|
+
this.options.present?.(window);
|
|
69424
|
+
return;
|
|
69425
|
+
}
|
|
69426
|
+
this.options.host.reopen();
|
|
69427
|
+
}
|
|
69428
|
+
}
|
|
69429
|
+
const TEAM_BRIDGE_NOTIFY_CURSOR_BOUND = 2048;
|
|
69430
|
+
const VERSION = 1;
|
|
69431
|
+
function isCursor(value) {
|
|
69432
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
69433
|
+
}
|
|
69434
|
+
class TeamBridgeNotifyStore {
|
|
69435
|
+
constructor(file, onError = () => void 0) {
|
|
69436
|
+
this.file = file;
|
|
69437
|
+
this.onError = onError;
|
|
69438
|
+
this.load();
|
|
69439
|
+
}
|
|
69440
|
+
cursors = /* @__PURE__ */ new Map();
|
|
69441
|
+
/** The newest seq a banner was raised for, or `undefined`. */
|
|
69442
|
+
notifiedSeq(conversationId) {
|
|
69443
|
+
return this.cursors.get(conversationId);
|
|
69444
|
+
}
|
|
69445
|
+
/**
|
|
69446
|
+
* Remember that this conversation was notified at `seq`.
|
|
69447
|
+
*
|
|
69448
|
+
* Only advances: a late poll whose seq is older than the recorded one must
|
|
69449
|
+
* not move the cursor backwards and re-open the door to a duplicate banner.
|
|
69450
|
+
* Touching an existing key moves it to the newest position so the bound
|
|
69451
|
+
* evicts by usefulness rather than alphabetically.
|
|
69452
|
+
*/
|
|
69453
|
+
record(conversationId, seq2) {
|
|
69454
|
+
if (!isCursor(seq2)) return;
|
|
69455
|
+
const previous = this.cursors.get(conversationId);
|
|
69456
|
+
if (previous !== void 0 && seq2 <= previous) return;
|
|
69457
|
+
this.cursors.delete(conversationId);
|
|
69458
|
+
this.cursors.set(conversationId, seq2);
|
|
69459
|
+
this.trim();
|
|
69460
|
+
this.persist();
|
|
69461
|
+
}
|
|
69462
|
+
/**
|
|
69463
|
+
* Enforce the bound on BOTH paths: `record` while a run is live and `load` on
|
|
69464
|
+
* a file written by an older or hand-edited build. A bound enforced only on
|
|
69465
|
+
* the write path is a promise about files this process wrote itself, which is
|
|
69466
|
+
* not the file it has just read.
|
|
69467
|
+
*/
|
|
69468
|
+
trim() {
|
|
69469
|
+
while (this.cursors.size > TEAM_BRIDGE_NOTIFY_CURSOR_BOUND) {
|
|
69470
|
+
const oldest = this.cursors.keys().next();
|
|
69471
|
+
if (oldest.done) break;
|
|
69472
|
+
this.cursors.delete(oldest.value);
|
|
69473
|
+
}
|
|
69474
|
+
}
|
|
69475
|
+
load() {
|
|
69476
|
+
let raw;
|
|
69477
|
+
try {
|
|
69478
|
+
raw = fs.readFileSync(this.file, "utf8");
|
|
69479
|
+
} catch {
|
|
69480
|
+
return;
|
|
69481
|
+
}
|
|
69482
|
+
try {
|
|
69483
|
+
const parsed = JSON.parse(raw);
|
|
69484
|
+
if (parsed === null || typeof parsed !== "object" || parsed.version !== VERSION) {
|
|
69485
|
+
return;
|
|
69486
|
+
}
|
|
69487
|
+
const cursors = parsed.cursors;
|
|
69488
|
+
if (cursors === null || typeof cursors !== "object") return;
|
|
69489
|
+
for (const [conversationId, seq2] of Object.entries(
|
|
69490
|
+
cursors
|
|
69491
|
+
)) {
|
|
69492
|
+
if (isCursor(seq2)) this.cursors.set(conversationId, seq2);
|
|
69493
|
+
}
|
|
69494
|
+
this.trim();
|
|
69495
|
+
} catch (error) {
|
|
69496
|
+
this.onError("team-bridge notification cursor file is unreadable", error);
|
|
69497
|
+
}
|
|
69498
|
+
}
|
|
69499
|
+
persist() {
|
|
69500
|
+
const payload = {
|
|
69501
|
+
version: VERSION,
|
|
69502
|
+
cursors: Object.fromEntries(this.cursors)
|
|
69503
|
+
};
|
|
69504
|
+
try {
|
|
69505
|
+
fs.mkdirSync(path$1.dirname(this.file), { recursive: true, mode: 448 });
|
|
69506
|
+
const temporary = `${this.file}.${process.pid}.tmp`;
|
|
69507
|
+
fs.writeFileSync(temporary, JSON.stringify(payload), { mode: 384 });
|
|
69508
|
+
fs.renameSync(temporary, this.file);
|
|
69509
|
+
} catch (error) {
|
|
69510
|
+
this.onError(
|
|
69511
|
+
"team-bridge notification cursor could not be written",
|
|
69512
|
+
error
|
|
69513
|
+
);
|
|
69514
|
+
}
|
|
69515
|
+
}
|
|
69516
|
+
}
|
|
68847
69517
|
function titlebarOptions(platform, chrome) {
|
|
68848
69518
|
if (platform === "darwin") {
|
|
68849
69519
|
return { titleBarStyle: "hidden" };
|
|
@@ -77317,6 +77987,25 @@ function createApplicationMenu() {
|
|
|
77317
77987
|
{
|
|
77318
77988
|
label: "View",
|
|
77319
77989
|
submenu: [
|
|
77990
|
+
{
|
|
77991
|
+
id: "app-new-tab",
|
|
77992
|
+
label: "New Browser Tab",
|
|
77993
|
+
accelerator: "CmdOrCtrl+T",
|
|
77994
|
+
/*
|
|
77995
|
+
* THE NATIVE ACCELERATOR ROUTE FOR CMD+T, which had no menu item at all.
|
|
77996
|
+
* The browser owns the command through the same predicate as Reload
|
|
77997
|
+
* (`ownsPage` for a focused driven page, `ownsChrome` for browser chrome);
|
|
77998
|
+
* outside the browser this is deliberately a no-op, never a window close.
|
|
77999
|
+
* When the chrome's own `before-input-event` already claimed the press it
|
|
78000
|
+
* prevents this accelerator, so rapid/legit presses stay exactly once.
|
|
78001
|
+
*/
|
|
78002
|
+
click: (_item, target2) => runBrowserMenuAction(
|
|
78003
|
+
"new-tab",
|
|
78004
|
+
target2,
|
|
78005
|
+
mainWindow,
|
|
78006
|
+
routeBrowserMenu
|
|
78007
|
+
)
|
|
78008
|
+
},
|
|
77320
78009
|
{
|
|
77321
78010
|
id: "app-reload",
|
|
77322
78011
|
label: "Reload",
|
|
@@ -78160,6 +78849,28 @@ electron.app.whenReady().then(async () => {
|
|
|
78160
78849
|
// line is what tells that trigger apart from the other four.
|
|
78161
78850
|
reportRaise
|
|
78162
78851
|
);
|
|
78852
|
+
const teamBridgeNotifier = new TeamBridgeNotifier({
|
|
78853
|
+
window: () => mainWindow,
|
|
78854
|
+
show: windowLaunch.show,
|
|
78855
|
+
icon: image,
|
|
78856
|
+
store: new TeamBridgeNotifyStore(
|
|
78857
|
+
path$1.join(electron.app.getPath("userData"), "team-bridge-notifications.json"),
|
|
78858
|
+
(message, error) => logger.warn(`${message}: ${String(error)}`, LogFileType.BACKEND)
|
|
78859
|
+
),
|
|
78860
|
+
host: {
|
|
78861
|
+
signalOpen: () => {
|
|
78862
|
+
const window = mainWindow;
|
|
78863
|
+
if (window && !window.isDestroyed()) {
|
|
78864
|
+
window.webContents.send("team-bridge:open");
|
|
78865
|
+
}
|
|
78866
|
+
},
|
|
78867
|
+
reopen: () => electron.app.emit("activate")
|
|
78868
|
+
},
|
|
78869
|
+
present: (window) => raiseWindow(window, windowLaunch.show, {
|
|
78870
|
+
trigger: "banner-click",
|
|
78871
|
+
report: reportRaise
|
|
78872
|
+
})
|
|
78873
|
+
});
|
|
78163
78874
|
backendService.onBackendReady(() => {
|
|
78164
78875
|
void desktopNotifier.refreshNotificationContract();
|
|
78165
78876
|
void backendService.getDesktopFeedRelay().start();
|
|
@@ -78432,7 +79143,8 @@ electron.app.whenReady().then(async () => {
|
|
|
78432
79143
|
* same instance `createWindow` gave the navigation guard: the arm channel
|
|
78433
79144
|
* and the guard are two halves of one decision and must share one list.
|
|
78434
79145
|
*/
|
|
78435
|
-
supplementMounts
|
|
79146
|
+
supplementMounts,
|
|
79147
|
+
teamBridgeNotifier
|
|
78436
79148
|
);
|
|
78437
79149
|
if (devDriverArming.armed && devDriverArming.outDir) {
|
|
78438
79150
|
registerDevDriverIPC({
|