local-operator-ui 0.36.7 → 0.36.9
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 +874 -30
- package/out/preload/index.js +42 -1
- package/out/renderer/assets/{_basePickBy-Cp4-k2Ra.js → _basePickBy-DMcJ3S7k.js} +1 -1
- package/out/renderer/assets/{_baseUniq-SW_cXbV_.js → _baseUniq-D1lM95PP.js} +1 -1
- package/out/renderer/assets/{agent-details-page-N3zxLs5x.js → agent-details-page-BtlkMdIG.js} +2 -2
- package/out/renderer/assets/{agent-hub-page-BlZWarvE.js → agent-hub-page-CvnosPnb.js} +2 -2
- package/out/renderer/assets/{agents-page-C7c-PG8v.js → agents-page-C3p0casO.js} +3 -3
- package/out/renderer/assets/{arc-CH4PDipB.js → arc-DsWPhFjP.js} +1 -1
- package/out/renderer/assets/{architectureDiagram-IEHRJDOE-YJo8Ggxb.js → architectureDiagram-IEHRJDOE-DNfaqYw7.js} +1 -1
- package/out/renderer/assets/{arrow-up-BB9CxXVA.js → arrow-up-Begz0H6P.js} +1 -1
- package/out/renderer/assets/{blockDiagram-JOT3LUYC-rOqQnp0E.js → blockDiagram-JOT3LUYC-BJENelAS.js} +1 -1
- package/out/renderer/assets/{book-open-DkVxCJ61.js → book-open-5BRzSc1Z.js} +1 -1
- package/out/renderer/assets/browser-page-Dwy1BXTz.js +1 -0
- package/out/renderer/assets/{browser-webauthn-prompt-Dna4BiM9.js → browser-webauthn-prompt-yiiGM34k.js} +1 -1
- package/out/renderer/assets/{building-2-CavXM_-r.js → building-2-T3OwRXqF.js} +1 -1
- package/out/renderer/assets/{c4Diagram-VJAJSXHY-DEPLadlT.js → c4Diagram-VJAJSXHY-CEijvBuX.js} +1 -1
- package/out/renderer/assets/channel-BuIK1RR0.js +1 -0
- package/out/renderer/assets/{chunk-4BMEZGHF-klJwtJH4.js → chunk-4BMEZGHF-CtdEc_y-.js} +1 -1
- package/out/renderer/assets/{chunk-A2AXSNBT-DRT8OSGB.js → chunk-A2AXSNBT-DzhnEf46.js} +1 -1
- package/out/renderer/assets/{chunk-AEK57VVT-kqK_zO-a.js → chunk-AEK57VVT-BNPXglh5.js} +1 -1
- package/out/renderer/assets/{chunk-D6G4REZN-CJZaq5OR.js → chunk-D6G4REZN-xyBvlSTD.js} +1 -1
- package/out/renderer/assets/{chunk-RZ5BOZE2-D4tpPnZf.js → chunk-RZ5BOZE2-8dmoMKQZ.js} +1 -1
- package/out/renderer/assets/{chunk-XZIHB7SX-D4Kppo6Q.js → chunk-XZIHB7SX-DLfyXOIE.js} +1 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-CcLuC1It.js +1 -0
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-CcLuC1It.js +1 -0
- package/out/renderer/assets/clone-C-B3TV1U.js +1 -0
- package/out/renderer/assets/{console-mirror-BOyWikJU.js → console-mirror-Ddv0LHdM.js} +1 -1
- package/out/renderer/assets/{consoleCapture-Ctr4ZgwO.js → consoleCapture-Cm0PxzNK.js} +1 -1
- package/out/renderer/assets/{conversation-input-sync-DdFRR8Sk.js → conversation-input-sync-i6ilfEnc.js} +271 -271
- package/out/renderer/assets/{dagre-OKDRZEBW-ZzTMDgQF.js → dagre-OKDRZEBW-Dob_U_wx.js} +1 -1
- package/out/renderer/assets/{diagram-SSKATNLV-D-OEK7di.js → diagram-SSKATNLV-Dh8_PC2b.js} +1 -1
- package/out/renderer/assets/{diagram-VNBRO52H-CM6lMapK.js → diagram-VNBRO52H-NZ9qo5oG.js} +1 -1
- package/out/renderer/assets/{erDiagram-Q7BY3M3F-2khnybxo.js → erDiagram-Q7BY3M3F-BOUqITNj.js} +1 -1
- package/out/renderer/assets/{error-boundary-B2fmvLyi.js → error-boundary-LwhkYl0Z.js} +2 -2
- package/out/renderer/assets/{flowDiagram-4HSFHLVR-PmXhc4g8.js → flowDiagram-4HSFHLVR-CZiUXOWe.js} +1 -1
- package/out/renderer/assets/{ganttDiagram-APWFNJXF-DXqSjI8D.js → ganttDiagram-APWFNJXF-DqweVTOi.js} +1 -1
- package/out/renderer/assets/{gitGraphDiagram-7IBYFJ6S-CE0xYGI6.js → gitGraphDiagram-7IBYFJ6S-KbIhBWBs.js} +1 -1
- package/out/renderer/assets/{graph-ydqZFY1l.js → graph-O8aHYPDC.js} +1 -1
- package/out/renderer/assets/{hash-Dc3JifaZ.js → hash-WYoE1Khd.js} +1 -1
- package/out/renderer/assets/index-6crVx9hx.js +57 -0
- package/out/renderer/assets/index-D4j9Ycfd.js +7 -0
- package/out/renderer/assets/index-D8fns19J.js +1 -0
- package/out/renderer/assets/index-O8V3Lal4.css +1 -0
- package/out/renderer/assets/index-Re5k_KqO.js +824 -0
- package/out/renderer/assets/{infoDiagram-PH2N3AL5-DOZ3-Qro.js → infoDiagram-PH2N3AL5-DU0dbmt7.js} +1 -1
- package/out/renderer/assets/{installer-DWToCmOf.js → installer-C-rmt1Yr.js} +1 -1
- package/out/renderer/assets/{journeyDiagram-U35MCT3I-DWis6Sd2.js → journeyDiagram-U35MCT3I-DUybkPWl.js} +1 -1
- package/out/renderer/assets/{kanban-definition-NDS4AKOZ-B9e7wrf9.js → kanban-definition-NDS4AKOZ-onKwvi0l.js} +1 -1
- package/out/renderer/assets/{layout-CAcs3Q5o.js → layout-RKbPA5d2.js} +1 -1
- package/out/renderer/assets/{legacy-agents-page-DrGkO870.js → legacy-agents-page-DmUlGbZ_.js} +5 -5
- package/out/renderer/assets/{library-page-J-oYtewu.js → library-page-CsUF7SOa.js} +3 -3
- package/out/renderer/assets/{mermaid.core-BKDqOsvz.js → mermaid.core-DdYe4AYl.js} +5 -5
- package/out/renderer/assets/mesh-page-CW4tQHZJ.js +1 -0
- package/out/renderer/assets/{mindmap-definition-ALO5MXBD-B8ubJP7r.js → mindmap-definition-ALO5MXBD-DrsGVqDZ.js} +1 -1
- package/out/renderer/assets/{mini-CSnAsFlT.js → mini-CHtVBEDV.js} +1 -1
- package/out/renderer/assets/{notebook-pen-eF7NwmC0.js → notebook-pen-BHmA9Aor.js} +1 -1
- package/out/renderer/assets/{org-access-CJDIOfTA.js → org-access-Bqdb8uRz.js} +1 -1
- package/out/renderer/assets/{org-surface-gate-BFLSYyz1.js → org-surface-gate-UD-oXlvB.js} +1 -1
- package/out/renderer/assets/{page-header-BMDtYfV0.js → page-header-CoSSp6Ks.js} +1 -1
- package/out/renderer/assets/{pieDiagram-IB7DONF6-C4Lho4yQ.js → pieDiagram-IB7DONF6-C0gYyuJA.js} +1 -1
- package/out/renderer/assets/projects-page-DU4wZXNY.js +45 -0
- package/out/renderer/assets/publication-validation-D4Bef-1h.js +1 -0
- package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-DauXMmcp.js → quadrantDiagram-7GDLP6J5-DbEt_1Ti.js} +1 -1
- package/out/renderer/assets/{radar-MK3ICKWK-_FJ6NjKi.js → radar-MK3ICKWK-BCsS7AKJ.js} +1 -1
- package/out/renderer/assets/{radient-auth-buttons-B4LrTMwy.js → radient-auth-buttons-vBcfzZdx.js} +1 -1
- package/out/renderer/assets/{requirementDiagram-KVF5MWMF-BBMnxRwM.js → requirementDiagram-KVF5MWMF-C3WoUU_2.js} +1 -1
- package/out/renderer/assets/{sankeyDiagram-QLVOVGJD-ZAgJNulV.js → sankeyDiagram-QLVOVGJD-vE9T4I2u.js} +1 -1
- package/out/renderer/assets/{schedules-page-BDxSAX-g.js → schedules-page-CGCopxbo.js} +1 -1
- package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-ixhBbax-.js → sequenceDiagram-X6HHIX6F-CqwLiiP3.js} +1 -1
- package/out/renderer/assets/settings-page-DrZcB4mR.js +287 -0
- package/out/renderer/assets/{smartart-CsYIjueA.js → smartart-C6SIDcio.js} +1 -1
- package/out/renderer/assets/{stateDiagram-DGXRK772-Cyo1D1sd.js → stateDiagram-DGXRK772-W9r7i0O7.js} +1 -1
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-cX4iVUJF.js +1 -0
- package/out/renderer/assets/{tags-input-chips-DeSDZmGf.js → tags-input-chips-CqW7e8j3.js} +1 -1
- package/out/renderer/assets/team-bridge-page-Dt4lEU3y.js +11 -0
- package/out/renderer/assets/{timeline-definition-BDJGKUSR-dHKNC0_-.js → timeline-definition-BDJGKUSR-QYcBKPg2.js} +1 -1
- package/out/renderer/assets/ui-preferences-store-BWYRkg79.js +1 -0
- package/out/renderer/assets/{use-download-agent-mutation-Du8Okjj5.js → use-download-agent-mutation-CNw_prc9.js} +5 -5
- package/out/renderer/assets/{use-session-snapshot-hoogT7-L.js → use-session-snapshot-CzQdg29b.js} +1 -1
- package/out/renderer/assets/{xychartDiagram-VJFVF3MP-y9FbutsK.js → xychartDiagram-VJFVF3MP-B37S1SAD.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-Dr5j9bQE.js +0 -1
- package/out/renderer/assets/channel-BUsgjri2.js +0 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-YCOFP_Sl.js +0 -1
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-YCOFP_Sl.js +0 -1
- package/out/renderer/assets/clone-DVoefRFN.js +0 -1
- package/out/renderer/assets/index-BHi1lUGF.js +0 -1
- package/out/renderer/assets/index-BoPP-Dip.js +0 -7
- package/out/renderer/assets/index-DY17TKlm.js +0 -824
- package/out/renderer/assets/index-Doo51Mbi.js +0 -57
- package/out/renderer/assets/index-JreDTE2U.css +0 -1
- package/out/renderer/assets/mesh-page-CHZ2qVtJ.js +0 -1
- package/out/renderer/assets/projects-page-CNUJUnDM.js +0 -40
- package/out/renderer/assets/publication-validation-5oR6aluM.js +0 -1
- package/out/renderer/assets/settings-page-DpSl6AZf.js +0 -287
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-BylkQbLa.js +0 -1
- package/out/renderer/assets/team-bridge-page-BnsNoiEd.js +0 -1
- package/out/renderer/assets/ui-preferences-store-CFbBU1td.js +0 -1
- package/out/renderer/assets/use-memberships-query-C0ico4nv.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) {
|
|
@@ -33259,6 +33314,12 @@ const enUiBrowser = {
|
|
|
33259
33314
|
"ui.browser.browser_tab_strip.unmute_tab": "Unmute tab",
|
|
33260
33315
|
"ui.browser.browser_tab_strip.watch": 'Watch "{title}"',
|
|
33261
33316
|
"ui.browser.browser_url_bar.address": "Address",
|
|
33317
|
+
"ui.browser.browser_url_bar.address_required": "Enter a web address or choose a suggestion.",
|
|
33318
|
+
"ui.browser.browser_url_bar.address_suggestions_available": "{count, plural, one {{count, number, ::group-off} suggestion available} other {{count, number, ::group-off} suggestions available}}",
|
|
33319
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "No links from these tabs yet.",
|
|
33320
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "From this browser session",
|
|
33321
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "No matching links from this browser session.",
|
|
33322
|
+
"ui.browser.browser_url_bar.address_suggestions_unavailable": "Address suggestions are unavailable.",
|
|
33262
33323
|
"ui.browser.browser_url_bar.approvals_waiting": "Approvals, {count, plural, other {{count, number, ::group-off} waiting}}",
|
|
33263
33324
|
"ui.browser.browser_url_bar.back": "Back",
|
|
33264
33325
|
"ui.browser.browser_url_bar.back_shortcut": "Back ({shortcut})",
|
|
@@ -33524,7 +33585,26 @@ const enUiChatTags = {
|
|
|
33524
33585
|
"ui.chat.tags.move_undone": "Tag move undone",
|
|
33525
33586
|
"ui.chat.tags.move_title": "Move “{title}”",
|
|
33526
33587
|
"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."
|
|
33588
|
+
"ui.chat.tags.move_failed": "Tags were not moved. Try again.",
|
|
33589
|
+
"ui.chat.tags.selection_count": "{count} of 8",
|
|
33590
|
+
"ui.chat.tags.registry_count": "{count} of 32",
|
|
33591
|
+
"ui.chat.tags.create_name": "Create “{name}”",
|
|
33592
|
+
"ui.chat.tags.create_helper": "Saved for all conversations",
|
|
33593
|
+
"ui.chat.tags.selection_limit": "Choose up to 8 tags",
|
|
33594
|
+
"ui.chat.tags.registry_limit": "You can have up to 32 tags",
|
|
33595
|
+
"ui.chat.tags.name_long": "Use 1–24 characters",
|
|
33596
|
+
"ui.chat.tags.name_reserved": "“Untagged” is reserved",
|
|
33597
|
+
"ui.chat.tags.create_failed": "Tag was not created. Try again.",
|
|
33598
|
+
"ui.chat.tags.remove_named": "Remove {name}",
|
|
33599
|
+
"ui.chat.tags.reorder_filtered": "Clear search to reorder tags",
|
|
33600
|
+
"ui.chat.tags.created_name": "Created “{name}”",
|
|
33601
|
+
"ui.chat.tags.selection_status": "{count} selected. Group under {name}.",
|
|
33602
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# conversation} other {# conversations}}",
|
|
33603
|
+
"ui.chat.tags.create_pending": "Saving tag…",
|
|
33604
|
+
"ui.chat.tags.remote": "Tags cannot be changed on a remote conversation.",
|
|
33605
|
+
"ui.chat.tags.renamed_name": "Renamed to “{name}”",
|
|
33606
|
+
"ui.chat.tags.staged_added": "Added “{name}” to draft",
|
|
33607
|
+
"ui.chat.tags.registry_changed": "Some tags changed elsewhere. Review your selection."
|
|
33528
33608
|
};
|
|
33529
33609
|
const enUiChatTranscriptCopy = {
|
|
33530
33610
|
"ui.chat.transcript_copy.menu.copy_text": "Copy text",
|
|
@@ -33534,7 +33614,8 @@ const enUiChatTranscriptCopy = {
|
|
|
33534
33614
|
"ui.chat.transcript_copy.toast.copied_selection": "Copied selection",
|
|
33535
33615
|
"ui.chat.transcript_copy.row.your_message": "Your message",
|
|
33536
33616
|
"ui.chat.transcript_copy.row.agent_message": "Agent message",
|
|
33537
|
-
"ui.chat.transcript_copy.selection.copy": "Copy selection"
|
|
33617
|
+
"ui.chat.transcript_copy.selection.copy": "Copy selection",
|
|
33618
|
+
"ui.chat.transcript_copy.selection.toolbar": "Selection actions"
|
|
33538
33619
|
};
|
|
33539
33620
|
const enUiCodeReview = {
|
|
33540
33621
|
"ui.code_review.activity.close": "closed",
|
|
@@ -35031,10 +35112,18 @@ const enUiProjects = {
|
|
|
35031
35112
|
"ui.projects.project_todos.no_to_do_snapshots_from_the_linked_sessions_yet_a_session_publish": "No to-do snapshots from the linked sessions yet. A session publishes its list as it works, and it appears here once it has.",
|
|
35032
35113
|
"ui.projects.project_todos.to_dos": "To-dos",
|
|
35033
35114
|
"ui.projects.project_updates.attachment": "Attachment",
|
|
35115
|
+
"ui.projects.project_updates.attachments": "Attachments",
|
|
35034
35116
|
"ui.projects.project_updates.file_actions_for_name": "File actions for {name}",
|
|
35035
35117
|
"ui.projects.project_updates.loading": "Loading ",
|
|
35036
35118
|
"ui.projects.project_updates.no_updates_yet_progress_reported_by_you_or_by_the_sessions_workin": "No updates yet. Progress reported by you or by the sessions working on this project is appended here.",
|
|
35037
35119
|
"ui.projects.project_updates.open_name": "Open {name}",
|
|
35120
|
+
"ui.projects.project_updates.play_name": "Play {name}",
|
|
35121
|
+
"ui.projects.project_updates.preview_failed": "This file could not be opened.",
|
|
35122
|
+
"ui.projects.project_updates.preview_loading": "Loading preview…",
|
|
35123
|
+
"ui.projects.project_updates.preview_moved": "Its stored copy may have moved or was deleted.",
|
|
35124
|
+
"ui.projects.project_updates.preview_unavailable": "Preview is unavailable outside the desktop app.",
|
|
35125
|
+
"ui.projects.project_updates.preview_name": "Preview {name}",
|
|
35126
|
+
"ui.projects.project_updates.show_asset_name": "Show {name}, asset {index} of {count}",
|
|
35038
35127
|
"ui.projects.project_updates.updates": "Updates",
|
|
35039
35128
|
"ui.projects.projects_page.checking_the_server_s_projects_support": "Checking the server's Projects support",
|
|
35040
35129
|
"ui.projects.projects_page.clear_all": "Clear all",
|
|
@@ -36212,7 +36301,23 @@ const enUiTeamBridge = {
|
|
|
36212
36301
|
"ui.teamBridge.scope.unknown": "Unknown organization",
|
|
36213
36302
|
"ui.teamBridge.scope.thread_unknown": "This conversation's organization is not available.",
|
|
36214
36303
|
"ui.teamBridge.scope.create_needs_org": "Choose an organization to start a conversation.",
|
|
36215
|
-
"ui.teamBridge.group.more_unread": "{count, plural, one {More destinations, # unread message} other {More destinations, # unread messages}}"
|
|
36304
|
+
"ui.teamBridge.group.more_unread": "{count, plural, one {More destinations, # unread message} other {More destinations, # unread messages}}",
|
|
36305
|
+
"ui.teamBridge.preview.chip": "Preview",
|
|
36306
|
+
"ui.teamBridge.preview.banner": "You’re previewing this channel. Join to see its history and get notifications.",
|
|
36307
|
+
"ui.teamBridge.preview.join": "Join",
|
|
36308
|
+
"ui.teamBridge.preview.join_error": "You could not join this channel. Try again.",
|
|
36309
|
+
"ui.teamBridge.menu.label": "Conversation options",
|
|
36310
|
+
"ui.teamBridge.menu.mute": "Mute conversation",
|
|
36311
|
+
"ui.teamBridge.menu.unmute": "Unmute conversation",
|
|
36312
|
+
"ui.teamBridge.notify.label": "Notification preferences",
|
|
36313
|
+
"ui.teamBridge.notify.all": "All messages",
|
|
36314
|
+
"ui.teamBridge.notify.mention": "Mentions",
|
|
36315
|
+
"ui.teamBridge.notify.mute": "Mute",
|
|
36316
|
+
"ui.teamBridge.notify.muted": "Muted",
|
|
36317
|
+
"ui.teamBridge.notify.error": "Your notification preference was not saved. Try again.",
|
|
36318
|
+
"ui.teamBridge.notify.title": "{conversation} ({organization})",
|
|
36319
|
+
"ui.teamBridge.notify.body": "{sender} sent a message",
|
|
36320
|
+
"ui.teamBridge.notify.body_fallback": "New message"
|
|
36216
36321
|
};
|
|
36217
36322
|
const esUiAgentMessages = {
|
|
36218
36323
|
"ui.agentMessages.dialog.title": "Mensajes de agentes en Radient",
|
|
@@ -36627,6 +36732,12 @@ const esUiBrowser = {
|
|
|
36627
36732
|
"ui.browser.browser_url_bar.stop_loading": "Detener carga",
|
|
36628
36733
|
"ui.browser.browser_url_bar.reload": "Recargar",
|
|
36629
36734
|
"ui.browser.browser_url_bar.address": "Dirección",
|
|
36735
|
+
"ui.browser.browser_url_bar.address_required": "Escribe una dirección web o elige una sugerencia.",
|
|
36736
|
+
"ui.browser.browser_url_bar.address_suggestions_available": "{count, plural, one {{count, number, ::group-off} sugerencia disponible} other {{count, number, ::group-off} sugerencias disponibles}}",
|
|
36737
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "Aún no hay enlaces de estas pestañas.",
|
|
36738
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "De esta sesión del navegador",
|
|
36739
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "No hay enlaces que coincidan en esta sesión del navegador.",
|
|
36740
|
+
"ui.browser.browser_url_bar.address_suggestions_unavailable": "Las sugerencias de direcciones no están disponibles.",
|
|
36630
36741
|
"ui.browser.browser_url_bar.approvals_waiting": "Aprobaciones, {count, plural, other {{count, number, ::group-off} en espera}}",
|
|
36631
36742
|
"ui.browser.browser_url_bar.home_destination": "Inicio — ir a la página inicial (en blanco)",
|
|
36632
36743
|
"ui.browser.browser_url_bar.site_unverified": "No se pudo verificar la conexión con {origin}",
|
|
@@ -36892,7 +37003,26 @@ const esUiChatTags = {
|
|
|
36892
37003
|
"ui.chat.tags.move_undone": "Movimiento de etiquetas deshecho",
|
|
36893
37004
|
"ui.chat.tags.move_title": "Mover «{title}»",
|
|
36894
37005
|
"ui.chat.tags.move_description": "Elige una etiqueta para hacerla principal, o Sin etiqueta para eliminar todas las etiquetas.",
|
|
36895
|
-
"ui.chat.tags.move_failed": "No se han movido las etiquetas. Inténtalo de nuevo."
|
|
37006
|
+
"ui.chat.tags.move_failed": "No se han movido las etiquetas. Inténtalo de nuevo.",
|
|
37007
|
+
"ui.chat.tags.selection_count": "{count} de 8",
|
|
37008
|
+
"ui.chat.tags.registry_count": "{count} de 32",
|
|
37009
|
+
"ui.chat.tags.create_name": "Crear «{name}»",
|
|
37010
|
+
"ui.chat.tags.create_helper": "Se guarda para todas las conversaciones",
|
|
37011
|
+
"ui.chat.tags.selection_limit": "Elige hasta 8 etiquetas",
|
|
37012
|
+
"ui.chat.tags.registry_limit": "Puedes tener hasta 32 etiquetas",
|
|
37013
|
+
"ui.chat.tags.name_long": "Usa entre 1 y 24 caracteres",
|
|
37014
|
+
"ui.chat.tags.name_reserved": "«Untagged» es un nombre reservado",
|
|
37015
|
+
"ui.chat.tags.create_failed": "No se ha creado la etiqueta. Inténtalo de nuevo.",
|
|
37016
|
+
"ui.chat.tags.remove_named": "Quitar {name}",
|
|
37017
|
+
"ui.chat.tags.reorder_filtered": "Borra la búsqueda para reordenar las etiquetas",
|
|
37018
|
+
"ui.chat.tags.created_name": "Se ha creado «{name}»",
|
|
37019
|
+
"ui.chat.tags.selection_status": "Selección: {count}. Agrupar en {name}.",
|
|
37020
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# conversación} many {# de conversaciones} other {# conversaciones}}",
|
|
37021
|
+
"ui.chat.tags.create_pending": "Guardando etiqueta…",
|
|
37022
|
+
"ui.chat.tags.remote": "No se pueden cambiar las etiquetas de una conversación remota.",
|
|
37023
|
+
"ui.chat.tags.renamed_name": "Se ha cambiado el nombre a «{name}»",
|
|
37024
|
+
"ui.chat.tags.staged_added": "Se ha añadido «{name}» al borrador",
|
|
37025
|
+
"ui.chat.tags.registry_changed": "Algunas etiquetas han cambiado en otro lugar. Revisa la selección."
|
|
36896
37026
|
};
|
|
36897
37027
|
const esUiCodeReview = {
|
|
36898
37028
|
"ui.code_review.activity.close": "cerraste",
|
|
@@ -38224,10 +38354,18 @@ const esUiProjects = {
|
|
|
38224
38354
|
"ui.projects.project_todos.no_to_do_snapshots_from_the_linked_sessions_yet_a_session_publish": "Aún no hay instantáneas de tareas pendientes de las sesiones vinculadas. Una sesión publica su lista a medida que trabaja, y aparecerá aquí cuando lo haga.",
|
|
38225
38355
|
"ui.projects.project_todos.to_dos": "Tareas pendientes",
|
|
38226
38356
|
"ui.projects.project_updates.attachment": "Adjunto",
|
|
38357
|
+
"ui.projects.project_updates.attachments": "Adjuntos",
|
|
38227
38358
|
"ui.projects.project_updates.file_actions_for_name": "Acciones de archivo para {name}",
|
|
38228
38359
|
"ui.projects.project_updates.loading": "Cargando ",
|
|
38229
38360
|
"ui.projects.project_updates.no_updates_yet_progress_reported_by_you_or_by_the_sessions_workin": "Aún no hay actualizaciones. El progreso que informes tú o las sesiones que trabajan en este proyecto se añade aquí.",
|
|
38230
38361
|
"ui.projects.project_updates.open_name": "Abrir {name}",
|
|
38362
|
+
"ui.projects.project_updates.play_name": "Reproducir {name}",
|
|
38363
|
+
"ui.projects.project_updates.preview_failed": "No se pudo abrir este archivo.",
|
|
38364
|
+
"ui.projects.project_updates.preview_loading": "Cargando vista previa…",
|
|
38365
|
+
"ui.projects.project_updates.preview_moved": "Su copia guardada puede haberse movido o eliminado.",
|
|
38366
|
+
"ui.projects.project_updates.preview_name": "Vista previa de {name}",
|
|
38367
|
+
"ui.projects.project_updates.preview_unavailable": "La vista previa no está disponible fuera de la aplicación de escritorio.",
|
|
38368
|
+
"ui.projects.project_updates.show_asset_name": "Mostrar {name}, recurso {index} de {count}",
|
|
38231
38369
|
"ui.projects.project_updates.updates": "Actualizaciones",
|
|
38232
38370
|
"ui.projects.projects_page.checking_the_server_s_projects_support": "Comprobando la compatibilidad del servidor con Proyectos",
|
|
38233
38371
|
"ui.projects.projects_page.clear_all": "Borrar todo",
|
|
@@ -39767,6 +39905,12 @@ const frUiBrowser = {
|
|
|
39767
39905
|
"ui.browser.browser_url_bar.stop_loading": "Arrêter le chargement",
|
|
39768
39906
|
"ui.browser.browser_url_bar.reload": "Recharger",
|
|
39769
39907
|
"ui.browser.browser_url_bar.address": "Adresse",
|
|
39908
|
+
"ui.browser.browser_url_bar.address_required": "Saisissez une adresse web ou choisissez une suggestion.",
|
|
39909
|
+
"ui.browser.browser_url_bar.address_suggestions_available": "{count, plural, one {{count, number, ::group-off} suggestion disponible} many {{count, number, ::group-off} de suggestions disponibles} other {{count, number, ::group-off} suggestions disponibles}}",
|
|
39910
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "Aucun lien de ces onglets pour l’instant.",
|
|
39911
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "De cette session de navigation",
|
|
39912
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "Aucun lien correspondant dans cette session de navigation.",
|
|
39913
|
+
"ui.browser.browser_url_bar.address_suggestions_unavailable": "Les suggestions d’adresses ne sont pas disponibles.",
|
|
39770
39914
|
"ui.browser.browser_url_bar.approvals_waiting": "Approbations, {count, plural, one {{count, number, ::group-off} en attente} many {{count, number, ::group-off} en attente} other {{count, number, ::group-off} en attente}}",
|
|
39771
39915
|
"ui.browser.browser_url_bar.home_destination": "Accueil — aller à la page de départ (vide)",
|
|
39772
39916
|
"ui.browser.browser_url_bar.site_unverified": "La connexion à {origin} n’a pas pu être vérifiée",
|
|
@@ -40032,7 +40176,26 @@ const frUiChatTags = {
|
|
|
40032
40176
|
"ui.chat.tags.move_undone": "Déplacement des étiquettes annulé",
|
|
40033
40177
|
"ui.chat.tags.move_title": "Déplacer « {title} »",
|
|
40034
40178
|
"ui.chat.tags.move_description": "Choisissez une étiquette principale, ou Sans étiquette pour retirer toutes les étiquettes.",
|
|
40035
|
-
"ui.chat.tags.move_failed": "Les étiquettes n’ont pas été déplacées. Réessayez."
|
|
40179
|
+
"ui.chat.tags.move_failed": "Les étiquettes n’ont pas été déplacées. Réessayez.",
|
|
40180
|
+
"ui.chat.tags.selection_count": "{count} sur 8",
|
|
40181
|
+
"ui.chat.tags.registry_count": "{count} sur 32",
|
|
40182
|
+
"ui.chat.tags.create_name": "Créer « {name} »",
|
|
40183
|
+
"ui.chat.tags.create_helper": "Enregistré pour toutes les conversations",
|
|
40184
|
+
"ui.chat.tags.selection_limit": "Choisissez jusqu’à 8 étiquettes",
|
|
40185
|
+
"ui.chat.tags.registry_limit": "Vous pouvez avoir jusqu’à 32 étiquettes",
|
|
40186
|
+
"ui.chat.tags.name_long": "Utilisez de 1 à 24 caractères",
|
|
40187
|
+
"ui.chat.tags.name_reserved": "« Untagged » est un nom réservé",
|
|
40188
|
+
"ui.chat.tags.create_failed": "L’étiquette n’a pas été créée. Réessayez.",
|
|
40189
|
+
"ui.chat.tags.remove_named": "Retirer {name}",
|
|
40190
|
+
"ui.chat.tags.reorder_filtered": "Effacez la recherche pour réordonner les étiquettes",
|
|
40191
|
+
"ui.chat.tags.created_name": "« {name} » a été créée",
|
|
40192
|
+
"ui.chat.tags.selection_status": "{count} sélectionnées. Regrouper sous {name}.",
|
|
40193
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# conversation} many {# de conversations} other {# conversations}}",
|
|
40194
|
+
"ui.chat.tags.create_pending": "Enregistrement de l’étiquette…",
|
|
40195
|
+
"ui.chat.tags.remote": "Les étiquettes d’une conversation distante ne peuvent pas être modifiées.",
|
|
40196
|
+
"ui.chat.tags.renamed_name": "Renommée « {name} »",
|
|
40197
|
+
"ui.chat.tags.staged_added": "« {name} » a été ajoutée au brouillon",
|
|
40198
|
+
"ui.chat.tags.registry_changed": "Des étiquettes ont été modifiées ailleurs. Vérifiez votre sélection."
|
|
40036
40199
|
};
|
|
40037
40200
|
const frUiCodeReview = {
|
|
40038
40201
|
"ui.code_review.activity.close": "avez fermé",
|
|
@@ -41364,10 +41527,18 @@ const frUiProjects = {
|
|
|
41364
41527
|
"ui.projects.project_todos.no_to_do_snapshots_from_the_linked_sessions_yet_a_session_publish": "Aucun instantané de tâches provenant des sessions liées pour l’instant. Une session publie sa liste au fil du travail, et elle apparaît ici dès qu’elle l’a fait.",
|
|
41365
41528
|
"ui.projects.project_todos.to_dos": "Tâches",
|
|
41366
41529
|
"ui.projects.project_updates.attachment": "Pièce jointe",
|
|
41530
|
+
"ui.projects.project_updates.attachments": "Pièces jointes",
|
|
41367
41531
|
"ui.projects.project_updates.file_actions_for_name": "Actions de fichier pour {name}",
|
|
41368
41532
|
"ui.projects.project_updates.loading": "Chargement ",
|
|
41369
41533
|
"ui.projects.project_updates.no_updates_yet_progress_reported_by_you_or_by_the_sessions_workin": "Aucune mise à jour pour l’instant. Les progrès signalés par vous ou par les sessions qui travaillent sur ce projet sont ajoutés ici.",
|
|
41370
41534
|
"ui.projects.project_updates.open_name": "Ouvrir {name}",
|
|
41535
|
+
"ui.projects.project_updates.play_name": "Lire {name}",
|
|
41536
|
+
"ui.projects.project_updates.preview_failed": "Impossible d’ouvrir ce fichier.",
|
|
41537
|
+
"ui.projects.project_updates.preview_loading": "Chargement de l’aperçu…",
|
|
41538
|
+
"ui.projects.project_updates.preview_moved": "Sa copie enregistrée a peut-être été déplacée ou supprimée.",
|
|
41539
|
+
"ui.projects.project_updates.preview_name": "Aperçu de {name}",
|
|
41540
|
+
"ui.projects.project_updates.preview_unavailable": "L’aperçu n’est pas disponible en dehors de l’application de bureau.",
|
|
41541
|
+
"ui.projects.project_updates.show_asset_name": "Afficher {name}, élément {index} sur {count}",
|
|
41371
41542
|
"ui.projects.project_updates.updates": "Mises à jour",
|
|
41372
41543
|
"ui.projects.projects_page.checking_the_server_s_projects_support": "Vérification de la prise en charge des projets par le serveur",
|
|
41373
41544
|
"ui.projects.projects_page.clear_all": "Tout effacer",
|
|
@@ -42994,6 +43165,12 @@ const hiUiBrowser = {
|
|
|
42994
43165
|
"ui.browser.browser_tab_strip.unmute_tab": "टैब की आवाज़ चालू करें",
|
|
42995
43166
|
"ui.browser.browser_tab_strip.watch": '"{title}" देखें',
|
|
42996
43167
|
"ui.browser.browser_url_bar.address": "पता",
|
|
43168
|
+
"ui.browser.browser_url_bar.address_required": "वेब पता दर्ज करें या कोई सुझाव चुनें।",
|
|
43169
|
+
"ui.browser.browser_url_bar.address_suggestions_available": "{count, plural, one {{count, number, ::group-off} सुझाव उपलब्ध है} other {{count, number, ::group-off} सुझाव उपलब्ध हैं}}",
|
|
43170
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "इन टैब से अभी कोई लिंक नहीं है।",
|
|
43171
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "इस ब्राउज़र सत्र से",
|
|
43172
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "इस ब्राउज़र सत्र में कोई मेल खाता लिंक नहीं है।",
|
|
43173
|
+
"ui.browser.browser_url_bar.address_suggestions_unavailable": "पते के सुझाव उपलब्ध नहीं हैं।",
|
|
42997
43174
|
"ui.browser.browser_url_bar.approvals_waiting": "स्वीकृतियाँ, {count, plural, other {{count, number, ::group-off} इंतज़ार में}}",
|
|
42998
43175
|
"ui.browser.browser_url_bar.back": "पीछे",
|
|
42999
43176
|
"ui.browser.browser_url_bar.back_shortcut": "पीछे ({shortcut})",
|
|
@@ -43259,7 +43436,26 @@ const hiUiChatTags = {
|
|
|
43259
43436
|
"ui.chat.tags.move_undone": "टैग का ले जाना पूर्ववत किया गया",
|
|
43260
43437
|
"ui.chat.tags.move_title": "“{title}” ले जाएँ",
|
|
43261
43438
|
"ui.chat.tags.move_description": "किसी टैग को प्राथमिक बनाने के लिए उसे चुनें, या सभी टैग हटाने के लिए “बिना टैग” चुनें।",
|
|
43262
|
-
"ui.chat.tags.move_failed": "टैग नहीं ले जाए गए। फिर कोशिश करें।"
|
|
43439
|
+
"ui.chat.tags.move_failed": "टैग नहीं ले जाए गए। फिर कोशिश करें।",
|
|
43440
|
+
"ui.chat.tags.selection_count": "8 में से {count}",
|
|
43441
|
+
"ui.chat.tags.registry_count": "32 में से {count}",
|
|
43442
|
+
"ui.chat.tags.create_name": "“{name}” बनाएँ",
|
|
43443
|
+
"ui.chat.tags.create_helper": "सभी बातचीतों के लिए सहेजा जाता है",
|
|
43444
|
+
"ui.chat.tags.selection_limit": "अधिकतम 8 टैग चुनें",
|
|
43445
|
+
"ui.chat.tags.registry_limit": "आप अधिकतम 32 टैग रख सकते हैं",
|
|
43446
|
+
"ui.chat.tags.name_long": "1–24 अक्षर इस्तेमाल करें",
|
|
43447
|
+
"ui.chat.tags.name_reserved": "“Untagged” नाम आरक्षित है",
|
|
43448
|
+
"ui.chat.tags.create_failed": "टैग नहीं बनाया गया। फिर कोशिश करें।",
|
|
43449
|
+
"ui.chat.tags.remove_named": "{name} हटाएँ",
|
|
43450
|
+
"ui.chat.tags.reorder_filtered": "टैग का क्रम बदलने के लिए खोज साफ़ करें",
|
|
43451
|
+
"ui.chat.tags.created_name": "“{name}” बनाया गया",
|
|
43452
|
+
"ui.chat.tags.selection_status": "{count, plural, =1 {# चुना गया} other {# चुने गए}}। {name} के तहत समूह बनाएँ।",
|
|
43453
|
+
"ui.chat.tags.tag_usage": "{count} बातचीत",
|
|
43454
|
+
"ui.chat.tags.create_pending": "टैग सहेजा जा रहा है…",
|
|
43455
|
+
"ui.chat.tags.remote": "दूरस्थ बातचीत के टैग नहीं बदले जा सकते।",
|
|
43456
|
+
"ui.chat.tags.renamed_name": "नाम बदलकर “{name}” किया गया",
|
|
43457
|
+
"ui.chat.tags.staged_added": "“{name}” मसौदे में जोड़ा गया",
|
|
43458
|
+
"ui.chat.tags.registry_changed": "कुछ टैग कहीं और बदले गए। अपना चयन जाँचें।"
|
|
43263
43459
|
};
|
|
43264
43460
|
const hiUiCodeReview = {
|
|
43265
43461
|
"ui.code_review.activity.close": "बंद किया",
|
|
@@ -44725,10 +44921,18 @@ const hiUiProjects = {
|
|
|
44725
44921
|
"ui.projects.project_todos.no_to_do_snapshots_from_the_linked_sessions_yet_a_session_publish": "जुड़े सत्रों से अभी कार्य सूची का कोई स्नैपशॉट नहीं है। काम करते समय सत्र अपनी सूची प्रकाशित करता है, जिसके बाद वह यहाँ दिखती है।",
|
|
44726
44922
|
"ui.projects.project_todos.to_dos": "कार्य सूची",
|
|
44727
44923
|
"ui.projects.project_updates.attachment": "अटैचमेंट",
|
|
44924
|
+
"ui.projects.project_updates.attachments": "अनुलग्नक",
|
|
44728
44925
|
"ui.projects.project_updates.file_actions_for_name": "{name} की फ़ाइल कार्रवाइयाँ",
|
|
44729
44926
|
"ui.projects.project_updates.loading": "लोड हो रहा है ",
|
|
44730
44927
|
"ui.projects.project_updates.no_updates_yet_progress_reported_by_you_or_by_the_sessions_workin": "अभी कोई अपडेट नहीं है। आपकी या इस प्रोजेक्ट पर काम कर रहे सत्रों की बताई गई प्रगति यहाँ जोड़ी जाती है।",
|
|
44731
44928
|
"ui.projects.project_updates.open_name": "{name} खोलें",
|
|
44929
|
+
"ui.projects.project_updates.play_name": "{name} चलाएँ",
|
|
44930
|
+
"ui.projects.project_updates.preview_failed": "यह फ़ाइल खोली नहीं जा सकी।",
|
|
44931
|
+
"ui.projects.project_updates.preview_loading": "पूर्वावलोकन लोड हो रहा है…",
|
|
44932
|
+
"ui.projects.project_updates.preview_moved": "इसकी संग्रहीत प्रतिलिपि स्थानांतरित या हटा दी गई हो सकती है।",
|
|
44933
|
+
"ui.projects.project_updates.preview_name": "{name} का पूर्वावलोकन",
|
|
44934
|
+
"ui.projects.project_updates.preview_unavailable": "डेस्कटॉप ऐप के बाहर पूर्वावलोकन उपलब्ध नहीं है।",
|
|
44935
|
+
"ui.projects.project_updates.show_asset_name": "{name} दिखाएँ, संपत्ति {index} / {count}",
|
|
44732
44936
|
"ui.projects.project_updates.updates": "अपडेट",
|
|
44733
44937
|
"ui.projects.projects_page.checking_the_server_s_projects_support": "सर्वर पर प्रोजेक्ट सपोर्ट जाँचा जा रहा है",
|
|
44734
44938
|
"ui.projects.projects_page.clear_all": "सभी साफ़ करें",
|
|
@@ -46269,6 +46473,12 @@ const ruUiBrowser = {
|
|
|
46269
46473
|
"ui.browser.browser_tab_strip.unmute_tab": "Включить звук вкладки",
|
|
46270
46474
|
"ui.browser.browser_tab_strip.watch": "Смотреть «{title}»",
|
|
46271
46475
|
"ui.browser.browser_url_bar.address": "Адрес",
|
|
46476
|
+
"ui.browser.browser_url_bar.address_required": "Введите веб-адрес или выберите подсказку.",
|
|
46477
|
+
"ui.browser.browser_url_bar.address_suggestions_available": "{count, plural, one {{count, number, ::group-off} подсказка доступна} few {{count, number, ::group-off} подсказки доступны} many {{count, number, ::group-off} подсказок доступно} other {{count, number, ::group-off} подсказки доступны}}",
|
|
46478
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "В этих вкладках пока нет ссылок.",
|
|
46479
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "Из этой сессии браузера",
|
|
46480
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "В этой сессии браузера нет подходящих ссылок.",
|
|
46481
|
+
"ui.browser.browser_url_bar.address_suggestions_unavailable": "Подсказки адресов недоступны.",
|
|
46272
46482
|
"ui.browser.browser_url_bar.approvals_waiting": "Одобрения, {count, plural, one {ожидает {count, number, ::group-off}} few {ожидают {count, number, ::group-off}} many {ожидают {count, number, ::group-off}} other {ожидают {count, number, ::group-off}}}",
|
|
46273
46483
|
"ui.browser.browser_url_bar.back": "Назад",
|
|
46274
46484
|
"ui.browser.browser_url_bar.back_shortcut": "Назад ({shortcut})",
|
|
@@ -46534,7 +46744,26 @@ const ruUiChatTags = {
|
|
|
46534
46744
|
"ui.chat.tags.move_undone": "Перемещение тега отменено",
|
|
46535
46745
|
"ui.chat.tags.move_title": "Переместить «{title}»",
|
|
46536
46746
|
"ui.chat.tags.move_description": "Выберите основной тег или «Без тега», чтобы удалить все теги.",
|
|
46537
|
-
"ui.chat.tags.move_failed": "Не удалось переместить теги. Попробуйте ещё раз."
|
|
46747
|
+
"ui.chat.tags.move_failed": "Не удалось переместить теги. Попробуйте ещё раз.",
|
|
46748
|
+
"ui.chat.tags.selection_count": "{count} из 8",
|
|
46749
|
+
"ui.chat.tags.registry_count": "{count} из 32",
|
|
46750
|
+
"ui.chat.tags.create_name": "Создать «{name}»",
|
|
46751
|
+
"ui.chat.tags.create_helper": "Сохраняется для всех разговоров",
|
|
46752
|
+
"ui.chat.tags.selection_limit": "Выберите не более 8 тегов",
|
|
46753
|
+
"ui.chat.tags.registry_limit": "Можно создать не более 32 тегов",
|
|
46754
|
+
"ui.chat.tags.name_long": "Используйте от 1 до 24 символов",
|
|
46755
|
+
"ui.chat.tags.name_reserved": "Имя «Untagged» зарезервировано",
|
|
46756
|
+
"ui.chat.tags.create_failed": "Тег не создан. Попробуйте ещё раз.",
|
|
46757
|
+
"ui.chat.tags.remove_named": "Убрать {name}",
|
|
46758
|
+
"ui.chat.tags.reorder_filtered": "Очистите поиск, чтобы изменить порядок тегов",
|
|
46759
|
+
"ui.chat.tags.created_name": "Создан тег «{name}»",
|
|
46760
|
+
"ui.chat.tags.selection_status": "Выбрано: {count}. Основной тег: {name}.",
|
|
46761
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# разговор} few {# разговора} many {# разговоров} other {# разговора}}",
|
|
46762
|
+
"ui.chat.tags.create_pending": "Сохранение тега…",
|
|
46763
|
+
"ui.chat.tags.remote": "Нельзя изменить теги удалённого разговора.",
|
|
46764
|
+
"ui.chat.tags.renamed_name": "Новое имя: «{name}»",
|
|
46765
|
+
"ui.chat.tags.staged_added": "Тег «{name}» добавлен в черновик",
|
|
46766
|
+
"ui.chat.tags.registry_changed": "Некоторые теги изменены в другом месте. Проверьте выбор."
|
|
46538
46767
|
};
|
|
46539
46768
|
const ruUiCodeReview = {
|
|
46540
46769
|
"ui.code_review.activity.close": "закрыли",
|
|
@@ -47866,10 +48095,18 @@ const ruUiProjects = {
|
|
|
47866
48095
|
"ui.projects.project_todos.no_to_do_snapshots_from_the_linked_sessions_yet_a_session_publish": "Снимков списка задач от связанных сессий пока нет. Сессия публикует список по ходу работы, и он появится здесь.",
|
|
47867
48096
|
"ui.projects.project_todos.to_dos": "Задачи",
|
|
47868
48097
|
"ui.projects.project_updates.attachment": "Вложение",
|
|
48098
|
+
"ui.projects.project_updates.attachments": "Вложения",
|
|
47869
48099
|
"ui.projects.project_updates.file_actions_for_name": "Действия с файлом {name}",
|
|
47870
48100
|
"ui.projects.project_updates.loading": "Загрузка ",
|
|
47871
48101
|
"ui.projects.project_updates.no_updates_yet_progress_reported_by_you_or_by_the_sessions_workin": "Обновлений пока нет. Прогресс, о котором сообщили вы или сессии, работающие над проектом, будет добавляться здесь.",
|
|
47872
48102
|
"ui.projects.project_updates.open_name": "Открыть {name}",
|
|
48103
|
+
"ui.projects.project_updates.play_name": "Воспроизвести {name}",
|
|
48104
|
+
"ui.projects.project_updates.preview_failed": "Не удалось открыть этот файл.",
|
|
48105
|
+
"ui.projects.project_updates.preview_loading": "Загрузка предпросмотра…",
|
|
48106
|
+
"ui.projects.project_updates.preview_moved": "Возможно, сохранённая копия была перемещена или удалена.",
|
|
48107
|
+
"ui.projects.project_updates.preview_name": "Предпросмотр {name}",
|
|
48108
|
+
"ui.projects.project_updates.preview_unavailable": "Предпросмотр недоступен вне настольного приложения.",
|
|
48109
|
+
"ui.projects.project_updates.show_asset_name": "Показать {name}, элемент {index} из {count}",
|
|
47873
48110
|
"ui.projects.project_updates.updates": "Обновления",
|
|
47874
48111
|
"ui.projects.projects_page.checking_the_server_s_projects_support": "Проверка поддержки проектов на сервере",
|
|
47875
48112
|
"ui.projects.projects_page.clear_all": "Сбросить всё",
|
|
@@ -49496,6 +49733,12 @@ const urUiBrowser = {
|
|
|
49496
49733
|
"ui.browser.browser_tab_strip.unmute_tab": "ٹیب کی آواز بحال کریں",
|
|
49497
49734
|
"ui.browser.browser_tab_strip.watch": "“{title}” پر نظر رکھیں",
|
|
49498
49735
|
"ui.browser.browser_url_bar.address": "پتہ",
|
|
49736
|
+
"ui.browser.browser_url_bar.address_required": "ویب پتہ درج کریں یا کوئی تجویز منتخب کریں۔",
|
|
49737
|
+
"ui.browser.browser_url_bar.address_suggestions_available": "{count, plural, one {{count, number, ::group-off} تجویز دستیاب ہے} other {{count, number, ::group-off} تجاویز دستیاب ہیں}}",
|
|
49738
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "ان ٹیب سے ابھی کوئی لنک نہیں ہے۔",
|
|
49739
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "اس براؤزر سیشن سے",
|
|
49740
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "اس براؤزر سیشن میں کوئی مماثل لنک نہیں ہے۔",
|
|
49741
|
+
"ui.browser.browser_url_bar.address_suggestions_unavailable": "پتے کی تجاویز دستیاب نہیں ہیں۔",
|
|
49499
49742
|
"ui.browser.browser_url_bar.approvals_waiting": "منظوریاں، {count, plural, other {{count, number, ::group-off} منتظر}}",
|
|
49500
49743
|
"ui.browser.browser_url_bar.back": "پیچھے",
|
|
49501
49744
|
"ui.browser.browser_url_bar.back_shortcut": "پیچھے ({shortcut})",
|
|
@@ -49761,7 +50004,26 @@ const urUiChatTags = {
|
|
|
49761
50004
|
"ui.chat.tags.move_undone": "ٹیگ کی منتقلی واپس کر دی گئی",
|
|
49762
50005
|
"ui.chat.tags.move_title": "“{title}” منتقل کریں",
|
|
49763
50006
|
"ui.chat.tags.move_description": "کسی ٹیگ کو بنیادی بنانے کے لیے اسے منتخب کریں، یا تمام ٹیگز ہٹانے کے لیے “بغیر ٹیگ” منتخب کریں۔",
|
|
49764
|
-
"ui.chat.tags.move_failed": "ٹیگز منتقل نہیں ہوئے۔ دوبارہ کوشش کریں۔"
|
|
50007
|
+
"ui.chat.tags.move_failed": "ٹیگز منتقل نہیں ہوئے۔ دوبارہ کوشش کریں۔",
|
|
50008
|
+
"ui.chat.tags.selection_count": "8 میں سے {count}",
|
|
50009
|
+
"ui.chat.tags.registry_count": "32 میں سے {count}",
|
|
50010
|
+
"ui.chat.tags.create_name": "“{name}” بنائیں",
|
|
50011
|
+
"ui.chat.tags.create_helper": "تمام گفتگوؤں کے لیے محفوظ",
|
|
50012
|
+
"ui.chat.tags.selection_limit": "زیادہ سے زیادہ 8 ٹیگز منتخب کریں",
|
|
50013
|
+
"ui.chat.tags.registry_limit": "آپ زیادہ سے زیادہ 32 ٹیگز رکھ سکتے ہیں",
|
|
50014
|
+
"ui.chat.tags.name_long": "1–24 حروف استعمال کریں",
|
|
50015
|
+
"ui.chat.tags.name_reserved": "“Untagged” نام مخصوص ہے",
|
|
50016
|
+
"ui.chat.tags.create_failed": "ٹیگ نہیں بنا۔ دوبارہ کوشش کریں۔",
|
|
50017
|
+
"ui.chat.tags.remove_named": "{name} ہٹائیں",
|
|
50018
|
+
"ui.chat.tags.reorder_filtered": "ٹیگز کی ترتیب بدلنے کے لیے تلاش صاف کریں",
|
|
50019
|
+
"ui.chat.tags.created_name": "“{name}” بنا دیا گیا",
|
|
50020
|
+
"ui.chat.tags.selection_status": "منتخب: {count}۔ {name} کے گروہ میں رکھیں۔",
|
|
50021
|
+
"ui.chat.tags.tag_usage": "{count, plural, one {# گفتگو} other {# گفتگوئیں}}",
|
|
50022
|
+
"ui.chat.tags.create_pending": "ٹیگ محفوظ ہو رہا ہے…",
|
|
50023
|
+
"ui.chat.tags.remote": "ریموٹ گفتگو کے ٹیگز تبدیل نہیں کیے جا سکتے۔",
|
|
50024
|
+
"ui.chat.tags.renamed_name": "نام بدل کر “{name}” کر دیا گیا",
|
|
50025
|
+
"ui.chat.tags.staged_added": "“{name}” مسودے میں شامل کر دیا گیا",
|
|
50026
|
+
"ui.chat.tags.registry_changed": "کچھ ٹیگز کہیں اور تبدیل ہو گئے ہیں۔ اپنے انتخاب کا جائزہ لیں۔"
|
|
49765
50027
|
};
|
|
49766
50028
|
const urUiCodeReview = {
|
|
49767
50029
|
"ui.code_review.activity.close": "بند کیا",
|
|
@@ -51247,10 +51509,18 @@ const urUiProjects = {
|
|
|
51247
51509
|
"ui.projects.project_todos.no_to_do_snapshots_from_the_linked_sessions_yet_a_session_publish": "ابھی منسلک سیشن سے کاموں کی فہرست کا کوئی عکس نہیں آیا۔ سیشن کام کرتے ہوئے اپنی فہرست شائع کرتا ہے اور تب یہ یہاں نظر آتی ہے۔",
|
|
51248
51510
|
"ui.projects.project_todos.to_dos": "کاموں کی فہرست",
|
|
51249
51511
|
"ui.projects.project_updates.attachment": "منسلکہ",
|
|
51512
|
+
"ui.projects.project_updates.attachments": "منسلکات",
|
|
51250
51513
|
"ui.projects.project_updates.file_actions_for_name": "{name} فائل کے اقدامات",
|
|
51251
51514
|
"ui.projects.project_updates.loading": "لوڈ ہو رہا ہے ",
|
|
51252
51515
|
"ui.projects.project_updates.no_updates_yet_progress_reported_by_you_or_by_the_sessions_workin": "ابھی کوئی اپ ڈیٹ نہیں ہے۔ آپ یا اس پروجیکٹ پر کام کرنے والے سیشن کی رپورٹ کردہ پیش رفت یہاں شامل ہوتی ہے۔",
|
|
51253
51516
|
"ui.projects.project_updates.open_name": "{name} کھولیں",
|
|
51517
|
+
"ui.projects.project_updates.play_name": "{name} چلائیں",
|
|
51518
|
+
"ui.projects.project_updates.preview_failed": "یہ فائل کھولی نہیں جا سکی۔",
|
|
51519
|
+
"ui.projects.project_updates.preview_loading": "پیش منظر لوڈ ہو رہا ہے…",
|
|
51520
|
+
"ui.projects.project_updates.preview_moved": "اس کی محفوظ کاپی منتقل یا حذف ہو گئی ہو سکتی ہے۔",
|
|
51521
|
+
"ui.projects.project_updates.preview_name": "{name} کا پیش منظر",
|
|
51522
|
+
"ui.projects.project_updates.preview_unavailable": "ڈیسک ٹاپ ایپ سے باہر پیش منظر دستیاب نہیں ہے۔",
|
|
51523
|
+
"ui.projects.project_updates.show_asset_name": "{name} دکھائیں، اثاثہ {index} از {count}",
|
|
51254
51524
|
"ui.projects.project_updates.updates": "اپ ڈیٹس",
|
|
51255
51525
|
"ui.projects.projects_page.checking_the_server_s_projects_support": "سرور میں پروجیکٹس کی سہولت جانچی جا رہی ہے",
|
|
51256
51526
|
"ui.projects.projects_page.clear_all": "سب صاف کریں",
|
|
@@ -52791,6 +53061,12 @@ const viUiBrowser = {
|
|
|
52791
53061
|
"ui.browser.browser_tab_strip.unmute_tab": "Bật tiếng tab",
|
|
52792
53062
|
"ui.browser.browser_tab_strip.watch": 'Theo dõi "{title}"',
|
|
52793
53063
|
"ui.browser.browser_url_bar.address": "Địa chỉ",
|
|
53064
|
+
"ui.browser.browser_url_bar.address_required": "Nhập địa chỉ web hoặc chọn một gợi ý.",
|
|
53065
|
+
"ui.browser.browser_url_bar.address_suggestions_available": "{count, plural, other {{count, number, ::group-off} gợi ý có sẵn}}",
|
|
53066
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "Chưa có liên kết nào từ các tab này.",
|
|
53067
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "Từ phiên trình duyệt này",
|
|
53068
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "Không có liên kết phù hợp từ phiên trình duyệt này.",
|
|
53069
|
+
"ui.browser.browser_url_bar.address_suggestions_unavailable": "Gợi ý địa chỉ không khả dụng.",
|
|
52794
53070
|
"ui.browser.browser_url_bar.approvals_waiting": "Phê duyệt, {count, plural, other {{count, number, ::group-off} đang chờ}}",
|
|
52795
53071
|
"ui.browser.browser_url_bar.back": "Quay lại",
|
|
52796
53072
|
"ui.browser.browser_url_bar.back_shortcut": "Quay lại ({shortcut})",
|
|
@@ -53056,7 +53332,26 @@ const viUiChatTags = {
|
|
|
53056
53332
|
"ui.chat.tags.move_undone": "Đã hoàn tác thao tác chuyển nhãn",
|
|
53057
53333
|
"ui.chat.tags.move_title": "Chuyển “{title}”",
|
|
53058
53334
|
"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.",
|
|
53059
|
-
"ui.chat.tags.move_failed": "Chưa chuyển được nhãn. Hãy thử lại."
|
|
53335
|
+
"ui.chat.tags.move_failed": "Chưa chuyển được nhãn. Hãy thử lại.",
|
|
53336
|
+
"ui.chat.tags.selection_count": "{count} trên 8",
|
|
53337
|
+
"ui.chat.tags.registry_count": "{count} trên 32",
|
|
53338
|
+
"ui.chat.tags.create_name": "Tạo “{name}”",
|
|
53339
|
+
"ui.chat.tags.create_helper": "Được lưu cho mọi cuộc trò chuyện",
|
|
53340
|
+
"ui.chat.tags.selection_limit": "Chọn tối đa 8 nhãn",
|
|
53341
|
+
"ui.chat.tags.registry_limit": "Bạn có thể có tối đa 32 nhãn",
|
|
53342
|
+
"ui.chat.tags.name_long": "Dùng từ 1 đến 24 ký tự",
|
|
53343
|
+
"ui.chat.tags.name_reserved": "“Untagged” là tên dành riêng",
|
|
53344
|
+
"ui.chat.tags.create_failed": "Chưa tạo được nhãn. Hãy thử lại.",
|
|
53345
|
+
"ui.chat.tags.remove_named": "Bỏ {name}",
|
|
53346
|
+
"ui.chat.tags.reorder_filtered": "Xóa tìm kiếm để sắp xếp lại nhãn",
|
|
53347
|
+
"ui.chat.tags.created_name": "Đã tạo “{name}”",
|
|
53348
|
+
"ui.chat.tags.selection_status": "Đã chọn {count}. Nhóm vào {name}.",
|
|
53349
|
+
"ui.chat.tags.tag_usage": "{count} cuộc trò chuyện",
|
|
53350
|
+
"ui.chat.tags.create_pending": "Đang lưu nhãn…",
|
|
53351
|
+
"ui.chat.tags.remote": "Không thể thay đổi nhãn của cuộc trò chuyện từ xa.",
|
|
53352
|
+
"ui.chat.tags.renamed_name": "Đã đổi tên thành “{name}”",
|
|
53353
|
+
"ui.chat.tags.staged_added": "Đã thêm “{name}” vào bản nháp",
|
|
53354
|
+
"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."
|
|
53060
53355
|
};
|
|
53061
53356
|
const viUiCodeReview = {
|
|
53062
53357
|
"ui.code_review.activity.close": "đã đóng",
|
|
@@ -54388,10 +54683,18 @@ const viUiProjects = {
|
|
|
54388
54683
|
"ui.projects.project_todos.no_to_do_snapshots_from_the_linked_sessions_yet_a_session_publish": "Chưa có bản chụp danh sách việc cần làm từ các phiên liên kết. Phiên sẽ công bố danh sách khi làm việc và danh sách sẽ xuất hiện ở đây.",
|
|
54389
54684
|
"ui.projects.project_todos.to_dos": "Việc cần làm",
|
|
54390
54685
|
"ui.projects.project_updates.attachment": "Tệp đính kèm",
|
|
54686
|
+
"ui.projects.project_updates.attachments": "Tệp đính kèm",
|
|
54391
54687
|
"ui.projects.project_updates.file_actions_for_name": "Thao tác tệp cho {name}",
|
|
54392
54688
|
"ui.projects.project_updates.loading": "Đang tải ",
|
|
54393
54689
|
"ui.projects.project_updates.no_updates_yet_progress_reported_by_you_or_by_the_sessions_workin": "Chưa có cập nhật. Tiến độ do bạn hoặc các phiên đang thực hiện dự án báo cáo sẽ được thêm vào đây.",
|
|
54394
54690
|
"ui.projects.project_updates.open_name": "Mở {name}",
|
|
54691
|
+
"ui.projects.project_updates.play_name": "Phát {name}",
|
|
54692
|
+
"ui.projects.project_updates.preview_failed": "Không thể mở tệp này.",
|
|
54693
|
+
"ui.projects.project_updates.preview_loading": "Đang tải bản xem trước…",
|
|
54694
|
+
"ui.projects.project_updates.preview_moved": "Bản sao đã lưu của tệp có thể đã bị di chuyển hoặc xóa.",
|
|
54695
|
+
"ui.projects.project_updates.preview_name": "Xem trước {name}",
|
|
54696
|
+
"ui.projects.project_updates.preview_unavailable": "Bản xem trước không khả dụng ngoài ứng dụng máy tính.",
|
|
54697
|
+
"ui.projects.project_updates.show_asset_name": "Hiển thị {name}, tài sản {index} trên {count}",
|
|
54395
54698
|
"ui.projects.project_updates.updates": "Cập nhật",
|
|
54396
54699
|
"ui.projects.projects_page.checking_the_server_s_projects_support": "Đang kiểm tra khả năng hỗ trợ Dự án của máy chủ",
|
|
54397
54700
|
"ui.projects.projects_page.clear_all": "Xóa tất cả",
|
|
@@ -55741,6 +56044,12 @@ const zhCNUiBrowser = {
|
|
|
55741
56044
|
"ui.browser.browser_tab_strip.unmute_tab": "取消标签页静音",
|
|
55742
56045
|
"ui.browser.browser_tab_strip.watch": "查看“{title}”",
|
|
55743
56046
|
"ui.browser.browser_url_bar.address": "地址",
|
|
56047
|
+
"ui.browser.browser_url_bar.address_required": "请输入地址或选择一条建议。",
|
|
56048
|
+
"ui.browser.browser_url_bar.address_suggestions_available": "{count, plural, other {{count, number, ::group-off}条建议可用}}",
|
|
56049
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "这些标签页中还没有链接。",
|
|
56050
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "来自此浏览器会话",
|
|
56051
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "此浏览器会话中没有匹配的链接。",
|
|
56052
|
+
"ui.browser.browser_url_bar.address_suggestions_unavailable": "地址建议不可用。",
|
|
55744
56053
|
"ui.browser.browser_url_bar.approvals_waiting": "审批,{count, plural, other {{count, number, ::group-off}项待处理}}",
|
|
55745
56054
|
"ui.browser.browser_url_bar.back": "后退",
|
|
55746
56055
|
"ui.browser.browser_url_bar.back_shortcut": "后退({shortcut})",
|
|
@@ -56006,7 +56315,26 @@ const zhCNUiChatTags = {
|
|
|
56006
56315
|
"ui.chat.tags.move_undone": "已撤销标签移动",
|
|
56007
56316
|
"ui.chat.tags.move_title": "移动“{title}”",
|
|
56008
56317
|
"ui.chat.tags.move_description": "选择一个标签将其设为主标签,或选择“无标签”以移除所有标签。",
|
|
56009
|
-
"ui.chat.tags.move_failed": "标签未移动。请重试。"
|
|
56318
|
+
"ui.chat.tags.move_failed": "标签未移动。请重试。",
|
|
56319
|
+
"ui.chat.tags.selection_count": "已选 {count}/8",
|
|
56320
|
+
"ui.chat.tags.registry_count": "{count}/32",
|
|
56321
|
+
"ui.chat.tags.create_name": "创建“{name}”",
|
|
56322
|
+
"ui.chat.tags.create_helper": "保存后可用于所有对话",
|
|
56323
|
+
"ui.chat.tags.selection_limit": "最多选择 8 个标签",
|
|
56324
|
+
"ui.chat.tags.registry_limit": "最多可有 32 个标签",
|
|
56325
|
+
"ui.chat.tags.name_long": "请使用 1–24 个字符",
|
|
56326
|
+
"ui.chat.tags.name_reserved": "“Untagged”是保留名称",
|
|
56327
|
+
"ui.chat.tags.create_failed": "未能创建标签。请重试。",
|
|
56328
|
+
"ui.chat.tags.remove_named": "移除{name}",
|
|
56329
|
+
"ui.chat.tags.reorder_filtered": "清空搜索以调整标签顺序",
|
|
56330
|
+
"ui.chat.tags.created_name": "已创建“{name}”",
|
|
56331
|
+
"ui.chat.tags.selection_status": "已选择 {count} 个,归入{name}。",
|
|
56332
|
+
"ui.chat.tags.tag_usage": "{count} 个对话",
|
|
56333
|
+
"ui.chat.tags.create_pending": "正在保存标签…",
|
|
56334
|
+
"ui.chat.tags.remote": "无法更改远程对话的标签。",
|
|
56335
|
+
"ui.chat.tags.renamed_name": "已重命名为“{name}”",
|
|
56336
|
+
"ui.chat.tags.staged_added": "已将“{name}”加入草稿",
|
|
56337
|
+
"ui.chat.tags.registry_changed": "部分标签已在别处更改。请检查所选标签。"
|
|
56010
56338
|
};
|
|
56011
56339
|
const zhCNUiCodeReview = {
|
|
56012
56340
|
"ui.code_review.activity.close": "已关闭",
|
|
@@ -57338,10 +57666,18 @@ const zhCNUiProjects = {
|
|
|
57338
57666
|
"ui.projects.project_todos.no_to_do_snapshots_from_the_linked_sessions_yet_a_session_publish": "关联会话尚未提供待办快照。会话在工作过程中发布待办列表后,便会显示在此处。",
|
|
57339
57667
|
"ui.projects.project_todos.to_dos": "待办事项",
|
|
57340
57668
|
"ui.projects.project_updates.attachment": "附件",
|
|
57669
|
+
"ui.projects.project_updates.attachments": "附件",
|
|
57341
57670
|
"ui.projects.project_updates.file_actions_for_name": "{name}的文件操作",
|
|
57342
57671
|
"ui.projects.project_updates.loading": "正在加载 ",
|
|
57343
57672
|
"ui.projects.project_updates.no_updates_yet_progress_reported_by_you_or_by_the_sessions_workin": "暂无更新。你或处理此项目的会话汇报的进展会追加到此处。",
|
|
57344
57673
|
"ui.projects.project_updates.open_name": "打开{name}",
|
|
57674
|
+
"ui.projects.project_updates.play_name": "播放 {name}",
|
|
57675
|
+
"ui.projects.project_updates.preview_failed": "无法打开此文件。",
|
|
57676
|
+
"ui.projects.project_updates.preview_loading": "正在加载预览…",
|
|
57677
|
+
"ui.projects.project_updates.preview_moved": "其已保存的副本可能已被移动或删除。",
|
|
57678
|
+
"ui.projects.project_updates.preview_name": "预览 {name}",
|
|
57679
|
+
"ui.projects.project_updates.preview_unavailable": "预览在桌面应用之外不可用。",
|
|
57680
|
+
"ui.projects.project_updates.show_asset_name": "显示 {name},第 {index} 个,共 {count} 个",
|
|
57345
57681
|
"ui.projects.project_updates.updates": "更新",
|
|
57346
57682
|
"ui.projects.projects_page.checking_the_server_s_projects_support": "正在检查服务器是否支持项目功能",
|
|
57347
57683
|
"ui.projects.projects_page.clear_all": "清除全部",
|
|
@@ -61586,6 +61922,121 @@ function factOf(path2) {
|
|
|
61586
61922
|
sha256: ""
|
|
61587
61923
|
};
|
|
61588
61924
|
}
|
|
61925
|
+
const ADDRESS_HISTORY_MAX_TABS = 20;
|
|
61926
|
+
const ADDRESS_HISTORY_MAX_ENTRIES_PER_TAB = 50;
|
|
61927
|
+
const ADDRESS_HISTORY_MAX_ENTRIES = 256;
|
|
61928
|
+
const ADDRESS_HISTORY_MAX_URL_LENGTH = 2048;
|
|
61929
|
+
const ADDRESS_HISTORY_MAX_TITLE_LENGTH = 256;
|
|
61930
|
+
const ADDRESS_HISTORY_MAX_SESSION_ID_LENGTH = 256;
|
|
61931
|
+
const CONTROL_CHARS$1 = /[\p{Cc}]/u;
|
|
61932
|
+
function windowAround(entries, activeIndexRaw, max) {
|
|
61933
|
+
const activeIndex = Math.min(
|
|
61934
|
+
Math.max(0, Number.isSafeInteger(activeIndexRaw) ? activeIndexRaw : 0),
|
|
61935
|
+
Math.max(0, entries.length - 1)
|
|
61936
|
+
);
|
|
61937
|
+
const start = Math.min(
|
|
61938
|
+
Math.max(0, activeIndex - Math.floor(max / 2)),
|
|
61939
|
+
Math.max(0, entries.length - max)
|
|
61940
|
+
);
|
|
61941
|
+
return {
|
|
61942
|
+
entries: entries.slice(start, start + max),
|
|
61943
|
+
activeIndex,
|
|
61944
|
+
startIndex: start
|
|
61945
|
+
};
|
|
61946
|
+
}
|
|
61947
|
+
function readStack(tab) {
|
|
61948
|
+
const contents = tab.webContents;
|
|
61949
|
+
if (!contents || contents.isDestroyed()) return null;
|
|
61950
|
+
const history = contents.navigationHistory;
|
|
61951
|
+
if (history?.getEntryAtIndex && typeof history.length === "function" && typeof history.getActiveIndex === "function") {
|
|
61952
|
+
try {
|
|
61953
|
+
const total = history.length();
|
|
61954
|
+
if (total > 0) {
|
|
61955
|
+
const activeIndex = Math.max(0, history.getActiveIndex());
|
|
61956
|
+
const max = ADDRESS_HISTORY_MAX_ENTRIES_PER_TAB;
|
|
61957
|
+
const start = Math.min(
|
|
61958
|
+
Math.max(0, activeIndex - Math.floor(max / 2)),
|
|
61959
|
+
Math.max(0, total - max)
|
|
61960
|
+
);
|
|
61961
|
+
const end = Math.min(total, start + max);
|
|
61962
|
+
const entries = [];
|
|
61963
|
+
for (let index = start; index < end; index += 1) {
|
|
61964
|
+
const entry = history.getEntryAtIndex(index);
|
|
61965
|
+
if (entry) entries.push(entry);
|
|
61966
|
+
}
|
|
61967
|
+
return {
|
|
61968
|
+
entries,
|
|
61969
|
+
activeIndex,
|
|
61970
|
+
startIndex: start
|
|
61971
|
+
};
|
|
61972
|
+
}
|
|
61973
|
+
} catch {
|
|
61974
|
+
}
|
|
61975
|
+
}
|
|
61976
|
+
const row = tab.restoreRow;
|
|
61977
|
+
if (!row || row.entries.length === 0) return null;
|
|
61978
|
+
return windowAround(
|
|
61979
|
+
row.entries,
|
|
61980
|
+
row.activeIndex,
|
|
61981
|
+
ADDRESS_HISTORY_MAX_ENTRIES_PER_TAB
|
|
61982
|
+
);
|
|
61983
|
+
}
|
|
61984
|
+
function canonicalHistoryUrl(raw) {
|
|
61985
|
+
if (typeof raw !== "string") return null;
|
|
61986
|
+
if (raw.length === 0 || raw.length > ADDRESS_HISTORY_MAX_URL_LENGTH)
|
|
61987
|
+
return null;
|
|
61988
|
+
if (CONTROL_CHARS$1.test(raw)) return null;
|
|
61989
|
+
let url;
|
|
61990
|
+
try {
|
|
61991
|
+
url = new URL(raw);
|
|
61992
|
+
} catch {
|
|
61993
|
+
return null;
|
|
61994
|
+
}
|
|
61995
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return null;
|
|
61996
|
+
if (url.username !== "" || url.password !== "") return null;
|
|
61997
|
+
if (url.href === "about:blank") return null;
|
|
61998
|
+
if (url.href.length > ADDRESS_HISTORY_MAX_URL_LENGTH) return null;
|
|
61999
|
+
return url.href;
|
|
62000
|
+
}
|
|
62001
|
+
function historyTitle(raw) {
|
|
62002
|
+
if (typeof raw !== "string") return "";
|
|
62003
|
+
const cleaned = raw.replace(CONTROL_CHARS$1, " ").replace(/\s+/g, " ").trim();
|
|
62004
|
+
return cleaned.length > ADDRESS_HISTORY_MAX_TITLE_LENGTH ? cleaned.slice(0, ADDRESS_HISTORY_MAX_TITLE_LENGTH) : cleaned;
|
|
62005
|
+
}
|
|
62006
|
+
function collectAddressHistory(tabs2, scope, activeTabId) {
|
|
62007
|
+
const inScope = scope === "all" ? [...tabs2] : tabs2.filter(
|
|
62008
|
+
(tab) => tab.sessionId !== null && tab.sessionId === scope.sessionId
|
|
62009
|
+
);
|
|
62010
|
+
const active = inScope.find((tab) => tab.tabId === activeTabId);
|
|
62011
|
+
const ordered = active ? [active, ...inScope.filter((tab) => tab.tabId !== activeTabId)] : inScope;
|
|
62012
|
+
const seen = /* @__PURE__ */ new Set();
|
|
62013
|
+
const entries = [];
|
|
62014
|
+
for (const tab of ordered.slice(0, ADDRESS_HISTORY_MAX_TABS)) {
|
|
62015
|
+
const stack = readStack(tab);
|
|
62016
|
+
if (!stack) continue;
|
|
62017
|
+
stack.entries.forEach((entry, windowIndex) => {
|
|
62018
|
+
const url = canonicalHistoryUrl(entry.url);
|
|
62019
|
+
if (!url) return;
|
|
62020
|
+
if (seen.has(url)) return;
|
|
62021
|
+
if (entries.length >= ADDRESS_HISTORY_MAX_ENTRIES) return;
|
|
62022
|
+
seen.add(url);
|
|
62023
|
+
const sourceIndex = stack.startIndex + windowIndex;
|
|
62024
|
+
entries.push({
|
|
62025
|
+
url,
|
|
62026
|
+
title: historyTitle(entry.title),
|
|
62027
|
+
sourceTabId: tab.tabId,
|
|
62028
|
+
sourceIndex,
|
|
62029
|
+
activeTab: tab.tabId === activeTabId,
|
|
62030
|
+
// The restore fallback's window is computed by the same policy, so this
|
|
62031
|
+
// distance is comparable across live and restored stacks: negative is a
|
|
62032
|
+
// back entry, which the absolute value deliberately discards (the
|
|
62033
|
+
// renderer ranks by closeness, not direction).
|
|
62034
|
+
distanceFromCurrent: Math.abs(sourceIndex - stack.activeIndex)
|
|
62035
|
+
});
|
|
62036
|
+
});
|
|
62037
|
+
}
|
|
62038
|
+
return { activeTabId, entries };
|
|
62039
|
+
}
|
|
61589
62040
|
class ChromeTabOrder {
|
|
61590
62041
|
ids = [];
|
|
61591
62042
|
customized = false;
|
|
@@ -62518,6 +62969,15 @@ class BrowserHost {
|
|
|
62518
62969
|
}
|
|
62519
62970
|
/** Main owns this short-lived UI focus fact; it conveys no page capability. */
|
|
62520
62971
|
chordFocus = false;
|
|
62972
|
+
/**
|
|
62973
|
+
* The tab whose native view last reported focus. Tracked from each view's own
|
|
62974
|
+
* `focus`/`blur` events because `webContents.getFocusedWebContents()` can
|
|
62975
|
+
* answer null while a `WebContentsView` holds focus (measured on Electron
|
|
62976
|
+
* 44.3.0 in a window that is not itself activated). Like `chordFocus`, this
|
|
62977
|
+
* is an input-ownership fact and carries no page capability; `ownsPage`
|
|
62978
|
+
* refuses it unless the tab is the active, presented one.
|
|
62979
|
+
*/
|
|
62980
|
+
focusedPageTabId = null;
|
|
62521
62981
|
onChordFocusChanged;
|
|
62522
62982
|
/** An explicit tab id fences queued chrome intents: a switch between key
|
|
62523
62983
|
* delivery and IPC must never search/zoom the newly active tab instead. */
|
|
@@ -62540,6 +63000,16 @@ class BrowserHost {
|
|
|
62540
63000
|
this.chordFocus = focused;
|
|
62541
63001
|
this.onChordFocusChanged?.(focused);
|
|
62542
63002
|
}
|
|
63003
|
+
/** One view gained or lost native focus. Only the id that lost it may clear
|
|
63004
|
+
* the fact: a departing view's blur must not erase a successor's focus. */
|
|
63005
|
+
setPageFocused(tabId, focused) {
|
|
63006
|
+
if (focused) this.focusedPageTabId = tabId;
|
|
63007
|
+
else if (this.focusedPageTabId === tabId) this.focusedPageTabId = null;
|
|
63008
|
+
}
|
|
63009
|
+
/** The window's own renderer gained focus (the user clicked chrome/chat). */
|
|
63010
|
+
clearPageFocus() {
|
|
63011
|
+
this.focusedPageTabId = null;
|
|
63012
|
+
}
|
|
62543
63013
|
/** Only user URLs survive a close, never a capability, page state or nonce.
|
|
62544
63014
|
* Conversation attribution is retained only to find the appropriate scope. */
|
|
62545
63015
|
closedUserTabs = [];
|
|
@@ -62558,6 +63028,7 @@ class BrowserHost {
|
|
|
62558
63028
|
clearChordState() {
|
|
62559
63029
|
this.pageControls.clear();
|
|
62560
63030
|
this.setChordFocus(false);
|
|
63031
|
+
this.clearPageFocus();
|
|
62561
63032
|
this.closedUserTabs = [];
|
|
62562
63033
|
}
|
|
62563
63034
|
/**
|
|
@@ -62849,6 +63320,41 @@ class BrowserHost {
|
|
|
62849
63320
|
this.onChanged();
|
|
62850
63321
|
return this.chromeState();
|
|
62851
63322
|
}
|
|
63323
|
+
/**
|
|
63324
|
+
* Local address suggestions for the field the user is editing.
|
|
63325
|
+
*
|
|
63326
|
+
* THE EXPECTED TAB IS A GUARD, not a hint: a response about tab A rendered
|
|
63327
|
+
* over tab B is how a stale completion navigates a tab the user is no longer
|
|
63328
|
+
* looking at. Main answers the read only when the request still names the
|
|
63329
|
+
* active tab; the renderer separately discards responses whose `activeTabId`
|
|
63330
|
+
* no longer matches, which covers the race between this check and the reply
|
|
63331
|
+
* landing.
|
|
63332
|
+
*
|
|
63333
|
+
* Collection is bounded and derived (`address-history.ts`); this method adds
|
|
63334
|
+
* only the authority the collector must not pretend to own.
|
|
63335
|
+
*/
|
|
63336
|
+
addressHistory(request) {
|
|
63337
|
+
const activeTabId = this.registry.activeTab?.tabId ?? null;
|
|
63338
|
+
if (activeTabId !== request.expectedTabId) {
|
|
63339
|
+
throw new BridgeCommandError(
|
|
63340
|
+
"nav_failed",
|
|
63341
|
+
"the active tab changed before suggestions were read"
|
|
63342
|
+
);
|
|
63343
|
+
}
|
|
63344
|
+
return {
|
|
63345
|
+
requestId: request.requestId,
|
|
63346
|
+
...collectAddressHistory(
|
|
63347
|
+
this.registry.list().map((record) => ({
|
|
63348
|
+
tabId: record.tabId,
|
|
63349
|
+
sessionId: record.sessionId,
|
|
63350
|
+
webContents: record.view.webContents,
|
|
63351
|
+
restoreRow: record.restoreRow ?? null
|
|
63352
|
+
})),
|
|
63353
|
+
request.scope,
|
|
63354
|
+
activeTabId
|
|
63355
|
+
)
|
|
63356
|
+
};
|
|
63357
|
+
}
|
|
62852
63358
|
/**
|
|
62853
63359
|
* A URL the USER typed goes through here, and it is deliberately different from
|
|
62854
63360
|
* an agent navigation in one way and identical in another (design 6.1):
|
|
@@ -62861,10 +63367,16 @@ class BrowserHost {
|
|
|
62861
63367
|
* `file:` or `javascript:` here would hand a page (or a paste) a way to reach
|
|
62862
63368
|
* the local filesystem through the app's own URL bar.
|
|
62863
63369
|
*/
|
|
62864
|
-
async navigateActive(rawUrl) {
|
|
63370
|
+
async navigateActive(rawUrl, expectedTabId) {
|
|
62865
63371
|
const record = this.registry.activeTab;
|
|
62866
63372
|
if (!record)
|
|
62867
63373
|
throw new BridgeCommandError("tab_closed", "no browser tab is open");
|
|
63374
|
+
if (expectedTabId !== void 0 && record.tabId !== expectedTabId) {
|
|
63375
|
+
throw new BridgeCommandError(
|
|
63376
|
+
"nav_failed",
|
|
63377
|
+
"the active tab changed before the address was submitted"
|
|
63378
|
+
);
|
|
63379
|
+
}
|
|
62868
63380
|
let url;
|
|
62869
63381
|
try {
|
|
62870
63382
|
url = new URL(rawUrl.includes("://") ? rawUrl : `https://${rawUrl}`);
|
|
@@ -62948,12 +63460,14 @@ class BrowserHost {
|
|
|
62948
63460
|
* area and reports it, and main applies it to the active tab only. */
|
|
62949
63461
|
setContentRect(rect) {
|
|
62950
63462
|
this.registry.setContentRect(rect);
|
|
63463
|
+
if (rect === null) this.clearPageFocus();
|
|
62951
63464
|
return this.chromeState();
|
|
62952
63465
|
}
|
|
62953
63466
|
/** Full-window overlays hide the view: a native view paints above all DOM, so
|
|
62954
63467
|
* an overlay is invisible unless the view goes away (design 11.3). */
|
|
62955
63468
|
setViewVisible(visible) {
|
|
62956
63469
|
this.registry.setViewVisible(visible);
|
|
63470
|
+
if (!visible) this.clearPageFocus();
|
|
62957
63471
|
return this.chromeState();
|
|
62958
63472
|
}
|
|
62959
63473
|
/** Hand a user tab to a session, minting the capability. The RENDERER never
|
|
@@ -63927,6 +64441,18 @@ async function startWithRetries(options) {
|
|
|
63927
64441
|
});
|
|
63928
64442
|
throw failure;
|
|
63929
64443
|
}
|
|
64444
|
+
function numberOrThrow(value, name) {
|
|
64445
|
+
if (typeof value !== "number" || !Number.isInteger(value)) {
|
|
64446
|
+
throw new Error(`${name} must be an integer.`);
|
|
64447
|
+
}
|
|
64448
|
+
return value;
|
|
64449
|
+
}
|
|
64450
|
+
function tabIdOrThrow(value, name) {
|
|
64451
|
+
const id2 = numberOrThrow(value, name);
|
|
64452
|
+
if (id2 <= 0) throw new Error(`${name} must be a positive tab id.`);
|
|
64453
|
+
return id2;
|
|
64454
|
+
}
|
|
64455
|
+
const CONTROL_CHARS = /[\p{Cc}]/u;
|
|
63930
64456
|
const BROWSER_IPC_CHANNELS = [
|
|
63931
64457
|
"browser-state",
|
|
63932
64458
|
"browser-set-chord-focus",
|
|
@@ -63939,6 +64465,7 @@ const BROWSER_IPC_CHANNELS = [
|
|
|
63939
64465
|
"browser-close-tab",
|
|
63940
64466
|
"browser-close-tabs",
|
|
63941
64467
|
"browser-activate-tab",
|
|
64468
|
+
"browser-address-history",
|
|
63942
64469
|
"browser-navigate",
|
|
63943
64470
|
"browser-home",
|
|
63944
64471
|
"browser-reload",
|
|
@@ -64035,12 +64562,22 @@ function registerBrowserIpc(options) {
|
|
|
64035
64562
|
const host = authorize(event);
|
|
64036
64563
|
return host.activateTab(numberOrThrow(tabId, "tabId"));
|
|
64037
64564
|
});
|
|
64038
|
-
electron.ipcMain.handle(
|
|
64039
|
-
|
|
64040
|
-
|
|
64041
|
-
|
|
64565
|
+
electron.ipcMain.handle(
|
|
64566
|
+
"browser-navigate",
|
|
64567
|
+
async (event, url, expectedTabId) => {
|
|
64568
|
+
const host = authorize(event);
|
|
64569
|
+
if (typeof url !== "string" || !url.trim()) {
|
|
64570
|
+
throw new Error("A URL is required.");
|
|
64571
|
+
}
|
|
64572
|
+
return host.navigateActive(
|
|
64573
|
+
url.trim(),
|
|
64574
|
+
expectedTabId === void 0 || expectedTabId === null ? void 0 : tabIdOrThrow(expectedTabId, "expectedTabId")
|
|
64575
|
+
);
|
|
64042
64576
|
}
|
|
64043
|
-
|
|
64577
|
+
);
|
|
64578
|
+
electron.ipcMain.handle("browser-address-history", (event, request) => {
|
|
64579
|
+
const host = authorize(event);
|
|
64580
|
+
return host.addressHistory(addressHistoryRequestOrThrow(request));
|
|
64044
64581
|
});
|
|
64045
64582
|
electron.ipcMain.handle(
|
|
64046
64583
|
"browser-page-control",
|
|
@@ -64198,11 +64735,28 @@ function registerBrowserIpc(options) {
|
|
|
64198
64735
|
function unregisterBrowserIpc() {
|
|
64199
64736
|
for (const channel of BROWSER_IPC_CHANNELS) electron.ipcMain.removeHandler(channel);
|
|
64200
64737
|
}
|
|
64201
|
-
function
|
|
64202
|
-
if (typeof value !== "
|
|
64203
|
-
throw new Error(
|
|
64738
|
+
function addressHistoryRequestOrThrow(value) {
|
|
64739
|
+
if (!value || typeof value !== "object") {
|
|
64740
|
+
throw new Error("An address history request is required.");
|
|
64741
|
+
}
|
|
64742
|
+
const request = value;
|
|
64743
|
+
const requestId2 = numberOrThrow(request.requestId, "requestId");
|
|
64744
|
+
const expectedTabId = tabIdOrThrow(request.expectedTabId, "expectedTabId");
|
|
64745
|
+
let scope;
|
|
64746
|
+
if (request.scope === "all") {
|
|
64747
|
+
scope = "all";
|
|
64748
|
+
} else if (request.scope && typeof request.scope === "object" && typeof request.scope.sessionId === "string") {
|
|
64749
|
+
const sessionId2 = request.scope.sessionId.trim();
|
|
64750
|
+
if (!sessionId2 || sessionId2.length > ADDRESS_HISTORY_MAX_SESSION_ID_LENGTH || CONTROL_CHARS.test(sessionId2)) {
|
|
64751
|
+
throw new Error(
|
|
64752
|
+
"The address history scope needs a valid conversation id."
|
|
64753
|
+
);
|
|
64754
|
+
}
|
|
64755
|
+
scope = { sessionId: sessionId2 };
|
|
64756
|
+
} else {
|
|
64757
|
+
throw new Error("The address history scope is invalid.");
|
|
64204
64758
|
}
|
|
64205
|
-
return
|
|
64759
|
+
return { requestId: requestId2, expectedTabId, scope };
|
|
64206
64760
|
}
|
|
64207
64761
|
function closeTabsIntentOrThrow(value) {
|
|
64208
64762
|
if (!value || typeof value !== "object") {
|
|
@@ -66217,6 +66771,8 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66217
66771
|
return view;
|
|
66218
66772
|
}, wireView = function(view, tabId) {
|
|
66219
66773
|
const contents = view.webContents;
|
|
66774
|
+
contents.on("focus", () => host.setPageFocused(tabId, true));
|
|
66775
|
+
contents.on("blur", () => host.setPageFocused(tabId, false));
|
|
66220
66776
|
const popupChildren = /* @__PURE__ */ new Set();
|
|
66221
66777
|
contents.setWindowOpenHandler((details) => {
|
|
66222
66778
|
const decision = decidePopup(
|
|
@@ -66378,6 +66934,7 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66378
66934
|
if (token) approvals.forgetDocument(token);
|
|
66379
66935
|
registry.forget(tabId);
|
|
66380
66936
|
}
|
|
66937
|
+
host.setPageFocused(tabId, false);
|
|
66381
66938
|
host.clearLoadFailure(tabId);
|
|
66382
66939
|
releaseTab(tabId, contents.id);
|
|
66383
66940
|
});
|
|
@@ -66653,9 +67210,18 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66653
67210
|
ownsChrome,
|
|
66654
67211
|
ownsPage: () => {
|
|
66655
67212
|
const record = registry.activeTab;
|
|
66656
|
-
return
|
|
66657
|
-
record
|
|
66658
|
-
|
|
67213
|
+
return browserPageOwnsChord({
|
|
67214
|
+
activeTab: record ? {
|
|
67215
|
+
tabId: record.tabId,
|
|
67216
|
+
webContentsId: record.view.webContents.id,
|
|
67217
|
+
presented: record.presented
|
|
67218
|
+
} : null,
|
|
67219
|
+
// Read lazily after the window/presented floor: a startup or test host
|
|
67220
|
+
// may carry a webContents slice without the getter.
|
|
67221
|
+
focusedContents: () => electron.webContents.getFocusedWebContents()?.id ?? null,
|
|
67222
|
+
focusedViewTabId: host.focusedPageTabId,
|
|
67223
|
+
window: options.window
|
|
67224
|
+
});
|
|
66659
67225
|
},
|
|
66660
67226
|
reload: (hard) => {
|
|
66661
67227
|
host.reloadActive(hard);
|
|
@@ -66687,6 +67253,9 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66687
67253
|
const resetChordFocus = () => {
|
|
66688
67254
|
host.setChordFocus(false);
|
|
66689
67255
|
};
|
|
67256
|
+
const resetPageFocus = () => {
|
|
67257
|
+
host.clearPageFocus();
|
|
67258
|
+
};
|
|
66690
67259
|
const resetMenuShortcutSuppression = () => {
|
|
66691
67260
|
if (!options.window.webContents.isDestroyed())
|
|
66692
67261
|
options.window.webContents.setIgnoreMenuShortcuts(false);
|
|
@@ -66695,6 +67264,7 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66695
67264
|
if (!focused) resetMenuShortcutSuppression();
|
|
66696
67265
|
};
|
|
66697
67266
|
options.window.webContents.on("before-input-event", onChromeInput);
|
|
67267
|
+
options.window.webContents.on("focus", resetPageFocus);
|
|
66698
67268
|
options.window.on("blur", resetMenuShortcutSuppression);
|
|
66699
67269
|
options.window.on("closed", resetChordFocus);
|
|
66700
67270
|
const resetOnNavigation = (details) => {
|
|
@@ -66708,6 +67278,7 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
66708
67278
|
"before-input-event",
|
|
66709
67279
|
onChromeInput
|
|
66710
67280
|
);
|
|
67281
|
+
options.window.webContents.removeListener("focus", resetPageFocus);
|
|
66711
67282
|
options.window.removeListener("blur", resetMenuShortcutSuppression);
|
|
66712
67283
|
options.window.removeListener("closed", resetChordFocus);
|
|
66713
67284
|
options.window.webContents.removeListener(
|
|
@@ -66999,7 +67570,7 @@ function isAdmittedSender(event, admitted) {
|
|
|
66999
67570
|
(candidate) => candidate.window !== null && !candidate.window.isDestroyed() && event.sender === candidate.window.webContents && event.senderFrame === candidate.window.webContents.mainFrame && trustedDesktopFrame(event.senderFrame.url, candidate.url)
|
|
67000
67571
|
);
|
|
67001
67572
|
}
|
|
67002
|
-
function registerDesktopIPC(window, expectedUrl, request, streams, media, notifier, noteLeftSession, onKeymapSettingEdited, additionalWindows, supplementMounts2) {
|
|
67573
|
+
function registerDesktopIPC(window, expectedUrl, request, streams, media, notifier, noteLeftSession, onKeymapSettingEdited, additionalWindows, supplementMounts2, teamBridgeNotifier) {
|
|
67003
67574
|
const opened = /* @__PURE__ */ new Map();
|
|
67004
67575
|
function authorize(event) {
|
|
67005
67576
|
const admitted = [
|
|
@@ -67063,6 +67634,16 @@ function registerDesktopIPC(window, expectedUrl, request, streams, media, notifi
|
|
|
67063
67634
|
noteLeftSession?.(args.sessionId);
|
|
67064
67635
|
});
|
|
67065
67636
|
}
|
|
67637
|
+
if (teamBridgeNotifier) {
|
|
67638
|
+
electron.ipcMain.handle("team-bridge:notify", (event, input) => {
|
|
67639
|
+
authorize(event);
|
|
67640
|
+
return teamBridgeNotifier.notify(input);
|
|
67641
|
+
});
|
|
67642
|
+
electron.ipcMain.handle("team-bridge:pending-open", (event) => {
|
|
67643
|
+
authorize(event);
|
|
67644
|
+
return teamBridgeNotifier.takePendingOpen();
|
|
67645
|
+
});
|
|
67646
|
+
}
|
|
67066
67647
|
if (media) {
|
|
67067
67648
|
electron.ipcMain.handle("desktop-media", (event, input, bytes) => {
|
|
67068
67649
|
authorize(event);
|
|
@@ -69020,6 +69601,227 @@ function installSupplementProtocol(fetchDocument, log2) {
|
|
|
69020
69601
|
});
|
|
69021
69602
|
});
|
|
69022
69603
|
}
|
|
69604
|
+
const TEAM_BRIDGE_NOTIFY_MAX_TITLE = 320;
|
|
69605
|
+
const TEAM_BRIDGE_NOTIFY_MAX_BODY = 200;
|
|
69606
|
+
const MAX_SEQ = Number.MAX_SAFE_INTEGER;
|
|
69607
|
+
const SAFE_ID = /^[A-Za-z0-9_.:-]{1,128}$/;
|
|
69608
|
+
function hasUnsafeText(value) {
|
|
69609
|
+
for (const character of value) {
|
|
69610
|
+
const code = character.codePointAt(0) ?? 0;
|
|
69611
|
+
if (character === "<" || character === ">" || code < 32 || code === 127) {
|
|
69612
|
+
return true;
|
|
69613
|
+
}
|
|
69614
|
+
}
|
|
69615
|
+
return false;
|
|
69616
|
+
}
|
|
69617
|
+
function cleanId(value) {
|
|
69618
|
+
return typeof value === "string" && SAFE_ID.test(value) ? value : null;
|
|
69619
|
+
}
|
|
69620
|
+
function cleanText(value, max) {
|
|
69621
|
+
if (typeof value !== "string") return null;
|
|
69622
|
+
const trimmed = value.trim();
|
|
69623
|
+
if (trimmed.length === 0 || trimmed.length > max) return null;
|
|
69624
|
+
if (hasUnsafeText(trimmed)) return null;
|
|
69625
|
+
return trimmed;
|
|
69626
|
+
}
|
|
69627
|
+
function parseTeamBridgeNotifyRequest(value) {
|
|
69628
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
69629
|
+
return null;
|
|
69630
|
+
}
|
|
69631
|
+
const input = value;
|
|
69632
|
+
const conversationId = cleanId(input.conversationId);
|
|
69633
|
+
const tenantId = cleanId(input.tenantId);
|
|
69634
|
+
const title = cleanText(input.title, TEAM_BRIDGE_NOTIFY_MAX_TITLE);
|
|
69635
|
+
const body = cleanText(input.body, TEAM_BRIDGE_NOTIFY_MAX_BODY);
|
|
69636
|
+
const seq2 = input.seq;
|
|
69637
|
+
if (conversationId === null || tenantId === null || title === null || body === null || typeof seq2 !== "number" || !Number.isSafeInteger(seq2) || seq2 < 0 || seq2 > MAX_SEQ) {
|
|
69638
|
+
return null;
|
|
69639
|
+
}
|
|
69640
|
+
return { conversationId, tenantId, title, body, seq: seq2 };
|
|
69641
|
+
}
|
|
69642
|
+
function teamBridgeWindowIsQuiet(window) {
|
|
69643
|
+
if (!window) return false;
|
|
69644
|
+
return !window.isDestroyed() && window.isVisible() && !window.isMinimized() && window.isFocused();
|
|
69645
|
+
}
|
|
69646
|
+
class TeamBridgeNotifier {
|
|
69647
|
+
constructor(options) {
|
|
69648
|
+
this.options = options;
|
|
69649
|
+
this.createBanner = options.createBanner ?? ((bannerOptions) => new electron.Notification(bannerOptions));
|
|
69650
|
+
this.canNotify = options.canNotify ?? (() => electron.Notification.isSupported());
|
|
69651
|
+
}
|
|
69652
|
+
/** The live banner per conversation, so a new seq REPLACES it. */
|
|
69653
|
+
banners = /* @__PURE__ */ new Map();
|
|
69654
|
+
/** The banners this process must keep reachable for their clicks to fire. */
|
|
69655
|
+
lifetime = new NotificationLifetime();
|
|
69656
|
+
pendingOpen = null;
|
|
69657
|
+
createBanner;
|
|
69658
|
+
canNotify;
|
|
69659
|
+
/**
|
|
69660
|
+
* Validate, dedupe and deliver one banner.
|
|
69661
|
+
*
|
|
69662
|
+
* REFUSAL IS AN ERROR, not a quiet `false`: a malformed payload is a bug in
|
|
69663
|
+
* the caller, and the IPC handler should reject rather than let the renderer
|
|
69664
|
+
* believe it raised something. A well-formed payload that is suppressed
|
|
69665
|
+
* (quiet, muted by focus, duplicate, unsupported) answers `shown: false`.
|
|
69666
|
+
*/
|
|
69667
|
+
notify(input) {
|
|
69668
|
+
const request = parseTeamBridgeNotifyRequest(input);
|
|
69669
|
+
if (request === null) {
|
|
69670
|
+
throw new Error("Invalid Team Bridge notification payload.");
|
|
69671
|
+
}
|
|
69672
|
+
if (this.options.show === "never") return { shown: false };
|
|
69673
|
+
if (!this.canNotify()) return { shown: false };
|
|
69674
|
+
if (teamBridgeWindowIsQuiet(this.options.window())) {
|
|
69675
|
+
return { shown: false };
|
|
69676
|
+
}
|
|
69677
|
+
const previous = this.options.store.notifiedSeq(request.conversationId);
|
|
69678
|
+
if (previous !== void 0 && request.seq <= previous) {
|
|
69679
|
+
return { shown: false };
|
|
69680
|
+
}
|
|
69681
|
+
this.replace(request.conversationId);
|
|
69682
|
+
const notification = this.createBanner({
|
|
69683
|
+
title: request.title,
|
|
69684
|
+
body: request.body,
|
|
69685
|
+
silent: false,
|
|
69686
|
+
...this.options.icon ? { icon: this.options.icon } : {}
|
|
69687
|
+
});
|
|
69688
|
+
this.lifetime.retain(notification, () => {
|
|
69689
|
+
this.banners.delete(request.conversationId);
|
|
69690
|
+
this.open(request);
|
|
69691
|
+
});
|
|
69692
|
+
notification.once("close", () => {
|
|
69693
|
+
if (this.banners.get(request.conversationId) === notification) {
|
|
69694
|
+
this.banners.delete(request.conversationId);
|
|
69695
|
+
}
|
|
69696
|
+
});
|
|
69697
|
+
notification.show();
|
|
69698
|
+
this.banners.set(request.conversationId, notification);
|
|
69699
|
+
this.options.store.record(request.conversationId, request.seq);
|
|
69700
|
+
return { shown: true };
|
|
69701
|
+
}
|
|
69702
|
+
/**
|
|
69703
|
+
* The target a click parked for the renderer.
|
|
69704
|
+
*
|
|
69705
|
+
* Consumed exactly once: the renderer asks for it on mount and on every
|
|
69706
|
+
* `team-bridge:open` signal, and a later pull gets `null` rather than
|
|
69707
|
+
* replaying a conversation the user has already seen. The value was built
|
|
69708
|
+
* from an already-validated notification payload, so this read does not
|
|
69709
|
+
* re-parse ids.
|
|
69710
|
+
*/
|
|
69711
|
+
takePendingOpen() {
|
|
69712
|
+
const pending = this.pendingOpen;
|
|
69713
|
+
this.pendingOpen = null;
|
|
69714
|
+
return pending;
|
|
69715
|
+
}
|
|
69716
|
+
replace(conversationId) {
|
|
69717
|
+
const previous = this.banners.get(conversationId);
|
|
69718
|
+
if (!previous) return;
|
|
69719
|
+
this.banners.delete(conversationId);
|
|
69720
|
+
previous.close?.();
|
|
69721
|
+
}
|
|
69722
|
+
open(request) {
|
|
69723
|
+
const target2 = {
|
|
69724
|
+
conversationId: request.conversationId,
|
|
69725
|
+
tenantId: request.tenantId
|
|
69726
|
+
};
|
|
69727
|
+
this.pendingOpen = target2;
|
|
69728
|
+
const window = this.options.window();
|
|
69729
|
+
if (window && !window.isDestroyed()) {
|
|
69730
|
+
this.options.host.signalOpen();
|
|
69731
|
+
this.options.present?.(window);
|
|
69732
|
+
return;
|
|
69733
|
+
}
|
|
69734
|
+
this.options.host.reopen();
|
|
69735
|
+
}
|
|
69736
|
+
}
|
|
69737
|
+
const TEAM_BRIDGE_NOTIFY_CURSOR_BOUND = 2048;
|
|
69738
|
+
const VERSION = 1;
|
|
69739
|
+
function isCursor(value) {
|
|
69740
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
69741
|
+
}
|
|
69742
|
+
class TeamBridgeNotifyStore {
|
|
69743
|
+
constructor(file, onError = () => void 0) {
|
|
69744
|
+
this.file = file;
|
|
69745
|
+
this.onError = onError;
|
|
69746
|
+
this.load();
|
|
69747
|
+
}
|
|
69748
|
+
cursors = /* @__PURE__ */ new Map();
|
|
69749
|
+
/** The newest seq a banner was raised for, or `undefined`. */
|
|
69750
|
+
notifiedSeq(conversationId) {
|
|
69751
|
+
return this.cursors.get(conversationId);
|
|
69752
|
+
}
|
|
69753
|
+
/**
|
|
69754
|
+
* Remember that this conversation was notified at `seq`.
|
|
69755
|
+
*
|
|
69756
|
+
* Only advances: a late poll whose seq is older than the recorded one must
|
|
69757
|
+
* not move the cursor backwards and re-open the door to a duplicate banner.
|
|
69758
|
+
* Touching an existing key moves it to the newest position so the bound
|
|
69759
|
+
* evicts by usefulness rather than alphabetically.
|
|
69760
|
+
*/
|
|
69761
|
+
record(conversationId, seq2) {
|
|
69762
|
+
if (!isCursor(seq2)) return;
|
|
69763
|
+
const previous = this.cursors.get(conversationId);
|
|
69764
|
+
if (previous !== void 0 && seq2 <= previous) return;
|
|
69765
|
+
this.cursors.delete(conversationId);
|
|
69766
|
+
this.cursors.set(conversationId, seq2);
|
|
69767
|
+
this.trim();
|
|
69768
|
+
this.persist();
|
|
69769
|
+
}
|
|
69770
|
+
/**
|
|
69771
|
+
* Enforce the bound on BOTH paths: `record` while a run is live and `load` on
|
|
69772
|
+
* a file written by an older or hand-edited build. A bound enforced only on
|
|
69773
|
+
* the write path is a promise about files this process wrote itself, which is
|
|
69774
|
+
* not the file it has just read.
|
|
69775
|
+
*/
|
|
69776
|
+
trim() {
|
|
69777
|
+
while (this.cursors.size > TEAM_BRIDGE_NOTIFY_CURSOR_BOUND) {
|
|
69778
|
+
const oldest = this.cursors.keys().next();
|
|
69779
|
+
if (oldest.done) break;
|
|
69780
|
+
this.cursors.delete(oldest.value);
|
|
69781
|
+
}
|
|
69782
|
+
}
|
|
69783
|
+
load() {
|
|
69784
|
+
let raw;
|
|
69785
|
+
try {
|
|
69786
|
+
raw = fs.readFileSync(this.file, "utf8");
|
|
69787
|
+
} catch {
|
|
69788
|
+
return;
|
|
69789
|
+
}
|
|
69790
|
+
try {
|
|
69791
|
+
const parsed = JSON.parse(raw);
|
|
69792
|
+
if (parsed === null || typeof parsed !== "object" || parsed.version !== VERSION) {
|
|
69793
|
+
return;
|
|
69794
|
+
}
|
|
69795
|
+
const cursors = parsed.cursors;
|
|
69796
|
+
if (cursors === null || typeof cursors !== "object") return;
|
|
69797
|
+
for (const [conversationId, seq2] of Object.entries(
|
|
69798
|
+
cursors
|
|
69799
|
+
)) {
|
|
69800
|
+
if (isCursor(seq2)) this.cursors.set(conversationId, seq2);
|
|
69801
|
+
}
|
|
69802
|
+
this.trim();
|
|
69803
|
+
} catch (error) {
|
|
69804
|
+
this.onError("team-bridge notification cursor file is unreadable", error);
|
|
69805
|
+
}
|
|
69806
|
+
}
|
|
69807
|
+
persist() {
|
|
69808
|
+
const payload = {
|
|
69809
|
+
version: VERSION,
|
|
69810
|
+
cursors: Object.fromEntries(this.cursors)
|
|
69811
|
+
};
|
|
69812
|
+
try {
|
|
69813
|
+
fs.mkdirSync(path$1.dirname(this.file), { recursive: true, mode: 448 });
|
|
69814
|
+
const temporary = `${this.file}.${process.pid}.tmp`;
|
|
69815
|
+
fs.writeFileSync(temporary, JSON.stringify(payload), { mode: 384 });
|
|
69816
|
+
fs.renameSync(temporary, this.file);
|
|
69817
|
+
} catch (error) {
|
|
69818
|
+
this.onError(
|
|
69819
|
+
"team-bridge notification cursor could not be written",
|
|
69820
|
+
error
|
|
69821
|
+
);
|
|
69822
|
+
}
|
|
69823
|
+
}
|
|
69824
|
+
}
|
|
69023
69825
|
function titlebarOptions(platform, chrome) {
|
|
69024
69826
|
if (platform === "darwin") {
|
|
69025
69827
|
return { titleBarStyle: "hidden" };
|
|
@@ -77493,6 +78295,25 @@ function createApplicationMenu() {
|
|
|
77493
78295
|
{
|
|
77494
78296
|
label: "View",
|
|
77495
78297
|
submenu: [
|
|
78298
|
+
{
|
|
78299
|
+
id: "app-new-tab",
|
|
78300
|
+
label: "New Browser Tab",
|
|
78301
|
+
accelerator: "CmdOrCtrl+T",
|
|
78302
|
+
/*
|
|
78303
|
+
* THE NATIVE ACCELERATOR ROUTE FOR CMD+T, which had no menu item at all.
|
|
78304
|
+
* The browser owns the command through the same predicate as Reload
|
|
78305
|
+
* (`ownsPage` for a focused driven page, `ownsChrome` for browser chrome);
|
|
78306
|
+
* outside the browser this is deliberately a no-op, never a window close.
|
|
78307
|
+
* When the chrome's own `before-input-event` already claimed the press it
|
|
78308
|
+
* prevents this accelerator, so rapid/legit presses stay exactly once.
|
|
78309
|
+
*/
|
|
78310
|
+
click: (_item, target2) => runBrowserMenuAction(
|
|
78311
|
+
"new-tab",
|
|
78312
|
+
target2,
|
|
78313
|
+
mainWindow,
|
|
78314
|
+
routeBrowserMenu
|
|
78315
|
+
)
|
|
78316
|
+
},
|
|
77496
78317
|
{
|
|
77497
78318
|
id: "app-reload",
|
|
77498
78319
|
label: "Reload",
|
|
@@ -78336,6 +79157,28 @@ electron.app.whenReady().then(async () => {
|
|
|
78336
79157
|
// line is what tells that trigger apart from the other four.
|
|
78337
79158
|
reportRaise
|
|
78338
79159
|
);
|
|
79160
|
+
const teamBridgeNotifier = new TeamBridgeNotifier({
|
|
79161
|
+
window: () => mainWindow,
|
|
79162
|
+
show: windowLaunch.show,
|
|
79163
|
+
icon: image,
|
|
79164
|
+
store: new TeamBridgeNotifyStore(
|
|
79165
|
+
path$1.join(electron.app.getPath("userData"), "team-bridge-notifications.json"),
|
|
79166
|
+
(message, error) => logger.warn(`${message}: ${String(error)}`, LogFileType.BACKEND)
|
|
79167
|
+
),
|
|
79168
|
+
host: {
|
|
79169
|
+
signalOpen: () => {
|
|
79170
|
+
const window = mainWindow;
|
|
79171
|
+
if (window && !window.isDestroyed()) {
|
|
79172
|
+
window.webContents.send("team-bridge:open");
|
|
79173
|
+
}
|
|
79174
|
+
},
|
|
79175
|
+
reopen: () => electron.app.emit("activate")
|
|
79176
|
+
},
|
|
79177
|
+
present: (window) => raiseWindow(window, windowLaunch.show, {
|
|
79178
|
+
trigger: "banner-click",
|
|
79179
|
+
report: reportRaise
|
|
79180
|
+
})
|
|
79181
|
+
});
|
|
78339
79182
|
backendService.onBackendReady(() => {
|
|
78340
79183
|
void desktopNotifier.refreshNotificationContract();
|
|
78341
79184
|
void backendService.getDesktopFeedRelay().start();
|
|
@@ -78608,7 +79451,8 @@ electron.app.whenReady().then(async () => {
|
|
|
78608
79451
|
* same instance `createWindow` gave the navigation guard: the arm channel
|
|
78609
79452
|
* and the guard are two halves of one decision and must share one list.
|
|
78610
79453
|
*/
|
|
78611
|
-
supplementMounts
|
|
79454
|
+
supplementMounts,
|
|
79455
|
+
teamBridgeNotifier
|
|
78612
79456
|
);
|
|
78613
79457
|
if (devDriverArming.armed && devDriverArming.outDir) {
|
|
78614
79458
|
registerDevDriverIPC({
|