local-operator-ui 0.39.5 → 0.39.6
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 +499 -70
- package/out/renderer/assets/{_basePickBy-BgM1I5lG.js → _basePickBy-CEM-62na.js} +1 -1
- package/out/renderer/assets/{_baseUniq-Bmkgy85v.js → _baseUniq-DKUG2lEn.js} +1 -1
- package/out/renderer/assets/{addressOverlayList-8wdZRD_t.css → addressOverlayList-B7X6o95l.css} +1 -1
- package/out/renderer/assets/{addressOverlayList-BEh9WU4R.js → addressOverlayList-SGt8bawf.js} +1 -1
- package/out/renderer/assets/{agent-details-page-Du26ZU6E.js → agent-details-page-uwmizvcA.js} +1 -1
- package/out/renderer/assets/{agent-hub-page-BwVMuSzt.js → agent-hub-page-DY0hrFjh.js} +1 -1
- package/out/renderer/assets/{agents-page-BhSbjEpr.js → agents-page-B82GhyEm.js} +3 -3
- package/out/renderer/assets/{arc-3zNC_x2n.js → arc-CwS59wEx.js} +1 -1
- package/out/renderer/assets/{architectureDiagram-IEHRJDOE-CtDg0QNg.js → architectureDiagram-IEHRJDOE-CrSOPHPj.js} +1 -1
- package/out/renderer/assets/{blockDiagram-JOT3LUYC-4XryKcIu.js → blockDiagram-JOT3LUYC-DOKW2aS1.js} +1 -1
- package/out/renderer/assets/{book-open-lnC7oth0.js → book-open-BrVlmR50.js} +1 -1
- package/out/renderer/assets/browser-page-kxT2NYqz.js +1 -0
- package/out/renderer/assets/{browser-webauthn-prompt-BTC3LWcr.js → browser-webauthn-prompt-D4Pmblc_.js} +1 -1
- package/out/renderer/assets/{building-2-CRI7K1ut.js → building-2-BbJxBV3t.js} +1 -1
- package/out/renderer/assets/{c4Diagram-VJAJSXHY-n2cPdK4v.js → c4Diagram-VJAJSXHY-BNZOSwVL.js} +1 -1
- package/out/renderer/assets/channel-D2-Cirxc.js +1 -0
- package/out/renderer/assets/{chunk-4BMEZGHF-P7BOtABr.js → chunk-4BMEZGHF-DatYJ8Pc.js} +1 -1
- package/out/renderer/assets/{chunk-A2AXSNBT-BmO2P02x.js → chunk-A2AXSNBT-kofNI-nh.js} +1 -1
- package/out/renderer/assets/{chunk-AEK57VVT-KMJMGzZF.js → chunk-AEK57VVT-RG-vyDkt.js} +1 -1
- package/out/renderer/assets/{chunk-D6G4REZN-WA3nwEd_.js → chunk-D6G4REZN-DbgxdXuD.js} +1 -1
- package/out/renderer/assets/{chunk-RZ5BOZE2-C4md2pdG.js → chunk-RZ5BOZE2-Pwbky5G7.js} +1 -1
- package/out/renderer/assets/{chunk-XZIHB7SX-MPSf1VFR.js → chunk-XZIHB7SX-nMQwH5Ev.js} +1 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-D1u4IPED.js +1 -0
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-D1u4IPED.js +1 -0
- package/out/renderer/assets/clone-D45gbF22.js +1 -0
- package/out/renderer/assets/{console-mirror-CnVv9rOt.js → console-mirror-B7HDmLVb.js} +1 -1
- package/out/renderer/assets/{consoleCapture-B_hi3E9g.js → consoleCapture-wuvuMPlf.js} +1 -1
- package/out/renderer/assets/{conversation-input-sync-CQ0nQbSV.js → conversation-input-sync-DeQTtOSG.js} +4 -4
- package/out/renderer/assets/{dagre-OKDRZEBW-QrYk8i27.js → dagre-OKDRZEBW-BXF3VqDs.js} +1 -1
- package/out/renderer/assets/{diagram-SSKATNLV-CpIwEDtE.js → diagram-SSKATNLV-C6ZzdCUp.js} +1 -1
- package/out/renderer/assets/{diagram-VNBRO52H-DtHOhSDJ.js → diagram-VNBRO52H-ND-gVRs3.js} +1 -1
- package/out/renderer/assets/{erDiagram-Q7BY3M3F-AEs8Bb_A.js → erDiagram-Q7BY3M3F-DJ8vCpMT.js} +1 -1
- package/out/renderer/assets/{error-boundary-CU2PiR3H.js → error-boundary-D81PAlVn.js} +1 -1
- package/out/renderer/assets/{flowDiagram-4HSFHLVR-CliaNR7R.js → flowDiagram-4HSFHLVR-C0lG2NYg.js} +1 -1
- package/out/renderer/assets/{ganttDiagram-APWFNJXF-Br5lLrlI.js → ganttDiagram-APWFNJXF-BBxt5Pgj.js} +1 -1
- package/out/renderer/assets/{gitGraphDiagram-7IBYFJ6S-D68CT6c8.js → gitGraphDiagram-7IBYFJ6S-B5eei6E_.js} +1 -1
- package/out/renderer/assets/{graph-LIDYSJHC.js → graph-lWFNtwh7.js} +1 -1
- package/out/renderer/assets/{hash-5VU7fofJ.js → hash-3k6_lTgk.js} +1 -1
- package/out/renderer/assets/{index-BoQsbSXg.js → index-BtI7uak5.js} +197 -192
- package/out/renderer/assets/index-DsY6xpO9.js +57 -0
- package/out/renderer/assets/{index-Bpi83aqM.js → index-FqHXqlQT.js} +1 -1
- package/out/renderer/assets/{index-BpJ3H71K.js → index-tyh1i-0R.js} +1 -1
- package/out/renderer/assets/{infoDiagram-PH2N3AL5-U0UUgi63.js → infoDiagram-PH2N3AL5-DfdIGj2q.js} +1 -1
- package/out/renderer/assets/{installer-9uv2KfFf.js → installer-OLhNHLbA.js} +1 -1
- package/out/renderer/assets/{journeyDiagram-U35MCT3I-FFIRpntM.js → journeyDiagram-U35MCT3I-DY36aDPm.js} +1 -1
- package/out/renderer/assets/{kanban-definition-NDS4AKOZ-BRpcp-A3.js → kanban-definition-NDS4AKOZ-DkmkP4pt.js} +1 -1
- package/out/renderer/assets/{layout-MxBLCasM.js → layout-Wh_eVbud.js} +1 -1
- package/out/renderer/assets/{legacy-agents-page-D-vnYlfr.js → legacy-agents-page-m5-4VKbu.js} +1 -1
- package/out/renderer/assets/{library-page-D5TOCNDL.js → library-page-vUP7gWsI.js} +3 -3
- package/out/renderer/assets/{mermaid.core-D0JYobPd.js → mermaid.core-CIUeSke9.js} +5 -5
- package/out/renderer/assets/{mesh-page-MMyOu2-i.js → mesh-page-CoUCZ19i.js} +1 -1
- package/out/renderer/assets/{mindmap-definition-ALO5MXBD-BSmr1_Tl.js → mindmap-definition-ALO5MXBD-E7Cl2drf.js} +1 -1
- package/out/renderer/assets/{mini-DX97EGZ9.js → mini-D6HdkQvd.js} +1 -1
- package/out/renderer/assets/{notebook-pen-CaY2CqYY.js → notebook-pen-CiUgTpp-.js} +1 -1
- package/out/renderer/assets/{org-access-D-BFcZvI.js → org-access-DMUk8SEr.js} +1 -1
- package/out/renderer/assets/{org-surface-gate-BmRiAyd4.js → org-surface-gate-DdKUA8S8.js} +1 -1
- package/out/renderer/assets/{page-header-B078STNU.js → page-header-DyRHEB-L.js} +1 -1
- package/out/renderer/assets/{pieDiagram-IB7DONF6-DkC-Pw7E.js → pieDiagram-IB7DONF6-C3KFzuOU.js} +1 -1
- package/out/renderer/assets/{projects-page-2kYMpXGt.js → projects-page-BdU99VZf.js} +1 -1
- package/out/renderer/assets/{publication-validation-Cp6mINOP.js → publication-validation-Cv6lnH83.js} +1 -1
- package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-IVRMgBez.js → quadrantDiagram-7GDLP6J5-DommBk0z.js} +1 -1
- package/out/renderer/assets/{radar-MK3ICKWK-sedwCyEl.js → radar-MK3ICKWK-D5VUcmjY.js} +1 -1
- package/out/renderer/assets/{radient-auth-buttons-vFQgdlYP.js → radient-auth-buttons-BXc5xVU7.js} +1 -1
- package/out/renderer/assets/{requirementDiagram-KVF5MWMF-DwdfgrvA.js → requirementDiagram-KVF5MWMF-RSR1-rSs.js} +1 -1
- package/out/renderer/assets/{sankeyDiagram-QLVOVGJD-BPvKdY7g.js → sankeyDiagram-QLVOVGJD-Caojpkpm.js} +1 -1
- package/out/renderer/assets/{schedules-page-BWxSAtp5.js → schedules-page-BWM0NUo9.js} +1 -1
- package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-swhS4JaV.js → sequenceDiagram-X6HHIX6F-CrZCUpMQ.js} +1 -1
- package/out/renderer/assets/{settings-page-CNeq8zEo.js → settings-page-sXBnyGof.js} +1 -1
- package/out/renderer/assets/{smartart-h3hobM9P.js → smartart-BJStpUh7.js} +1 -1
- package/out/renderer/assets/{stateDiagram-DGXRK772-DQjtzeCn.js → stateDiagram-DGXRK772-PFp2Dzsd.js} +1 -1
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-DhzpDrem.js +1 -0
- package/out/renderer/assets/{team-bridge-page-DwXTOl4x.js → team-bridge-page-pZkYpCnA.js} +1 -1
- package/out/renderer/assets/{timeline-definition-BDJGKUSR-BE4DUnJN.js → timeline-definition-BDJGKUSR-BI2T4N_q.js} +1 -1
- package/out/renderer/assets/{ui-preferences-store-DUB1goHr.js → ui-preferences-store-BZs48Tq1.js} +1 -1
- package/out/renderer/assets/{use-download-agent-mutation-C_zKpXBu.js → use-download-agent-mutation-B3ghS441.js} +1 -1
- package/out/renderer/assets/{use-session-snapshot-B6UGWZI5.js → use-session-snapshot-BbulmIXL.js} +1 -1
- package/out/renderer/assets/{xychartDiagram-VJFVF3MP-D6nHKfw6.js → xychartDiagram-VJFVF3MP-CuNt7ik-.js} +1 -1
- package/out/renderer/browser-address-overlay-list.html +2 -2
- package/out/renderer/console-capture.html +4 -4
- package/out/renderer/index.html +6 -6
- package/out/renderer/installer.html +3 -3
- package/out/renderer/mini.html +6 -6
- package/package.json +2 -2
- package/out/renderer/assets/browser-page-CsoEGi9k.js +0 -1
- package/out/renderer/assets/channel-MJ9Q5Gdp.js +0 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-PYFoG-nl.js +0 -1
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-PYFoG-nl.js +0 -1
- package/out/renderer/assets/clone-BWjAp2XI.js +0 -1
- package/out/renderer/assets/index-B_mT8ft1.js +0 -57
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-BoHuPFVZ.js +0 -1
package/out/main/index.js
CHANGED
|
@@ -28848,7 +28848,6 @@ const ADDRESS_LIST_THEME_FALLBACK = "#1b1f24";
|
|
|
28848
28848
|
const DIP_INT32_MAX$1 = 2 ** 31 - 1;
|
|
28849
28849
|
const NOTICE_KINDS = [
|
|
28850
28850
|
"error",
|
|
28851
|
-
"hint",
|
|
28852
28851
|
"empty",
|
|
28853
28852
|
"no_match"
|
|
28854
28853
|
];
|
|
@@ -35358,11 +35357,15 @@ const enUiBrowser = {
|
|
|
35358
35357
|
"ui.browser.browser_tab_strip.unmute_tab": "Unmute tab",
|
|
35359
35358
|
"ui.browser.browser_tab_strip.watch": 'Watch "{title}"',
|
|
35360
35359
|
"ui.browser.browser_url_bar.address": "Address",
|
|
35361
|
-
"ui.browser.browser_url_bar.
|
|
35360
|
+
"ui.browser.browser_url_bar.address_search_row": 'Search DuckDuckGo for "{query}"',
|
|
35361
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab": "Already open — {title}",
|
|
35362
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab_untitled": "Already open",
|
|
35362
35363
|
"ui.browser.browser_url_bar.address_suggestions_available": "{count, plural, one {{count, number, ::group-off} suggestion available} other {{count, number, ::group-off} suggestions available}}",
|
|
35363
|
-
"ui.browser.browser_url_bar.
|
|
35364
|
-
"ui.browser.browser_url_bar.
|
|
35365
|
-
"ui.browser.browser_url_bar.
|
|
35364
|
+
"ui.browser.browser_url_bar.address_suggestions_blocked": "Only web addresses can open here.",
|
|
35365
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "No browsing history yet.",
|
|
35366
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "From your history",
|
|
35367
|
+
"ui.browser.browser_url_bar.address_suggestions_label_mixed": "Suggestions",
|
|
35368
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "No matching pages in your history.",
|
|
35366
35369
|
"ui.browser.browser_url_bar.address_suggestions_unavailable": "Address suggestions are unavailable.",
|
|
35367
35370
|
"ui.browser.browser_url_bar.approvals_waiting": "Approvals, {count, plural, other {{count, number, ::group-off} waiting}}",
|
|
35368
35371
|
"ui.browser.browser_url_bar.back": "Back",
|
|
@@ -39088,11 +39091,15 @@ const esUiBrowser = {
|
|
|
39088
39091
|
"ui.browser.browser_url_bar.stop_loading": "Detener carga",
|
|
39089
39092
|
"ui.browser.browser_url_bar.reload": "Recargar",
|
|
39090
39093
|
"ui.browser.browser_url_bar.address": "Dirección",
|
|
39091
|
-
"ui.browser.browser_url_bar.
|
|
39094
|
+
"ui.browser.browser_url_bar.address_search_row": "Buscar «{query}» en DuckDuckGo",
|
|
39095
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab": "Ya abierto — {title}",
|
|
39096
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab_untitled": "Ya abierto",
|
|
39092
39097
|
"ui.browser.browser_url_bar.address_suggestions_available": "{count, plural, one {{count, number, ::group-off} sugerencia disponible} other {{count, number, ::group-off} sugerencias disponibles}}",
|
|
39093
|
-
"ui.browser.browser_url_bar.
|
|
39094
|
-
"ui.browser.browser_url_bar.
|
|
39095
|
-
"ui.browser.browser_url_bar.
|
|
39098
|
+
"ui.browser.browser_url_bar.address_suggestions_blocked": "Aquí solo se pueden abrir direcciones web.",
|
|
39099
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "Aún no hay historial de navegación.",
|
|
39100
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "De tu historial",
|
|
39101
|
+
"ui.browser.browser_url_bar.address_suggestions_label_mixed": "Sugerencias",
|
|
39102
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "No hay páginas coincidentes en tu historial.",
|
|
39096
39103
|
"ui.browser.browser_url_bar.address_suggestions_unavailable": "Las sugerencias de direcciones no están disponibles.",
|
|
39097
39104
|
"ui.browser.browser_url_bar.approvals_waiting": "Aprobaciones, {count, plural, other {{count, number, ::group-off} en espera}}",
|
|
39098
39105
|
"ui.browser.browser_url_bar.home_destination": "Inicio — ir a la página inicial (en blanco)",
|
|
@@ -42665,11 +42672,15 @@ const frUiBrowser = {
|
|
|
42665
42672
|
"ui.browser.browser_url_bar.stop_loading": "Arrêter le chargement",
|
|
42666
42673
|
"ui.browser.browser_url_bar.reload": "Recharger",
|
|
42667
42674
|
"ui.browser.browser_url_bar.address": "Adresse",
|
|
42668
|
-
"ui.browser.browser_url_bar.
|
|
42675
|
+
"ui.browser.browser_url_bar.address_search_row": "Rechercher « {query} » sur DuckDuckGo",
|
|
42676
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab": "Déjà ouvert — {title}",
|
|
42677
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab_untitled": "Déjà ouvert",
|
|
42669
42678
|
"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}}",
|
|
42670
|
-
"ui.browser.browser_url_bar.
|
|
42671
|
-
"ui.browser.browser_url_bar.
|
|
42672
|
-
"ui.browser.browser_url_bar.
|
|
42679
|
+
"ui.browser.browser_url_bar.address_suggestions_blocked": "Seules les adresses web peuvent s’ouvrir ici.",
|
|
42680
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "Pas encore d'historique de navigation.",
|
|
42681
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "De votre historique",
|
|
42682
|
+
"ui.browser.browser_url_bar.address_suggestions_label_mixed": "Suggestions",
|
|
42683
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "Aucune page correspondante dans votre historique.",
|
|
42673
42684
|
"ui.browser.browser_url_bar.address_suggestions_unavailable": "Les suggestions d’adresses ne sont pas disponibles.",
|
|
42674
42685
|
"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}}",
|
|
42675
42686
|
"ui.browser.browser_url_bar.home_destination": "Accueil — aller à la page de départ (vide)",
|
|
@@ -46241,11 +46252,15 @@ const hiUiBrowser = {
|
|
|
46241
46252
|
"ui.browser.browser_tab_strip.unmute_tab": "टैब की आवाज़ चालू करें",
|
|
46242
46253
|
"ui.browser.browser_tab_strip.watch": '"{title}" देखें',
|
|
46243
46254
|
"ui.browser.browser_url_bar.address": "पता",
|
|
46244
|
-
"ui.browser.browser_url_bar.
|
|
46255
|
+
"ui.browser.browser_url_bar.address_search_row": 'DuckDuckGo पर "{query}" खोजें',
|
|
46256
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab": "पहले से खुला — {title}",
|
|
46257
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab_untitled": "पहले से खुला",
|
|
46245
46258
|
"ui.browser.browser_url_bar.address_suggestions_available": "{count, plural, one {{count, number, ::group-off} सुझाव उपलब्ध है} other {{count, number, ::group-off} सुझाव उपलब्ध हैं}}",
|
|
46246
|
-
"ui.browser.browser_url_bar.
|
|
46247
|
-
"ui.browser.browser_url_bar.
|
|
46248
|
-
"ui.browser.browser_url_bar.
|
|
46259
|
+
"ui.browser.browser_url_bar.address_suggestions_blocked": "यहाँ केवल वेब पते खुल सकते हैं।",
|
|
46260
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "अभी तक कोई ब्राउज़िंग इतिहास नहीं।",
|
|
46261
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "आपके इतिहास से",
|
|
46262
|
+
"ui.browser.browser_url_bar.address_suggestions_label_mixed": "सुझाव",
|
|
46263
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "आपके इतिहास में कोई मेल खाता पृष्ठ नहीं।",
|
|
46249
46264
|
"ui.browser.browser_url_bar.address_suggestions_unavailable": "पते के सुझाव उपलब्ध नहीं हैं।",
|
|
46250
46265
|
"ui.browser.browser_url_bar.approvals_waiting": "स्वीकृतियाँ, {count, plural, other {{count, number, ::group-off} इंतज़ार में}}",
|
|
46251
46266
|
"ui.browser.browser_url_bar.back": "पीछे",
|
|
@@ -49595,11 +49610,15 @@ const ruUiBrowser = {
|
|
|
49595
49610
|
"ui.browser.browser_tab_strip.unmute_tab": "Включить звук вкладки",
|
|
49596
49611
|
"ui.browser.browser_tab_strip.watch": "Смотреть «{title}»",
|
|
49597
49612
|
"ui.browser.browser_url_bar.address": "Адрес",
|
|
49598
|
-
"ui.browser.browser_url_bar.
|
|
49613
|
+
"ui.browser.browser_url_bar.address_search_row": "Искать «{query}» в DuckDuckGo",
|
|
49614
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab": "Уже открыто — {title}",
|
|
49615
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab_untitled": "Уже открыто",
|
|
49599
49616
|
"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} подсказки доступны}}",
|
|
49600
|
-
"ui.browser.browser_url_bar.
|
|
49601
|
-
"ui.browser.browser_url_bar.
|
|
49602
|
-
"ui.browser.browser_url_bar.
|
|
49617
|
+
"ui.browser.browser_url_bar.address_suggestions_blocked": "Здесь можно открывать только веб-адреса.",
|
|
49618
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "Истории просмотров пока нет.",
|
|
49619
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "Из вашей истории",
|
|
49620
|
+
"ui.browser.browser_url_bar.address_suggestions_label_mixed": "Подсказки",
|
|
49621
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "В вашей истории нет подходящих страниц.",
|
|
49603
49622
|
"ui.browser.browser_url_bar.address_suggestions_unavailable": "Подсказки адресов недоступны.",
|
|
49604
49623
|
"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}}}",
|
|
49605
49624
|
"ui.browser.browser_url_bar.back": "Назад",
|
|
@@ -53055,11 +53074,15 @@ const urUiBrowser = {
|
|
|
53055
53074
|
"ui.browser.browser_tab_strip.unmute_tab": "ٹیب کی آواز بحال کریں",
|
|
53056
53075
|
"ui.browser.browser_tab_strip.watch": "“{title}” پر نظر رکھیں",
|
|
53057
53076
|
"ui.browser.browser_url_bar.address": "پتہ",
|
|
53058
|
-
"ui.browser.browser_url_bar.
|
|
53077
|
+
"ui.browser.browser_url_bar.address_search_row": 'DuckDuckGo پر "{query}" تلاش کریں',
|
|
53078
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab": "پہلے سے کھلا — {title}",
|
|
53079
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab_untitled": "پہلے سے کھلا",
|
|
53059
53080
|
"ui.browser.browser_url_bar.address_suggestions_available": "{count, plural, one {{count, number, ::group-off} تجویز دستیاب ہے} other {{count, number, ::group-off} تجاویز دستیاب ہیں}}",
|
|
53060
|
-
"ui.browser.browser_url_bar.
|
|
53061
|
-
"ui.browser.browser_url_bar.
|
|
53062
|
-
"ui.browser.browser_url_bar.
|
|
53081
|
+
"ui.browser.browser_url_bar.address_suggestions_blocked": "یہاں صرف ویب پتے کھل سکتے ہیں۔",
|
|
53082
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "ابھی تک کوئی براؤزنگ سرگزشت نہیں۔",
|
|
53083
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "آپ کی سرگزشت سے",
|
|
53084
|
+
"ui.browser.browser_url_bar.address_suggestions_label_mixed": "تجاویز",
|
|
53085
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "آپ کی سرگزشت میں کوئی مماثل صفحہ نہیں۔",
|
|
53063
53086
|
"ui.browser.browser_url_bar.address_suggestions_unavailable": "پتے کی تجاویز دستیاب نہیں ہیں۔",
|
|
53064
53087
|
"ui.browser.browser_url_bar.approvals_waiting": "منظوریاں، {count, plural, other {{count, number, ::group-off} منتظر}}",
|
|
53065
53088
|
"ui.browser.browser_url_bar.back": "پیچھے",
|
|
@@ -56429,11 +56452,15 @@ const viUiBrowser = {
|
|
|
56429
56452
|
"ui.browser.browser_tab_strip.unmute_tab": "Bật tiếng tab",
|
|
56430
56453
|
"ui.browser.browser_tab_strip.watch": 'Theo dõi "{title}"',
|
|
56431
56454
|
"ui.browser.browser_url_bar.address": "Địa chỉ",
|
|
56432
|
-
"ui.browser.browser_url_bar.
|
|
56455
|
+
"ui.browser.browser_url_bar.address_search_row": 'Tìm "{query}" trên DuckDuckGo',
|
|
56456
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab": "Đã mở — {title}",
|
|
56457
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab_untitled": "Đã mở",
|
|
56433
56458
|
"ui.browser.browser_url_bar.address_suggestions_available": "{count, plural, other {{count, number, ::group-off} gợi ý có sẵn}}",
|
|
56434
|
-
"ui.browser.browser_url_bar.
|
|
56435
|
-
"ui.browser.browser_url_bar.
|
|
56436
|
-
"ui.browser.browser_url_bar.
|
|
56459
|
+
"ui.browser.browser_url_bar.address_suggestions_blocked": "Chỉ có thể mở địa chỉ web ở đây.",
|
|
56460
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "Chưa có lịch sử duyệt web.",
|
|
56461
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "Từ lịch sử của bạn",
|
|
56462
|
+
"ui.browser.browser_url_bar.address_suggestions_label_mixed": "Gợi ý",
|
|
56463
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "Không có trang nào phù hợp trong lịch sử của bạn.",
|
|
56437
56464
|
"ui.browser.browser_url_bar.address_suggestions_unavailable": "Gợi ý địa chỉ không khả dụng.",
|
|
56438
56465
|
"ui.browser.browser_url_bar.approvals_waiting": "Phê duyệt, {count, plural, other {{count, number, ::group-off} đang chờ}}",
|
|
56439
56466
|
"ui.browser.browser_url_bar.back": "Quay lại",
|
|
@@ -59698,11 +59725,15 @@ const zhCNUiBrowser = {
|
|
|
59698
59725
|
"ui.browser.browser_tab_strip.unmute_tab": "取消标签页静音",
|
|
59699
59726
|
"ui.browser.browser_tab_strip.watch": "查看“{title}”",
|
|
59700
59727
|
"ui.browser.browser_url_bar.address": "地址",
|
|
59701
|
-
"ui.browser.browser_url_bar.
|
|
59728
|
+
"ui.browser.browser_url_bar.address_search_row": "在 DuckDuckGo 中搜索“{query}”",
|
|
59729
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab": "已打开 — {title}",
|
|
59730
|
+
"ui.browser.browser_url_bar.address_suggestion_open_tab_untitled": "已打开",
|
|
59702
59731
|
"ui.browser.browser_url_bar.address_suggestions_available": "{count, plural, other {{count, number, ::group-off}条建议可用}}",
|
|
59703
|
-
"ui.browser.browser_url_bar.
|
|
59704
|
-
"ui.browser.browser_url_bar.
|
|
59705
|
-
"ui.browser.browser_url_bar.
|
|
59732
|
+
"ui.browser.browser_url_bar.address_suggestions_blocked": "此处只能打开网页地址。",
|
|
59733
|
+
"ui.browser.browser_url_bar.address_suggestions_empty": "还没有浏览历史记录。",
|
|
59734
|
+
"ui.browser.browser_url_bar.address_suggestions_label": "来自你的历史记录",
|
|
59735
|
+
"ui.browser.browser_url_bar.address_suggestions_label_mixed": "建议",
|
|
59736
|
+
"ui.browser.browser_url_bar.address_suggestions_no_match": "你的历史记录中没有匹配的页面。",
|
|
59706
59737
|
"ui.browser.browser_url_bar.address_suggestions_unavailable": "地址建议不可用。",
|
|
59707
59738
|
"ui.browser.browser_url_bar.approvals_waiting": "审批,{count, plural, other {{count, number, ::group-off}项待处理}}",
|
|
59708
59739
|
"ui.browser.browser_url_bar.back": "后退",
|
|
@@ -65995,7 +66026,8 @@ const ADDRESS_HISTORY_MAX_ENTRIES_PER_TAB = 50;
|
|
|
65995
66026
|
const ADDRESS_HISTORY_MAX_ENTRIES = 256;
|
|
65996
66027
|
const ADDRESS_HISTORY_MAX_URL_LENGTH = 2048;
|
|
65997
66028
|
const ADDRESS_HISTORY_MAX_TITLE_LENGTH = 256;
|
|
65998
|
-
const
|
|
66029
|
+
const ADDRESS_HISTORY_MAX_QUERY_LENGTH = ADDRESS_HISTORY_MAX_URL_LENGTH;
|
|
66030
|
+
const ADDRESS_HISTORY_MAX_LIMIT = 20;
|
|
65999
66031
|
const CONTROL_CHARS$1 = /[\p{Cc}]/u;
|
|
66000
66032
|
function windowAround(entries, activeIndexRaw, max) {
|
|
66001
66033
|
const activeIndex = Math.min(
|
|
@@ -66071,12 +66103,9 @@ function historyTitle(raw) {
|
|
|
66071
66103
|
const cleaned = raw.replace(CONTROL_CHARS$1, " ").replace(/\s+/g, " ").trim();
|
|
66072
66104
|
return cleaned.length > ADDRESS_HISTORY_MAX_TITLE_LENGTH ? cleaned.slice(0, ADDRESS_HISTORY_MAX_TITLE_LENGTH) : cleaned;
|
|
66073
66105
|
}
|
|
66074
|
-
function collectAddressHistory(tabs2,
|
|
66075
|
-
const
|
|
66076
|
-
|
|
66077
|
-
);
|
|
66078
|
-
const active = inScope.find((tab) => tab.tabId === activeTabId);
|
|
66079
|
-
const ordered = active ? [active, ...inScope.filter((tab) => tab.tabId !== activeTabId)] : inScope;
|
|
66106
|
+
function collectAddressHistory(tabs2, activeTabId) {
|
|
66107
|
+
const active = tabs2.find((tab) => tab.tabId === activeTabId);
|
|
66108
|
+
const ordered = active ? [active, ...tabs2.filter((tab) => tab.tabId !== activeTabId)] : [...tabs2];
|
|
66080
66109
|
const seen = /* @__PURE__ */ new Set();
|
|
66081
66110
|
const entries = [];
|
|
66082
66111
|
for (const tab of ordered.slice(0, ADDRESS_HISTORY_MAX_TABS)) {
|
|
@@ -66092,6 +66121,12 @@ function collectAddressHistory(tabs2, scope, activeTabId) {
|
|
|
66092
66121
|
entries.push({
|
|
66093
66122
|
url,
|
|
66094
66123
|
title: historyTitle(entry.title),
|
|
66124
|
+
// A stack has no visit count and no visit timestamp. Zero is the
|
|
66125
|
+
// honest absence; the renderer treats a tab row's order as stack
|
|
66126
|
+
// distance, never as frequency.
|
|
66127
|
+
visitCount: 0,
|
|
66128
|
+
lastVisitedAt: 0,
|
|
66129
|
+
source: "tab",
|
|
66095
66130
|
sourceTabId: tab.tabId,
|
|
66096
66131
|
sourceIndex,
|
|
66097
66132
|
activeTab: tab.tabId === activeTabId,
|
|
@@ -66105,6 +66140,38 @@ function collectAddressHistory(tabs2, scope, activeTabId) {
|
|
|
66105
66140
|
}
|
|
66106
66141
|
return { activeTabId, entries };
|
|
66107
66142
|
}
|
|
66143
|
+
function foldAscii(value) {
|
|
66144
|
+
return value.replace(/[A-Z]/g, (letter) => letter.toLowerCase());
|
|
66145
|
+
}
|
|
66146
|
+
function mergeAddressHistory(tabEntries, historyEntries, query, limit) {
|
|
66147
|
+
const cap = Math.max(0, Math.floor(limit));
|
|
66148
|
+
if (cap === 0) return [];
|
|
66149
|
+
const seen = /* @__PURE__ */ new Set();
|
|
66150
|
+
const merged = [];
|
|
66151
|
+
for (const entry of historyEntries) {
|
|
66152
|
+
if (merged.length >= cap) break;
|
|
66153
|
+
const url = canonicalHistoryUrl(entry.url);
|
|
66154
|
+
if (!url || seen.has(url)) continue;
|
|
66155
|
+
seen.add(url);
|
|
66156
|
+
merged.push({
|
|
66157
|
+
url,
|
|
66158
|
+
title: historyTitle(entry.title),
|
|
66159
|
+
visitCount: entry.visitCount,
|
|
66160
|
+
lastVisitedAt: entry.lastVisitedAt,
|
|
66161
|
+
source: "history"
|
|
66162
|
+
});
|
|
66163
|
+
}
|
|
66164
|
+
const needle = foldAscii(query.trim());
|
|
66165
|
+
for (const entry of tabEntries) {
|
|
66166
|
+
if (merged.length >= cap) break;
|
|
66167
|
+
if (seen.has(entry.url)) continue;
|
|
66168
|
+
if (needle.length > 0 && !foldAscii(entry.url).includes(needle) && !foldAscii(entry.title).includes(needle))
|
|
66169
|
+
continue;
|
|
66170
|
+
seen.add(entry.url);
|
|
66171
|
+
merged.push(entry);
|
|
66172
|
+
}
|
|
66173
|
+
return merged;
|
|
66174
|
+
}
|
|
66108
66175
|
class ChromeTabOrder {
|
|
66109
66176
|
ids = [];
|
|
66110
66177
|
customized = false;
|
|
@@ -66134,6 +66201,305 @@ class ChromeTabOrder {
|
|
|
66134
66201
|
return true;
|
|
66135
66202
|
}
|
|
66136
66203
|
}
|
|
66204
|
+
const HISTORY_STORE_VERSION = 1;
|
|
66205
|
+
const HISTORY_STORE_MAX_ENTRIES = 5e3;
|
|
66206
|
+
const HISTORY_STORE_MAX_BYTES = 2 * 1024 * 1024;
|
|
66207
|
+
const HISTORY_STORE_WRITE_DEBOUNCE_MS = 500;
|
|
66208
|
+
const HISTORY_STORE_MAX_CANDIDATES = 200;
|
|
66209
|
+
const PREFIX_WIDTH = 3;
|
|
66210
|
+
const RECENCY_HALF_LIFE_DAYS = 7;
|
|
66211
|
+
const DAY_MS = 24 * 60 * 60 * 1e3;
|
|
66212
|
+
const SCHEME_PREFIX = /^([a-z][a-z0-9+.-]*):\/\//i;
|
|
66213
|
+
const PATH_OR_QUERY = /[/?#]/;
|
|
66214
|
+
function schemeLess(value) {
|
|
66215
|
+
const match = SCHEME_PREFIX.exec(value);
|
|
66216
|
+
return match ? value.slice(match[0].length) : value;
|
|
66217
|
+
}
|
|
66218
|
+
function stripWww(value) {
|
|
66219
|
+
return value.startsWith("www.") && value.length > "www.".length ? value.slice("www.".length) : value;
|
|
66220
|
+
}
|
|
66221
|
+
function matchKey(value) {
|
|
66222
|
+
return stripWww(schemeLess(value.trim()).toLowerCase());
|
|
66223
|
+
}
|
|
66224
|
+
function literalKey(value) {
|
|
66225
|
+
return schemeLess(value.trim()).toLowerCase();
|
|
66226
|
+
}
|
|
66227
|
+
function indexKeys(url) {
|
|
66228
|
+
const keys = /* @__PURE__ */ new Set([literalKey(url), matchKey(url)]);
|
|
66229
|
+
return [...keys].filter((key) => key.length > 0);
|
|
66230
|
+
}
|
|
66231
|
+
function queryNeedles(raw) {
|
|
66232
|
+
const literal = literalKey(raw);
|
|
66233
|
+
const keys = /* @__PURE__ */ new Set([literal, stripWww(literal)]);
|
|
66234
|
+
return [...keys].filter((key) => key.length > 0);
|
|
66235
|
+
}
|
|
66236
|
+
function matchesNeedle(value, needle) {
|
|
66237
|
+
if (!value.startsWith(needle)) return false;
|
|
66238
|
+
const hostOnly = !PATH_OR_QUERY.test(needle);
|
|
66239
|
+
if (!hostOnly) return true;
|
|
66240
|
+
if (!needle.includes(".") || needle.endsWith(".")) return true;
|
|
66241
|
+
const next = value.charAt(needle.length);
|
|
66242
|
+
return next === "" || next === "/" || next === "?" || next === "#" || next === ":";
|
|
66243
|
+
}
|
|
66244
|
+
function prefixKey(matchKeyValue) {
|
|
66245
|
+
return matchKeyValue.slice(0, PREFIX_WIDTH);
|
|
66246
|
+
}
|
|
66247
|
+
function historyScore(entry, now) {
|
|
66248
|
+
const ageDays = Math.max(0, now - entry.lastVisitedAt) / DAY_MS;
|
|
66249
|
+
return Math.log2(1 + entry.visitCount) + 0.5 ** (ageDays / RECENCY_HALF_LIFE_DAYS);
|
|
66250
|
+
}
|
|
66251
|
+
function compareEntries(now) {
|
|
66252
|
+
return (a, b) => {
|
|
66253
|
+
const scoreDiff = historyScore(b, now) - historyScore(a, now);
|
|
66254
|
+
if (scoreDiff !== 0) return scoreDiff;
|
|
66255
|
+
if (a.lastVisitedAt !== b.lastVisitedAt)
|
|
66256
|
+
return b.lastVisitedAt - a.lastVisitedAt;
|
|
66257
|
+
return a.url < b.url ? -1 : a.url > b.url ? 1 : 0;
|
|
66258
|
+
};
|
|
66259
|
+
}
|
|
66260
|
+
function storageUrl(raw) {
|
|
66261
|
+
const canonical = canonicalHistoryUrl(raw);
|
|
66262
|
+
if (!canonical) return null;
|
|
66263
|
+
const hash = canonical.indexOf("#");
|
|
66264
|
+
return hash < 0 ? canonical : canonical.slice(0, hash);
|
|
66265
|
+
}
|
|
66266
|
+
function isEntry(value) {
|
|
66267
|
+
if (typeof value !== "object" || value === null) return false;
|
|
66268
|
+
const record = value;
|
|
66269
|
+
return typeof record.url === "string" && typeof record.title === "string" && typeof record.host === "string" && Number.isSafeInteger(record.visitCount) && record.visitCount > 0 && typeof record.lastVisitedAt === "number" && Number.isFinite(record.lastVisitedAt);
|
|
66270
|
+
}
|
|
66271
|
+
function createBrowserHistoryStore(filePath, options = {}) {
|
|
66272
|
+
const now = options.now ?? Date.now;
|
|
66273
|
+
const byUrl = /* @__PURE__ */ new Map();
|
|
66274
|
+
const prefix = /* @__PURE__ */ new Map();
|
|
66275
|
+
let writeTimer = null;
|
|
66276
|
+
let approxBytes = 0;
|
|
66277
|
+
function estimate(entry) {
|
|
66278
|
+
return entry.url.length + entry.title.length + entry.host.length + 192;
|
|
66279
|
+
}
|
|
66280
|
+
function indexAdd(entry) {
|
|
66281
|
+
approxBytes += estimate(entry);
|
|
66282
|
+
for (const key of indexKeys(entry.url)) {
|
|
66283
|
+
const bucketKey = prefixKey(key);
|
|
66284
|
+
let bucket = prefix.get(bucketKey);
|
|
66285
|
+
if (!bucket) {
|
|
66286
|
+
bucket = /* @__PURE__ */ new Set();
|
|
66287
|
+
prefix.set(bucketKey, bucket);
|
|
66288
|
+
}
|
|
66289
|
+
bucket.add(entry.url);
|
|
66290
|
+
}
|
|
66291
|
+
}
|
|
66292
|
+
function indexRemove(entry) {
|
|
66293
|
+
approxBytes -= estimate(entry);
|
|
66294
|
+
for (const key of indexKeys(entry.url)) {
|
|
66295
|
+
const bucketKey = prefixKey(key);
|
|
66296
|
+
const bucket = prefix.get(bucketKey);
|
|
66297
|
+
bucket?.delete(entry.url);
|
|
66298
|
+
if (bucket?.size === 0) prefix.delete(bucketKey);
|
|
66299
|
+
}
|
|
66300
|
+
}
|
|
66301
|
+
function setTitle(entry, next) {
|
|
66302
|
+
const before = estimate(entry);
|
|
66303
|
+
entry.title = next;
|
|
66304
|
+
approxBytes += estimate(entry) - before;
|
|
66305
|
+
}
|
|
66306
|
+
function enforceBounds(at) {
|
|
66307
|
+
let changed = false;
|
|
66308
|
+
if (byUrl.size <= HISTORY_STORE_MAX_ENTRIES && approxBytes <= HISTORY_STORE_MAX_BYTES)
|
|
66309
|
+
return false;
|
|
66310
|
+
if (byUrl.size > HISTORY_STORE_MAX_ENTRIES) {
|
|
66311
|
+
const overflow = byUrl.size - HISTORY_STORE_MAX_ENTRIES;
|
|
66312
|
+
const victims = [...byUrl.values()].sort(compareEntries(at)).reverse().slice(0, overflow);
|
|
66313
|
+
for (const victim of victims) {
|
|
66314
|
+
byUrl.delete(victim.url);
|
|
66315
|
+
indexRemove(victim);
|
|
66316
|
+
changed = true;
|
|
66317
|
+
}
|
|
66318
|
+
}
|
|
66319
|
+
let guard = 0;
|
|
66320
|
+
while (guard < 200 && byUrl.size > 0) {
|
|
66321
|
+
guard += 1;
|
|
66322
|
+
const bytes = Buffer.byteLength(
|
|
66323
|
+
JSON.stringify(document(), null, 2),
|
|
66324
|
+
"utf8"
|
|
66325
|
+
);
|
|
66326
|
+
if (bytes <= HISTORY_STORE_MAX_BYTES) {
|
|
66327
|
+
approxBytes = bytes;
|
|
66328
|
+
break;
|
|
66329
|
+
}
|
|
66330
|
+
const batch = Math.max(1, Math.ceil(byUrl.size / 100));
|
|
66331
|
+
const victims = [...byUrl.values()].sort(compareEntries(at)).reverse().slice(0, batch);
|
|
66332
|
+
for (const victim of victims) {
|
|
66333
|
+
byUrl.delete(victim.url);
|
|
66334
|
+
indexRemove(victim);
|
|
66335
|
+
changed = true;
|
|
66336
|
+
}
|
|
66337
|
+
}
|
|
66338
|
+
return changed;
|
|
66339
|
+
}
|
|
66340
|
+
function document() {
|
|
66341
|
+
return {
|
|
66342
|
+
version: HISTORY_STORE_VERSION,
|
|
66343
|
+
entries: [...byUrl.values()]
|
|
66344
|
+
};
|
|
66345
|
+
}
|
|
66346
|
+
function writeNow() {
|
|
66347
|
+
if (writeTimer !== null) {
|
|
66348
|
+
clearTimeout(writeTimer);
|
|
66349
|
+
writeTimer = null;
|
|
66350
|
+
}
|
|
66351
|
+
writeJsonAtomic(filePath, document());
|
|
66352
|
+
}
|
|
66353
|
+
function scheduleWrite2() {
|
|
66354
|
+
if (writeTimer !== null) return;
|
|
66355
|
+
writeTimer = setTimeout(() => {
|
|
66356
|
+
writeTimer = null;
|
|
66357
|
+
writeJsonAtomic(filePath, document());
|
|
66358
|
+
}, HISTORY_STORE_WRITE_DEBOUNCE_MS);
|
|
66359
|
+
writeTimer.unref?.();
|
|
66360
|
+
}
|
|
66361
|
+
const loaded = readJson(filePath);
|
|
66362
|
+
if (loaded && loaded.version === HISTORY_STORE_VERSION && Array.isArray(loaded.entries)) {
|
|
66363
|
+
for (const raw of loaded.entries) {
|
|
66364
|
+
if (!isEntry(raw)) continue;
|
|
66365
|
+
const url = storageUrl(raw.url);
|
|
66366
|
+
if (!url) continue;
|
|
66367
|
+
const host = new URL(url).host;
|
|
66368
|
+
const existing = byUrl.get(url);
|
|
66369
|
+
if (existing) {
|
|
66370
|
+
existing.visitCount = Math.max(existing.visitCount, raw.visitCount);
|
|
66371
|
+
existing.lastVisitedAt = Math.max(
|
|
66372
|
+
existing.lastVisitedAt,
|
|
66373
|
+
raw.lastVisitedAt
|
|
66374
|
+
);
|
|
66375
|
+
if (existing.title.length === 0) {
|
|
66376
|
+
const title = historyTitle(raw.title);
|
|
66377
|
+
if (title.length > 0) setTitle(existing, title);
|
|
66378
|
+
}
|
|
66379
|
+
continue;
|
|
66380
|
+
}
|
|
66381
|
+
const entry = {
|
|
66382
|
+
url,
|
|
66383
|
+
title: historyTitle(raw.title),
|
|
66384
|
+
host,
|
|
66385
|
+
visitCount: raw.visitCount,
|
|
66386
|
+
lastVisitedAt: raw.lastVisitedAt
|
|
66387
|
+
};
|
|
66388
|
+
byUrl.set(url, entry);
|
|
66389
|
+
indexAdd(entry);
|
|
66390
|
+
}
|
|
66391
|
+
if (enforceBounds(now())) {
|
|
66392
|
+
writeNow();
|
|
66393
|
+
}
|
|
66394
|
+
}
|
|
66395
|
+
return {
|
|
66396
|
+
record(rawUrl, rawTitle, at = now()) {
|
|
66397
|
+
const url = storageUrl(rawUrl);
|
|
66398
|
+
if (!url) return;
|
|
66399
|
+
const title = historyTitle(rawTitle);
|
|
66400
|
+
const existing = byUrl.get(url);
|
|
66401
|
+
if (existing) {
|
|
66402
|
+
existing.visitCount += 1;
|
|
66403
|
+
existing.lastVisitedAt = at;
|
|
66404
|
+
if (title.length > 0 && title !== existing.title)
|
|
66405
|
+
setTitle(existing, title);
|
|
66406
|
+
} else {
|
|
66407
|
+
const entry = {
|
|
66408
|
+
url,
|
|
66409
|
+
title,
|
|
66410
|
+
host: new URL(url).host,
|
|
66411
|
+
visitCount: 1,
|
|
66412
|
+
lastVisitedAt: at
|
|
66413
|
+
};
|
|
66414
|
+
byUrl.set(url, entry);
|
|
66415
|
+
indexAdd(entry);
|
|
66416
|
+
}
|
|
66417
|
+
enforceBounds(at);
|
|
66418
|
+
scheduleWrite2();
|
|
66419
|
+
},
|
|
66420
|
+
updateTitle(rawUrl, rawTitle) {
|
|
66421
|
+
const url = storageUrl(rawUrl);
|
|
66422
|
+
if (!url) return;
|
|
66423
|
+
const entry = byUrl.get(url);
|
|
66424
|
+
if (!entry) return;
|
|
66425
|
+
const title = historyTitle(rawTitle);
|
|
66426
|
+
if (title.length === 0 || title === entry.title) return;
|
|
66427
|
+
setTitle(entry, title);
|
|
66428
|
+
enforceBounds(now());
|
|
66429
|
+
scheduleWrite2();
|
|
66430
|
+
},
|
|
66431
|
+
suggest(rawQuery, limit) {
|
|
66432
|
+
const wanted = Math.max(0, Math.floor(limit));
|
|
66433
|
+
if (wanted === 0 || byUrl.size === 0) return [];
|
|
66434
|
+
const at = now();
|
|
66435
|
+
if (rawQuery.length === 0) {
|
|
66436
|
+
return [...byUrl.values()].sort(compareEntries(at)).slice(0, wanted);
|
|
66437
|
+
}
|
|
66438
|
+
const needles = queryNeedles(rawQuery);
|
|
66439
|
+
if (needles.length === 0) return [];
|
|
66440
|
+
const bucketSet = /* @__PURE__ */ new Set();
|
|
66441
|
+
for (const needle of needles) {
|
|
66442
|
+
if (needle.length >= PREFIX_WIDTH) {
|
|
66443
|
+
const bucket = prefix.get(prefixKey(needle));
|
|
66444
|
+
if (bucket) bucketSet.add(bucket);
|
|
66445
|
+
} else {
|
|
66446
|
+
for (const [key, bucket] of prefix) {
|
|
66447
|
+
if (key.startsWith(needle)) bucketSet.add(bucket);
|
|
66448
|
+
}
|
|
66449
|
+
}
|
|
66450
|
+
}
|
|
66451
|
+
const buckets = [...bucketSet];
|
|
66452
|
+
if (buckets.length === 0) return [];
|
|
66453
|
+
const candidates = [];
|
|
66454
|
+
const seen = /* @__PURE__ */ new Set();
|
|
66455
|
+
for (const bucket of buckets) {
|
|
66456
|
+
for (const url of bucket) {
|
|
66457
|
+
if (candidates.length >= HISTORY_STORE_MAX_CANDIDATES) break;
|
|
66458
|
+
if (seen.has(url)) continue;
|
|
66459
|
+
const keys = indexKeys(url);
|
|
66460
|
+
const hit = needles.some(
|
|
66461
|
+
(needle) => keys.some((key) => matchesNeedle(key, needle))
|
|
66462
|
+
);
|
|
66463
|
+
if (!hit) continue;
|
|
66464
|
+
const entry = byUrl.get(url);
|
|
66465
|
+
if (!entry) continue;
|
|
66466
|
+
seen.add(url);
|
|
66467
|
+
candidates.push(entry);
|
|
66468
|
+
}
|
|
66469
|
+
if (candidates.length >= HISTORY_STORE_MAX_CANDIDATES) break;
|
|
66470
|
+
}
|
|
66471
|
+
candidates.sort(compareEntries(at));
|
|
66472
|
+
return candidates.slice(0, wanted);
|
|
66473
|
+
},
|
|
66474
|
+
size() {
|
|
66475
|
+
return byUrl.size;
|
|
66476
|
+
},
|
|
66477
|
+
clear() {
|
|
66478
|
+
byUrl.clear();
|
|
66479
|
+
prefix.clear();
|
|
66480
|
+
writeNow();
|
|
66481
|
+
},
|
|
66482
|
+
clearOrigin(rawOrigin) {
|
|
66483
|
+
let parsed;
|
|
66484
|
+
try {
|
|
66485
|
+
parsed = new URL(rawOrigin);
|
|
66486
|
+
} catch {
|
|
66487
|
+
return;
|
|
66488
|
+
}
|
|
66489
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return;
|
|
66490
|
+
const origin = parsed.origin;
|
|
66491
|
+
for (const [url, entry] of [...byUrl.entries()]) {
|
|
66492
|
+
if (new URL(url).origin !== origin) continue;
|
|
66493
|
+
byUrl.delete(url);
|
|
66494
|
+
indexRemove(entry);
|
|
66495
|
+
}
|
|
66496
|
+
writeNow();
|
|
66497
|
+
},
|
|
66498
|
+
flush() {
|
|
66499
|
+
if (writeTimer !== null) writeNow();
|
|
66500
|
+
}
|
|
66501
|
+
};
|
|
66502
|
+
}
|
|
66137
66503
|
const PAGE_ZOOM_STEPS = [
|
|
66138
66504
|
0.25,
|
|
66139
66505
|
0.33,
|
|
@@ -66512,6 +66878,9 @@ class BrowserHost {
|
|
|
66512
66878
|
* projection as the tabs, so the renderer has one source for "child or
|
|
66513
66879
|
* fallback" and never guesses from a failed IPC call. */
|
|
66514
66880
|
addressOverlayMode;
|
|
66881
|
+
/** One instance per host, constructed once in the constructor. `null` when
|
|
66882
|
+
* no path was supplied (see `BrowserHostOptions.historyFilePath`). */
|
|
66883
|
+
historyStore;
|
|
66515
66884
|
/**
|
|
66516
66885
|
* The last main-frame load failure per tab, cleared by the next load.
|
|
66517
66886
|
*
|
|
@@ -66538,6 +66907,7 @@ class BrowserHost {
|
|
|
66538
66907
|
this.facts = options.facts;
|
|
66539
66908
|
this.forgetSiteData = options.forgetSiteData;
|
|
66540
66909
|
this.addressOverlayMode = options.addressOverlayMode ?? (() => ({ mode: "suspend", reason: "unavailable" }));
|
|
66910
|
+
this.historyStore = options.historyFilePath ? createBrowserHistoryStore(options.historyFilePath) : null;
|
|
66541
66911
|
}
|
|
66542
66912
|
/** Answer one wire request. The only place a method name becomes an action. */
|
|
66543
66913
|
async dispatch(method, params, requestId2) {
|
|
@@ -67405,8 +67775,13 @@ class BrowserHost {
|
|
|
67405
67775
|
* no longer matches, which covers the race between this check and the reply
|
|
67406
67776
|
* landing.
|
|
67407
67777
|
*
|
|
67408
|
-
*
|
|
67409
|
-
*
|
|
67778
|
+
* RANKING MOVED HERE with the persistent store: the renderer used to rank a
|
|
67779
|
+
* snapshot of every stack, which cannot scale to a 5000-entry history either
|
|
67780
|
+
* in memory or across IPC. Main now asks the store for its top matches, puts
|
|
67781
|
+
* them ahead of the live-tab rows (`mergeAddressHistory`), and bounds the
|
|
67782
|
+
* answer by `request.limit`. The renderer still derives display text, the
|
|
67783
|
+
* target URL and the inline suffix, because those depend on exactly what the
|
|
67784
|
+
* user typed.
|
|
67410
67785
|
*/
|
|
67411
67786
|
addressHistory(request) {
|
|
67412
67787
|
const activeTabId = this.registry.activeTab?.tabId ?? null;
|
|
@@ -67416,20 +67791,59 @@ class BrowserHost {
|
|
|
67416
67791
|
"the active tab changed before suggestions were read"
|
|
67417
67792
|
);
|
|
67418
67793
|
}
|
|
67794
|
+
const live = collectAddressHistory(
|
|
67795
|
+
this.registry.list().map((record) => ({
|
|
67796
|
+
tabId: record.tabId,
|
|
67797
|
+
sessionId: record.sessionId,
|
|
67798
|
+
webContents: record.view.webContents,
|
|
67799
|
+
restoreRow: record.restoreRow ?? null
|
|
67800
|
+
})),
|
|
67801
|
+
activeTabId
|
|
67802
|
+
);
|
|
67803
|
+
const historyMatches = this.historyStore?.suggest(request.query, request.limit) ?? [];
|
|
67419
67804
|
return {
|
|
67420
67805
|
requestId: request.requestId,
|
|
67421
|
-
|
|
67422
|
-
|
|
67423
|
-
|
|
67424
|
-
|
|
67425
|
-
|
|
67426
|
-
|
|
67427
|
-
})),
|
|
67428
|
-
request.scope,
|
|
67429
|
-
activeTabId
|
|
67806
|
+
activeTabId: live.activeTabId,
|
|
67807
|
+
entries: mergeAddressHistory(
|
|
67808
|
+
live.entries,
|
|
67809
|
+
historyMatches,
|
|
67810
|
+
request.query,
|
|
67811
|
+
request.limit
|
|
67430
67812
|
)
|
|
67431
67813
|
};
|
|
67432
67814
|
}
|
|
67815
|
+
/**
|
|
67816
|
+
* Record one committed top-level navigation.
|
|
67817
|
+
*
|
|
67818
|
+
* Called from the per-view wiring in `index.ts`, which is the only place that
|
|
67819
|
+
* sees the event for every tab. A non-HTTP(S) URL is dropped by the store, so
|
|
67820
|
+
* `about:blank`, `chrome://` and a refused scheme never enter the document.
|
|
67821
|
+
* The title is filled in by `recordHistoryTitle` when Chromium announces it;
|
|
67822
|
+
* recording the visit first is deliberate, because the commit is the fact and
|
|
67823
|
+
* the title is a later, optional update.
|
|
67824
|
+
*/
|
|
67825
|
+
recordHistoryVisit(url) {
|
|
67826
|
+
this.historyStore?.record(url, "");
|
|
67827
|
+
}
|
|
67828
|
+
/** Update the stored title for a URL that is already in the history. Never
|
|
67829
|
+
* increments a visit: `page-title-updated` fires for a page that has already
|
|
67830
|
+
* been counted, sometimes several times. */
|
|
67831
|
+
recordHistoryTitle(url, title) {
|
|
67832
|
+
this.historyStore?.updateTitle(url, title);
|
|
67833
|
+
}
|
|
67834
|
+
/** Write any debounced history change now (quit, and the host's own stop). */
|
|
67835
|
+
flushHistory() {
|
|
67836
|
+
this.historyStore?.flush();
|
|
67837
|
+
}
|
|
67838
|
+
/** "Clear everything" also forgets the suggestion history (`profile.ts` is
|
|
67839
|
+
* the path that calls this, so cookies/cache alone cannot reach it). */
|
|
67840
|
+
clearHistory() {
|
|
67841
|
+
this.historyStore?.clear();
|
|
67842
|
+
}
|
|
67843
|
+
/** "Forget this site" drops that origin's rows; other origins stay. */
|
|
67844
|
+
clearOriginHistory(origin) {
|
|
67845
|
+
this.historyStore?.clearOrigin(origin);
|
|
67846
|
+
}
|
|
67433
67847
|
/**
|
|
67434
67848
|
* A URL the USER typed goes through here, and it is deliberately different from
|
|
67435
67849
|
* an agent navigation in one way and identical in another (design 6.1):
|
|
@@ -68889,21 +69303,17 @@ function addressHistoryRequestOrThrow(value) {
|
|
|
68889
69303
|
const request = value;
|
|
68890
69304
|
const requestId2 = numberOrThrow(request.requestId, "requestId");
|
|
68891
69305
|
const expectedTabId = tabIdOrThrow(request.expectedTabId, "expectedTabId");
|
|
68892
|
-
|
|
68893
|
-
|
|
68894
|
-
|
|
68895
|
-
|
|
68896
|
-
|
|
68897
|
-
|
|
68898
|
-
|
|
68899
|
-
|
|
68900
|
-
|
|
68901
|
-
}
|
|
68902
|
-
scope = { sessionId: sessionId2 };
|
|
68903
|
-
} else {
|
|
68904
|
-
throw new Error("The address history scope is invalid.");
|
|
69306
|
+
if (typeof request.query !== "string") {
|
|
69307
|
+
throw new Error("The address history query must be a string.");
|
|
69308
|
+
}
|
|
69309
|
+
const query = request.query;
|
|
69310
|
+
if (query.length > ADDRESS_HISTORY_MAX_QUERY_LENGTH || CONTROL_CHARS.test(query)) {
|
|
69311
|
+
throw new Error("The address history query is invalid.");
|
|
69312
|
+
}
|
|
69313
|
+
if (typeof request.limit !== "number" || !Number.isSafeInteger(request.limit) || request.limit < 1 || request.limit > ADDRESS_HISTORY_MAX_LIMIT) {
|
|
69314
|
+
throw new Error("The address history limit is invalid.");
|
|
68905
69315
|
}
|
|
68906
|
-
return { requestId: requestId2, expectedTabId,
|
|
69316
|
+
return { requestId: requestId2, expectedTabId, query, limit: request.limit };
|
|
68907
69317
|
}
|
|
68908
69318
|
function closeTabsIntentOrThrow(value) {
|
|
68909
69319
|
if (!value || typeof value !== "object") {
|
|
@@ -69422,7 +69832,7 @@ function installBrowserSessionHandlers(browserSession, hooks = {}) {
|
|
|
69422
69832
|
browserSession.removeListener("will-download", onDownload);
|
|
69423
69833
|
};
|
|
69424
69834
|
}
|
|
69425
|
-
async function clearBrowsingData(browserSession, what) {
|
|
69835
|
+
async function clearBrowsingData(browserSession, what, history) {
|
|
69426
69836
|
browserSession.flushStorageData();
|
|
69427
69837
|
if (what === "cache") {
|
|
69428
69838
|
await browserSession.clearCache();
|
|
@@ -69444,8 +69854,9 @@ async function clearBrowsingData(browserSession, what) {
|
|
|
69444
69854
|
}
|
|
69445
69855
|
await browserSession.clearData();
|
|
69446
69856
|
await browserSession.clearCache();
|
|
69857
|
+
history?.clear();
|
|
69447
69858
|
}
|
|
69448
|
-
async function clearOriginData(browserSession, origin) {
|
|
69859
|
+
async function clearOriginData(browserSession, origin, history) {
|
|
69449
69860
|
browserSession.flushStorageData();
|
|
69450
69861
|
await browserSession.clearData({
|
|
69451
69862
|
origins: [origin],
|
|
@@ -69461,6 +69872,7 @@ async function clearOriginData(browserSession, origin) {
|
|
|
69461
69872
|
"cache"
|
|
69462
69873
|
]
|
|
69463
69874
|
});
|
|
69875
|
+
history?.clearOrigin(origin);
|
|
69464
69876
|
}
|
|
69465
69877
|
function flushBrowserStorage(browserSession) {
|
|
69466
69878
|
try {
|
|
@@ -70747,6 +71159,9 @@ function refusesNavigation(rawUrl) {
|
|
|
70747
71159
|
}
|
|
70748
71160
|
}
|
|
70749
71161
|
let activeHost = null;
|
|
71162
|
+
electron.app.on("before-quit", () => {
|
|
71163
|
+
activeHost?.host.flushHistory();
|
|
71164
|
+
});
|
|
70750
71165
|
function routeBrowserZoomInput(event, input) {
|
|
70751
71166
|
const candidate = browserChordIntent(
|
|
70752
71167
|
{ ...input, isAutoRepeat: false, isComposing: false },
|
|
@@ -71094,7 +71509,10 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
71094
71509
|
notifyChrome();
|
|
71095
71510
|
});
|
|
71096
71511
|
contents.on("did-stop-loading", notifyChrome);
|
|
71097
|
-
contents.on("page-title-updated",
|
|
71512
|
+
contents.on("page-title-updated", (_event, title) => {
|
|
71513
|
+
host.recordHistoryTitle(contents.getURL(), title);
|
|
71514
|
+
notifyChrome();
|
|
71515
|
+
});
|
|
71098
71516
|
contents.on("render-process-gone", () => {
|
|
71099
71517
|
addressOverlay?.onPageGone(tabId);
|
|
71100
71518
|
});
|
|
@@ -71122,12 +71540,14 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
71122
71540
|
stopLogCapture(contents.id);
|
|
71123
71541
|
startLogCapture(contents.id);
|
|
71124
71542
|
log2(`[browser] tab ${tabId} navigated to ${url}`);
|
|
71543
|
+
host.recordHistoryVisit(url);
|
|
71125
71544
|
notifyChanged();
|
|
71126
71545
|
});
|
|
71127
71546
|
contents.on("did-navigate-in-page", (_event, url, isMainFrame) => {
|
|
71128
71547
|
if (!isMainFrame) return;
|
|
71129
71548
|
registry.bumpEpoch(tabId, false);
|
|
71130
71549
|
log2(`[browser] tab ${tabId} navigated in page to ${url}`);
|
|
71550
|
+
host.recordHistoryVisit(url);
|
|
71131
71551
|
notifyChanged();
|
|
71132
71552
|
});
|
|
71133
71553
|
contents.on("destroyed", () => {
|
|
@@ -71266,6 +71686,9 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
71266
71686
|
rollback.add(() => webauthn.dispose());
|
|
71267
71687
|
const detachWebauthn = attachWebauthnChooser(browserSession, webauthn, log2);
|
|
71268
71688
|
rollback.add(detachWebauthn);
|
|
71689
|
+
const historyClearer = {
|
|
71690
|
+
current: null
|
|
71691
|
+
};
|
|
71269
71692
|
const cookieJar = createHiddenCookieJarTarget(
|
|
71270
71693
|
new electron.WebContentsView({
|
|
71271
71694
|
webPreferences: { ...HIDDEN_COOKIE_JAR_WEB_PREFERENCES }
|
|
@@ -71277,7 +71700,7 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
71277
71700
|
cipher: browserProfileCipher(),
|
|
71278
71701
|
...sessionCookiePaths(options.userDataDir),
|
|
71279
71702
|
flushStore: () => browserSession.cookies.flushStore(),
|
|
71280
|
-
clearSessionData: (what) => clearBrowsingData(browserSession, what),
|
|
71703
|
+
clearSessionData: (what) => clearBrowsingData(browserSession, what, historyClearer.current),
|
|
71281
71704
|
log: log2
|
|
71282
71705
|
});
|
|
71283
71706
|
let restoreReport = null;
|
|
@@ -71434,12 +71857,17 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
71434
71857
|
log: log2,
|
|
71435
71858
|
onChanged: notifyChanged,
|
|
71436
71859
|
facts: () => facts,
|
|
71437
|
-
forgetSiteData: (origin) => clearOriginData(browserSession, origin),
|
|
71860
|
+
forgetSiteData: (origin) => clearOriginData(browserSession, origin, historyClearer.current),
|
|
71861
|
+
historyFilePath: path$1.join(options.userDataDir, "browser-history.json"),
|
|
71438
71862
|
addressOverlayMode: () => addressOverlay ? addressOverlay.mode() : {
|
|
71439
71863
|
mode: "suspend",
|
|
71440
71864
|
reason: options.addressOverlay?.product === true ? "unavailable" : "platform"
|
|
71441
71865
|
}
|
|
71442
71866
|
});
|
|
71867
|
+
historyClearer.current = {
|
|
71868
|
+
clear: () => host.clearHistory(),
|
|
71869
|
+
clearOrigin: (origin) => host.clearOriginHistory(origin)
|
|
71870
|
+
};
|
|
71443
71871
|
const ownsChrome = () => browserChromeOwnsChord({
|
|
71444
71872
|
logicalFocus: host.chordFocus,
|
|
71445
71873
|
chromeVisible: registry.chromeVisible,
|
|
@@ -71687,6 +72115,7 @@ async function initializeBrowserHost(options, bindings) {
|
|
|
71687
72115
|
...addressOverlay ? { addressOverlay: probeAddressOverlay } : {},
|
|
71688
72116
|
stop: async () => {
|
|
71689
72117
|
detachChords();
|
|
72118
|
+
host.flushHistory();
|
|
71690
72119
|
const atStop = captureTabs(
|
|
71691
72120
|
registry.list(),
|
|
71692
72121
|
registry.activeTab?.tabId ?? null,
|