dsh-deeppilot 0.9.14 → 0.9.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -4
- package/README.zh-CN.md +10 -3
- package/docs/DSH_RELEASE_MEMORY.md +33 -0
- package/docs/NPM_PUBLISHING.md +15 -0
- package/lib/client.js +491 -375
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +45 -0
- package/lib/index.js +284 -3
- package/lib/index.js.map +1 -1
- package/package.json +10 -2
package/lib/client.js
CHANGED
|
@@ -27,6 +27,7 @@ window.__ModuleLoader__.load({
|
|
|
27
27
|
enumerable: true
|
|
28
28
|
}) : target, mod));
|
|
29
29
|
let react = require("react");
|
|
30
|
+
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
30
31
|
// src/client/snapshot-store.ts
|
|
31
32
|
function createSnapshotStore(initial) {
|
|
32
33
|
let snapshot = initial;
|
|
@@ -492,11 +493,39 @@ window.__ModuleLoader__.load({
|
|
|
492
493
|
*/
|
|
493
494
|
const TABLES = {
|
|
494
495
|
zh: {
|
|
496
|
+
"local.options": "局域网连接选项",
|
|
497
|
+
"remote.options": "远程连接选项",
|
|
498
|
+
"local.errorDetails": "局域网连接异常,请检查连接选项({message})。",
|
|
499
|
+
"remote.errorDetails": "远程连接异常,请检查授权与连接选项({message})。",
|
|
500
|
+
"pair.add": "添加手机",
|
|
501
|
+
"pair.close": "收起",
|
|
502
|
+
"devices.count": "{count} 台",
|
|
503
|
+
"devices.moreAria": "设备“{name}”的更多操作",
|
|
504
|
+
"tools.title": "工具与信息",
|
|
505
|
+
"diag.reportFailed": "读取连接状态失败",
|
|
506
|
+
"diagnostics.historyCount": "{count} 条历史失败记录",
|
|
507
|
+
"diagnostics.kind.upgrade": "连接请求被拒绝",
|
|
508
|
+
"diagnostics.kind.pair": "配对请求被拒绝",
|
|
509
|
+
"diagnostics.kind.auth": "设备认证失败",
|
|
510
|
+
"diagnostics.kind.opened": "连接已建立",
|
|
511
|
+
"diagnostics.kind.closed": "连接异常断开",
|
|
512
|
+
"diagnostics.kind.error": "连接发生错误",
|
|
513
|
+
"diagnostics.kind.identity": "设备身份异常",
|
|
514
|
+
"diagnostics.kind.storage": "设备信息保存失败",
|
|
515
|
+
"diagnostics.kind.unknown": "连接异常",
|
|
516
|
+
"push.outcome.sent": "已发送",
|
|
517
|
+
"push.outcome.failed": "发送失败",
|
|
518
|
+
"push.outcome.invalid": "设备推送凭据无效",
|
|
519
|
+
"push.environment.development": "开发环境",
|
|
520
|
+
"push.environment.production": "正式环境",
|
|
521
|
+
"push.environment.other": "其他环境({environment})",
|
|
522
|
+
"push.outcome.other": "推送状态({outcome})",
|
|
523
|
+
"push.resultDetail": "推送结果({message})",
|
|
495
524
|
"nav": "DeepPilot",
|
|
496
525
|
"meta.title": "DeepPilot",
|
|
497
|
-
"meta.intro": "
|
|
526
|
+
"meta.intro": "在手机上使用这台电脑的 DSH。",
|
|
498
527
|
"meta.refresh": "刷新",
|
|
499
|
-
"master.title": "
|
|
528
|
+
"master.title": "允许手机连接",
|
|
500
529
|
"master.loading": "正在读取配置…",
|
|
501
530
|
"master.on": "已开启:接受手机连接。",
|
|
502
531
|
"master.off": "已关闭:不接受手机连接。",
|
|
@@ -509,11 +538,11 @@ window.__ModuleLoader__.load({
|
|
|
509
538
|
"connection.optionsSummary": "连接选项",
|
|
510
539
|
"pair.description": "选择连接方式并生成一次性配对信息。",
|
|
511
540
|
"devices.description": "管理已经配对的 iPhone。",
|
|
512
|
-
"troubleshooting.summary": "
|
|
541
|
+
"troubleshooting.summary": "诊断工具",
|
|
513
542
|
"troubleshooting.title": "诊断工具",
|
|
514
543
|
"troubleshooting.description": "仅在排查连接或推送问题时使用。",
|
|
515
544
|
"troubleshooting.debugTitle": "调试日志",
|
|
516
|
-
"troubleshooting.debugDescription": "
|
|
545
|
+
"troubleshooting.debugDescription": "开启后,新的手机连接会在 DSH 终端输出诊断日志;已连接手机需重连后生效。日志不包含配对码、推送凭据或消息内容。",
|
|
517
546
|
"diagnostics.title": "连接诊断",
|
|
518
547
|
"diagnostics.description": "最近的连接失败事件;可一键复制后发给维护者排查。",
|
|
519
548
|
"diagnostics.recent": "最近失败",
|
|
@@ -557,7 +586,7 @@ window.__ModuleLoader__.load({
|
|
|
557
586
|
"local.portApplied": "局域网端口已保存,监听器正在重新加载。",
|
|
558
587
|
"local.portInvalid": "请输入 1024–65535 之间的整数。",
|
|
559
588
|
"local.portFailed": "局域网端口保存失败:",
|
|
560
|
-
"remote.title": "
|
|
589
|
+
"remote.title": "远程连接",
|
|
561
590
|
"remote.on": "已配置:内嵌 Funnel 会自动启动并同步状态。",
|
|
562
591
|
"remote.off": "关闭:仅保留局域网连接。",
|
|
563
592
|
"remote.openAuth": "打开授权页面",
|
|
@@ -605,12 +634,12 @@ window.__ModuleLoader__.load({
|
|
|
605
634
|
"panel.tokenRotateWarning": "更换会使当前 Token 立即失效、断开所有手机连接;5 秒内再次点击确认。",
|
|
606
635
|
"panel.tokenRotated": "新 Token 已生效,旧 Token 已失效;请重新配对所有设备。",
|
|
607
636
|
"panel.tokenRotateFailed": "更换失败:",
|
|
608
|
-
"pair.qrPanelTitle": "
|
|
637
|
+
"pair.qrPanelTitle": "添加手机",
|
|
609
638
|
"pair.kind.public": "公网",
|
|
610
639
|
"pair.kind.lan": "内网",
|
|
611
640
|
"pair.noAddress": "没有可用地址",
|
|
612
641
|
"pair.noAddressHelp": "没有可用的局域网或远程入口。请确认局域网连接已启动,或启用远程连接。",
|
|
613
|
-
"pair.disabledHelp": "
|
|
642
|
+
"pair.disabledHelp": "请先开启“允许手机连接”,再添加手机。",
|
|
614
643
|
"pair.qrAlt": "DeepPilot 配对二维码",
|
|
615
644
|
"pair.qrShow": "显示二维码",
|
|
616
645
|
"pair.qrHide": "隐藏二维码",
|
|
@@ -621,7 +650,7 @@ window.__ModuleLoader__.load({
|
|
|
621
650
|
"pair.infoLabel": "配对信息(复制一次,粘贴到 App 即可)",
|
|
622
651
|
"pair.infoCopyDone": "配对信息已复制",
|
|
623
652
|
"pair.infoCopyFailed": "配对信息复制失败:",
|
|
624
|
-
"pair.qrHint": "
|
|
653
|
+
"pair.qrHint": "二维码与「配对信息」内容相同:包含{kind}地址、一次性配对码、证书指纹(内网时)与主机标识。在局域网与公网之间切换会立即生成对应的新配对信息,配对码 5 分钟后失效。",
|
|
625
654
|
"advanced.summary": "高级信息",
|
|
626
655
|
"advanced.protocolVersion": "协议版本",
|
|
627
656
|
"advanced.serverVersion": "服务器版本",
|
|
@@ -647,9 +676,9 @@ window.__ModuleLoader__.load({
|
|
|
647
676
|
"push.pushNotEnabled": "推送未启用",
|
|
648
677
|
"push.relayStep.health": "服务可达",
|
|
649
678
|
"push.relayStep.enroll": "自动注册",
|
|
650
|
-
"push.prefix.ok": "
|
|
651
|
-
"push.prefix.fail": "
|
|
652
|
-
"devices.title": "
|
|
679
|
+
"push.prefix.ok": "通过:",
|
|
680
|
+
"push.prefix.fail": "未通过:",
|
|
681
|
+
"devices.title": "已配对设备",
|
|
653
682
|
"devices.col.name": "设备",
|
|
654
683
|
"devices.col.appVersion": "App 版本",
|
|
655
684
|
"devices.col.push": "离线推送",
|
|
@@ -680,13 +709,13 @@ window.__ModuleLoader__.load({
|
|
|
680
709
|
"devices.pushNotRegistered": "未注册",
|
|
681
710
|
"devices.pushEnvProduction": "生产",
|
|
682
711
|
"devices.pushEnvDevelopment": "开发",
|
|
683
|
-
"devices.empty": "
|
|
712
|
+
"devices.empty": "还没有配对设备。点击“添加手机”,然后在 DeepPilot 中扫码连接。",
|
|
684
713
|
"help.remoteTitle": "远程连接帮助",
|
|
685
714
|
"help.recommended": "推荐设置流程",
|
|
686
|
-
"help.step1": "
|
|
715
|
+
"help.step1": "先打开“允许手机连接”,再打开“远程连接”。",
|
|
687
716
|
"help.step2": "状态变为\"等待 Tailscale 授权\"后,点击\"打开授权页面\"。",
|
|
688
717
|
"help.step3": "使用有权管理此 Tailnet 的账号登录,并按授权页提示启用 Funnel。通常需要 Owner、Admin 或 Network admin 权限。",
|
|
689
|
-
"help.step4": "
|
|
718
|
+
"help.step4": "返回此页面并点击“刷新”。远程连接显示“已就绪”后,点击“添加手机”并扫码。",
|
|
690
719
|
"help.funnelHint": "插件已内嵌 Tailscale 网络组件,这台电脑和手机都不需要另外安装 Tailscale App;但首次启用仍需由 Tailnet 管理员授权。",
|
|
691
720
|
"help.httpsTitle": "授权页未自动完成时:开启 HTTPS",
|
|
692
721
|
"help.httpsStep1": "打开 Tailscale 管理后台的 Network → DNS。",
|
|
@@ -745,11 +774,39 @@ window.__ModuleLoader__.load({
|
|
|
745
774
|
"update.badge": "有新版本"
|
|
746
775
|
},
|
|
747
776
|
en: {
|
|
777
|
+
"local.options": "LAN connection options",
|
|
778
|
+
"remote.options": "Remote connection options",
|
|
779
|
+
"local.errorDetails": "LAN connection failed. Check the connection options ({message}).",
|
|
780
|
+
"remote.errorDetails": "Remote connection failed. Check authorization and connection options ({message}).",
|
|
781
|
+
"pair.add": "Add phone",
|
|
782
|
+
"pair.close": "Collapse",
|
|
783
|
+
"devices.count": "{count} devices",
|
|
784
|
+
"devices.moreAria": "More actions for “{name}”",
|
|
785
|
+
"tools.title": "Tools and information",
|
|
786
|
+
"diag.reportFailed": "Failed to read connection status",
|
|
787
|
+
"diagnostics.historyCount": "{count} past failures",
|
|
788
|
+
"diagnostics.kind.upgrade": "Connection request rejected",
|
|
789
|
+
"diagnostics.kind.pair": "Pairing request rejected",
|
|
790
|
+
"diagnostics.kind.auth": "Device authentication failed",
|
|
791
|
+
"diagnostics.kind.opened": "Connection opened",
|
|
792
|
+
"diagnostics.kind.closed": "Connection closed unexpectedly",
|
|
793
|
+
"diagnostics.kind.error": "Connection error",
|
|
794
|
+
"diagnostics.kind.identity": "Device identity error",
|
|
795
|
+
"diagnostics.kind.storage": "Saving device information failed",
|
|
796
|
+
"diagnostics.kind.unknown": "Connection problem",
|
|
797
|
+
"push.outcome.sent": "Sent",
|
|
798
|
+
"push.outcome.failed": "Failed to send",
|
|
799
|
+
"push.outcome.invalid": "Invalid push credentials",
|
|
800
|
+
"push.environment.development": "Development",
|
|
801
|
+
"push.environment.production": "Production",
|
|
802
|
+
"push.environment.other": "Other environment ({environment})",
|
|
803
|
+
"push.outcome.other": "Push status ({outcome})",
|
|
804
|
+
"push.resultDetail": "Push result ({message})",
|
|
748
805
|
"nav": "DeepPilot",
|
|
749
806
|
"meta.title": "DeepPilot",
|
|
750
|
-
"meta.intro": "
|
|
807
|
+
"meta.intro": "Use this computer’s DSH from your phone.",
|
|
751
808
|
"meta.refresh": "Refresh",
|
|
752
|
-
"master.title": "
|
|
809
|
+
"master.title": "Allow phone connections",
|
|
753
810
|
"master.loading": "Loading settings…",
|
|
754
811
|
"master.on": "On: accepting phone connections.",
|
|
755
812
|
"master.off": "Off: not accepting phone connections.",
|
|
@@ -762,11 +819,11 @@ window.__ModuleLoader__.load({
|
|
|
762
819
|
"connection.optionsSummary": "Connection options",
|
|
763
820
|
"pair.description": "Choose a connection type and generate one-time pairing information.",
|
|
764
821
|
"devices.description": "Manage iPhones that are already paired.",
|
|
765
|
-
"troubleshooting.summary": "
|
|
822
|
+
"troubleshooting.summary": "Diagnostic tools",
|
|
766
823
|
"troubleshooting.title": "Diagnostic tools",
|
|
767
824
|
"troubleshooting.description": "Use these only when diagnosing connection or push issues.",
|
|
768
825
|
"troubleshooting.debugTitle": "Debug logging",
|
|
769
|
-
"troubleshooting.debugDescription": "
|
|
826
|
+
"troubleshooting.debugDescription": "New phone connections write diagnostic logs to the DSH terminal. Connected phones must reconnect to pick up the change. Logs exclude pairing codes, push credentials, and message content.",
|
|
770
827
|
"diagnostics.title": "Connection diagnostics",
|
|
771
828
|
"diagnostics.description": "Recent connection failures; copy them for troubleshooting.",
|
|
772
829
|
"diagnostics.recent": "Recent failures",
|
|
@@ -810,7 +867,7 @@ window.__ModuleLoader__.load({
|
|
|
810
867
|
"local.portApplied": "LAN port saved; the listener is reloading.",
|
|
811
868
|
"local.portInvalid": "Enter an integer from 1024 to 65535.",
|
|
812
869
|
"local.portFailed": "Failed to save LAN port: ",
|
|
813
|
-
"remote.title": "Remote connection
|
|
870
|
+
"remote.title": "Remote connection",
|
|
814
871
|
"remote.on": "Configured: the embedded Funnel will start and sync state automatically.",
|
|
815
872
|
"remote.off": "Off: LAN connections only.",
|
|
816
873
|
"remote.openAuth": "Open authorization page",
|
|
@@ -858,12 +915,12 @@ window.__ModuleLoader__.load({
|
|
|
858
915
|
"panel.tokenRotateWarning": "Rotation invalidates the current token immediately and drops every paired phone. Click again within 5s to confirm.",
|
|
859
916
|
"panel.tokenRotated": "New token active, old token invalidated. Please re-pair every device.",
|
|
860
917
|
"panel.tokenRotateFailed": "Rotation failed: ",
|
|
861
|
-
"pair.qrPanelTitle": "
|
|
918
|
+
"pair.qrPanelTitle": "Add phone",
|
|
862
919
|
"pair.kind.public": "Public",
|
|
863
920
|
"pair.kind.lan": "LAN",
|
|
864
921
|
"pair.noAddress": "No address available",
|
|
865
922
|
"pair.noAddressHelp": "No LAN or remote endpoint is available. Make sure LAN is running or enable remote access.",
|
|
866
|
-
"pair.disabledHelp": "
|
|
923
|
+
"pair.disabledHelp": "Turn on “Allow phone connections” before adding a phone.",
|
|
867
924
|
"pair.qrAlt": "DeepPilot pairing QR code",
|
|
868
925
|
"pair.qrShow": "Show QR code",
|
|
869
926
|
"pair.qrHide": "Hide QR code",
|
|
@@ -874,7 +931,7 @@ window.__ModuleLoader__.load({
|
|
|
874
931
|
"pair.infoLabel": "Pairing info (copy once, paste it in the app)",
|
|
875
932
|
"pair.infoCopyDone": "Pairing info copied",
|
|
876
933
|
"pair.infoCopyFailed": "Failed to copy pairing info: ",
|
|
877
|
-
"pair.qrHint": "The QR code and the pairing info
|
|
934
|
+
"pair.qrHint": "The QR code and the pairing info carry the same {kind} address, single-use code, certificate fingerprint (for LAN) and host identity. Switching between LAN and public issues a matching new string immediately; the code expires after 5 minutes.",
|
|
878
935
|
"advanced.summary": "Advanced info",
|
|
879
936
|
"advanced.protocolVersion": "Protocol version",
|
|
880
937
|
"advanced.serverVersion": "Server version",
|
|
@@ -900,9 +957,9 @@ window.__ModuleLoader__.load({
|
|
|
900
957
|
"push.pushNotEnabled": "Push not enabled",
|
|
901
958
|
"push.relayStep.health": "Service reachable",
|
|
902
959
|
"push.relayStep.enroll": "Auto enrollment",
|
|
903
|
-
"push.prefix.ok": "
|
|
904
|
-
"push.prefix.fail": "
|
|
905
|
-
"devices.title": "
|
|
960
|
+
"push.prefix.ok": "Passed: ",
|
|
961
|
+
"push.prefix.fail": "Failed: ",
|
|
962
|
+
"devices.title": "Paired devices",
|
|
906
963
|
"devices.col.name": "Device",
|
|
907
964
|
"devices.col.appVersion": "App version",
|
|
908
965
|
"devices.col.push": "Push",
|
|
@@ -933,13 +990,13 @@ window.__ModuleLoader__.load({
|
|
|
933
990
|
"devices.pushNotRegistered": "Not registered",
|
|
934
991
|
"devices.pushEnvProduction": "Production",
|
|
935
992
|
"devices.pushEnvDevelopment": "Development",
|
|
936
|
-
"devices.empty": "No
|
|
993
|
+
"devices.empty": "No paired devices yet. Click “Add phone”, then scan the QR code in DeepPilot.",
|
|
937
994
|
"help.remoteTitle": "Remote connection help",
|
|
938
995
|
"help.recommended": "Recommended setup",
|
|
939
|
-
"help.step1": "Turn on
|
|
996
|
+
"help.step1": "Turn on “Allow phone connections”, then “Remote connection”.",
|
|
940
997
|
"help.step2": "When the status shows \"Awaiting Tailscale authorization\", click \"Open authorization page\".",
|
|
941
998
|
"help.step3": "Sign in with an account that can manage this Tailnet and follow the on-page prompts to enable Funnel. Owner / Admin / Network admin is usually required.",
|
|
942
|
-
"help.step4": "
|
|
999
|
+
"help.step4": "Return and click “Refresh”. Once the remote connection is ready, click “Add phone” and scan the QR code.",
|
|
943
1000
|
"help.funnelHint": "The plugin bundles the Tailscale networking stack, so neither this computer nor the phone needs the Tailscale app — but a Tailnet administrator must approve first-time use.",
|
|
944
1001
|
"help.httpsTitle": "If authorization does not complete: enable HTTPS",
|
|
945
1002
|
"help.httpsStep1": "Open the Tailscale admin console → Network → DNS.",
|
|
@@ -1061,170 +1118,149 @@ window.__ModuleLoader__.load({
|
|
|
1061
1118
|
});
|
|
1062
1119
|
}
|
|
1063
1120
|
// src/client/styles.ts
|
|
1064
|
-
const
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
".pbb-testTitle{font-size:13px;font-weight:500;color:var(--dsw-alias-label-primary)}",
|
|
1208
|
-
".pbb-testDescription{font-size:12px;color:var(--dsw-alias-label-tertiary);line-height:1.5}",
|
|
1209
|
-
".pbb-runtimeList{display:flex;flex-direction:column;border:1px solid var(--dsw-alias-border-l3);border-radius:8px;overflow:hidden}",
|
|
1210
|
-
".pbb-runtimeList>.pbb-runtimeRow,.pbb-runtimeRow{display:flex;align-items:center;gap:10px;padding:9px 10px;border-top:1px solid var(--dsw-alias-border-l2)}",
|
|
1211
|
-
".pbb-runtimeList>.pbb-runtimeRow:first-child{border-top:0}",
|
|
1212
|
-
".pbb-runtimeList>.pbb-runtimeRow>.pbb-row{flex:1;min-width:0}",
|
|
1213
|
-
".pbb-updateRow{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-business-primary,#4176e6) 35%,var(--dsw-alias-border-l3));border-radius:8px;color:var(--dsw-alias-label-primary);font-size:13px;text-decoration:none;cursor:pointer;transition:background-color 160ms " + EASE + "}",
|
|
1214
|
-
".pbb-disclosure{padding:0}",
|
|
1215
|
-
".pbb-disclosure>summary{list-style:none;display:flex;align-items:center;gap:10px;padding:13px 18px;cursor:pointer;color:var(--dsw-alias-label-primary)}",
|
|
1216
|
-
".pbb-disclosure>summary::-webkit-details-marker{display:none}",
|
|
1217
|
-
".pbb-disclosure[open]>summary .pbb-chev{transform:rotate(90deg)}",
|
|
1218
|
-
".pbb-disclosureTitle{font-size:13px;font-weight:500;flex:1}",
|
|
1219
|
-
".pbb-disclosureMeta{font-size:12px;color:var(--dsw-alias-label-tertiary);max-width:46%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}",
|
|
1220
|
-
".pbb-disclosureBody{display:flex;flex-direction:column;gap:12px;padding:2px 18px 16px}",
|
|
1221
|
-
".pbb-diagnostics>summary{color:var(--dsw-alias-label-secondary)}",
|
|
1222
|
-
"@media (hover:hover) and (pointer:fine){.pbb-refresh:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.pbb-cardHead:hover{background:var(--dsw-alias-bg-module-platform)}.pbb-action:hover:not(:disabled){color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-module-platform)}.pbb-buttonPrimary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover,var(--dsw-alias-interactive-bg-hover-solid))}.pbb-actionDangerGhost:hover:not(:disabled){color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 9%,transparent);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent)}.pbb-expand:hover{color:var(--dsw-alias-label-primary)}.pbb-updateRow:hover{background:color-mix(in srgb,var(--dsw-alias-state-business-primary,#4176e6) 8%,transparent)}}",
|
|
1223
|
-
"@media (prefers-reduced-motion:reduce){.pbb-section *{animation-duration:.01ms!important;animation-delay:0s!important;transition-duration:.01ms!important;transition-delay:0s!important}}",
|
|
1224
|
-
"@container pbb (max-width:640px){.pbb-statusStrip{grid-template-columns:repeat(2,1fr)}.pbb-statusCell:nth-child(3){border-left:0}.pbb-statusCell:nth-child(n+3){border-top:1px solid var(--dsw-alias-border-l2)}.pbb-cardSummary{display:none}}",
|
|
1225
|
-
"@container pbb (max-width:480px){.pbb-testGrid{grid-template-columns:1fr}.pbb-testItem:last-child:nth-child(odd){grid-column:auto}.pbb-qrPanel{grid-template-columns:1fr}.pbb-limitRow{align-items:flex-start;flex-direction:column}.pbb-limitControl{align-self:flex-end}.pbb-deviceRow{grid-template-columns:minmax(0,1fr)}.pbb-deviceActions{grid-row:auto;grid-column:auto;justify-content:flex-start}}",
|
|
1226
|
-
"@media (pointer:coarse){.pbb-action{min-height:32px;padding:7px 10px;font-size:13px}.pbb-buttonPrimary{font-size:14px}.pbb-cardHead{min-height:56px}.pbb-expand{padding:5px 0}.pbb-refresh{padding:5px 0}}"
|
|
1227
|
-
].join("\n");
|
|
1121
|
+
const CSS = String.raw`
|
|
1122
|
+
.pbb-section{--pbb-ink:var(--dsw-alias-label-primary,#0f1115);--pbb-secondary:var(--dsw-alias-label-secondary,#61666b);--pbb-line:var(--dsw-alias-settings-card-stroke,var(--dsw-alias-border-l3,#e4e5e7));--pbb-fill:var(--dsw-alias-settings-card-fill,var(--dsw-alias-bg-layer-2,#fff));--pbb-soft:var(--dsw-alias-bg-module-platform,#f5f6f8);container:pbb/inline-size;max-width:760px;color:var(--pbb-ink);font-size:14px;line-height:20px;display:flex;flex-direction:column;gap:20px}
|
|
1123
|
+
.pbb-section *{box-sizing:border-box}
|
|
1124
|
+
.pbb-section :is(.pbb-action,.pbb-refresh,.pbb-iconButton,.pbb-cardHead,.pbb-menuAction,.pbb-targetButton),.pbb-section input{font-family:inherit}
|
|
1125
|
+
.pbb-icon{display:block;flex:none;color:inherit}
|
|
1126
|
+
.pbb-pageHeader{display:flex;align-items:flex-start;gap:12px;min-height:56px}
|
|
1127
|
+
.pbb-pageHeader>div{min-width:0;flex:1;padding-top:2px}
|
|
1128
|
+
.pbb-title{margin:0;font-size:20px;line-height:27px;font-weight:600;letter-spacing:-.3px}
|
|
1129
|
+
.pbb-intro{color:var(--pbb-secondary);font-size:14px;line-height:20px;margin:5px 0 0}
|
|
1130
|
+
.pbb-refresh{display:inline-flex;align-items:center;justify-content:center;gap:5px;height:28px;padding:0 7px;flex:none;border:0;border-radius:6px;background:transparent;color:var(--pbb-secondary);font-size:12px;cursor:pointer}
|
|
1131
|
+
.pbb-card{border:1px solid var(--pbb-line);border-radius:18px;background:var(--pbb-fill)}
|
|
1132
|
+
.pbb-cardTitle{margin:0;font-size:14px;line-height:20px;font-weight:600;color:var(--pbb-ink)}
|
|
1133
|
+
.pbb-cardBody{display:flex;flex-direction:column;gap:12px;padding:4px 16px 16px}
|
|
1134
|
+
.pbb-connections>.pbb-cardBody{padding:0;gap:0}
|
|
1135
|
+
.pbb-row{display:flex;align-items:center;gap:8px;min-width:0}
|
|
1136
|
+
.pbb-masterRow{display:flex;align-items:center;gap:12px;min-height:66px;padding:11px 16px}
|
|
1137
|
+
.pbb-controlText{display:flex;flex:1;min-width:0;flex-direction:column;gap:2px}
|
|
1138
|
+
.pbb-masterRow>.pbb-controlText{gap:4px}
|
|
1139
|
+
.pbb-controlTitle{font-size:14px;line-height:20px;font-weight:400;color:var(--pbb-ink)}
|
|
1140
|
+
.pbb-masterRow .pbb-controlTitle{font-weight:600}
|
|
1141
|
+
.pbb-controlDescription,.pbb-diag,.pbb-label,.pbb-value{font-size:12px;line-height:18px;color:var(--pbb-secondary)}
|
|
1142
|
+
.pbb-serviceSummary,.pbb-channelState{display:flex;align-items:center;flex-wrap:wrap;gap:6px;font-size:12px;line-height:18px;color:var(--pbb-secondary)}
|
|
1143
|
+
.pbb-serviceSummary{gap:5px}
|
|
1144
|
+
.pbb-serviceState{display:inline-flex}
|
|
1145
|
+
.pbb-metaDivider{height:10px;border-left:1px solid var(--pbb-line);margin:0 2px}
|
|
1146
|
+
.pbb-channel{position:relative}
|
|
1147
|
+
.pbb-channel::before{content:"";position:absolute;top:0;left:16px;right:16px;border-top:1px solid var(--pbb-line)}
|
|
1148
|
+
.pbb-channel+.pbb-channel::before{left:46px}
|
|
1149
|
+
.pbb-channelRow{gap:12px;min-height:60px;padding:8px 16px}
|
|
1150
|
+
.pbb-channelRow>.pbb-icon{color:var(--pbb-secondary)}
|
|
1151
|
+
.pbb-channelBody{display:flex;flex-direction:column;gap:12px;padding:2px 16px 14px 46px}
|
|
1152
|
+
.pbb-channel>.pbb-diag,.pbb-channel>.pbb-rowAction{margin:0;padding:0 16px 8px 46px}
|
|
1153
|
+
.pbb-fold[hidden]{display:none}
|
|
1154
|
+
.pbb-action:disabled,.pbb-refresh:disabled,.pbb-menuAction:disabled,.pbb-targetButton:disabled{opacity:.5;cursor:default}
|
|
1155
|
+
.pbb-action{display:inline-flex;align-items:center;justify-content:center;gap:5px;flex:none;height:28px;max-width:100%;padding:0 9px;border:1px solid var(--pbb-line);border-radius:6px;background:transparent;color:var(--pbb-secondary);font:inherit;font-size:14px;line-height:20px;text-decoration:none;cursor:pointer;white-space:nowrap}
|
|
1156
|
+
.pbb-addAction{display:flex;margin-left:auto}
|
|
1157
|
+
.pbb-buttonPrimary{background:var(--dsw-alias-button-primary-fill,var(--pbb-ink));border-color:transparent;color:var(--dsw-alias-label-primary-foreground,#fff)}
|
|
1158
|
+
.pbb-actionDangerGhost{color:var(--dsw-alias-state-error-primary,#bc2222);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary,#bc2222) 35%,transparent)}
|
|
1159
|
+
.pbb-iconButton{display:flex;align-items:center;justify-content:center;flex:none;width:28px;height:28px;padding:0;border:0;border-radius:6px;background:transparent;color:var(--pbb-secondary);cursor:pointer}
|
|
1160
|
+
.pbb-chev{display:inline-flex;flex:none;color:var(--pbb-secondary)}
|
|
1161
|
+
.pbb-chevIcon{width:14px;height:14px;display:block}
|
|
1162
|
+
[aria-expanded="true"]>.pbb-chev,.pbb-helpDisclosure[open]>summary>.pbb-chev,.pbb-disclosure[open]>summary>.pbb-chev{transform:rotate(90deg)}
|
|
1163
|
+
.pbb-diag{margin:0;overflow-wrap:anywhere}
|
|
1164
|
+
.pbb-diagBad,.pbb-bad{color:var(--dsw-alias-state-error-primary,#bc2222)}
|
|
1165
|
+
.pbb-ok{color:color-mix(in srgb,var(--dsw-alias-state-success-primary,#287a45) 65%,var(--pbb-ink))}
|
|
1166
|
+
.pbb-label{flex:1;min-width:0;font-weight:500;color:var(--pbb-ink)}
|
|
1167
|
+
.pbb-value{text-align:right;overflow-wrap:anywhere}
|
|
1168
|
+
.pbb-token{max-width:100%;font:12px/18px ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--pbb-secondary);overflow-wrap:anywhere}
|
|
1169
|
+
.pbb-empty{margin:0;padding:16px;font-size:14px;line-height:20px;color:var(--pbb-secondary)}
|
|
1170
|
+
.pbb-limitRow{display:flex;align-items:center;gap:12px}
|
|
1171
|
+
.pbb-limitControl{display:flex;align-items:center;gap:8px;flex:none}
|
|
1172
|
+
.pbb-numberInput,.pbb-deviceNameInput{min-width:0;height:28px;border:1px solid var(--pbb-line);border-radius:6px;background:var(--dsw-alias-bg-layer-3,var(--pbb-fill));color:var(--pbb-ink);font:inherit;font-size:14px;line-height:20px;padding:3px 8px;caret-color:var(--pbb-ink)}
|
|
1173
|
+
.pbb-numberInput{width:72px}
|
|
1174
|
+
.pbb-numberInput:disabled,.pbb-deviceNameInput:disabled{opacity:.5}
|
|
1175
|
+
.pbb-endpoint{user-select:all}
|
|
1176
|
+
.pbb-devicesSection{display:flex;flex-direction:column;gap:8px}
|
|
1177
|
+
.pbb-devicesHeader{display:flex;align-items:center;gap:8px;min-height:44px;padding:0 2px}
|
|
1178
|
+
.pbb-deviceCount{font-size:12px;line-height:18px;color:var(--pbb-secondary);white-space:nowrap}
|
|
1179
|
+
.pbb-devicesCard{overflow:visible}
|
|
1180
|
+
.pbb-deviceList{display:flex;flex-direction:column}
|
|
1181
|
+
.pbb-deviceRow{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:12px;row-gap:0;min-height:56px;padding:6px 14px 6px 16px}
|
|
1182
|
+
.pbb-deviceRow+.pbb-deviceRow::before{content:"";position:absolute;top:0;left:46px;right:16px;border-top:1px solid var(--pbb-line)}
|
|
1183
|
+
.pbb-deviceRow:has(details[open]){z-index:2}
|
|
1184
|
+
.pbb-deviceMain{display:flex;align-items:center;gap:12px;min-width:0}
|
|
1185
|
+
.pbb-deviceMain>.pbb-icon{color:var(--pbb-secondary)}
|
|
1186
|
+
.pbb-deviceText{display:flex;flex-direction:column;gap:2px;min-width:0}
|
|
1187
|
+
.pbb-deviceName{font-size:14px;line-height:20px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
1188
|
+
.pbb-deviceMeta{display:flex;flex-wrap:wrap;gap:0 6px;color:var(--pbb-secondary);font-size:12px;line-height:18px}
|
|
1189
|
+
.pbb-deviceMeta>*+*::before{content:"\00B7";margin-right:6px}
|
|
1190
|
+
.pbb-deviceActions{grid-row:1;grid-column:2;display:flex;align-items:center}
|
|
1191
|
+
.pbb-deviceRenameForm,.pbb-deviceConfirm{grid-column:1/-1;display:flex;gap:8px;padding:8px 0;min-width:0}
|
|
1192
|
+
.pbb-deviceRenameForm{flex-wrap:wrap}
|
|
1193
|
+
.pbb-deviceNameInput{flex:1}
|
|
1194
|
+
.pbb-deviceRenameActions{display:flex;align-items:center;gap:5px;flex:none}
|
|
1195
|
+
.pbb-deviceConfirm{flex-direction:column}
|
|
1196
|
+
.pbb-deviceMessage{padding:10px 16px}
|
|
1197
|
+
.pbb-deviceMenu{position:relative}
|
|
1198
|
+
.pbb-deviceMenu>summary{list-style:none}
|
|
1199
|
+
.pbb-deviceMenu>summary::-webkit-details-marker{display:none}
|
|
1200
|
+
.pbb-deviceMenuBody{position:absolute;z-index:3;top:34px;right:0;width:250px;max-width:calc(100cqw - 32px);padding:5px;border:1px solid var(--pbb-line);border-radius:10px;background:var(--dsw-alias-bg-layer-3,var(--pbb-fill));box-shadow:0 8px 24px color-mix(in srgb,var(--pbb-ink) 12%,transparent)}
|
|
1201
|
+
.pbb-deviceMenuInfo{display:flex;flex-direction:column;gap:3px;padding:7px 8px 10px;border-bottom:1px solid var(--pbb-line)}
|
|
1202
|
+
.pbb-menuAction{display:block;width:100%;min-height:32px;padding:5px 8px;border:0;border-radius:5px;background:transparent;color:var(--pbb-ink);text-align:left;font:inherit;font-size:14px;cursor:pointer}
|
|
1203
|
+
.pbb-menuDanger{color:var(--dsw-alias-state-error-primary,#bc2222)}
|
|
1204
|
+
.pbb-actionBusy{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--pbb-secondary)}
|
|
1205
|
+
.pbb-actionBusy::before{content:"";width:10px;height:10px;border:1.5px solid var(--pbb-line);border-top-color:currentColor;border-radius:50%;animation:pbb-spin .7s linear infinite}
|
|
1206
|
+
@keyframes pbb-spin{to{transform:rotate(360deg)}}
|
|
1207
|
+
.pbb-rowAction{display:flex;flex-wrap:wrap;gap:8px}
|
|
1208
|
+
.pbb-pairingPanel{border:1px solid var(--pbb-line);border-radius:16px;padding:16px;background:var(--pbb-fill)}
|
|
1209
|
+
.pbb-pairingHeader{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px}
|
|
1210
|
+
.pbb-pairingBody{display:flex;flex-direction:column;gap:10px}
|
|
1211
|
+
.pbb-targetList{display:flex;flex-wrap:wrap;gap:4px;min-width:0}
|
|
1212
|
+
.pbb-targetButton{max-width:100%;padding:5px 9px;border:1px solid transparent;border-radius:7px;background:var(--pbb-soft);color:var(--pbb-secondary);font:inherit;font-size:12px;line-height:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}
|
|
1213
|
+
.pbb-targetSelected{color:var(--pbb-ink);border-color:var(--pbb-line);background:var(--pbb-fill)}
|
|
1214
|
+
.pbb-qrPanel{display:grid;grid-template-columns:224px minmax(0,1fr);gap:20px;align-items:start}
|
|
1215
|
+
.pbb-qrImage{display:block;width:224px;height:224px;max-width:100%;padding:8px;border-radius:12px;background:#fff}
|
|
1216
|
+
.pbb-countdown{margin-top:10px;display:flex;flex-direction:column;gap:6px}
|
|
1217
|
+
.pbb-countdownBar{height:4px;border-radius:99px;background:var(--pbb-soft);overflow:hidden}
|
|
1218
|
+
.pbb-countdownBar i{display:block;width:100%;height:100%;transform-origin:left center;background:var(--dsw-alias-state-business-primary,#4176e6);border-radius:99px}
|
|
1219
|
+
.pbb-countdownText{font-size:12px;line-height:18px;color:var(--pbb-secondary);font-variant-numeric:tabular-nums}
|
|
1220
|
+
.pbb-pairInfo,.pbb-pairCodeBlock{display:flex;flex-direction:column;gap:8px;min-width:0}
|
|
1221
|
+
.pbb-pairCodeLabel,.pbb-qrHint{font-size:12px;line-height:18px;color:var(--pbb-secondary);margin:0}
|
|
1222
|
+
.pbb-pairCodeRow{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
|
|
1223
|
+
.pbb-pairCode{font:12px/18px ui-monospace,SFMono-Regular,Menlo,monospace;overflow-wrap:anywhere;user-select:all}
|
|
1224
|
+
.pbb-tools{border-radius:16px;overflow:hidden}
|
|
1225
|
+
.pbb-toolSection+.pbb-toolSection{border-top:1px solid var(--pbb-line)}
|
|
1226
|
+
.pbb-cardHead{display:flex;align-items:center;gap:10px;width:100%;min-height:44px;padding:0 16px;border:0;background:transparent;color:var(--pbb-secondary);font:inherit;text-align:left;cursor:pointer}
|
|
1227
|
+
.pbb-cardHead>.pbb-cardTitle{flex:1;font-weight:400}
|
|
1228
|
+
.pbb-toolMeta{max-width:50%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px;color:var(--pbb-secondary)}
|
|
1229
|
+
.pbb-toolMeta.pbb-ok{color:color-mix(in srgb,var(--dsw-alias-state-success-primary,#287a45) 65%,var(--pbb-ink))}
|
|
1230
|
+
.pbb-toolMeta.pbb-bad{color:var(--dsw-alias-state-error-primary,#bc2222)}
|
|
1231
|
+
.pbb-testGrid{display:flex;flex-direction:column;gap:0}
|
|
1232
|
+
.pbb-testItem{display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--pbb-line)}
|
|
1233
|
+
.pbb-testTitle{font-size:14px;line-height:20px;font-weight:500;color:var(--pbb-ink)}
|
|
1234
|
+
.pbb-testDescription{font-size:12px;line-height:18px;color:var(--pbb-secondary)}
|
|
1235
|
+
.pbb-helpBody,.pbb-disclosureBody{display:flex;flex-direction:column;gap:14px}
|
|
1236
|
+
.pbb-helpSection{display:flex;flex-direction:column;gap:6px}
|
|
1237
|
+
.pbb-helpHeading{font-size:14px;line-height:20px;font-weight:500;color:var(--pbb-ink)}
|
|
1238
|
+
.pbb-helpList{margin:0;padding-left:20px;font-size:14px;line-height:22px;color:var(--pbb-secondary)}
|
|
1239
|
+
.pbb-helpList li+li{margin-top:4px}
|
|
1240
|
+
.pbb-helpText{margin:0;font-size:14px;line-height:22px;color:var(--pbb-secondary)}
|
|
1241
|
+
.pbb-helpCode{display:block;margin:0;padding:10px;border:1px solid var(--pbb-line);border-radius:8px;background:var(--pbb-soft);color:var(--pbb-ink);font:12px/18px ui-monospace,SFMono-Regular,Menlo,monospace;white-space:pre-wrap;overflow-wrap:anywhere}
|
|
1242
|
+
.pbb-helpLink{color:var(--pbb-ink);text-decoration:underline;text-underline-offset:3px}
|
|
1243
|
+
.pbb-helpDisclosure>summary{display:flex;align-items:center;gap:6px;min-height:28px;list-style:none;cursor:pointer;color:var(--pbb-secondary);font-size:12px}
|
|
1244
|
+
.pbb-helpDisclosure>summary::-webkit-details-marker{display:none}
|
|
1245
|
+
.pbb-helpDisclosure[open]>.pbb-helpBody{padding-top:10px}
|
|
1246
|
+
.pbb-runtimeList{display:flex;flex-direction:column}
|
|
1247
|
+
.pbb-runtimeRow{display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid var(--pbb-line)}
|
|
1248
|
+
.pbb-runtimeRow>.pbb-row{flex:1;min-width:0}
|
|
1249
|
+
.pbb-updateRow{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 0;color:var(--pbb-ink);font-size:14px;text-decoration:none}
|
|
1250
|
+
.pbb-resultRow{display:flex;align-items:flex-start;gap:6px}
|
|
1251
|
+
.pbb-resultIcon{display:inline-flex;flex:none;margin-top:3px;color:var(--dsw-alias-state-success-primary,#287a45)}
|
|
1252
|
+
.pbb-resultIconBad{color:var(--dsw-alias-state-error-primary,#bc2222)}
|
|
1253
|
+
.pbb-disclosure>summary{list-style:none;display:flex;align-items:center;gap:10px;min-height:44px;padding:0 16px;cursor:pointer;font-size:14px}
|
|
1254
|
+
.pbb-disclosure>summary::-webkit-details-marker{display:none}
|
|
1255
|
+
.pbb-disclosureBody{padding:2px 16px 16px}
|
|
1256
|
+
.pbb-disclosureTitle{flex:1}
|
|
1257
|
+
.pbb-section :is(.pbb-action,.pbb-refresh,.pbb-iconButton,.pbb-cardHead,.pbb-menuAction,.pbb-targetButton,input,summary,a):focus-visible{outline:2px solid var(--dsw-focus-ring-color,#5276b4);outline-offset:2px}
|
|
1258
|
+
@media (hover:hover) and (pointer:fine){.pbb-refresh:hover:not(:disabled),.pbb-iconButton:hover,.pbb-action:hover:not(:disabled),.pbb-cardHead:hover,.pbb-menuAction:hover:not(:disabled){background:var(--pbb-soft)}.pbb-buttonPrimary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover,#30343b)}.pbb-action:active:not(:disabled),.pbb-refresh:active:not(:disabled),.pbb-iconButton:active{transform:scale(.97)}}
|
|
1259
|
+
@media (prefers-reduced-motion:reduce){.pbb-action,.pbb-refresh,.pbb-iconButton{transition:none;transform:none!important}.pbb-actionBusy::before{animation:none}}
|
|
1260
|
+
@container pbb (max-width:480px){.pbb-qrPanel{grid-template-columns:1fr}.pbb-limitRow{align-items:flex-start;flex-direction:column}.pbb-limitControl{align-self:flex-end}.pbb-deviceMeta{column-gap:4px}.pbb-toolMeta{max-width:42%}.pbb-channelRow{gap:8px}.pbb-testItem{flex-wrap:wrap}.pbb-testItem>.pbb-controlText{flex-basis:65%}}
|
|
1261
|
+
@container pbb (max-width:340px){.pbb-devicesHeader{flex-wrap:wrap}.pbb-deviceRow{column-gap:6px;padding-right:10px}.pbb-channelBody{padding-left:16px}.pbb-toolMeta{max-width:38%}}
|
|
1262
|
+
@media (pointer:coarse){.pbb-action,.pbb-iconButton,.pbb-refresh,.pbb-targetButton,.pbb-menuAction,.pbb-helpDisclosure>summary{min-width:44px;min-height:44px}.pbb-numberInput,.pbb-deviceNameInput{height:44px;font-size:16px}.pbb-deviceMenuBody{top:48px}}
|
|
1263
|
+
`;
|
|
1228
1264
|
/**
|
|
1229
1265
|
* Client bundle id, identical to the `window.__ModuleLoader__.load({ id })`
|
|
1230
1266
|
* identity emitted by tsdown.config.ts. DSH's module system owns style
|
|
@@ -1252,6 +1288,102 @@ window.__ModuleLoader__.load({
|
|
|
1252
1288
|
tag.textContent = CSS;
|
|
1253
1289
|
document.head.appendChild(tag);
|
|
1254
1290
|
}
|
|
1291
|
+
// src/client/settings-icons.ts
|
|
1292
|
+
/** 设置页的小图标共用线宽与 currentColor,随宿主主题变色,不额外引入图标包。 */
|
|
1293
|
+
function settingsIcon(name, size = 18) {
|
|
1294
|
+
const path = (d) => (0, react.createElement)("path", { d });
|
|
1295
|
+
const circle = (cx, cy, r) => (0, react.createElement)("circle", {
|
|
1296
|
+
cx,
|
|
1297
|
+
cy,
|
|
1298
|
+
r
|
|
1299
|
+
});
|
|
1300
|
+
return (0, react.createElement)("svg", {
|
|
1301
|
+
className: "pbb-icon",
|
|
1302
|
+
viewBox: "0 0 24 24",
|
|
1303
|
+
width: size,
|
|
1304
|
+
height: size,
|
|
1305
|
+
fill: "none",
|
|
1306
|
+
stroke: "currentColor",
|
|
1307
|
+
strokeWidth: 1.6,
|
|
1308
|
+
strokeLinecap: "round",
|
|
1309
|
+
strokeLinejoin: "round",
|
|
1310
|
+
"aria-hidden": true
|
|
1311
|
+
}, ...{
|
|
1312
|
+
phone: () => [(0, react.createElement)("rect", {
|
|
1313
|
+
x: 6.5,
|
|
1314
|
+
y: 2.5,
|
|
1315
|
+
width: 11,
|
|
1316
|
+
height: 19,
|
|
1317
|
+
rx: 2.2
|
|
1318
|
+
}), path("M10 5h4M11 18.5h2")],
|
|
1319
|
+
wifi: () => [path("M2 8.8a16 16 0 0 1 20 0M5 12.1a11 11 0 0 1 14 0M8.3 15.5a6 6 0 0 1 7.4 0"), circle(12, 19, .7)],
|
|
1320
|
+
globe: () => [circle(12, 12, 9), path("M3 12h18M12 3a17 17 0 0 1 0 18 17 17 0 0 1 0-18")],
|
|
1321
|
+
refresh: () => [path("M20 7v5h-5M4 17v-5h5M6.1 7a7 7 0 0 1 11.5-1L20 9M4 15l2.4 3A7 7 0 0 0 18 17")],
|
|
1322
|
+
plus: () => [path("M12 5v14M5 12h14")],
|
|
1323
|
+
more: () => [
|
|
1324
|
+
circle(5, 12, 1.2),
|
|
1325
|
+
circle(12, 12, 1.2),
|
|
1326
|
+
circle(19, 12, 1.2)
|
|
1327
|
+
],
|
|
1328
|
+
activity: () => [path("M3 12h4l3-7 4 14 3-7h4")],
|
|
1329
|
+
info: () => [circle(12, 12, 9), path("M12 11v6M12 7h.01")],
|
|
1330
|
+
ready: () => [circle(12, 12, 9), path("m8 12 3 3 5-6")],
|
|
1331
|
+
attention: () => [circle(12, 12, 9), path("M12 7v6M12 17h.01")]
|
|
1332
|
+
}[name]());
|
|
1333
|
+
}
|
|
1334
|
+
// src/client/device-actions.ts
|
|
1335
|
+
/**
|
|
1336
|
+
* 原生 disclosure(折叠控件)负责 Enter/Space 与焦点顺序;操作仍是普通按钮,
|
|
1337
|
+
* 不冒充需要方向键导航的 ARIA menu。详情只在展开时进入无障碍读取顺序。
|
|
1338
|
+
*/
|
|
1339
|
+
function DeviceActions(props) {
|
|
1340
|
+
const ref = (0, react.useRef)(null);
|
|
1341
|
+
const close = (restoreFocus = false) => {
|
|
1342
|
+
const details = ref.current;
|
|
1343
|
+
if (details === null) return;
|
|
1344
|
+
details.open = false;
|
|
1345
|
+
if (restoreFocus) details.querySelector("summary")?.focus();
|
|
1346
|
+
};
|
|
1347
|
+
(0, react.useEffect)(() => {
|
|
1348
|
+
const outside = (event) => {
|
|
1349
|
+
if (event.target instanceof Node && !ref.current?.contains(event.target)) close();
|
|
1350
|
+
};
|
|
1351
|
+
document.addEventListener("pointerdown", outside);
|
|
1352
|
+
return () => document.removeEventListener("pointerdown", outside);
|
|
1353
|
+
}, []);
|
|
1354
|
+
const act = (action) => {
|
|
1355
|
+
close();
|
|
1356
|
+
action();
|
|
1357
|
+
};
|
|
1358
|
+
return (0, react.createElement)("details", {
|
|
1359
|
+
ref,
|
|
1360
|
+
className: "pbb-deviceMenu",
|
|
1361
|
+
onKeyDown: (event) => {
|
|
1362
|
+
if (event.key !== "Escape" || !ref.current?.open) return;
|
|
1363
|
+
event.preventDefault();
|
|
1364
|
+
event.stopPropagation();
|
|
1365
|
+
close(true);
|
|
1366
|
+
}
|
|
1367
|
+
}, (0, react.createElement)("summary", {
|
|
1368
|
+
className: "pbb-iconButton",
|
|
1369
|
+
"aria-label": props.t("devices.moreAria", { name: props.name })
|
|
1370
|
+
}, settingsIcon("more", 16)), (0, react.createElement)("div", {
|
|
1371
|
+
className: "pbb-deviceMenuBody",
|
|
1372
|
+
"aria-label": props.t("devices.col.actions")
|
|
1373
|
+
}, (0, react.createElement)("div", { className: "pbb-deviceMenuInfo" }, props.customName ? (0, react.createElement)("span", { className: "pbb-diag" }, props.t("devices.customBadge")) : null, (0, react.createElement)("span", { className: "pbb-diag" }, props.t("devices.col.fingerprint")), (0, react.createElement)("code", { className: "pbb-token" }, props.fingerprint || "—")), (0, react.createElement)("button", {
|
|
1374
|
+
type: "button",
|
|
1375
|
+
className: "pbb-menuAction",
|
|
1376
|
+
disabled: !props.canRename,
|
|
1377
|
+
"aria-label": props.t("devices.renameAria", { name: props.name }),
|
|
1378
|
+
onClick: () => act(props.onRename)
|
|
1379
|
+
}, props.t("devices.rename")), (0, react.createElement)("button", {
|
|
1380
|
+
type: "button",
|
|
1381
|
+
className: "pbb-menuAction pbb-menuDanger",
|
|
1382
|
+
disabled: !props.canRevoke,
|
|
1383
|
+
"aria-label": props.t("devices.revokeAria", { name: props.name }),
|
|
1384
|
+
onClick: () => act(props.onRevoke)
|
|
1385
|
+
}, props.t("devices.revoke"))));
|
|
1386
|
+
}
|
|
1255
1387
|
// node_modules/qrcode/lib/can-promise.js
|
|
1256
1388
|
var require_can_promise = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1257
1389
|
module.exports = function() {
|
|
@@ -3911,15 +4043,6 @@ window.__ModuleLoader__.load({
|
|
|
3911
4043
|
};
|
|
3912
4044
|
}
|
|
3913
4045
|
// src/client/settings-view-models.ts
|
|
3914
|
-
/**
|
|
3915
|
-
* 设置页的 view model:把原先住在渲染函数里的三块逻辑变成可单测的纯模块。
|
|
3916
|
-
*
|
|
3917
|
-
* 迁移前 `settings-page.ts` 是一个 1059 行的组件,funnel phase → {dot, label}、
|
|
3918
|
-
端口/连接数草稿的编辑与合法性、serviceStatus 派生全在渲染函数里,没有任何
|
|
3919
|
-
直接测试。这里按 pairing-panel.ts 的形状把它们拆成 state / action / reduce /
|
|
3920
|
-
view 四件套——shape 与该先例一致,但**不继承它唯一的泄漏**:view model 只返回
|
|
3921
|
-
语义值,i18n key 的映射留在页面(措辞归页面,测试不跟着措辞漂)。
|
|
3922
|
-
*/
|
|
3923
4046
|
const REMOTE_PHASE_META = {
|
|
3924
4047
|
disabled: {
|
|
3925
4048
|
dot: "",
|
|
@@ -4055,24 +4178,9 @@ window.__ModuleLoader__.load({
|
|
|
4055
4178
|
return (device.customName ?? device.deviceName).trim();
|
|
4056
4179
|
}
|
|
4057
4180
|
// src/client/settings-page.ts
|
|
4058
|
-
/**
|
|
4059
|
-
const
|
|
4060
|
-
|
|
4061
|
-
starting: "phase.starting",
|
|
4062
|
-
login_required: "phase.login_required",
|
|
4063
|
-
online: "phase.online",
|
|
4064
|
-
error: "phase.error",
|
|
4065
|
-
unavailable: "phase.unavailable",
|
|
4066
|
-
stopped: "phase.stopped"
|
|
4067
|
-
};
|
|
4068
|
-
const LOCAL_LABEL_KEY = {
|
|
4069
|
-
disabled: "local.phaseDisabled",
|
|
4070
|
-
starting: "local.phaseStarting",
|
|
4071
|
-
online: "local.phaseOnline",
|
|
4072
|
-
error: "local.phaseError",
|
|
4073
|
-
stopped: "local.phaseStopped"
|
|
4074
|
-
};
|
|
4075
|
-
/** 状态条用的短状态:列标签已经写明是哪条通道,值只说状态,免得在窄格里被截断。 */
|
|
4181
|
+
/** 中文结论由调用处提供,原始上游信息统一放入括号,保留排查依据。 */
|
|
4182
|
+
const errorDetails = (error) => "(" + (error instanceof Error ? error.message : String(error)) + ")";
|
|
4183
|
+
/** 通道标题旁的短状态;完整端点和参数放入对应的连接选项。 */
|
|
4076
4184
|
const CHANNEL_STATE_KEY = {
|
|
4077
4185
|
disabled: "channel.state.disabled",
|
|
4078
4186
|
starting: "channel.state.starting",
|
|
@@ -4089,21 +4197,6 @@ window.__ModuleLoader__.load({
|
|
|
4089
4197
|
attention: "status.attention",
|
|
4090
4198
|
ready: "status.ready"
|
|
4091
4199
|
};
|
|
4092
|
-
/** Inline trash icon for the compact destructive row action. Kept as a tiny
|
|
4093
|
-
* element (no icon dependency) so the client bundle stays dependency-free
|
|
4094
|
-
* apart from React. */
|
|
4095
|
-
const TrashIcon = () => (0, react.createElement)("svg", {
|
|
4096
|
-
className: "pbb-actionIcon",
|
|
4097
|
-
viewBox: "0 0 16 16",
|
|
4098
|
-
width: 13,
|
|
4099
|
-
height: 13,
|
|
4100
|
-
fill: "none",
|
|
4101
|
-
stroke: "currentColor",
|
|
4102
|
-
strokeWidth: 1.5,
|
|
4103
|
-
strokeLinecap: "round",
|
|
4104
|
-
strokeLinejoin: "round",
|
|
4105
|
-
"aria-hidden": true
|
|
4106
|
-
}, (0, react.createElement)("path", { d: "M2.5 4.5h11" }), (0, react.createElement)("path", { d: "M6.5 2.5h3" }), (0, react.createElement)("path", { d: "M4 4.5l.6 8.2a1 1 0 0 0 1 .9h4.8a1 1 0 0 0 1-.9l.6-8.2" }), (0, react.createElement)("path", { d: "M6.6 7v4.2" }), (0, react.createElement)("path", { d: "M9.4 7v4.2" }));
|
|
4107
4200
|
/** Chevron icon (linear, currentColor). CSS rotates it 90° while its owner is
|
|
4108
4201
|
* expanded, so collapsed always means "points right, more content behind". */
|
|
4109
4202
|
const ChevronIcon = () => (0, react.createElement)("svg", {
|
|
@@ -4118,8 +4211,7 @@ window.__ModuleLoader__.load({
|
|
|
4118
4211
|
strokeLinejoin: "round",
|
|
4119
4212
|
"aria-hidden": true
|
|
4120
4213
|
}, (0, react.createElement)("path", { d: "M6 3.5 10.5 8 6 12.5" }));
|
|
4121
|
-
/**
|
|
4122
|
-
* dingbats '✓'/'✗', which the repo's visual rules reject as character icons. */
|
|
4214
|
+
/** 诊断结果使用线性 SVG,与页面其余图标保持一致。 */
|
|
4123
4215
|
const CheckIcon = () => (0, react.createElement)("svg", {
|
|
4124
4216
|
viewBox: "0 0 16 16",
|
|
4125
4217
|
width: 12,
|
|
@@ -4186,6 +4278,13 @@ window.__ModuleLoader__.load({
|
|
|
4186
4278
|
const [remoteLimitDraft, dispatchRemoteLimitDraft] = (0, react.useReducer)((state, action) => numericDraftReduce(state, action, REMOTE_LIMIT_RANGE), initialNumericDraft(REMOTE_LIMIT_RANGE));
|
|
4187
4279
|
const [localPortDraft, dispatchLocalPortDraft] = (0, react.useReducer)((state, action) => numericDraftReduce(state, action, LOCAL_PORT_RANGE), initialNumericDraft(LOCAL_PORT_RANGE));
|
|
4188
4280
|
const [selectedPairingHost, setSelectedPairingHost] = (0, react.useState)(null);
|
|
4281
|
+
const [pairingOpen, setPairingOpen] = (0, react.useState)(false);
|
|
4282
|
+
const pageId = (0, react.useId)();
|
|
4283
|
+
const localOptionsId = pageId + "-local";
|
|
4284
|
+
const remoteOptionsId = pageId + "-remote";
|
|
4285
|
+
const troubleshootingId = pageId + "-troubleshooting";
|
|
4286
|
+
const systemId = pageId + "-system";
|
|
4287
|
+
const pairingId = pageId + "-pairing";
|
|
4189
4288
|
const [pairingPanel, dispatchPairingPanel] = (0, react.useReducer)(pairingPanelReduce, initialPairingPanelState);
|
|
4190
4289
|
const qrRequestId = (0, react.useRef)(0);
|
|
4191
4290
|
const [troubleshootingOpen, setTroubleshootingOpen] = (0, react.useState)(false);
|
|
@@ -4196,7 +4295,6 @@ window.__ModuleLoader__.load({
|
|
|
4196
4295
|
const [pushTestResult, setPushTestResult] = (0, react.useState)(null);
|
|
4197
4296
|
const [pushTestError, setPushTestError] = (0, react.useState)("");
|
|
4198
4297
|
const [deviceBusy, setDeviceBusy] = (0, react.useState)(null);
|
|
4199
|
-
const [deviceBusyAction, setDeviceBusyAction] = (0, react.useState)(null);
|
|
4200
4298
|
const [deviceMessage, setDeviceMessage] = (0, react.useState)("");
|
|
4201
4299
|
const [editingDeviceId, setEditingDeviceId] = (0, react.useState)(null);
|
|
4202
4300
|
const [deviceNameDraft, setDeviceNameDraft] = (0, react.useState)("");
|
|
@@ -4230,7 +4328,7 @@ window.__ModuleLoader__.load({
|
|
|
4230
4328
|
setPushTestResult(result);
|
|
4231
4329
|
setPushTestBusy(false);
|
|
4232
4330
|
}, (error) => {
|
|
4233
|
-
setPushTestError(
|
|
4331
|
+
setPushTestError(translateWith(props.t, "push.pushFailed") + errorDetails(error));
|
|
4234
4332
|
setPushTestBusy(false);
|
|
4235
4333
|
});
|
|
4236
4334
|
};
|
|
@@ -4247,7 +4345,7 @@ window.__ModuleLoader__.load({
|
|
|
4247
4345
|
setRelayTestResult(result);
|
|
4248
4346
|
setRelayTestBusy(false);
|
|
4249
4347
|
}, (error) => {
|
|
4250
|
-
setRelayTestError(
|
|
4348
|
+
setRelayTestError(translateWith(props.t, "push.relayBad") + errorDetails(error));
|
|
4251
4349
|
setRelayTestBusy(false);
|
|
4252
4350
|
});
|
|
4253
4351
|
};
|
|
@@ -4283,7 +4381,7 @@ window.__ModuleLoader__.load({
|
|
|
4283
4381
|
const reportState = props.useDeepPilotReport((s) => s);
|
|
4284
4382
|
hooks.report = reportState.report;
|
|
4285
4383
|
if (reportState.status === "error" && reportState.message) {
|
|
4286
|
-
diag.push(reportState.message);
|
|
4384
|
+
diag.push(translateWith(props.t, "diag.reportFailed") + errorDetails(reportState.message));
|
|
4287
4385
|
failed = true;
|
|
4288
4386
|
}
|
|
4289
4387
|
const enabledState = props.useDeepPilotEnabled((s) => s);
|
|
@@ -4324,7 +4422,7 @@ window.__ModuleLoader__.load({
|
|
|
4324
4422
|
try {
|
|
4325
4423
|
readHooks();
|
|
4326
4424
|
} catch (error) {
|
|
4327
|
-
diag.push(translateWith(props.t, "diag.renderError") + (error
|
|
4425
|
+
diag.push(translateWith(props.t, "diag.renderError") + errorDetails(error));
|
|
4328
4426
|
failed = true;
|
|
4329
4427
|
}
|
|
4330
4428
|
const report = hooks.report;
|
|
@@ -4371,7 +4469,7 @@ window.__ModuleLoader__.load({
|
|
|
4371
4469
|
}, (error) => {
|
|
4372
4470
|
dispatchLocalPortDraft({
|
|
4373
4471
|
type: "failed",
|
|
4374
|
-
message: translateWith(props.t, "local.portFailed") + (error
|
|
4472
|
+
message: translateWith(props.t, "local.portFailed") + errorDetails(error)
|
|
4375
4473
|
});
|
|
4376
4474
|
});
|
|
4377
4475
|
};
|
|
@@ -4392,7 +4490,7 @@ window.__ModuleLoader__.load({
|
|
|
4392
4490
|
}, (error) => {
|
|
4393
4491
|
dispatchRemoteLimitDraft({
|
|
4394
4492
|
type: "failed",
|
|
4395
|
-
message: translateWith(props.t, "remote.limitFailed") + (error
|
|
4493
|
+
message: translateWith(props.t, "remote.limitFailed") + errorDetails(error)
|
|
4396
4494
|
});
|
|
4397
4495
|
});
|
|
4398
4496
|
};
|
|
@@ -4442,7 +4540,7 @@ window.__ModuleLoader__.load({
|
|
|
4442
4540
|
dispatchPairingPanel({
|
|
4443
4541
|
type: "failed",
|
|
4444
4542
|
requestId,
|
|
4445
|
-
message: translateWith(props.t, "pair.qrFailed") + (error
|
|
4543
|
+
message: translateWith(props.t, "pair.qrFailed") + errorDetails(error)
|
|
4446
4544
|
});
|
|
4447
4545
|
});
|
|
4448
4546
|
};
|
|
@@ -4465,7 +4563,7 @@ window.__ModuleLoader__.load({
|
|
|
4465
4563
|
}, (error) => {
|
|
4466
4564
|
dispatchPairingPanel({
|
|
4467
4565
|
type: "notice",
|
|
4468
|
-
message: translateWith(props.t, "pair.infoCopyFailed") + (error
|
|
4566
|
+
message: translateWith(props.t, "pair.infoCopyFailed") + errorDetails(error)
|
|
4469
4567
|
});
|
|
4470
4568
|
});
|
|
4471
4569
|
};
|
|
@@ -4486,15 +4584,13 @@ window.__ModuleLoader__.load({
|
|
|
4486
4584
|
const revokeDevice = (deviceId, _name) => {
|
|
4487
4585
|
if (!can("revokeDevice")) return;
|
|
4488
4586
|
setDeviceBusy(deviceId);
|
|
4489
|
-
setDeviceBusyAction("revoke");
|
|
4490
4587
|
setDeviceMessage("");
|
|
4491
4588
|
props.revokeDevice(deviceId).then(() => {
|
|
4492
4589
|
setDeviceMessage(translateWith(props.t, "devices.revoked"));
|
|
4493
4590
|
}, (error) => {
|
|
4494
|
-
setDeviceMessage(translateWith(props.t, "devices.revokeFailed") + (error
|
|
4591
|
+
setDeviceMessage(translateWith(props.t, "devices.revokeFailed") + errorDetails(error));
|
|
4495
4592
|
}).finally(() => {
|
|
4496
4593
|
setDeviceBusy(null);
|
|
4497
|
-
setDeviceBusyAction(null);
|
|
4498
4594
|
});
|
|
4499
4595
|
};
|
|
4500
4596
|
const deviceLabel$1 = (device) => deviceLabel(device) || translateWith(props.t, "devices.unnamed");
|
|
@@ -4517,17 +4613,15 @@ window.__ModuleLoader__.load({
|
|
|
4517
4613
|
return;
|
|
4518
4614
|
}
|
|
4519
4615
|
setDeviceBusy(deviceId);
|
|
4520
|
-
setDeviceBusyAction("rename");
|
|
4521
4616
|
setDeviceMessage("");
|
|
4522
4617
|
props.setDeviceName(deviceId, normalized === "" ? null : normalized).then(() => {
|
|
4523
4618
|
setDeviceMessage(normalized === "" ? translateWith(props.t, "devices.nameCleared") : translateWith(props.t, "devices.renamed"));
|
|
4524
4619
|
setEditingDeviceId(null);
|
|
4525
4620
|
setDeviceNameDraft("");
|
|
4526
4621
|
}, (error) => {
|
|
4527
|
-
setDeviceMessage(translateWith(props.t, "devices.renameFailed") + (error
|
|
4622
|
+
setDeviceMessage(translateWith(props.t, "devices.renameFailed") + errorDetails(error));
|
|
4528
4623
|
}).finally(() => {
|
|
4529
4624
|
setDeviceBusy(null);
|
|
4530
|
-
setDeviceBusyAction(null);
|
|
4531
4625
|
});
|
|
4532
4626
|
};
|
|
4533
4627
|
const visibleDevices$1 = visibleDevices(report);
|
|
@@ -4543,10 +4637,10 @@ window.__ModuleLoader__.load({
|
|
|
4543
4637
|
"data-armed": armed || void 0,
|
|
4544
4638
|
"aria-busy": busy,
|
|
4545
4639
|
"aria-label": translateWith(props.t, "devices.col.name") + ": " + label
|
|
4546
|
-
}, (0, react.createElement)("div", { className: "pbb-deviceMain" }, (0, react.createElement)("div", { className: "pbb-
|
|
4640
|
+
}, (0, react.createElement)("div", { className: "pbb-deviceMain" }, settingsIcon("phone"), (0, react.createElement)("div", { className: "pbb-deviceText" }, (0, react.createElement)("span", {
|
|
4547
4641
|
className: "pbb-deviceName",
|
|
4548
4642
|
title: label
|
|
4549
|
-
}, label),
|
|
4643
|
+
}, label), (0, react.createElement)("div", { className: "pbb-deviceMeta" }, (0, react.createElement)("span", null, d.appVersion), (0, react.createElement)("span", null, translateWith(props.t, "devices.col.lastSeen") + " " + formatLastSeen(d.lastSeenTs))))), editing ? (0, react.createElement)("form", {
|
|
4550
4644
|
className: "pbb-deviceRenameForm",
|
|
4551
4645
|
onSubmit: (event) => {
|
|
4552
4646
|
event.preventDefault();
|
|
@@ -4584,25 +4678,22 @@ window.__ModuleLoader__.load({
|
|
|
4584
4678
|
title: translateWith(props.t, "devices.nameCancel"),
|
|
4585
4679
|
"aria-label": translateWith(props.t, "devices.nameCancel"),
|
|
4586
4680
|
onClick: cancelDeviceRename
|
|
4587
|
-
}, translateWith(props.t, "devices.nameCancel"))), deviceNameDraft.length > 64 ? (0, react.createElement)("p", { className: "pbb-diag pbb-diagBad" }, translateWith(props.t, "devices.nameInvalid")) : null) : null, armed ? null : (0, react.createElement)("div", {
|
|
4588
|
-
className: "pbb-
|
|
4589
|
-
|
|
4590
|
-
},
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
disabled: busy,
|
|
4600
|
-
"aria-label": busy && deviceBusyAction === "revoke" ? translateWith(props.t, "devices.deleting", { name: label }) : translateWith(props.t, "devices.revokeAria", { name: label }),
|
|
4601
|
-
onClick: () => {
|
|
4681
|
+
}, translateWith(props.t, "devices.nameCancel"))), deviceNameDraft.length > 64 ? (0, react.createElement)("p", { className: "pbb-diag pbb-diagBad" }, translateWith(props.t, "devices.nameInvalid")) : null) : null, armed || editing ? null : (0, react.createElement)("div", { className: "pbb-deviceActions" }, busy ? (0, react.createElement)("span", {
|
|
4682
|
+
className: "pbb-actionBusy",
|
|
4683
|
+
role: "status"
|
|
4684
|
+
}, translateWith(props.t, "devices.deleting")) : (0, react.createElement)(DeviceActions, {
|
|
4685
|
+
name: label,
|
|
4686
|
+
fingerprint,
|
|
4687
|
+
customName: d.customName,
|
|
4688
|
+
canRename: editingDeviceId === null && can("setDeviceName"),
|
|
4689
|
+
canRevoke: can("revokeDevice"),
|
|
4690
|
+
t: props.t,
|
|
4691
|
+
onRename: () => beginDeviceRename(d),
|
|
4692
|
+
onRevoke: () => {
|
|
4602
4693
|
cancelDeviceRename();
|
|
4603
4694
|
setArmedRevokeDeviceId(d.deviceId);
|
|
4604
4695
|
}
|
|
4605
|
-
}
|
|
4696
|
+
})), armed && !busy ? (0, react.createElement)("div", { className: "pbb-deviceConfirm" }, (0, react.createElement)("p", {
|
|
4606
4697
|
className: "pbb-diag pbb-diagBad",
|
|
4607
4698
|
role: "alert"
|
|
4608
4699
|
}, translateWith(props.t, "devices.revokeConfirm", { name: label })), (0, react.createElement)("div", { className: "pbb-rowAction" }, (0, react.createElement)("button", {
|
|
@@ -4620,27 +4711,32 @@ window.__ModuleLoader__.load({
|
|
|
4620
4711
|
}, translateWith(props.t, "devices.nameCancel")))) : null);
|
|
4621
4712
|
})) : (0, react.createElement)("p", { className: "pbb-empty" }, translateWith(props.t, "devices.empty"));
|
|
4622
4713
|
const switchTitle = translateWith(props.t, "master.title");
|
|
4623
|
-
const switchDesc = switchReady ? enabled ? translateWith(props.t, "master.on") : translateWith(props.t, "master.off") : translateWith(props.t, "master.loading");
|
|
4624
4714
|
const localMeta = report === null ? null : LOCAL_PHASE_META[report.local.phase];
|
|
4625
4715
|
const remoteMeta = report === null ? null : REMOTE_PHASE_META[report.remote.phase];
|
|
4626
4716
|
const service = serviceStatus({
|
|
4627
4717
|
enabled,
|
|
4628
|
-
switchReady,
|
|
4718
|
+
switchReady: switchReady && report !== null,
|
|
4629
4719
|
localDot: localMeta?.dot,
|
|
4630
4720
|
remoteDot: remoteMeta?.dot
|
|
4631
4721
|
});
|
|
4632
4722
|
const serviceStatusText = translateWith(props.t, SERVICE_STATUS_KEY[service.kind]);
|
|
4633
|
-
const serviceDot = service.dot;
|
|
4634
|
-
const localPhaseText = localMeta === null ? translateWith(props.t, "phase.unknown") : translateWith(props.t, LOCAL_LABEL_KEY[localMeta.label]);
|
|
4635
|
-
const remotePhaseText = remoteMeta === null ? translateWith(props.t, "phase.unknown") : translateWith(props.t, REMOTE_LABEL_KEY[remoteMeta.label]);
|
|
4636
4723
|
const localStateText = localMeta === null ? translateWith(props.t, "phase.unknown") : translateWith(props.t, CHANNEL_STATE_KEY[localMeta.label]);
|
|
4637
4724
|
const remoteStateText = remoteMeta === null ? translateWith(props.t, "phase.unknown") : translateWith(props.t, CHANNEL_STATE_KEY[remoteMeta.label]);
|
|
4638
4725
|
/** 一条失败事件的单行文本:时间 · 类型 · 分因,附带可选排查字段。 */
|
|
4639
4726
|
const diagnosticLine = (failure) => {
|
|
4640
4727
|
const base = translateWith(props.t, "diagnostics.item", {
|
|
4641
4728
|
time: new Date(failure.ts).toLocaleString(),
|
|
4642
|
-
kind:
|
|
4643
|
-
|
|
4729
|
+
kind: translateWith(props.t, {
|
|
4730
|
+
"upgrade-rejected": "diagnostics.kind.upgrade",
|
|
4731
|
+
"pair-rejected": "diagnostics.kind.pair",
|
|
4732
|
+
"auth-failed": "diagnostics.kind.auth",
|
|
4733
|
+
"connection-opened": "diagnostics.kind.opened",
|
|
4734
|
+
"connection-closed": "diagnostics.kind.closed",
|
|
4735
|
+
"connection-error": "diagnostics.kind.error",
|
|
4736
|
+
identity: "diagnostics.kind.identity",
|
|
4737
|
+
storage: "diagnostics.kind.storage"
|
|
4738
|
+
}[failure.kind] ?? "diagnostics.kind.unknown"),
|
|
4739
|
+
reason: "(" + failure.kind + " / " + failure.reason + ")"
|
|
4644
4740
|
});
|
|
4645
4741
|
const extras = [];
|
|
4646
4742
|
if (failure.attemptId !== void 0) extras.push(translateWith(props.t, "diagnostics.attempt", { id: failure.attemptId }));
|
|
@@ -4677,12 +4773,12 @@ window.__ModuleLoader__.load({
|
|
|
4677
4773
|
});
|
|
4678
4774
|
}, (error) => {
|
|
4679
4775
|
setDiagnosticsCopy({
|
|
4680
|
-
message: translateWith(props.t, "diagnostics.copyFailed") + (error
|
|
4776
|
+
message: translateWith(props.t, "diagnostics.copyFailed") + errorDetails(error),
|
|
4681
4777
|
failed: true
|
|
4682
4778
|
});
|
|
4683
4779
|
});
|
|
4684
4780
|
};
|
|
4685
|
-
const diagnosticsSection = report === null ? null : (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("div", { className: "pbb-
|
|
4781
|
+
const diagnosticsSection = report === null ? null : (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-testTitle" }, translateWith(props.t, "diagnostics.title")), (0, react.createElement)("span", { className: "pbb-testDescription" }, translateWith(props.t, "diagnostics.description"))), (0, react.createElement)("button", {
|
|
4686
4782
|
type: "button",
|
|
4687
4783
|
className: "pbb-action",
|
|
4688
4784
|
onClick: copyDiagnostics,
|
|
@@ -4694,14 +4790,10 @@ window.__ModuleLoader__.load({
|
|
|
4694
4790
|
className: "pbb-diag",
|
|
4695
4791
|
key: String(index)
|
|
4696
4792
|
}, diagnosticLine(failure)))));
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
title: label + " · " + value + (sub === "" ? "" : " · " + sub)
|
|
4702
|
-
}, (0, react.createElement)("div", { className: "pbb-statusLabel" }, label), (0, react.createElement)("div", { className: "pbb-statusValue" }, dot === null ? null : (0, react.createElement)("span", { className: "pbb-dot" + dot }), value), (0, react.createElement)("div", { className: "pbb-statusSub" }, sub));
|
|
4703
|
-
/** 折叠区:grid-rows 0fr→1fr 平滑开合(mockup 的做法),不用 <details> 的瞬时跳变。 */
|
|
4704
|
-
const fold = (open, body) => (0, react.createElement)("div", { className: "pbb-fold" + (open ? "" : " pbb-foldClosed") }, (0, react.createElement)("div", null, body));
|
|
4793
|
+
const fold = (open, body) => (0, react.createElement)("div", {
|
|
4794
|
+
className: "pbb-fold",
|
|
4795
|
+
hidden: !open
|
|
4796
|
+
}, body);
|
|
4705
4797
|
/** 配对倒计时:仅在 QR 面板打开且 grant 在场时每秒刷新一次。 */
|
|
4706
4798
|
(0, react.useEffect)(() => {
|
|
4707
4799
|
if (!panel.open || pairingPanel.grant === null) return;
|
|
@@ -4711,44 +4803,19 @@ window.__ModuleLoader__.load({
|
|
|
4711
4803
|
const grantRemainingMs = pairingPanel.grant === null ? 0 : Math.max(0, pairingPanel.grant.expiresAt - nowMs);
|
|
4712
4804
|
const grantRemainingText = String(Math.floor(grantRemainingMs / 6e4)) + ":" + String(Math.floor(grantRemainingMs / 1e3) % 60).padStart(2, "0");
|
|
4713
4805
|
const grantRemainingPct = Math.min(100, grantRemainingMs / 3e5 * 100);
|
|
4714
|
-
const localDesc = localSwitchReady ? localEnabled ? translateWith(props.t, "local.on", { port: localPort }) : translateWith(props.t, "local.off") : translateWith(props.t, "master.loading");
|
|
4715
|
-
const remoteDesc = remoteSwitchReady ? remoteEnabled ? translateWith(props.t, "remote.on") : translateWith(props.t, "remote.off") : translateWith(props.t, "master.loading");
|
|
4716
|
-
/** 端点 → 状态条副行只暴露 host[:port],去掉协议前缀让一行能放下。 */
|
|
4717
|
-
const endpointHost = (value) => {
|
|
4718
|
-
if (value === void 0 || value === "") return void 0;
|
|
4719
|
-
try {
|
|
4720
|
-
return new URL(value).host;
|
|
4721
|
-
} catch {
|
|
4722
|
-
return value;
|
|
4723
|
-
}
|
|
4724
|
-
};
|
|
4725
|
-
const localStatusSub = !localSwitchReady ? translateWith(props.t, "master.loading") : report !== null && report.local.phase === "online" ? endpointHost(report.local.endpoints[0]) ?? localDesc : report !== null && report.local.phase === "error" ? report.local.message !== void 0 && report.local.message !== "" ? report.local.message : localDesc : report !== null && (report.local.phase === "disabled" || report.local.phase === "stopped") ? translateWith(props.t, "local.off") : localDesc;
|
|
4726
|
-
const remoteStatusSub = !remoteSwitchReady ? translateWith(props.t, "master.loading") : report !== null && report.remote.phase === "online" ? endpointHost(report.remote.publicURL) ?? remoteDesc : report !== null && report.remote.phase === "error" ? report.remote.message !== void 0 && report.remote.message !== "" ? report.remote.message : remoteDesc : report !== null && report.remote.phase === "disabled" ? translateWith(props.t, "remote.off") : remoteDesc;
|
|
4727
|
-
const isOffPhase = (phase) => phase === "disabled" || phase === "stopped";
|
|
4728
|
-
const localSettled = report === null || (localEnabled ? report.local.phase === "online" : isOffPhase(report.local.phase));
|
|
4729
|
-
const remoteSettled = report === null || (remoteEnabled ? report.remote.phase === "online" : isOffPhase(report.remote.phase));
|
|
4730
|
-
const localChannelDesc = localSettled ? localDesc : localPhaseText + " · " + localDesc;
|
|
4731
|
-
const remoteChannelDesc = remoteSettled ? remoteDesc : remotePhaseText + " · " + remoteDesc;
|
|
4732
4806
|
const recentFailures = report?.diagnostics?.recentFailures ?? [];
|
|
4733
4807
|
const troubleGood = relayTestResult !== null ? relayTestResult.overall === "ok" : pushTestResult !== null ? pushTestResult.overall === "sent" : false;
|
|
4734
4808
|
const troubleBad = relayTestResult !== null ? relayTestResult.overall !== "ok" : pushTestResult !== null ? pushTestResult.overall !== "sent" : recentFailures.length > 0;
|
|
4735
|
-
const troubleConclusion = relayTestResult !== null ? relayTestResult.overall === "ok" ? translateWith(props.t, "push.relayOk") : translateWith(props.t, "push.relayBad") : pushTestResult !== null ? pushTestResult.overall === "sent" ? translateWith(props.t, "push.pushSent") : translateWith(props.t, "push.pushFailed") : recentFailures.length > 0 ? translateWith(props.t, "diagnostics.
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
if (can("refresh")) props.refresh();
|
|
4741
|
-
}
|
|
4742
|
-
}, translateWith(props.t, "meta.refresh"))), (0, react.createElement)("section", { className: "pbb-statusStrip" }, statusCell(translateWith(props.t, "master.title"), serviceDot, serviceStatusText, switchDesc), statusCell(translateWith(props.t, "local.title"), localMeta?.dot ?? "", localStateText, localStatusSub), statusCell(translateWith(props.t, "remote.title"), remoteMeta?.dot ?? "", remoteStateText, remoteStatusSub), statusCell(translateWith(props.t, "panel.activeConnections"), null, report === null ? translateWith(props.t, "status.loading") : String(report.activeConnections), translateWith(props.t, "panel.identity") + " · " + (report !== null && report.pairingReady ? translateWith(props.t, "panel.identityReady") : translateWith(props.t, "panel.identityNotReady")))), report === null ? null : (0, react.createElement)("div", { className: "pbb-card" }, (0, react.createElement)("div", { className: "pbb-cardHeader" }, (0, react.createElement)("div", null, (0, react.createElement)("h3", { className: "pbb-cardTitle" }, translateWith(props.t, "pair.qrPanelTitle")), (0, react.createElement)("p", { className: "pbb-cardDescription" }, translateWith(props.t, "pair.description"))), pairingTarget === null ? (0, react.createElement)("span", { className: "pbb-statusBadge" + (enabled ? " pbb-bad" : "") }, enabled ? translateWith(props.t, "pair.noAddress") : translateWith(props.t, "status.off")) : (0, react.createElement)("button", {
|
|
4809
|
+
const troubleConclusion = relayTestResult !== null ? relayTestResult.overall === "ok" ? translateWith(props.t, "push.relayOk") : translateWith(props.t, "push.relayBad") : pushTestResult !== null ? pushTestResult.overall === "sent" ? translateWith(props.t, "push.pushSent") : translateWith(props.t, "push.pushFailed") : recentFailures.length > 0 ? translateWith(props.t, "diagnostics.historyCount", { count: recentFailures.length }) : "";
|
|
4810
|
+
const pairingSection = (0, react.createElement)("div", {
|
|
4811
|
+
id: pairingId,
|
|
4812
|
+
hidden: !pairingOpen
|
|
4813
|
+
}, !pairingOpen || report === null ? null : (0, react.createElement)("div", { className: "pbb-pairingPanel" }, (0, react.createElement)("div", { className: "pbb-pairingHeader" }, (0, react.createElement)("h3", { className: "pbb-cardTitle" }, translateWith(props.t, "pair.qrPanelTitle")), !panel.open && pairingTarget !== null ? (0, react.createElement)("button", {
|
|
4743
4814
|
type: "button",
|
|
4744
|
-
className: "pbb-action
|
|
4745
|
-
disabled: panel.busy ||
|
|
4746
|
-
onClick: () =>
|
|
4747
|
-
|
|
4748
|
-
if (panel.open) hidePairingQR();
|
|
4749
|
-
else showPairingQR(pairingTarget);
|
|
4750
|
-
}
|
|
4751
|
-
}, translateWith(props.t, panel.action))), (0, react.createElement)("div", { className: "pbb-pairingBody" }, pairingTarget === null ? (0, react.createElement)("p", { className: "pbb-diag" }, enabled ? translateWith(props.t, "pair.noAddressHelp") : translateWith(props.t, "pair.disabledHelp")) : null, pairingTargets.length < 2 ? null : (0, react.createElement)("div", { className: "pbb-targetList" }, pairingTargets.map((target) => (0, react.createElement)("button", {
|
|
4815
|
+
className: "pbb-action",
|
|
4816
|
+
disabled: panel.busy || !report.pairingReady,
|
|
4817
|
+
onClick: () => showPairingQR(pairingTarget)
|
|
4818
|
+
}, translateWith(props.t, "pair.qrShow")) : null), (0, react.createElement)("div", { className: "pbb-pairingBody" }, pairingTarget === null ? (0, react.createElement)("p", { className: "pbb-diag" }, enabled ? translateWith(props.t, "pair.noAddressHelp") : translateWith(props.t, "pair.disabledHelp")) : null, pairingTargets.length < 2 ? null : (0, react.createElement)("div", { className: "pbb-targetList" }, pairingTargets.map((target) => (0, react.createElement)("button", {
|
|
4752
4819
|
type: "button",
|
|
4753
4820
|
key: target.host,
|
|
4754
4821
|
className: "pbb-targetButton" + (target.host === pairingTarget?.host ? " pbb-targetSelected" : ""),
|
|
@@ -4778,35 +4845,49 @@ window.__ModuleLoader__.load({
|
|
|
4778
4845
|
className: "pbb-action pbb-buttonPrimary",
|
|
4779
4846
|
onClick: copyPairingInfo,
|
|
4780
4847
|
"data-testid": "pairingInfoCopy"
|
|
4781
|
-
}, translateWith(props.t, "panel.tokenAction.copy")))), (0, react.createElement)("p", { className: "pbb-qrHint" }, translateWith(props.t, "pair.qrHint", { kind: panel.target?.kind === "public" ? translateWith(props.t, "pair.kind.public") : translateWith(props.t, "pair.kind.lan") })))) : null))
|
|
4848
|
+
}, translateWith(props.t, "panel.tokenAction.copy")))), (0, react.createElement)("p", { className: "pbb-qrHint" }, translateWith(props.t, "pair.qrHint", { kind: panel.target?.kind === "public" ? translateWith(props.t, "pair.kind.public") : translateWith(props.t, "pair.kind.lan") })))) : null)));
|
|
4849
|
+
return (0, react.createElement)("div", { className: "pbb-section" }, (0, react.createElement)("header", { className: "pbb-pageHeader" }, (0, react.createElement)("div", null, (0, react.createElement)("h2", { className: "pbb-title" }, "DeepPilot"), (0, react.createElement)("p", { className: "pbb-intro" }, translateWith(props.t, "meta.intro"))), (0, react.createElement)("button", {
|
|
4782
4850
|
type: "button",
|
|
4783
|
-
|
|
4784
|
-
"
|
|
4785
|
-
|
|
4851
|
+
className: "pbb-refresh",
|
|
4852
|
+
disabled: !can("refresh"),
|
|
4853
|
+
onClick: () => props.refresh?.()
|
|
4854
|
+
}, settingsIcon("refresh", 14), translateWith(props.t, "meta.refresh"))), (0, react.createElement)("section", {
|
|
4855
|
+
className: "pbb-card pbb-connections",
|
|
4856
|
+
"aria-label": translateWith(props.t, "connection.title")
|
|
4857
|
+
}, (0, react.createElement)("div", { className: "pbb-cardBody" }, (0, react.createElement)("div", { className: "pbb-masterRow" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-controlTitle" }, switchTitle), (0, react.createElement)("div", { className: "pbb-serviceSummary" }, (0, react.createElement)("span", { className: "pbb-serviceState" + (service.kind === "ready" ? " pbb-ok" : service.kind === "attention" ? " pbb-bad" : "") }, settingsIcon(service.kind === "ready" ? "ready" : service.kind === "attention" ? "attention" : "info", 13)), (0, react.createElement)("span", null, serviceStatusText), (0, react.createElement)("span", {
|
|
4858
|
+
className: "pbb-metaDivider",
|
|
4859
|
+
"aria-hidden": true
|
|
4860
|
+
}), (0, react.createElement)("span", null, translateWith(props.t, "panel.activeConnections") + " " + (report === null ? "—" : String(report.activeConnections))))), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
4861
|
+
checked: enabled,
|
|
4862
|
+
label: switchTitle,
|
|
4786
4863
|
disabled: !switchReady,
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
if (can("setEnabled")) props.setDeepPilotEnabled(!enabled);
|
|
4864
|
+
onChange: (next) => {
|
|
4865
|
+
if (can("setEnabled")) props.setDeepPilotEnabled(next);
|
|
4790
4866
|
}
|
|
4791
|
-
})), (0, react.createElement)("div", { className: "pbb-channel" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("div", { className: "pbb-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
"aria-checked": localEnabled,
|
|
4795
|
-
"aria-label": translateWith(props.t, "local.title"),
|
|
4867
|
+
})), (0, react.createElement)("div", { className: "pbb-channel" }, (0, react.createElement)("div", { className: "pbb-row pbb-channelRow" }, settingsIcon("wifi"), (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-controlTitle" }, translateWith(props.t, "local.title")), (0, react.createElement)("div", { className: "pbb-channelState" }, (0, react.createElement)("span", { className: localMeta?.label === "online" ? "pbb-ok" : localMeta?.label === "error" ? "pbb-bad" : void 0 }, localStateText))), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
4868
|
+
checked: localEnabled,
|
|
4869
|
+
label: translateWith(props.t, "local.title"),
|
|
4796
4870
|
disabled: !localSwitchReady,
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
if (can("setLocalEnabled")) props.setDeepPilotLocalEnabled(!localEnabled);
|
|
4871
|
+
onChange: (next) => {
|
|
4872
|
+
if (can("setLocalEnabled")) props.setDeepPilotLocalEnabled(next);
|
|
4800
4873
|
}
|
|
4801
|
-
})
|
|
4874
|
+
}), (0, react.createElement)("button", {
|
|
4802
4875
|
type: "button",
|
|
4803
|
-
className: "pbb-expand",
|
|
4876
|
+
className: "pbb-iconButton pbb-expand",
|
|
4877
|
+
"aria-label": translateWith(props.t, "local.options"),
|
|
4804
4878
|
"aria-expanded": localOptionsOpen,
|
|
4879
|
+
"aria-controls": localOptionsId,
|
|
4805
4880
|
onClick: () => setLocalOptionsOpen(!localOptionsOpen)
|
|
4806
|
-
},
|
|
4807
|
-
className: "pbb-
|
|
4881
|
+
}, (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon()))), report !== null && report.local.message && report.local.phase === "error" ? (0, react.createElement)("p", {
|
|
4882
|
+
className: "pbb-diag pbb-diagBad",
|
|
4883
|
+
role: "alert"
|
|
4884
|
+
}, translateWith(props.t, "local.errorDetails", { message: report.local.message })) : null, report !== null && report.local.tlsIdentityRegenerated === true ? (0, react.createElement)("p", { className: "pbb-diag pbb-diagBad" }, translateWith(props.t, "local.tlsRegenerated")) : null, fold(localOptionsOpen, (0, react.createElement)("div", {
|
|
4885
|
+
className: "pbb-channelBody",
|
|
4886
|
+
id: localOptionsId
|
|
4887
|
+
}, report !== null && report.local.phase === "online" ? (0, react.createElement)("p", { className: "pbb-diag pbb-endpoint" }, report.local.endpoints.join(" · ")) : null, (0, react.createElement)("div", { className: "pbb-limitRow" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("label", {
|
|
4888
|
+
className: "pbb-controlTitle",
|
|
4808
4889
|
htmlFor: "deeppilot-local-port"
|
|
4809
|
-
}, translateWith(props.t, "local.portTitle")), (0, react.createElement)("span", { className: "pbb-
|
|
4890
|
+
}, translateWith(props.t, "local.portTitle")), (0, react.createElement)("span", { className: "pbb-controlDescription" }, translateWith(props.t, "local.portDescription")), !localPortView.valid ? (0, react.createElement)("p", { className: "pbb-diag pbb-diagBad" }, translateWith(props.t, "local.portInvalid")) : localPortDraft.message ? (0, react.createElement)("p", { className: "pbb-diag" + (localPortDraft.failed ? " pbb-diagBad" : "") }, localPortDraft.message) : null), (0, react.createElement)("div", { className: "pbb-limitControl" }, (0, react.createElement)("input", {
|
|
4810
4891
|
id: "deeppilot-local-port",
|
|
4811
4892
|
className: "pbb-numberInput",
|
|
4812
4893
|
type: "number",
|
|
@@ -4832,30 +4913,38 @@ window.__ModuleLoader__.load({
|
|
|
4832
4913
|
className: "pbb-action",
|
|
4833
4914
|
disabled: !localPortReady || !localPortView.valid || localPortView.unchanged,
|
|
4834
4915
|
onClick: applyLocalPort
|
|
4835
|
-
}, translateWith(props.t, "remote.limitApply")))), report !== null && report.local.phase === "online" && report.local.tlsFingerprint ? (0, react.createElement)("div", { className: "pbb-limitRow" }, (0, react.createElement)("div", { className: "pbb-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4916
|
+
}, translateWith(props.t, "remote.limitApply")))), report !== null && report.local.phase === "online" && report.local.tlsFingerprint ? (0, react.createElement)("div", { className: "pbb-limitRow" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-controlTitle" }, translateWith(props.t, "local.tlsFingerprint")), (0, react.createElement)("code", { className: "pbb-token" }, report.local.tlsFingerprint))) : null))), (0, react.createElement)("div", { className: "pbb-channel" }, (0, react.createElement)("div", { className: "pbb-row pbb-channelRow" }, settingsIcon("globe"), (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-controlTitle" }, translateWith(props.t, "remote.title")), (0, react.createElement)("div", { className: "pbb-channelState" }, (0, react.createElement)("span", { className: remoteMeta?.label === "online" ? "pbb-ok" : remoteMeta?.label === "error" || remoteMeta?.label === "unavailable" ? "pbb-bad" : void 0 }, remoteStateText), (0, react.createElement)("span", {
|
|
4917
|
+
className: "pbb-metaDivider",
|
|
4918
|
+
"aria-hidden": true
|
|
4919
|
+
}), (0, react.createElement)("span", null, "Tailscale Funnel"))), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
4920
|
+
checked: remoteEnabled,
|
|
4921
|
+
label: translateWith(props.t, "remote.title"),
|
|
4840
4922
|
disabled: !remoteSwitchReady,
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
if (can("setRemoteEnabled")) props.setDeepPilotRemoteEnabled(!remoteEnabled);
|
|
4923
|
+
onChange: (next) => {
|
|
4924
|
+
if (can("setRemoteEnabled")) props.setDeepPilotRemoteEnabled(next);
|
|
4844
4925
|
}
|
|
4845
|
-
})
|
|
4926
|
+
}), (0, react.createElement)("button", {
|
|
4927
|
+
type: "button",
|
|
4928
|
+
className: "pbb-iconButton pbb-expand",
|
|
4929
|
+
"aria-label": translateWith(props.t, "remote.options"),
|
|
4930
|
+
"aria-expanded": remoteOptionsOpen,
|
|
4931
|
+
"aria-controls": remoteOptionsId,
|
|
4932
|
+
onClick: () => setRemoteOptionsOpen(!remoteOptionsOpen)
|
|
4933
|
+
}, (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon()))), report !== null && report.remote.phase === "login_required" && typeof report.remote.authURL === "string" && report.remote.authURL.startsWith("https://") ? (0, react.createElement)("div", { className: "pbb-rowAction" }, (0, react.createElement)("a", {
|
|
4846
4934
|
className: "pbb-action pbb-buttonPrimary",
|
|
4847
4935
|
href: report.remote.authURL,
|
|
4848
4936
|
target: "_blank",
|
|
4849
4937
|
rel: "noreferrer"
|
|
4850
|
-
}, translateWith(props.t, "remote.openAuth"))) : null, report !== null && report.remote.message && (report.remote.phase === "error" || report.remote.phase === "unavailable") ? (0, react.createElement)("p", {
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4938
|
+
}, translateWith(props.t, "remote.openAuth"))) : null, report !== null && report.remote.message && (report.remote.phase === "error" || report.remote.phase === "unavailable") ? (0, react.createElement)("p", {
|
|
4939
|
+
className: "pbb-diag pbb-diagBad",
|
|
4940
|
+
role: "alert"
|
|
4941
|
+
}, translateWith(props.t, "remote.errorDetails", { message: report.remote.message })) : null, fold(remoteOptionsOpen, (0, react.createElement)("div", {
|
|
4942
|
+
className: "pbb-channelBody",
|
|
4943
|
+
id: remoteOptionsId
|
|
4944
|
+
}, report !== null && report.remote.phase === "online" ? (0, react.createElement)("p", { className: "pbb-diag pbb-endpoint" }, report.remote.publicURL) : null, (0, react.createElement)("div", { className: "pbb-limitRow" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("label", {
|
|
4945
|
+
className: "pbb-controlTitle",
|
|
4857
4946
|
htmlFor: "deeppilot-funnel-source-limit"
|
|
4858
|
-
}, translateWith(props.t, "remote.limitTitle")), (0, react.createElement)("span", { className: "pbb-
|
|
4947
|
+
}, translateWith(props.t, "remote.limitTitle")), (0, react.createElement)("span", { className: "pbb-controlDescription" }, translateWith(props.t, "remote.limitDescription")), !remoteLimitView.valid ? (0, react.createElement)("p", { className: "pbb-diag pbb-diagBad" }, translateWith(props.t, "remote.limitInvalid")) : remoteLimitDraft.message ? (0, react.createElement)("p", { className: "pbb-diag" + (remoteLimitDraft.failed ? " pbb-diagBad" : "") }, remoteLimitDraft.message) : null), (0, react.createElement)("div", { className: "pbb-limitControl" }, (0, react.createElement)("input", {
|
|
4859
4948
|
id: "deeppilot-funnel-source-limit",
|
|
4860
4949
|
className: "pbb-numberInput",
|
|
4861
4950
|
type: "number",
|
|
@@ -4881,56 +4970,83 @@ window.__ModuleLoader__.load({
|
|
|
4881
4970
|
className: "pbb-action",
|
|
4882
4971
|
disabled: !remoteConnectionLimitReady || !remoteLimitView.valid || remoteLimitView.unchanged,
|
|
4883
4972
|
onClick: applyRemoteLimit
|
|
4884
|
-
}, translateWith(props.t, "remote.limitApply")))), (0, react.createElement)("
|
|
4973
|
+
}, translateWith(props.t, "remote.limitApply")))), (0, react.createElement)("details", { className: "pbb-helpDisclosure" }, (0, react.createElement)("summary", null, (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon()), translateWith(props.t, "help.remoteTitle")), (0, react.createElement)("div", { className: "pbb-helpBody" }, (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-helpHeading" }, translateWith(props.t, "help.recommended")), (0, react.createElement)("ol", { className: "pbb-helpList" }, (0, react.createElement)("li", null, translateWith(props.t, "help.step1")), (0, react.createElement)("li", null, translateWith(props.t, "help.step2")), (0, react.createElement)("li", null, translateWith(props.t, "help.step3")), (0, react.createElement)("li", null, translateWith(props.t, "help.step4"))), (0, react.createElement)("p", { className: "pbb-helpText" }, translateWith(props.t, "help.funnelHint"))), (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-helpHeading" }, translateWith(props.t, "help.httpsTitle")), (0, react.createElement)("ol", { className: "pbb-helpList" }, (0, react.createElement)("li", null, translateWith(props.t, "help.httpsStep1")), (0, react.createElement)("li", null, translateWith(props.t, "help.httpsStep2")), (0, react.createElement)("li", null, translateWith(props.t, "help.httpsStep3"))), (0, react.createElement)("p", { className: "pbb-helpText" }, translateWith(props.t, "help.httpsHint"))), (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-helpHeading" }, translateWith(props.t, "help.allowTitle")), (0, react.createElement)("p", { className: "pbb-helpText" }, translateWith(props.t, "help.allowBody")), (0, react.createElement)("code", { className: "pbb-helpCode" }, "\"nodeAttrs\": [\n {\n \"target\": [\"autogroup:member\"],\n \"attr\": [\"funnel\"],\n },\n],"), (0, react.createElement)("p", { className: "pbb-helpText" }, translateWith(props.t, "help.allowHint"))), (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-helpHeading" }, translateWith(props.t, "help.faqTitle")), (0, react.createElement)("ul", { className: "pbb-helpList" }, (0, react.createElement)("li", null, translateWith(props.t, "help.faq1")), (0, react.createElement)("li", null, translateWith(props.t, "help.faq2")), (0, react.createElement)("li", null, translateWith(props.t, "help.faq3")), (0, react.createElement)("li", null, translateWith(props.t, "help.faq4")))), (0, react.createElement)("div", { className: "pbb-helpSection" }, (0, react.createElement)("div", { className: "pbb-helpHeading" }, translateWith(props.t, "help.securityTitle")), (0, react.createElement)("ul", { className: "pbb-helpList" }, (0, react.createElement)("li", null, translateWith(props.t, "help.security1")), (0, react.createElement)("li", null, translateWith(props.t, "help.security2")), (0, react.createElement)("li", null, translateWith(props.t, "help.security3")), (0, react.createElement)("li", null, translateWith(props.t, "help.security4")), (0, react.createElement)("li", null, translateWith(props.t, "help.security5"))), (0, react.createElement)("p", { className: "pbb-helpText" }, translateWith(props.t, "help.docsPrefix"), (0, react.createElement)("a", {
|
|
4885
4974
|
className: "pbb-helpLink",
|
|
4886
4975
|
href: "https://tailscale.com/docs/features/tailscale-funnel",
|
|
4887
4976
|
target: "_blank",
|
|
4888
4977
|
rel: "noreferrer"
|
|
4889
|
-
}, translateWith(props.t, "help.funnelDocs"))))))))))
|
|
4890
|
-
className: "pbb-
|
|
4978
|
+
}, translateWith(props.t, "help.funnelDocs"))))))))))), (0, react.createElement)("section", {
|
|
4979
|
+
className: "pbb-devicesSection",
|
|
4980
|
+
"aria-label": translateWith(props.t, "devices.title")
|
|
4981
|
+
}, (0, react.createElement)("div", { className: "pbb-devicesHeader" }, (0, react.createElement)("h3", { className: "pbb-cardTitle" }, translateWith(props.t, "devices.title")), (0, react.createElement)("span", { className: "pbb-deviceCount" }, translateWith(props.t, "devices.count", { count: visibleDevices$1.length })), (0, react.createElement)("div", { className: "pbb-addAction" }, (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
4982
|
+
variant: "outline",
|
|
4983
|
+
size: "sm",
|
|
4984
|
+
icon: settingsIcon("plus", 16),
|
|
4985
|
+
disabled: panel.busy || report === null || !report.pairingReady || !can("beginPairing"),
|
|
4986
|
+
"aria-expanded": pairingOpen,
|
|
4987
|
+
"aria-controls": pairingId,
|
|
4988
|
+
onClick: () => {
|
|
4989
|
+
if (pairingOpen) {
|
|
4990
|
+
hidePairingQR();
|
|
4991
|
+
setPairingOpen(false);
|
|
4992
|
+
return;
|
|
4993
|
+
}
|
|
4994
|
+
setPairingOpen(true);
|
|
4995
|
+
if (pairingTarget !== null && report?.pairingReady) showPairingQR(pairingTarget);
|
|
4996
|
+
}
|
|
4997
|
+
}, translateWith(props.t, pairingOpen ? "pair.close" : "pair.add")))), pairingSection, (0, react.createElement)("div", { className: "pbb-card pbb-devicesCard" }, deviceMessage ? (0, react.createElement)("p", {
|
|
4998
|
+
className: "pbb-diag pbb-deviceMessage" + (deviceMessage.startsWith(translateWith(props.t, "devices.renameFailed")) || deviceMessage.startsWith(translateWith(props.t, "devices.revokeFailed")) ? " pbb-diagBad" : ""),
|
|
4891
4999
|
role: "status"
|
|
4892
|
-
}, deviceMessage) : null, deviceRows)), (0, react.createElement)("
|
|
5000
|
+
}, deviceMessage) : null, deviceRows)), (0, react.createElement)("section", {
|
|
5001
|
+
className: "pbb-card pbb-tools",
|
|
5002
|
+
"aria-label": translateWith(props.t, "tools.title")
|
|
5003
|
+
}, (0, react.createElement)("div", { className: "pbb-toolSection" }, (0, react.createElement)("button", {
|
|
4893
5004
|
type: "button",
|
|
4894
5005
|
className: "pbb-cardHead",
|
|
4895
5006
|
"aria-expanded": troubleshootingOpen,
|
|
5007
|
+
"aria-controls": troubleshootingId,
|
|
4896
5008
|
onClick: () => setTroubleshootingOpen(!troubleshootingOpen)
|
|
4897
|
-
}, (
|
|
5009
|
+
}, settingsIcon("activity", 17), (0, react.createElement)("span", { className: "pbb-cardTitle" }, translateWith(props.t, "troubleshooting.summary")), (0, react.createElement)("span", { className: "pbb-toolMeta" + (troubleGood ? " pbb-ok" : troubleBad && relayTestResult !== null ? " pbb-bad" : "") }, troubleConclusion), (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon())), fold(troubleshootingOpen, (0, react.createElement)("div", {
|
|
5010
|
+
className: "pbb-cardBody",
|
|
5011
|
+
id: troubleshootingId
|
|
5012
|
+
}, (0, react.createElement)("div", { className: "pbb-testGrid" }, (0, react.createElement)("div", { className: "pbb-testItem" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-testTitle" }, translateWith(props.t, "push.relayTitle")), (0, react.createElement)("span", { className: "pbb-testDescription" }, translateWith(props.t, "push.relayDefault"))), (0, react.createElement)("button", {
|
|
4898
5013
|
type: "button",
|
|
4899
5014
|
className: "pbb-action",
|
|
4900
5015
|
disabled: relayTestBusy,
|
|
4901
5016
|
onClick: runRelayTest
|
|
4902
|
-
}, relayTestBusy ? translateWith(props.t, "push.relayTesting") : translateWith(props.t, "push.testRelay"))), (0, react.createElement)("div", { className: "pbb-testItem" }, (0, react.createElement)("div", { className: "pbb-
|
|
5017
|
+
}, relayTestBusy ? translateWith(props.t, "push.relayTesting") : translateWith(props.t, "push.testRelay"))), (0, react.createElement)("div", { className: "pbb-testItem" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-testTitle" }, translateWith(props.t, "push.testPush")), (0, react.createElement)("span", { className: "pbb-testDescription" }, translateWith(props.t, "push.pushDefault"))), (0, react.createElement)("button", {
|
|
4903
5018
|
type: "button",
|
|
4904
5019
|
className: "pbb-action",
|
|
4905
5020
|
disabled: pushTestBusy,
|
|
4906
5021
|
onClick: sendPushTest
|
|
4907
|
-
}, pushTestBusy ? translateWith(props.t, "push.pushSending") : translateWith(props.t, "push.testPush"))), (0, react.createElement)("div", { className: "pbb-testItem" }, (0, react.createElement)("div", { className: "pbb-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
"aria-checked": debugEnabled,
|
|
4911
|
-
"aria-label": translateWith(props.t, "troubleshooting.debugTitle"),
|
|
5022
|
+
}, pushTestBusy ? translateWith(props.t, "push.pushSending") : translateWith(props.t, "push.testPush"))), (0, react.createElement)("div", { className: "pbb-testItem" }, (0, react.createElement)("div", { className: "pbb-controlText" }, (0, react.createElement)("span", { className: "pbb-testTitle" }, translateWith(props.t, "troubleshooting.debugTitle")), (0, react.createElement)("span", { className: "pbb-testDescription" }, translateWith(props.t, "troubleshooting.debugDescription"))), (0, react.createElement)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
5023
|
+
checked: debugEnabled,
|
|
5024
|
+
label: translateWith(props.t, "troubleshooting.debugTitle"),
|
|
4912
5025
|
disabled: !debugSwitchReady,
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
if (can("setDebug")) props.setDeepPilotDebug(!debugEnabled);
|
|
5026
|
+
onChange: (next) => {
|
|
5027
|
+
if (can("setDebug")) props.setDeepPilotDebug(next);
|
|
4916
5028
|
}
|
|
4917
5029
|
}))), relayTestError ? (0, react.createElement)("p", {
|
|
4918
5030
|
className: "pbb-diag pbb-diagBad",
|
|
4919
5031
|
role: "alert"
|
|
4920
|
-
}, relayTestError) : null, relayTestResult === null ? null : (0, react.createElement)("div", { className: "pbb-helpBody" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("span", { className: "pbb-label" }, relayTestResult.url || translateWith(props.t, "push.relayUrlEmpty")), (0, react.createElement)("code", { className: "pbb-token " + (relayTestResult.overall === "ok" ? "pbb-ok" : "pbb-bad") }, relayTestResult.overall === "ok" ? translateWith(props.t, "push.relayOk") : translateWith(props.t, "push.relayBad"))), relayTestResult.steps.map((step, index) => resultRow(step.ok, (step.id === "health" ? translateWith(props.t, "push.relayStep.health") : translateWith(props.t, "push.relayStep.enroll")) + (step.latencyMs !== void 0 ? ` (${String(step.latencyMs)}ms)` : "") + "
|
|
5032
|
+
}, relayTestError) : null, relayTestResult === null ? null : (0, react.createElement)("div", { className: "pbb-helpBody" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("span", { className: "pbb-label" }, relayTestResult.url || translateWith(props.t, "push.relayUrlEmpty")), (0, react.createElement)("code", { className: "pbb-token " + (relayTestResult.overall === "ok" ? "pbb-ok" : "pbb-bad") }, relayTestResult.overall === "ok" ? translateWith(props.t, "push.relayOk") : translateWith(props.t, "push.relayBad"))), relayTestResult.steps.map((step, index) => resultRow(step.ok, (step.id === "health" ? translateWith(props.t, "push.relayStep.health") : translateWith(props.t, "push.relayStep.enroll")) + (step.latencyMs !== void 0 ? ` (${String(step.latencyMs)}ms)` : "") + "(" + step.message + ")", String(index)))), pushTestError ? (0, react.createElement)("p", {
|
|
4921
5033
|
className: "pbb-diag pbb-diagBad",
|
|
4922
5034
|
role: "alert"
|
|
4923
|
-
}, pushTestError) : null, pushTestResult === null ? null : (0, react.createElement)("div", { className: "pbb-helpBody" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("code", { className: "pbb-token " + (pushTestResult.overall === "sent" ? "pbb-ok" : pushTestResult.overall === "failed" ? "pbb-bad" : "") }, pushTestResult.overall === "sent" ? translateWith(props.t, "push.pushSent") : pushTestResult.overall === "failed" ? translateWith(props.t, "push.pushFailed") : pushTestResult.overall === "no-targets" ? translateWith(props.t, "push.pushNoTargets") : translateWith(props.t, "push.pushNotEnabled"))), pushTestResult.message ? (0, react.createElement)("p", { className: "pbb-diag" }, pushTestResult.message) : null, pushTestResult.results.map((r, index) => resultRow(r.outcome === "sent", r.name + "
|
|
5035
|
+
}, pushTestError) : null, pushTestResult === null ? null : (0, react.createElement)("div", { className: "pbb-helpBody" }, (0, react.createElement)("div", { className: "pbb-row" }, (0, react.createElement)("code", { className: "pbb-token " + (pushTestResult.overall === "sent" ? "pbb-ok" : pushTestResult.overall === "failed" ? "pbb-bad" : "") }, pushTestResult.overall === "sent" ? translateWith(props.t, "push.pushSent") : pushTestResult.overall === "failed" ? translateWith(props.t, "push.pushFailed") : pushTestResult.overall === "no-targets" ? translateWith(props.t, "push.pushNoTargets") : translateWith(props.t, "push.pushNotEnabled"))), pushTestResult.message ? (0, react.createElement)("p", { className: "pbb-diag" }, translateWith(props.t, "push.resultDetail", { message: pushTestResult.message })) : null, pushTestResult.results.map((r, index) => resultRow(r.outcome === "sent", r.name + "(" + translateWith(props.t, r.environment === "production" ? "push.environment.production" : r.environment === "development" ? "push.environment.development" : "push.environment.other", { environment: r.environment }) + ") · " + translateWith(props.t, r.outcome === "sent" ? "push.outcome.sent" : r.outcome === "invalid-token" ? "push.outcome.invalid" : r.outcome === "failed" ? "push.outcome.failed" : "push.outcome.other", { outcome: r.outcome }) + (r.reason ? "(" + r.reason + ")" : "") + (r.tokenFingerprint ? " token:" + r.tokenFingerprint + "…" : ""), String(index)))), diagnosticsSection))), report === null ? null : (0, react.createElement)("div", { className: "pbb-toolSection" }, (0, react.createElement)("button", {
|
|
4924
5036
|
type: "button",
|
|
4925
5037
|
className: "pbb-cardHead",
|
|
4926
5038
|
"aria-expanded": systemOpen,
|
|
5039
|
+
"aria-controls": systemId,
|
|
4927
5040
|
onClick: () => setSystemOpen(!systemOpen)
|
|
4928
|
-
}, (
|
|
5041
|
+
}, settingsIcon("info", 17), (0, react.createElement)("span", { className: "pbb-cardTitle" }, translateWith(props.t, "system.summary")), (0, react.createElement)("span", { className: "pbb-toolMeta" + (report.updateAvailable === true ? " pbb-ok" : "") }, "v" + report.pluginVersion + (report.updateAvailable === true ? " · " + translateWith(props.t, "update.badge") : "")), (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon())), fold(systemOpen, (0, react.createElement)("div", {
|
|
5042
|
+
className: "pbb-cardBody",
|
|
5043
|
+
id: systemId
|
|
5044
|
+
}, (0, react.createElement)("div", { className: "pbb-sectionIntro" }, (0, react.createElement)("h3", { className: "pbb-cardTitle" }, translateWith(props.t, "system.title"))), (0, react.createElement)("div", { className: "pbb-runtimeList" }, (0, react.createElement)("div", { className: "pbb-runtimeRow" }, (0, react.createElement)("span", { className: "pbb-label" }, "DeepPilot"), (0, react.createElement)("span", { className: "pbb-value" }, "v" + report.pluginVersion)), (0, react.createElement)("div", { className: "pbb-runtimeRow" }, (0, react.createElement)("span", { className: "pbb-label" }, translateWith(props.t, "advanced.tailscaleVersion")), (0, react.createElement)("span", { className: "pbb-value" }, report.remote.tailscaleVersion ?? translateWith(props.t, "advanced.tailscaleVersionUnknown"))), (0, react.createElement)("div", { className: "pbb-runtimeRow" }, (0, react.createElement)("span", { className: "pbb-label" }, translateWith(props.t, "panel.identity")), (0, react.createElement)("span", { className: "pbb-value" }, translateWith(props.t, report.pairingReady ? "panel.identityReady" : "panel.identityNotReady"))), advancedRows, report.updateAvailable === true ? (0, react.createElement)("a", {
|
|
4929
5045
|
className: "pbb-updateRow",
|
|
4930
5046
|
href: typeof report.releaseUrl === "string" && /^https:\/\//.test(report.releaseUrl) ? report.releaseUrl : "https://github.com/Mars-Sea/dsh-deeppilot/releases",
|
|
4931
5047
|
target: "_blank",
|
|
4932
5048
|
rel: "noreferrer"
|
|
4933
|
-
}, (0, react.createElement)("span", null, translateWith(props.t, "update.badge")), (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon())) : null)))), diag.length > 0 ? (0, react.createElement)("details", {
|
|
5049
|
+
}, (0, react.createElement)("span", null, translateWith(props.t, "update.badge")), (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon())) : null))))), diag.length > 0 ? (0, react.createElement)("details", {
|
|
4934
5050
|
className: "pbb-card pbb-disclosure pbb-diagnostics",
|
|
4935
5051
|
open: failed
|
|
4936
5052
|
}, (0, react.createElement)("summary", null, (0, react.createElement)("span", { className: "pbb-chev" }, ChevronIcon()), (0, react.createElement)("span", { className: "pbb-disclosureTitle" }, translateWith(props.t, "diag.summary"))), (0, react.createElement)("div", { className: "pbb-disclosureBody" }, (0, react.createElement)("p", { className: "pbb-diag" + (failed ? " pbb-diagBad" : "") }, translateWith(props.t, "diag.prefix") + diag.join(" | ")))) : null);
|