dshmarket 1.24.0 → 1.26.0
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/client/client.js +755 -39
- package/client/client.js.map +1 -1
- package/lib/index.js +2 -0
- package/lib/presets.js +273 -0
- package/lib/routes.js +294 -24
- package/lib/snapshot.js +275 -0
- package/lib/sources.js +120 -0
- package/lib/types/index.d.ts +1 -1
- package/lib/types/presets.d.ts +90 -0
- package/lib/types/routes.d.ts +2 -0
- package/lib/types/snapshot.d.ts +74 -0
- package/lib/types/sources.d.ts +36 -0
- package/package.json +1 -1
- package/src/client/Diagnostics.tsx +35 -18
- package/src/client/Market.module.css +11 -1
- package/src/client/MarketSection.tsx +47 -15
- package/src/client/locales.ts +103 -3
- package/src/client/preset-panel.tsx +262 -0
- package/src/client/snapshot-panel.tsx +243 -0
- package/src/index.ts +3 -1
- package/src/presets.ts +339 -0
- package/src/routes.ts +292 -24
- package/src/snapshot.ts +278 -0
- package/src/sources.ts +123 -0
package/client/client.js
CHANGED
|
@@ -126,7 +126,12 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
126
126
|
updateNow: "立即更新",
|
|
127
127
|
updateFail: "更新失败",
|
|
128
128
|
upToDate: "已是最新",
|
|
129
|
-
linkedDev: "
|
|
129
|
+
linkedDev: "本地开发",
|
|
130
|
+
restore: "恢复",
|
|
131
|
+
restoreHint: "会卸载本地版本,重新安装线上版本,并保持更新检测。无法回退,请二次确认。",
|
|
132
|
+
restoreContinue: "继续更新",
|
|
133
|
+
restoreNoCatalog: "精选目录里没有这个插件,无法恢复到线上版本。可以卸载本地版,或继续用本地开发。",
|
|
134
|
+
restoreFail: "恢复失败",
|
|
130
135
|
exportLog: "导出日志",
|
|
131
136
|
exportingLog: "导出中…",
|
|
132
137
|
exportedLog: "日志已导出:dsh-market-log.txt,请将其附在 issue 中",
|
|
@@ -425,6 +430,50 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
425
430
|
/** Summary-strip tooltip for the order count (before/after rule conflicts). */
|
|
426
431
|
checkOrderTip: "社区 bundle 加载顺序与插件声明的 before/after 规则冲突",
|
|
427
432
|
diagOkAll: "一切正常:未发现冲突、依赖或顺序问题",
|
|
433
|
+
presetSection: "插件组合",
|
|
434
|
+
presetHint: "把当前的 bundle 顺序与停用列表保存为组合,随时切换;应用前会做试启动校验并自动创建快照。",
|
|
435
|
+
presetName: "组合名称",
|
|
436
|
+
presetSave: "保存当前状态",
|
|
437
|
+
presetSaving: "保存中…",
|
|
438
|
+
presetSaved: "组合已保存",
|
|
439
|
+
presetApply: "应用",
|
|
440
|
+
presetApplied: "已应用,重启后生效",
|
|
441
|
+
presetDelete: "删除",
|
|
442
|
+
presetDeleted: "组合已删除",
|
|
443
|
+
presetEmpty: "还没有保存过组合",
|
|
444
|
+
presetNameEmpty: "请输入组合名称",
|
|
445
|
+
presetFail: "组合操作失败:",
|
|
446
|
+
presetListFail: "组合列表加载失败:",
|
|
447
|
+
presetBundleCount: "{0} 个 bundle",
|
|
448
|
+
presetPreview: "预览",
|
|
449
|
+
presetPreviewTitle: "应用此组合将:",
|
|
450
|
+
presetReorder: "重排 {0} 个 bundle 的位置",
|
|
451
|
+
presetEnable: "启用 {0} 个插件",
|
|
452
|
+
presetDisable: "停用 {0} 个插件",
|
|
453
|
+
presetNoop: "无变更",
|
|
454
|
+
presetPreviewFail: "预览失败:",
|
|
455
|
+
snapSection: "快照与回滚",
|
|
456
|
+
snapHint: "应用变更前会自动创建快照;也可以手动创建快照,随时回滚到任意状态。",
|
|
457
|
+
snapCreate: "创建快照",
|
|
458
|
+
snapCreating: "创建中…",
|
|
459
|
+
snapCreated: "快照已创建",
|
|
460
|
+
snapEmpty: "还没有快照",
|
|
461
|
+
snapListFail: "快照列表加载失败:",
|
|
462
|
+
snapCreateFail: "创建快照失败:",
|
|
463
|
+
snapRestore: "回滚",
|
|
464
|
+
snapRestoring: "回滚中…",
|
|
465
|
+
snapRestored: "已回滚,重启后生效",
|
|
466
|
+
snapRestoreFail: "回滚失败:",
|
|
467
|
+
snapRestoreConfirm: "确认回滚",
|
|
468
|
+
snapRestoreConfirmText: "回滚会用快照覆盖当前 profile 的 package.json 与配置,且不可撤销(可先创建新快照再回滚)。",
|
|
469
|
+
snapFiles: "包含文件",
|
|
470
|
+
snapDelete: "删除",
|
|
471
|
+
snapDeleting: "删除中…",
|
|
472
|
+
snapDeleted: "快照已删除",
|
|
473
|
+
snapDeleteFail: "删除快照失败:",
|
|
474
|
+
snapDeleteConfirm: "确认删除",
|
|
475
|
+
snapDeleteConfirmText: "删除后该快照将无法恢复。",
|
|
476
|
+
marketNoToggle: "市场自身不能停用",
|
|
428
477
|
hostDependencyWarning: "插件在 dependencies 中声明了已知的 DSH 共享宿主包,可能遮蔽宿主版本(仅依据清单,未确认运行时重复):",
|
|
429
478
|
hostDependencyMore: "另有 {0} 条,已省略"
|
|
430
479
|
};
|
|
@@ -521,7 +570,12 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
521
570
|
updateNow: "Update now",
|
|
522
571
|
updateFail: "Update failed",
|
|
523
572
|
upToDate: "Up to date",
|
|
524
|
-
linkedDev: "
|
|
573
|
+
linkedDev: "local",
|
|
574
|
+
restore: "Restore",
|
|
575
|
+
restoreHint: "This will uninstall the local version, reinstall the catalog version, and keep update checks. This cannot be undone — please confirm again.",
|
|
576
|
+
restoreContinue: "Continue update",
|
|
577
|
+
restoreNoCatalog: "This plugin is not in the curated catalog, so it cannot be restored. Uninstall the local copy, or keep developing it locally.",
|
|
578
|
+
restoreFail: "Restore failed",
|
|
525
579
|
exportLog: "Export log",
|
|
526
580
|
exportingLog: "Exporting…",
|
|
527
581
|
exportedLog: "Log exported: dsh-market-log.txt — please attach it to your issue",
|
|
@@ -820,6 +874,50 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
820
874
|
/** Summary-strip tooltip for the order count (before/after rule conflicts). */
|
|
821
875
|
checkOrderTip: "community bundle load order conflicts with declared before/after rules",
|
|
822
876
|
diagOkAll: "All good: no conflict, dependency or ordering issues found",
|
|
877
|
+
presetSection: "Plugin presets",
|
|
878
|
+
presetHint: "Save the current bundle order and disabled list as a preset and switch anytime; applying runs a trial-start check and creates a snapshot first.",
|
|
879
|
+
presetName: "Preset name",
|
|
880
|
+
presetSave: "Save current state",
|
|
881
|
+
presetSaving: "Saving…",
|
|
882
|
+
presetSaved: "Preset saved",
|
|
883
|
+
presetApply: "Apply",
|
|
884
|
+
presetApplied: "Applied — restart to apply",
|
|
885
|
+
presetDelete: "Delete",
|
|
886
|
+
presetDeleted: "Preset deleted",
|
|
887
|
+
presetEmpty: "No presets saved yet",
|
|
888
|
+
presetNameEmpty: "Enter a preset name",
|
|
889
|
+
presetFail: "Preset operation failed: ",
|
|
890
|
+
presetListFail: "Failed to load presets: ",
|
|
891
|
+
presetBundleCount: "{0} bundles",
|
|
892
|
+
presetPreview: "Preview",
|
|
893
|
+
presetPreviewTitle: "Applying this preset will:",
|
|
894
|
+
presetReorder: "reorder {0} bundles",
|
|
895
|
+
presetEnable: "enable {0} plugins",
|
|
896
|
+
presetDisable: "disable {0} plugins",
|
|
897
|
+
presetNoop: "no changes",
|
|
898
|
+
presetPreviewFail: "Preview failed: ",
|
|
899
|
+
snapSection: "Snapshots & Rollback",
|
|
900
|
+
snapHint: "Snapshots are taken automatically before applying changes; you can also create one manually and roll back anytime.",
|
|
901
|
+
snapCreate: "Create snapshot",
|
|
902
|
+
snapCreating: "Creating…",
|
|
903
|
+
snapCreated: "Snapshot created",
|
|
904
|
+
snapEmpty: "No snapshots yet",
|
|
905
|
+
snapListFail: "Failed to load snapshots: ",
|
|
906
|
+
snapCreateFail: "Failed to create snapshot: ",
|
|
907
|
+
snapRestore: "Restore",
|
|
908
|
+
snapRestoring: "Restoring…",
|
|
909
|
+
snapRestored: "Restored — restart to apply",
|
|
910
|
+
snapRestoreFail: "Failed to restore: ",
|
|
911
|
+
snapRestoreConfirm: "Confirm restore",
|
|
912
|
+
snapRestoreConfirmText: "Restoring overwrites the current profile package.json and configuration from the snapshot; this cannot be undone (create a fresh snapshot first if unsure).",
|
|
913
|
+
snapFiles: "files",
|
|
914
|
+
snapDelete: "Delete",
|
|
915
|
+
snapDeleting: "Deleting…",
|
|
916
|
+
snapDeleted: "Snapshot deleted",
|
|
917
|
+
snapDeleteFail: "Failed to delete snapshot: ",
|
|
918
|
+
snapDeleteConfirm: "Confirm delete",
|
|
919
|
+
snapDeleteConfirmText: "This snapshot cannot be recovered after deletion.",
|
|
920
|
+
marketNoToggle: "The market itself cannot be disabled",
|
|
823
921
|
hostDependencyWarning: "A plugin lists known shared DSH host packages in dependencies. This may shadow the host version; the check is manifest-only and does not confirm a duplicate runtime instance:",
|
|
824
922
|
hostDependencyMore: "{0} more finding(s) omitted"
|
|
825
923
|
};
|
|
@@ -1484,7 +1582,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
1484
1582
|
}
|
|
1485
1583
|
//#endregion
|
|
1486
1584
|
//#region \0dsh-css:src/client/Market.module.css.mjs
|
|
1487
|
-
const css = ".eGUBIq_root{min-width:0;height:100%;color:var(--dsw-alias-label-primary,#1f2328);flex-direction:column;display:flex;position:relative;container-type:inline-size}.eGUBIq_head{flex-direction:column;gap:12px;padding:4px 4px 6px;display:flex}.eGUBIq_title{margin:0;font-size:16px;font-weight:500;line-height:24px}.eGUBIq_sub{color:var(--dsw-alias-label-tertiary,#8b93a1);align-items:center;gap:8px;margin:0;font-size:12px;line-height:18px;display:flex}.eGUBIq_submitLink{color:var(--dsw-alias-label-tertiary,#8b93a1);white-space:nowrap;font-size:11px;line-height:18px;text-decoration:none}.eGUBIq_submitLink:hover{color:var(--dsw-alias-brand-primary,#4f6ef7);text-decoration:underline}.eGUBIq_tabs{border-bottom:1px solid var(--dsw-alias-border-l2,#e5e7eb);align-items:flex-end;gap:2px;display:flex}.eGUBIq_tab{font:inherit;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-bottom:2px solid #0000;padding:7px 12px;font-size:13px}.eGUBIq_tab.eGUBIq_on{color:var(--dsw-alias-brand-primary,#4f6ef7);border-bottom-color:var(--dsw-alias-brand-primary,#4f6ef7);font-weight:600}.eGUBIq_subTabs{align-items:flex-end;gap:2px;margin:-4px 0 4px;display:flex}.eGUBIq_banner{background:var(--dsw-alias-bg-layer-2,#fdf3e3);border:1px solid var(--dsw-alias-border-l2,#f3e3c3);border-radius:8px;align-items:center;gap:8px;margin:0;padding:8px 12px;font-size:12px;display:flex}.eGUBIq_bannerIcon{color:var(--dsw-alias-label-secondary,#6b7280);flex-shrink:0}.eGUBIq_bannerHint{color:var(--dsw-alias-label-tertiary,#8b93a1);cursor:help;display:inline-flex}.eGUBIq_body{flex:1;padding:12px 4px 24px;overflow-x:hidden;overflow-y:auto}.eGUBIq_stickyHead{z-index:5;background:var(--dsw-alias-bg-layer-2,#f7f8fa);position:sticky;top:-1px}.eGUBIq_stickyHead:before{content:\"\";background:inherit;pointer-events:none;height:14px;position:absolute;bottom:100%;left:0;right:0}.eGUBIq_cats{margin:0 -4px 2px;padding:12px 4px 4px}.eGUBIq_catsRow{align-items:flex-start;gap:8px;display:flex;position:relative}.eGUBIq_star{color:var(--dsw-alias-label-secondary,#9ca3af);white-space:nowrap;flex:none;font-size:11px}.eGUBIq_top{z-index:20;display:inline-flex;position:absolute;bottom:18px;right:18px}.eGUBIq_topBtn{border-radius:99px;width:38px;height:38px;padding:0}.eGUBIq_tag{border:1px solid var(--dsw-alias-border-l3,#d9dde3);color:var(--dsw-alias-label-secondary,#6b7280);border-radius:4px;flex-shrink:0;padding:1px 6px;font-size:11px;line-height:16px}.eGUBIq_okState{color:var(--dsw-alias-state-success-primary,#16a34a);white-space:nowrap;font-size:12px;font-weight:600}.eGUBIq_catsWrap{flex-wrap:wrap;flex:1;align-items:center;gap:6px;min-width:0;display:flex}.eGUBIq_catsCollapsed{max-height:62px;overflow:hidden}.eGUBIq_catsToggle.eGUBIq_catsToggle{height:26px;min-height:26px;color:var(--dsw-alias-label-secondary,#6b7280);padding:0 6px}.eGUBIq_shots{-webkit-overflow-scrolling:touch;scrollbar-width:thin;gap:8px;margin:6px 0 8px;padding:2px 0 6px;display:flex;overflow-x:auto}.eGUBIq_shot{object-fit:cover;border:1px solid var(--dsw-alias-border-default,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f3f4f6);cursor:pointer;border-radius:8px;flex:none;width:220px;height:150px}.eGUBIq_cardShots{-webkit-overflow-scrolling:touch;scrollbar-width:thin;gap:6px;margin:0 0 6px;padding:0 0 2px;display:flex;overflow-x:auto}.eGUBIq_cardShot{object-fit:contain;border:1px solid var(--dsw-alias-border-default,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f3f4f6);cursor:pointer;border-radius:8px;flex:none;width:132px;height:88px;display:block}.eGUBIq_lightbox{z-index:10000;cursor:zoom-out;background:#000000d9;justify-content:center;align-items:center;display:flex;position:fixed;top:0;bottom:0;left:0;right:0}.eGUBIq_lightboxImg{object-fit:contain;cursor:default;border-radius:4px;max-width:90vw;max-height:85vh}.eGUBIq_lightboxClose{color:#fff;cursor:pointer;background:#ffffff1f;border:none;border-radius:99px;place-items:center;width:36px;height:36px;font-size:22px;line-height:1;display:grid;position:absolute;top:16px;right:16px}.eGUBIq_lightboxClose:hover{background:#ffffff38}.eGUBIq_lightboxNav{color:#fff;cursor:pointer;background:#ffffff1f;border:none;border-radius:99px;place-items:center;width:44px;height:44px;display:grid;position:absolute;top:50%;transform:translateY(-50%)}.eGUBIq_lightboxNav:hover{background:#ffffff38}.eGUBIq_lightboxPrev{left:16px}.eGUBIq_lightboxNext{right:16px}.eGUBIq_lightboxDots{gap:8px;display:flex;position:absolute;bottom:20px;left:50%;transform:translate(-50%)}.eGUBIq_lightboxDot{cursor:pointer;background:#fff6;border-radius:99px;width:7px;height:7px}.eGUBIq_lightboxDotOn{background:#fff}.eGUBIq_cmd{background:var(--dsw-alias-bg-layer-2,#f3f4f6);word-break:break-all;border-radius:6px;margin:8px 0 0;padding:8px 10px;font-family:ui-monospace,Menlo,monospace;font-size:11px;line-height:18px}.eGUBIq_warnLine{color:var(--dsw-alias-state-warn-primary,#b45309);flex-wrap:wrap;align-items:center;gap:4px;margin:0;font-size:12px;font-weight:600;line-height:18px;display:flex}.eGUBIq_modalNote{color:var(--dsw-alias-label-tertiary,#8b93a1);align-items:center;gap:4px;margin:12px 0 0;font-size:12px;line-height:18px;display:flex}.eGUBIq_grid{grid-template-columns:repeat(2,minmax(0,1fr));align-items:start;gap:10px;display:grid}.eGUBIq_masonry{align-items:flex-start;gap:10px;display:flex}.eGUBIq_masonryCol{flex-direction:column;flex:1;gap:10px;min-width:0;display:flex}.eGUBIq_masonry>.eGUBIq_masonryCol>*{align-self:stretch;min-width:0}@media (max-width:680px){.eGUBIq_masonry{flex-direction:column}.eGUBIq_masonryCol{width:100%}.eGUBIq_grid{grid-template-columns:minmax(0,1fr)}}.eGUBIq_swatches{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:8px;gap:0;height:34px;display:flex;overflow:hidden}.eGUBIq_themesGrid{margin-bottom:12px}.eGUBIq_swatches i{flex:1}.eGUBIq_themeToolbar{grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:8px;padding:0 4px 12px;display:grid}.eGUBIq_themeSearch{box-sizing:border-box;width:100%;min-width:0}.eGUBIq_themeToolbarActions{justify-content:flex-end;align-items:center;gap:8px;display:flex}.eGUBIq_themeFullscreenBtn.eGUBIq_themeFullscreenBtn{width:28px;min-width:28px;padding:0}.eGUBIq_themeResultBar{min-height:24px;color:var(--dsw-alias-label-tertiary,#8b93a1);align-items:center;padding:0 4px 8px;font-size:12px;line-height:18px;display:flex}.eGUBIq_themeGallery{grid-template-columns:repeat(4,minmax(0,1fr));align-items:stretch;gap:10px;display:grid}.eGUBIq_themeCard{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);border-radius:8px;flex-direction:column;min-width:0;transition:border-color .16s cubic-bezier(.16,1,.3,1),box-shadow .16s cubic-bezier(.16,1,.3,1),transform .16s cubic-bezier(.16,1,.3,1);display:flex;overflow:hidden}.eGUBIq_themeCard:hover{border-color:var(--dsw-alias-border-l3,#d9dde3);box-shadow:var(--dsw-shadow-lv1,0 4px 12px #1f232814);transform:translateY(-1px)}.eGUBIq_themeCover{aspect-ratio:16/10;border:0;border-bottom:1px solid var(--dsw-alias-border-l2,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f3f4f6);width:100%;color:var(--dsw-alias-label-secondary,#6b7280);cursor:zoom-in;border-radius:0;padding:0;display:block;position:relative;overflow:hidden}.eGUBIq_themeCover img{object-fit:contain;background:var(--dsw-alias-bg-layer-2,#f3f4f6);width:100%;height:100%;transition:transform .18s cubic-bezier(.16,1,.3,1);display:block}.eGUBIq_themeCover:hover img{transform:scale(1.012)}.eGUBIq_themeCover:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,#4f6ef7);outline-offset:-3px}.eGUBIq_themeCoverEmpty{cursor:default;color:var(--dsw-alias-label-tertiary,#8b93a1);flex-direction:column;justify-content:center;align-items:center;gap:8px;font-size:12px;line-height:18px;display:flex}.eGUBIq_themePreviewAction,.eGUBIq_themePreviewCount{color:#fff;-webkit-backdrop-filter:blur(8px);background:#14181fc7;border:1px solid #ffffff57;border-radius:4px;align-items:center;height:24px;padding:0 8px;font-size:11px;line-height:16px;display:inline-flex;position:absolute;bottom:8px}.eGUBIq_themePreviewAction{gap:4px;right:8px}.eGUBIq_themePreviewCount{left:8px}.eGUBIq_themeCardBody{flex-direction:column;flex:1;gap:8px;padding:12px;display:flex}.eGUBIq_themeCardHead{align-items:flex-start;gap:8px;min-width:0;display:flex}.eGUBIq_themeIdentity{flex:1;min-width:0}.eGUBIq_themeStatus,.eGUBIq_themeStatusMuted{white-space:nowrap;border-radius:4px;flex:none;align-items:center;min-height:22px;padding:0 8px;font-size:11px;font-weight:600;display:inline-flex}.eGUBIq_themeStatus{background:var(--dsw-alias-state-success-tertiary,#16a34a1a);color:var(--dsw-alias-state-success-primary,#15803d)}.eGUBIq_themeStatusMuted{background:var(--dsw-alias-bg-layer-2,#f3f4f6);color:var(--dsw-alias-label-secondary,#6b7280)}.eGUBIq_themeDescription{min-height:36px;color:var(--dsw-alias-label-tertiary,#8b93a1);-webkit-line-clamp:2;-webkit-box-orient:vertical;margin:0;font-size:12px;line-height:18px;display:-webkit-box;overflow:hidden}.eGUBIq_themeCardFooter{justify-content:space-between;align-items:center;gap:8px;margin-top:auto;padding-top:4px;display:flex}.eGUBIq_themeLifecycle{min-width:0;color:var(--dsw-alias-label-tertiary,#8b93a1);text-overflow:ellipsis;white-space:nowrap;font-size:11px;line-height:18px;overflow:hidden}.eGUBIq_themeActions{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:8px;margin-left:auto;display:flex}@container (width<=900px){.eGUBIq_themeGallery{grid-template-columns:repeat(3,minmax(0,1fr))}}@container (width<=680px){.eGUBIq_themeGallery{grid-template-columns:repeat(2,minmax(0,1fr))}}@container (width<=460px){.eGUBIq_themeGallery{grid-template-columns:minmax(0,1fr)}}@container (width<=420px){.eGUBIq_sub{grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:2px 8px;display:grid}.eGUBIq_sub>span:first-child{grid-area:1/1}.eGUBIq_sub>.eGUBIq_grow{display:none}.eGUBIq_submitLink{grid-area:2/1}.eGUBIq_exportLogBtn{flex-shrink:0;grid-area:1/2/span 2}.eGUBIq_themeToolbar{grid-template-columns:minmax(0,1fr)}.eGUBIq_themeCardHead{flex-wrap:wrap}.eGUBIq_themeStatus,.eGUBIq_themeStatusMuted{order:3}}@container (width<=280px){.eGUBIq_themeCardFooter{flex-direction:column;align-items:flex-start}.eGUBIq_themeActions{justify-content:flex-start;width:100%;margin-left:0}}@media (max-width:560px){[role=dialog]:has([data-dsh-market-root])>nav{display:none}[role=dialog]:has([data-dsh-market-root])>div{flex:100%;width:100%;min-width:0}}[role=dialog]:has([data-dsh-market-fullscreen=true]){border-radius:0;width:100vw;max-width:none;height:100vh;max-height:none;position:fixed;top:0;bottom:0;left:0;right:0}@media (prefers-reduced-motion:reduce){.eGUBIq_themeCard,.eGUBIq_themeCover img{transition:none}.eGUBIq_themeCard:hover{transform:none}}.eGUBIq_card{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;flex-direction:column;align-self:start;gap:12px;padding:12px 14px;display:flex}.eGUBIq_row1{align-items:flex-start;gap:10px;min-width:0;display:flex}.eGUBIq_cardAction{flex-shrink:0;align-items:center;display:inline-flex}.eGUBIq_installBtn.eGUBIq_installBtn{min-width:64px}.eGUBIq_av{color:#fff;object-fit:cover;background:var(--dsw-alias-bg-layer-2,#f3f4f6);border-radius:50%;flex-shrink:0;place-items:center;width:16px;height:16px;font-size:9px;font-weight:700;display:grid}.eGUBIq_nm{text-overflow:ellipsis;white-space:nowrap;font-size:15px;font-weight:600;line-height:22px;overflow:hidden}.eGUBIq_nmLink{color:inherit;text-decoration:none;display:block}.eGUBIq_nmLink:hover{color:var(--dsw-alias-brand-primary,#4f6ef7);text-decoration:underline}.eGUBIq_repoMark{color:var(--dsw-alias-label-tertiary,#8b93a1);vertical-align:-1px;flex-shrink:0;margin-left:5px}.eGUBIq_nmLink:hover .eGUBIq_repoMark{color:var(--dsw-alias-brand-primary,#4f6ef7)}.eGUBIq_byline{flex-wrap:wrap;align-items:center;gap:6px;min-width:0;margin-top:2px;display:flex}.eGUBIq_meta{color:var(--dsw-alias-label-secondary,#9ca3af);margin-top:2px;font-size:11px}.eGUBIq_metaInline{color:var(--dsw-alias-label-secondary,#9ca3af);font-size:11px}.eGUBIq_owner{color:var(--dsw-alias-label-secondary,#9ca3af);text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:44px;font-size:11px;overflow:hidden}.eGUBIq_desc{color:var(--dsw-alias-label-tertiary,#8b93a1);margin:0;font-size:12px;line-height:18px}.eGUBIq_descClamp{-webkit-line-clamp:5;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.eGUBIq_descToggle{width:20px;height:16px;color:var(--dsw-alias-label-tertiary,#8b93a1);cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;margin-top:2px;padding:0;display:flex}.eGUBIq_descToggle:hover{color:var(--dsw-alias-brand-primary,#4f6ef7)}.eGUBIq_foot{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.eGUBIq_foot .eGUBIq_metaInline,.eGUBIq_foot .eGUBIq_src{white-space:nowrap}.eGUBIq_grow{flex:1}.eGUBIq_titleRow{align-items:center;gap:10px;display:flex}.eGUBIq_version{color:var(--dsw-alias-label-tertiary,#8b93a1);font-variant-numeric:tabular-nums;flex-shrink:0;font-size:12px;line-height:20px}.eGUBIq_repoLink{color:var(--dsw-alias-label-tertiary,#8b93a1);flex-shrink:0;font-size:12px;line-height:20px;text-decoration:none}.eGUBIq_repoLink:hover{color:var(--dsw-alias-brand-primary,#4f6ef7)}.eGUBIq_descTight{min-height:0}.eGUBIq_src{color:var(--dsw-alias-label-secondary,#9ca3af);font-size:11px;text-decoration:none}.eGUBIq_src:hover{color:var(--dsw-alias-brand-primary,#4f6ef7)}.eGUBIq_dot{vertical-align:2px;margin-left:5px}.eGUBIq_act{flex-wrap:wrap;align-items:center;gap:6px;margin-top:6px;font-size:11px;display:flex}.eGUBIq_actLive{color:var(--dsw-alias-state-success-primary,#16a34a);align-items:center;gap:4px;font-weight:600;display:inline-flex}.eGUBIq_actWarn{color:var(--dsw-alias-state-warn-primary,#b45309);align-items:center;gap:4px;font-weight:600;display:inline-flex}.eGUBIq_actBroken{color:var(--dsw-alias-state-error-primary,#dc2626);align-items:center;gap:4px;font-weight:600;display:inline-flex}.eGUBIq_actWhy{color:var(--dsw-alias-label-secondary,#6b7280);margin-top:2px}.eGUBIq_loading{color:var(--dsw-alias-label-secondary,#9ca3af);flex-direction:column;align-items:center;gap:12px;padding:48px;font-size:13px;display:flex}.eGUBIq_spin{color:var(--dsw-alias-brand-primary,#4f6ef7);flex-shrink:0;animation:.8s linear infinite eGUBIq_sp;display:inline-flex}.eGUBIq_logoMark{color:var(--dsw-alias-brand-primary,#4f6ef7);flex-shrink:0;display:inline-flex}.eGUBIq_logoPlug{transform-box:fill-box;transform-origin:50%;animation:1.5s cubic-bezier(.4,0,.2,1) infinite eGUBIq_dshmPlug}@keyframes eGUBIq_dshmPlug{0%,12%{transform:rotate(9deg)}45%,62%{transform:translate(-1.28px,1.27px)rotate(0)}95%,to{transform:rotate(9deg)}}@media (prefers-reduced-motion:reduce){.eGUBIq_logoPlug,.eGUBIq_spin{animation:1.5s ease-in-out infinite eGUBIq_dshmPlugFade}}@keyframes eGUBIq_dshmPlugFade{0%,to{opacity:1}50%{opacity:.35}}@keyframes eGUBIq_sp{to{transform:rotate(360deg)}}.eGUBIq_progress{background:var(--dsw-alias-bg-layer-2,#f3f4f6);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);color:var(--dsw-alias-label-secondary,#6b7280);border-radius:8px;flex-wrap:wrap;align-items:center;gap:9px;margin:0;padding:8px 12px;font-size:12px;display:flex}.eGUBIq_bar{background:var(--dsw-alias-border-l1,#e5e7eb);border-radius:99px;width:100%;height:4px;overflow:hidden}.eGUBIq_barFill{background:var(--dsw-alias-brand-primary,#4f6ef7);border-radius:99px;height:100%;transition:width .6s}.eGUBIq_barWave{width:30%;animation:1.2s ease-in-out infinite eGUBIq_dshmSlide}@keyframes eGUBIq_dshmSlide{0%{margin-left:-30%}to{margin-left:100%}}.eGUBIq_irow .eGUBIq_progress{margin-top:8px}.eGUBIq_progress code{text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,Menlo,monospace;font-size:11px;overflow:hidden}.eGUBIq_empty{color:var(--dsw-alias-label-secondary,#9ca3af);text-align:center;padding:32px;font-size:13px}.eGUBIq_err{color:var(--dsw-alias-state-error-primary,#dc2626);white-space:pre-wrap;word-break:break-all;margin:8px 0;font-size:12px}.eGUBIq_cardBlocked{border-color:var(--dsw-alias-state-error-primary,#dc2626)}.eGUBIq_conflictHead{align-items:flex-start;gap:8px;display:flex}.eGUBIq_conflictIcon{color:var(--dsw-alias-state-error-primary,#dc2626);flex-shrink:0;margin-top:1px}.eGUBIq_conflictTitle{color:var(--dsw-alias-state-error-primary,#dc2626);font-size:13px;font-weight:600;line-height:18px}.eGUBIq_conflictBody{margin:0;font-size:12px;line-height:19px}.eGUBIq_roster{background:var(--dsw-alias-border-l2,#e5e7eb);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:8px;flex-direction:column;gap:1px;display:flex;overflow:hidden}.eGUBIq_rosterRow{background:var(--dsw-alias-bg-layer-1,#fff);align-items:center;gap:8px;padding:7px 10px;display:flex}.eGUBIq_rosterMain{flex-direction:column;min-width:0;display:flex}.eGUBIq_rosterName{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:12px;font-weight:600;overflow:hidden}.eGUBIq_rosterAuthor{color:var(--dsw-alias-label-secondary,#9ca3af);text-overflow:ellipsis;white-space:nowrap;font-size:10.5px;overflow:hidden}.eGUBIq_rosterTag{border-radius:4px;flex-shrink:0;margin-left:auto;padding:1px 6px;font-size:10.5px;font-weight:600}.eGUBIq_rosterTagKeep{color:var(--dsw-alias-state-success-primary,#16a34a);background:#16a34a1f}.eGUBIq_rosterTagDrop{color:var(--dsw-alias-state-error-primary,#dc2626);background:#dc26261f}.eGUBIq_rosterRowOut .eGUBIq_rosterName{text-decoration:line-through}.eGUBIq_rosterRowOut{opacity:.62}.eGUBIq_rosterSplit{background:var(--dsw-alias-border-l2,#e5e7eb);height:1px}.eGUBIq_reassure{color:var(--dsw-alias-label-secondary,#6b7280);align-items:center;gap:5px;margin:0;font-size:11.5px;line-height:17px;display:flex}.eGUBIq_reassureOk{color:var(--dsw-alias-state-success-primary,#16a34a);flex-shrink:0}.eGUBIq_conflictWhy{color:var(--dsw-alias-label-tertiary,#8b93a1);overflow-wrap:anywhere;margin-top:2px;font-family:ui-monospace,Menlo,monospace;font-size:11px;line-height:17px}.eGUBIq_conflictWhyText{margin-top:5px;font-family:-apple-system,BlinkMacSystemFont,PingFang SC,sans-serif}.eGUBIq_choices{flex-direction:column;gap:7px;display:flex}.eGUBIq_choice{text-align:left;font:inherit;cursor:pointer;background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l3,#d9dde3);border-radius:9px;align-items:flex-start;gap:9px;padding:9px 11px;display:flex}.eGUBIq_choice:has(input:disabled){cursor:default;opacity:.6}.eGUBIq_choiceOn{border-color:var(--dsw-alias-brand-primary,#4f6ef7);background:var(--dsw-alias-bg-layer-2,#f5f7ff)}.eGUBIq_choiceRadio{width:13px;height:13px;accent-color:var(--dsw-alias-brand-primary,#4f6ef7);flex-shrink:0;margin:2px 0 0}.eGUBIq_choiceMain{flex-direction:column;gap:3px;min-width:0;display:flex}.eGUBIq_choiceTitle{font-size:12px;font-weight:600;line-height:17px}.eGUBIq_choiceNote{color:var(--dsw-alias-label-tertiary,#8b93a1);font-size:11px;line-height:16px}.eGUBIq_choiceSafe{color:var(--dsw-alias-state-success-primary,#16a34a)}.eGUBIq_stateTag{white-space:nowrap;background:var(--dsw-alias-bg-layer-2,#f3f4f6);min-height:20px;color:var(--dsw-alias-label-secondary,#6b7280);border-radius:5px;flex-shrink:0;align-items:center;gap:5px;padding:1px 7px;font-size:11px;line-height:16px;display:inline-flex}.eGUBIq_stateTag[data-on=true]{color:var(--dsw-alias-state-success-primary,#16a34a);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#16a34a) 10%, transparent)}.eGUBIq_stateDot{background:var(--dsw-alias-label-tertiary,#8b93a1);border-radius:999px;flex:none;width:6px;height:6px}.eGUBIq_stateDot[data-on=true]{background:var(--dsw-alias-state-success-primary,#16a34a)}.eGUBIq_metaTag{text-overflow:ellipsis;white-space:nowrap;background:var(--dsw-alias-bg-layer-2,#f3f4f6);min-width:0;max-width:100%;min-height:20px;color:var(--dsw-alias-label-tertiary,#8b93a1);border-radius:5px;flex-shrink:1;padding:1px 7px;font-size:11px;line-height:18px;display:inline-block;overflow:hidden}.eGUBIq_metaTagOk{color:var(--dsw-alias-state-success-primary,#16a34a);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#16a34a) 10%, transparent)}.eGUBIq_nameLink{color:inherit;text-decoration:none}.eGUBIq_irowName{text-overflow:clip;align-items:baseline;gap:6px;min-width:0;display:flex;overflow:visible}.eGUBIq_irowNameText{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.eGUBIq_irowName>.eGUBIq_owner{flex:none}.eGUBIq_nameLink:hover{color:var(--dsw-alias-brand-primary,#4f6ef7);text-decoration:underline}.eGUBIq_opWrap{flex-shrink:0;display:inline-flex;position:relative}.eGUBIq_opEntry{font:inherit;cursor:pointer;white-space:nowrap;color:var(--dsw-alias-label-primary,#1f2328);background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l3,#d9dde3);border-radius:7px;align-items:center;gap:6px;padding:4px 10px;font-size:12px;display:inline-flex;position:relative}.eGUBIq_opEntryQuiet{color:var(--dsw-alias-label-secondary,#6b7280);background:0 0;border-color:#0000}.eGUBIq_opEntryAlert{border-color:var(--dsw-alias-state-error-primary,#dc2626);color:var(--dsw-alias-state-error-primary,#dc2626)}.eGUBIq_opDot{background:var(--dsw-alias-state-error-primary,#dc2626);border-radius:99px;width:8px;height:8px;position:absolute;top:-3px;right:-3px}.eGUBIq_opPanel{z-index:40;background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l3,#d9dde3);border-radius:12px;width:460px;max-width:86vw;max-height:70vh;position:absolute;top:calc(100% + 6px);right:0;overflow-y:auto;box-shadow:0 20px 52px #00000047}.eGUBIq_opHead{border-bottom:1px solid var(--dsw-alias-border-l2,#e5e7eb);align-items:center;gap:8px;padding:9px 14px;display:flex}.eGUBIq_opPanelTitle{font-size:12.5px;font-weight:600}.eGUBIq_opCloseBtn.eGUBIq_opCloseBtn{min-width:0;color:var(--dsw-alias-label-secondary,#6b7280);padding:0 6px}.eGUBIq_opAggregate{border-bottom:1px solid var(--dsw-alias-border-l2,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f7f8fa);padding:9px 14px}.eGUBIq_opAggregateTop{font-variant-numeric:tabular-nums;font-size:12px;font-weight:600}.eGUBIq_opAggregateHint{color:var(--dsw-alias-label-tertiary,#8b93a1);margin-top:4px;font-size:10.5px}.eGUBIq_opRow{border-bottom:1px solid var(--dsw-alias-border-l2,#e5e7eb);align-items:flex-start;gap:9px;padding:9px 14px;display:flex}.eGUBIq_opRow:last-child{border-bottom:none}.eGUBIq_opRowAlert{background:#dc26260f}.eGUBIq_opIcon{flex-shrink:0;place-items:center;width:14px;margin-top:1px;display:grid}.eGUBIq_opQueuedIcon{color:var(--dsw-alias-label-tertiary,#8b93a1);font-size:12px}.eGUBIq_opMain{flex-direction:column;flex:1;gap:3px;min-width:0;display:flex}.eGUBIq_opTop{align-items:baseline;gap:6px;min-width:0;display:flex}.eGUBIq_opVerb{color:var(--dsw-alias-label-secondary,#6b7280);flex-shrink:0;font-size:12px}.eGUBIq_opName{text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:600;overflow:hidden}.eGUBIq_opStatus{color:var(--dsw-alias-label-tertiary,#8b93a1);overflow-wrap:anywhere;font-size:10.5px;line-height:16px}.eGUBIq_opStatusBad{color:var(--dsw-alias-state-error-primary,#dc2626)}.eGUBIq_opActions{flex-shrink:0;align-items:center;gap:6px;margin-top:1px;display:flex}.eGUBIq_opDecision{border-top:1px dashed var(--dsw-alias-border-l2,#e5e7eb);flex-direction:column;gap:8px;margin-top:8px;padding-top:8px;display:flex}.eGUBIq_opDecisionFoot{align-items:center;gap:8px;display:flex}.eGUBIq_conflictDetailsToggle{font:inherit;cursor:pointer;color:var(--dsw-alias-label-tertiary,#8b93a1);background:0 0;border:none;align-items:center;gap:4px;padding:2px 0;font-size:11px;display:inline-flex}.eGUBIq_conflictDetailsToggle:hover{color:var(--dsw-alias-label-secondary,#6b7280)}.eGUBIq_opEmpty{text-align:center;color:var(--dsw-alias-label-secondary,#6b7280);padding:30px 14px;font-size:12px}.eGUBIq_opEmptyHint{color:var(--dsw-alias-label-tertiary,#8b93a1);margin-top:4px;font-size:11px}.eGUBIq_cardBlockedMark{font:inherit;cursor:pointer;color:var(--dsw-alias-state-error-primary,#dc2626);border:1px solid var(--dsw-alias-state-error-primary,#dc2626);background:#dc262614;border-radius:7px;align-items:center;gap:5px;padding:4px 9px;font-size:11px;display:inline-flex}.eGUBIq_dangerBtn.eGUBIq_dangerBtn{color:var(--dsw-alias-state-error-primary,#dc2626);border-color:var(--dsw-alias-state-error-primary,#dc2626)}.eGUBIq_dangerBtn.eGUBIq_dangerBtn:hover:not(:disabled){background:var(--dsw-alias-state-error-primary,#dc2626);color:#fff}.eGUBIq_dangerArmed.eGUBIq_dangerArmed{background:var(--dsw-alias-state-error-primary,#dc2626);border-color:var(--dsw-alias-state-error-primary,#dc2626);color:#fff}.eGUBIq_retryBtn{margin-top:4px}.eGUBIq_irow{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:10px;flex-direction:column;gap:10px;min-width:0;padding:12px 14px;display:flex}.eGUBIq_irowActions{flex-wrap:wrap;justify-content:flex-start;align-items:center;gap:8px;min-width:0;display:flex}.eGUBIq_irowTrailing{flex-wrap:nowrap;align-items:center;gap:8px;min-width:0;display:inline-flex}.eGUBIq_irowMissing{filter:grayscale();opacity:.5}.eGUBIq_irow>.eGUBIq_src,.eGUBIq_irow>.eGUBIq_owner,.eGUBIq_irow button{white-space:nowrap;flex-shrink:0}.eGUBIq_tabSearchRow{padding:0 4px 6px;display:flex}.eGUBIq_tabSearch{width:100%}.eGUBIq_spec{color:var(--dsw-alias-label-secondary,#9ca3af);overflow-wrap:anywhere;min-width:0;font-family:ui-monospace,Menlo,monospace;font-size:11px}.eGUBIq_specTag{white-space:nowrap;border-radius:4px;flex-shrink:0;align-items:center;height:16px;padding:0 5px;font-size:10px;font-weight:600;display:inline-flex}.eGUBIq_specTagGit{color:#0b7285;background:#12a3c41f}.eGUBIq_specTagFile{color:#b07d1b;background:#f0b42924}.eGUBIq_backupCheckList .eGUBIq_grow{white-space:nowrap;text-overflow:ellipsis;flex:70%;min-width:0;overflow:hidden}.eGUBIq_backupCheckList .eGUBIq_spec{text-align:right;white-space:nowrap;text-overflow:ellipsis;flex:0 30%;max-width:30%;overflow:hidden}.eGUBIq_staleAction{margin-top:8px}.eGUBIq_pct{color:var(--dsw-alias-label-secondary,#6b7280);flex-shrink:0;font-size:11px;font-weight:600}.eGUBIq_pager{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;margin:16px 0 4px;display:flex}.eGUBIq_pagerPages{flex-wrap:wrap;flex:1;justify-content:center;align-items:center;gap:6px;min-width:0;display:flex}.eGUBIq_pageEllipsis{color:var(--dsw-alias-label-secondary,#9ca3af);padding:0 2px;font-size:12px}.eGUBIq_pageInfo{color:var(--dsw-alias-label-secondary,#6b7280);white-space:nowrap;font-size:12px}.eGUBIq_depBadge{border:1px solid var(--dsw-alias-state-warn-primary,#b45309);color:var(--dsw-alias-state-warn-primary,#b45309);white-space:nowrap;border-radius:4px;flex-shrink:0;margin-left:6px;padding:1px 6px;font-size:11px;font-weight:600;line-height:16px}.eGUBIq_deprecate{color:var(--dsw-alias-state-warn-primary,#b45309);background:var(--dsw-alias-bg-layer-2,#fdf3e3);border:1px solid var(--dsw-alias-border-l2,#f3e3c3);border-radius:8px;margin:0;padding:8px 10px;font-size:12px;line-height:18px}.eGUBIq_deprecate a{color:var(--dsw-alias-state-warn-primary,#b45309);text-decoration:underline}.eGUBIq_deprecate .eGUBIq_src{margin-left:8px}.eGUBIq_depLine{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.eGUBIq_switch{border:1px solid var(--dsw-alias-border-l2,#d9dde3);background:var(--dsw-alias-bg-layer-2,#e5e7eb);cursor:pointer;border-radius:99px;flex-shrink:0;width:38px;height:22px;padding:0;transition:background .15s,border-color .15s;position:relative}.eGUBIq_switchOn{background:var(--dsw-alias-state-success-primary,#16a34a);border-color:var(--dsw-alias-state-success-primary,#16a34a)}.eGUBIq_switchMixed{background:var(--dsw-alias-state-warn-primary,#b45309);border-color:var(--dsw-alias-state-warn-primary,#b45309)}.eGUBIq_switchKnob{background:#fff;border-radius:99px;width:16px;height:16px;transition:left .15s;position:absolute;top:2px;left:2px;box-shadow:0 1px 2px #00000040}.eGUBIq_switchOn .eGUBIq_switchKnob,.eGUBIq_switchMixed .eGUBIq_switchKnob{left:18px}.eGUBIq_switch:disabled{opacity:.5;cursor:default}.eGUBIq_viewBar{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:8px;align-items:center;gap:2px;width:fit-content;margin-bottom:12px;padding:2px;display:flex}.eGUBIq_viewBtn{font:inherit;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-radius:6px;padding:4px 10px;font-size:12px;line-height:18px}.eGUBIq_viewBtn:hover{color:var(--dsw-alias-brand-primary,#4f6ef7)}.eGUBIq_viewOn{background:var(--dsw-alias-bg-layer-2,#eef0f4);color:var(--dsw-alias-label-primary,#1f2328);font-weight:600}.eGUBIq_groupRow{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;margin-bottom:10px;padding:12px 14px}.eGUBIq_groupHead{align-items:center;gap:10px;min-width:0;display:flex}.eGUBIq_groupName{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;line-height:20px;overflow:hidden}.eGUBIq_groupActions{flex-shrink:0;align-items:center;gap:6px;display:flex}.eGUBIq_groupMembers{flex-direction:column;gap:6px;margin-top:10px;display:flex}.eGUBIq_groupMember{background:var(--dsw-alias-bg-layer-2,#f7f8fa);border-radius:8px;align-items:center;gap:8px;padding:6px 8px;font-size:12px;line-height:18px;display:flex}.eGUBIq_groupMember .eGUBIq_nm{flex:1;min-width:0;font-size:12px}.eGUBIq_groupAddPanel{border-top:1px dashed var(--dsw-alias-border-l2,#e5e7eb);flex-direction:column;gap:6px;margin-top:10px;padding-top:10px;display:flex}.eGUBIq_groupCreate{align-items:center;gap:8px;margin-bottom:10px;display:flex}.eGUBIq_inlineInput{flex:1;min-width:120px}.eGUBIq_assignRow{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.eGUBIq_assignSelect{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);color:var(--dsw-alias-label-primary,#1f2328);font:inherit;border-radius:6px;padding:3px 6px;font-size:12px;line-height:18px}.eGUBIq_groupHint{color:var(--dsw-alias-label-tertiary,#8b93a1);font-size:11px}.eGUBIq_sectAction{color:var(--dsw-alias-label-secondary,#6b7280);align-items:center;gap:8px;margin:14px 2px 8px;font-size:12px;font-weight:600;display:flex}.eGUBIq_backupGrid{grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:12px;display:grid}.eGUBIq_backupCard{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;flex-direction:column;gap:10px;padding:16px;display:flex}.eGUBIq_backupCard h3{margin:0;font-size:14px}.eGUBIq_backupCard p{color:var(--dsw-alias-label-secondary,#6b7280);margin:0;font-size:12px;line-height:18px}.eGUBIq_backupActions{flex-wrap:wrap;gap:8px;display:flex;position:relative}.eGUBIq_hiddenFile{opacity:0;pointer-events:none;width:1px;height:1px;position:absolute}.eGUBIq_backupInput{box-sizing:border-box;width:100%}.eGUBIq_backupCheck{cursor:pointer;align-items:center;gap:6px;font-size:12px;display:flex}.eGUBIq_backupWarn{margin:0;font-size:12px;line-height:18px;color:var(--dsw-alias-state-warn-primary,#b45309)!important}.eGUBIq_backupMessage{color:var(--dsw-alias-label-secondary,#6b7280);grid-column:1/-1;font-size:12px}.eGUBIq_backupCheckList{flex-direction:column;gap:6px;max-height:260px;margin:10px 0 4px;padding-right:4px;display:flex;overflow-y:auto}.eGUBIq_backupCheckList .eGUBIq_backupCheck{justify-content:space-between;gap:8px}.eGUBIq_diagPage{flex-direction:column;gap:12px;height:100%;min-height:0;display:flex;overflow-y:auto}.eGUBIq_diagSummary{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;flex-wrap:wrap;align-items:center;gap:12px;padding:10px 14px;font-size:12px;display:flex}.eGUBIq_diagSummaryItem{color:var(--dsw-alias-label-secondary,#6b7280);white-space:nowrap;align-items:center;gap:6px;display:inline-flex}.eGUBIq_diagSummaryMeta{color:var(--dsw-alias-label-tertiary,#9ca3af);text-overflow:ellipsis;white-space:nowrap;max-width:320px;font-family:ui-monospace,Menlo,monospace;font-size:11px;overflow:hidden}.eGUBIq_diagSection{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;flex-direction:column;gap:8px;padding:12px 14px;display:flex}.eGUBIq_diagSection h3{color:var(--dsw-alias-label-primary,#1f2328);margin:0;font-size:13px;font-weight:600}.eGUBIq_diagCount{color:var(--dsw-alias-label-tertiary,#9ca3af);font-size:11px;font-weight:400}.eGUBIq_diagEmpty{color:var(--dsw-alias-label-secondary,#9ca3af);padding:8px 0;font-size:12px}.eGUBIq_diagBundle{border-top:1px solid var(--dsw-alias-border-l2,#f0f1f3);flex-direction:column;gap:6px;padding-top:8px;display:flex}.eGUBIq_diagBundle:first-of-type{border-top:none;padding-top:0}.eGUBIq_diagRow{flex-wrap:wrap;align-items:center;gap:8px;min-width:0;font-size:12px;line-height:18px;display:flex}.eGUBIq_diagMeta{align-items:baseline;gap:8px;min-width:0;font-size:12px;display:flex}.eGUBIq_diagKey{color:var(--dsw-alias-label-tertiary,#9ca3af);flex-shrink:0;min-width:64px;font-size:11px}.eGUBIq_diagVal{color:var(--dsw-alias-label-primary,#1f2328);overflow-wrap:anywhere;min-width:0;font-family:ui-monospace,Menlo,monospace;font-size:12px;font-weight:500}.eGUBIq_diagIndex{background:var(--dsw-alias-bg-layer-2,#f3f4f6);min-width:18px;height:18px;color:var(--dsw-alias-label-secondary,#6b7280);border-radius:9px;flex-shrink:0;justify-content:center;align-items:center;font-size:11px;font-weight:600;display:inline-flex}.eGUBIq_diagArrow{color:var(--dsw-alias-label-tertiary,#9ca3af);flex-shrink:0;font-size:12px}.eGUBIq_diagBadgeOfficial{background:var(--dsw-alias-brand-primary,#4f6ef7);color:#fff;border-radius:9px;flex-shrink:0;align-items:center;height:18px;padding:0 8px;font-size:11px;font-weight:600;display:inline-flex}.eGUBIq_diagBadgeCommunity{background:var(--dsw-alias-bg-layer-2,#f3f4f6);height:18px;color:var(--dsw-alias-label-secondary,#6b7280);border-radius:9px;flex-shrink:0;align-items:center;padding:0 8px;font-size:11px;display:inline-flex}.eGUBIq_diagBadgeShadow{background:var(--dsw-alias-state-error-primary,#dc2626);color:#fff;border-radius:9px;flex-shrink:0;align-items:center;height:18px;padding:0 8px;font-size:11px;font-weight:600;display:inline-flex}.eGUBIq_diagBadgeWarn{background:var(--dsw-alias-state-warn-primary,#b45309);color:#fff;white-space:nowrap;border-radius:9px;flex-shrink:0;align-items:center;height:18px;padding:0 8px;font-size:11px;font-weight:600;display:inline-flex}.eGUBIq_diagBadgeInfo{background:var(--dsw-alias-bg-layer-2,#f3f4f6);height:18px;color:var(--dsw-alias-label-secondary,#6b7280);white-space:nowrap;border-radius:9px;flex-shrink:0;align-items:center;padding:0 8px;font-size:11px;display:inline-flex}.eGUBIq_diagList{flex-direction:column;gap:6px;display:flex}.eGUBIq_sectionOverview{color:var(--dsw-alias-label-tertiary,#8b93a1);text-overflow:ellipsis;white-space:nowrap;max-width:100%;padding:2px 0 6px;font-size:12px;line-height:18px;overflow:hidden}.eGUBIq_diagAlert{color:var(--dsw-alias-state-warn-primary,#b45309)}.eGUBIq_ovRow{background:var(--dsw-alias-bg-layer-2,#f7f8fa);border-radius:8px;flex-wrap:wrap;align-items:center;gap:8px;min-width:0;padding:6px 10px;font-size:12px;line-height:18px;display:flex}.eGUBIq_ovArrow{color:var(--dsw-alias-label-tertiary,#9ca3af);flex-shrink:0;font-size:12px}.eGUBIq_ovByTag{background:var(--dsw-alias-brand-primary,#4f6ef7);color:#fff;text-overflow:ellipsis;white-space:nowrap;border-radius:9px;flex-shrink:0;align-items:center;max-width:260px;height:18px;padding:0 8px;font-size:11px;font-weight:600;display:inline-flex;overflow:hidden}.eGUBIq_ovFrom{color:var(--dsw-alias-label-secondary,#6b7280);text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:12px;overflow:hidden}.eGUBIq_orphRow{background:var(--dsw-alias-bg-layer-2,#f7f8fa);border-radius:8px;flex-wrap:wrap;align-items:center;gap:8px;min-width:0;padding:6px 10px;font-size:12px;line-height:18px;display:flex}.eGUBIq_orphBadge{background:var(--dsw-alias-state-warn-primary,#b45309);color:#fff;white-space:nowrap;border-radius:9px;flex-shrink:0;align-items:center;height:18px;padding:0 8px;font-size:11px;font-weight:600;display:inline-flex}.eGUBIq_dragHandle{width:20px;height:20px;color:var(--dsw-alias-label-tertiary,#9ca3af);cursor:grab;-webkit-user-select:none;user-select:none;flex-shrink:0;justify-content:center;align-items:center;font-size:12px;line-height:20px;display:inline-flex}.eGUBIq_dragOver{outline:2px dashed var(--dsw-alias-brand-primary,#4f6ef7);outline-offset:2px;background:var(--dsw-alias-bg-layer-2,#f0f2f8);border-radius:8px}.eGUBIq_dragging{opacity:.45;background:var(--dsw-alias-bg-layer-2,#f3f4f6)}.eGUBIq_collapseHead{font:inherit;color:var(--dsw-alias-label-primary,#1f2328);cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;gap:8px;width:100%;padding:0;font-size:13px;font-weight:600;display:flex}.eGUBIq_collapseIcon{color:var(--dsw-alias-label-secondary,#6b7280);flex-shrink:0;display:inline-flex}.eGUBIq_collapseTitle{flex:1;min-width:0}.eGUBIq_collapseBody{border-top:1px solid var(--dsw-alias-border-l2,#f0f1f3);overflow-wrap:anywhere;flex-direction:column;gap:10px;min-width:0;margin-top:8px;padding-top:10px;display:flex}.eGUBIq_panelNote{color:var(--dsw-alias-label-secondary,#6b7280);margin:0;font-size:12px;line-height:18px}.eGUBIq_fixFallback{flex-direction:column;gap:6px;margin:8px 0;display:flex}.eGUBIq_fixFallbackText{box-sizing:border-box;width:100%;color:var(--dsw-alias-label-primary,#1f2328);background:var(--dsw-alias-bg-layer-2,#f3f4f6);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);resize:vertical;white-space:pre-wrap;word-break:break-all;border-radius:6px;padding:8px 10px;font-family:ui-monospace,Menlo,monospace;font-size:11px;line-height:16px}.eGUBIq_setCard{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);background:var(--dsw-alias-bg-layer-3,#fff);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.eGUBIq_setCard:hover{border-color:var(--dsw-alias-label-dimmed,#c8ccd4)}.eGUBIq_setCardOpen{background:var(--dsw-alias-bg-layer-2,#f7f8fa);border-color:var(--dsw-alias-label-dimmed,#c8ccd4)}.eGUBIq_setHeader{-webkit-appearance:none;appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.eGUBIq_setHeader:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#4f6ef7);outline-offset:-2px}.eGUBIq_setHeadText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.eGUBIq_setName{color:var(--dsw-alias-label-primary,#1f2328);font-size:15px;font-weight:600;line-height:1.4}.eGUBIq_setDesc{color:var(--dsw-alias-label-tertiary,#8b93a1);font-size:13px;line-height:1.5}.eGUBIq_setChevron{color:var(--dsw-alias-label-tertiary,#8b93a1);flex:none;transition:transform .16s;display:inline-flex}.eGUBIq_setChevronOpen{transform:rotate(180deg)}.eGUBIq_setBody{border-top:1px solid var(--dsw-alias-border-l2,#e5e7eb);margin:0 16px;padding-bottom:8px}.eGUBIq_setRow{align-items:center;gap:12px;padding:12px 0;display:flex}.eGUBIq_setRow+.eGUBIq_setRow{border-top:1px solid var(--dsw-alias-border-l2,#e5e7eb)}.eGUBIq_setLabelBox{flex-direction:column;flex:1;gap:3px;min-width:0;display:flex}.eGUBIq_setLabel{font-size:13px;line-height:20px}.eGUBIq_setHint{color:var(--dsw-alias-label-tertiary,#8b93a1);font-size:12px;line-height:18px}.eGUBIq_setConfirm{border-top:1px solid var(--dsw-alias-border-l2,#e5e7eb);flex-direction:column;gap:8px;padding:12px 0 4px;display:flex}.eGUBIq_setCheck{cursor:pointer;align-items:center;gap:8px;font-size:12px;line-height:18px;display:flex}.eGUBIq_setActions{border-top:1px solid var(--dsw-alias-border-l2,#e5e7eb);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.eGUBIq_setDanger{color:var(--dsw-alias-state-error-primary,#dc2626)}.eGUBIq_setSeg{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:8px;flex-shrink:0;gap:2px;padding:2px;display:inline-flex}.eGUBIq_setSegBtn{font:inherit;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border:none;border-radius:6px;padding:3px 10px;font-size:12px;line-height:18px}.eGUBIq_setSegBtn:disabled{cursor:default;opacity:.5}.eGUBIq_setSegOn{background:var(--dsw-alias-bg-layer-2,#eef0f4);color:var(--dsw-alias-label-primary,#1f2328);font-weight:600}.eGUBIq_setBetaTag{background:var(--dsw-alias-bg-module-platform,#eef0f4);color:var(--dsw-alias-label-secondary,#6b7280);border-radius:9px;margin-left:6px;padding:0 6px;font-size:11px;font-weight:600;line-height:17px}";
|
|
1585
|
+
const css = ".eGUBIq_root{min-width:0;height:100%;color:var(--dsw-alias-label-primary,#1f2328);flex-direction:column;display:flex;position:relative;container-type:inline-size}.eGUBIq_head{flex-direction:column;gap:12px;padding:4px 4px 6px;display:flex}.eGUBIq_title{margin:0;font-size:16px;font-weight:500;line-height:24px}.eGUBIq_sub{color:var(--dsw-alias-label-tertiary,#8b93a1);align-items:center;gap:8px;margin:0;font-size:12px;line-height:18px;display:flex}.eGUBIq_submitLink{color:var(--dsw-alias-label-tertiary,#8b93a1);white-space:nowrap;font-size:11px;line-height:18px;text-decoration:none}.eGUBIq_submitLink:hover{color:var(--dsw-alias-brand-primary,#4f6ef7);text-decoration:underline}.eGUBIq_tabs{border-bottom:1px solid var(--dsw-alias-border-l2,#e5e7eb);align-items:flex-end;gap:2px;display:flex}.eGUBIq_tab{font:inherit;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-bottom:2px solid #0000;padding:7px 12px;font-size:13px}.eGUBIq_tab.eGUBIq_on{color:var(--dsw-alias-brand-primary,#4f6ef7);border-bottom-color:var(--dsw-alias-brand-primary,#4f6ef7);font-weight:600}.eGUBIq_subTabs{align-items:flex-end;gap:2px;margin:-4px 0 4px;display:flex}.eGUBIq_banner{background:var(--dsw-alias-bg-layer-2,#fdf3e3);border:1px solid var(--dsw-alias-border-l2,#f3e3c3);border-radius:8px;align-items:center;gap:8px;margin:0;padding:8px 12px;font-size:12px;display:flex}.eGUBIq_bannerIcon{color:var(--dsw-alias-label-secondary,#6b7280);flex-shrink:0}.eGUBIq_bannerHint{color:var(--dsw-alias-label-tertiary,#8b93a1);cursor:help;display:inline-flex}.eGUBIq_body{flex:1;padding:12px 4px 24px;overflow-x:hidden;overflow-y:auto}.eGUBIq_stickyHead{z-index:5;background:var(--dsw-alias-bg-layer-2,#f7f8fa);position:sticky;top:-1px}.eGUBIq_stickyHead:before{content:\"\";background:inherit;pointer-events:none;height:14px;position:absolute;bottom:100%;left:0;right:0}.eGUBIq_cats{margin:0 -4px 2px;padding:12px 4px 4px}.eGUBIq_catsRow{align-items:flex-start;gap:8px;display:flex;position:relative}.eGUBIq_star{color:var(--dsw-alias-label-secondary,#9ca3af);white-space:nowrap;flex:none;font-size:11px}.eGUBIq_top{z-index:20;display:inline-flex;position:absolute;bottom:18px;right:18px}.eGUBIq_topBtn{border-radius:99px;width:38px;height:38px;padding:0}.eGUBIq_tag{border:1px solid var(--dsw-alias-border-l3,#d9dde3);color:var(--dsw-alias-label-secondary,#6b7280);border-radius:4px;flex-shrink:0;padding:1px 6px;font-size:11px;line-height:16px}.eGUBIq_okState{color:var(--dsw-alias-state-success-primary,#16a34a);white-space:nowrap;font-size:12px;font-weight:600}.eGUBIq_catsWrap{flex-wrap:wrap;flex:1;align-items:center;gap:6px;min-width:0;display:flex}.eGUBIq_catsCollapsed{max-height:62px;overflow:hidden}.eGUBIq_catsToggle.eGUBIq_catsToggle{height:26px;min-height:26px;color:var(--dsw-alias-label-secondary,#6b7280);padding:0 6px}.eGUBIq_shots{-webkit-overflow-scrolling:touch;scrollbar-width:thin;gap:8px;margin:6px 0 8px;padding:2px 0 6px;display:flex;overflow-x:auto}.eGUBIq_shot{object-fit:cover;border:1px solid var(--dsw-alias-border-default,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f3f4f6);cursor:pointer;border-radius:8px;flex:none;width:220px;height:150px}.eGUBIq_cardShots{-webkit-overflow-scrolling:touch;scrollbar-width:thin;gap:6px;margin:0 0 6px;padding:0 0 2px;display:flex;overflow-x:auto}.eGUBIq_cardShot{object-fit:contain;border:1px solid var(--dsw-alias-border-default,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f3f4f6);cursor:pointer;border-radius:8px;flex:none;width:132px;height:88px;display:block}.eGUBIq_lightbox{z-index:10000;cursor:zoom-out;background:#000000d9;justify-content:center;align-items:center;display:flex;position:fixed;top:0;bottom:0;left:0;right:0}.eGUBIq_lightboxImg{object-fit:contain;cursor:default;border-radius:4px;max-width:90vw;max-height:85vh}.eGUBIq_lightboxClose{color:#fff;cursor:pointer;background:#ffffff1f;border:none;border-radius:99px;place-items:center;width:36px;height:36px;font-size:22px;line-height:1;display:grid;position:absolute;top:16px;right:16px}.eGUBIq_lightboxClose:hover{background:#ffffff38}.eGUBIq_lightboxNav{color:#fff;cursor:pointer;background:#ffffff1f;border:none;border-radius:99px;place-items:center;width:44px;height:44px;display:grid;position:absolute;top:50%;transform:translateY(-50%)}.eGUBIq_lightboxNav:hover{background:#ffffff38}.eGUBIq_lightboxPrev{left:16px}.eGUBIq_lightboxNext{right:16px}.eGUBIq_lightboxDots{gap:8px;display:flex;position:absolute;bottom:20px;left:50%;transform:translate(-50%)}.eGUBIq_lightboxDot{cursor:pointer;background:#fff6;border-radius:99px;width:7px;height:7px}.eGUBIq_lightboxDotOn{background:#fff}.eGUBIq_cmd{background:var(--dsw-alias-bg-layer-2,#f3f4f6);word-break:break-all;border-radius:6px;margin:8px 0 0;padding:8px 10px;font-family:ui-monospace,Menlo,monospace;font-size:11px;line-height:18px}.eGUBIq_warnLine{color:var(--dsw-alias-state-warn-primary,#b45309);flex-wrap:wrap;align-items:center;gap:4px;margin:0;font-size:12px;font-weight:600;line-height:18px;display:flex}.eGUBIq_modalNote{color:var(--dsw-alias-label-tertiary,#8b93a1);align-items:center;gap:4px;margin:12px 0 0;font-size:12px;line-height:18px;display:flex}.eGUBIq_grid{grid-template-columns:repeat(2,minmax(0,1fr));align-items:start;gap:10px;display:grid}.eGUBIq_masonry{align-items:flex-start;gap:10px;display:flex}.eGUBIq_masonryCol{flex-direction:column;flex:1;gap:10px;min-width:0;display:flex}.eGUBIq_masonry>.eGUBIq_masonryCol>*{align-self:stretch;min-width:0}@media (max-width:680px){.eGUBIq_masonry{flex-direction:column}.eGUBIq_masonryCol{width:100%}.eGUBIq_grid{grid-template-columns:minmax(0,1fr)}}.eGUBIq_swatches{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:8px;gap:0;height:34px;display:flex;overflow:hidden}.eGUBIq_themesGrid{margin-bottom:12px}.eGUBIq_swatches i{flex:1}.eGUBIq_themeToolbar{grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:8px;padding:0 4px 12px;display:grid}.eGUBIq_themeSearch{box-sizing:border-box;width:100%;min-width:0}.eGUBIq_themeToolbarActions{justify-content:flex-end;align-items:center;gap:8px;display:flex}.eGUBIq_themeFullscreenBtn.eGUBIq_themeFullscreenBtn{width:28px;min-width:28px;padding:0}.eGUBIq_themeResultBar{min-height:24px;color:var(--dsw-alias-label-tertiary,#8b93a1);align-items:center;padding:0 4px 8px;font-size:12px;line-height:18px;display:flex}.eGUBIq_themeGallery{grid-template-columns:repeat(4,minmax(0,1fr));align-items:stretch;gap:10px;display:grid}.eGUBIq_themeCard{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);border-radius:8px;flex-direction:column;min-width:0;transition:border-color .16s cubic-bezier(.16,1,.3,1),box-shadow .16s cubic-bezier(.16,1,.3,1),transform .16s cubic-bezier(.16,1,.3,1);display:flex;overflow:hidden}.eGUBIq_themeCard:hover{border-color:var(--dsw-alias-border-l3,#d9dde3);box-shadow:var(--dsw-shadow-lv1,0 4px 12px #1f232814);transform:translateY(-1px)}.eGUBIq_themeCover{aspect-ratio:16/10;border:0;border-bottom:1px solid var(--dsw-alias-border-l2,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f3f4f6);width:100%;color:var(--dsw-alias-label-secondary,#6b7280);cursor:zoom-in;border-radius:0;padding:0;display:block;position:relative;overflow:hidden}.eGUBIq_themeCover img{object-fit:contain;background:var(--dsw-alias-bg-layer-2,#f3f4f6);width:100%;height:100%;transition:transform .18s cubic-bezier(.16,1,.3,1);display:block}.eGUBIq_themeCover:hover img{transform:scale(1.012)}.eGUBIq_themeCover:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,#4f6ef7);outline-offset:-3px}.eGUBIq_themeCoverEmpty{cursor:default;color:var(--dsw-alias-label-tertiary,#8b93a1);flex-direction:column;justify-content:center;align-items:center;gap:8px;font-size:12px;line-height:18px;display:flex}.eGUBIq_themePreviewAction,.eGUBIq_themePreviewCount{color:#fff;-webkit-backdrop-filter:blur(8px);background:#14181fc7;border:1px solid #ffffff57;border-radius:4px;align-items:center;height:24px;padding:0 8px;font-size:11px;line-height:16px;display:inline-flex;position:absolute;bottom:8px}.eGUBIq_themePreviewAction{gap:4px;right:8px}.eGUBIq_themePreviewCount{left:8px}.eGUBIq_themeCardBody{flex-direction:column;flex:1;gap:8px;padding:12px;display:flex}.eGUBIq_themeCardHead{align-items:flex-start;gap:8px;min-width:0;display:flex}.eGUBIq_themeIdentity{flex:1;min-width:0}.eGUBIq_themeStatus,.eGUBIq_themeStatusMuted{white-space:nowrap;border-radius:4px;flex:none;align-items:center;min-height:22px;padding:0 8px;font-size:11px;font-weight:600;display:inline-flex}.eGUBIq_themeStatus{background:var(--dsw-alias-state-success-tertiary,#16a34a1a);color:var(--dsw-alias-state-success-primary,#15803d)}.eGUBIq_themeStatusMuted{background:var(--dsw-alias-bg-layer-2,#f3f4f6);color:var(--dsw-alias-label-secondary,#6b7280)}.eGUBIq_themeDescription{min-height:36px;color:var(--dsw-alias-label-tertiary,#8b93a1);-webkit-line-clamp:2;-webkit-box-orient:vertical;margin:0;font-size:12px;line-height:18px;display:-webkit-box;overflow:hidden}.eGUBIq_themeCardFooter{justify-content:space-between;align-items:center;gap:8px;margin-top:auto;padding-top:4px;display:flex}.eGUBIq_themeLifecycle{min-width:0;color:var(--dsw-alias-label-tertiary,#8b93a1);text-overflow:ellipsis;white-space:nowrap;font-size:11px;line-height:18px;overflow:hidden}.eGUBIq_themeActions{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:8px;margin-left:auto;display:flex}@container (width<=900px){.eGUBIq_themeGallery{grid-template-columns:repeat(3,minmax(0,1fr))}}@container (width<=680px){.eGUBIq_themeGallery{grid-template-columns:repeat(2,minmax(0,1fr))}}@container (width<=460px){.eGUBIq_themeGallery{grid-template-columns:minmax(0,1fr)}}@container (width<=420px){.eGUBIq_sub{grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:2px 8px;display:grid}.eGUBIq_sub>span:first-child{grid-area:1/1}.eGUBIq_sub>.eGUBIq_grow{display:none}.eGUBIq_submitLink{grid-area:2/1}.eGUBIq_exportLogBtn{flex-shrink:0;grid-area:1/2/span 2}.eGUBIq_themeToolbar{grid-template-columns:minmax(0,1fr)}.eGUBIq_themeCardHead{flex-wrap:wrap}.eGUBIq_themeStatus,.eGUBIq_themeStatusMuted{order:3}}@container (width<=280px){.eGUBIq_themeCardFooter{flex-direction:column;align-items:flex-start}.eGUBIq_themeActions{justify-content:flex-start;width:100%;margin-left:0}}@media (max-width:560px){[role=dialog]:has([data-dsh-market-root])>nav{display:none}[role=dialog]:has([data-dsh-market-root])>div{flex:100%;width:100%;min-width:0}}[role=dialog]:has([data-dsh-market-fullscreen=true]){border-radius:0;width:100vw;max-width:none;height:100vh;max-height:none;position:fixed;top:0;bottom:0;left:0;right:0}@media (prefers-reduced-motion:reduce){.eGUBIq_themeCard,.eGUBIq_themeCover img{transition:none}.eGUBIq_themeCard:hover{transform:none}}.eGUBIq_card{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;flex-direction:column;align-self:start;gap:12px;padding:12px 14px;display:flex}.eGUBIq_row1{align-items:flex-start;gap:10px;min-width:0;display:flex}.eGUBIq_cardAction{flex-shrink:0;align-items:center;display:inline-flex}.eGUBIq_installBtn.eGUBIq_installBtn{min-width:64px}.eGUBIq_av{color:#fff;object-fit:cover;background:var(--dsw-alias-bg-layer-2,#f3f4f6);border-radius:50%;flex-shrink:0;place-items:center;width:16px;height:16px;font-size:9px;font-weight:700;display:grid}.eGUBIq_nm{text-overflow:ellipsis;white-space:nowrap;font-size:15px;font-weight:600;line-height:22px;overflow:hidden}.eGUBIq_nmLink{color:inherit;text-decoration:none;display:block}.eGUBIq_nmLink:hover{color:var(--dsw-alias-brand-primary,#4f6ef7);text-decoration:underline}.eGUBIq_repoMark{color:var(--dsw-alias-label-tertiary,#8b93a1);vertical-align:-1px;flex-shrink:0;margin-left:5px}.eGUBIq_nmLink:hover .eGUBIq_repoMark{color:var(--dsw-alias-brand-primary,#4f6ef7)}.eGUBIq_byline{flex-wrap:wrap;align-items:center;gap:6px;min-width:0;margin-top:2px;display:flex}.eGUBIq_meta{color:var(--dsw-alias-label-secondary,#9ca3af);margin-top:2px;font-size:11px}.eGUBIq_metaInline{color:var(--dsw-alias-label-secondary,#9ca3af);font-size:11px}.eGUBIq_owner{color:var(--dsw-alias-label-secondary,#9ca3af);text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:44px;font-size:11px;overflow:hidden}.eGUBIq_desc{color:var(--dsw-alias-label-tertiary,#8b93a1);margin:0;font-size:12px;line-height:18px}.eGUBIq_descClamp{-webkit-line-clamp:5;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.eGUBIq_descToggle{width:20px;height:16px;color:var(--dsw-alias-label-tertiary,#8b93a1);cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;margin-top:2px;padding:0;display:flex}.eGUBIq_descToggle:hover{color:var(--dsw-alias-brand-primary,#4f6ef7)}.eGUBIq_foot{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.eGUBIq_foot .eGUBIq_metaInline,.eGUBIq_foot .eGUBIq_src{white-space:nowrap}.eGUBIq_grow{flex:1}.eGUBIq_titleRow{align-items:center;gap:10px;display:flex}.eGUBIq_version{color:var(--dsw-alias-label-tertiary,#8b93a1);font-variant-numeric:tabular-nums;flex-shrink:0;font-size:12px;line-height:20px}.eGUBIq_repoLink{color:var(--dsw-alias-label-tertiary,#8b93a1);flex-shrink:0;font-size:12px;line-height:20px;text-decoration:none}.eGUBIq_repoLink:hover{color:var(--dsw-alias-brand-primary,#4f6ef7)}.eGUBIq_descTight{min-height:0}.eGUBIq_src{color:var(--dsw-alias-label-secondary,#9ca3af);font-size:11px;text-decoration:none}.eGUBIq_src:hover{color:var(--dsw-alias-brand-primary,#4f6ef7)}.eGUBIq_dot{vertical-align:2px;margin-left:5px}.eGUBIq_act{flex-wrap:wrap;align-items:center;gap:6px;margin-top:6px;font-size:11px;display:flex}.eGUBIq_actLive{color:var(--dsw-alias-state-success-primary,#16a34a);align-items:center;gap:4px;font-weight:600;display:inline-flex}.eGUBIq_actWarn{color:var(--dsw-alias-state-warn-primary,#b45309);align-items:center;gap:4px;font-weight:600;display:inline-flex}.eGUBIq_actBroken{color:var(--dsw-alias-state-error-primary,#dc2626);align-items:center;gap:4px;font-weight:600;display:inline-flex}.eGUBIq_actWhy{color:var(--dsw-alias-label-secondary,#6b7280);margin-top:2px}.eGUBIq_loading{color:var(--dsw-alias-label-secondary,#9ca3af);flex-direction:column;align-items:center;gap:12px;padding:48px;font-size:13px;display:flex}.eGUBIq_spin{color:var(--dsw-alias-brand-primary,#4f6ef7);flex-shrink:0;animation:.8s linear infinite eGUBIq_sp;display:inline-flex}.eGUBIq_logoMark{color:var(--dsw-alias-brand-primary,#4f6ef7);flex-shrink:0;display:inline-flex}.eGUBIq_logoPlug{transform-box:fill-box;transform-origin:50%;animation:1.5s cubic-bezier(.4,0,.2,1) infinite eGUBIq_dshmPlug}@keyframes eGUBIq_dshmPlug{0%,12%{transform:rotate(9deg)}45%,62%{transform:translate(-1.28px,1.27px)rotate(0)}95%,to{transform:rotate(9deg)}}@media (prefers-reduced-motion:reduce){.eGUBIq_logoPlug,.eGUBIq_spin{animation:1.5s ease-in-out infinite eGUBIq_dshmPlugFade}}@keyframes eGUBIq_dshmPlugFade{0%,to{opacity:1}50%{opacity:.35}}@keyframes eGUBIq_sp{to{transform:rotate(360deg)}}.eGUBIq_progress{background:var(--dsw-alias-bg-layer-2,#f3f4f6);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);color:var(--dsw-alias-label-secondary,#6b7280);border-radius:8px;flex-wrap:wrap;align-items:center;gap:9px;margin:0;padding:8px 12px;font-size:12px;display:flex}.eGUBIq_bar{background:var(--dsw-alias-border-l1,#e5e7eb);border-radius:99px;width:100%;height:4px;overflow:hidden}.eGUBIq_barFill{background:var(--dsw-alias-brand-primary,#4f6ef7);border-radius:99px;height:100%;transition:width .6s}.eGUBIq_barWave{width:30%;animation:1.2s ease-in-out infinite eGUBIq_dshmSlide}@keyframes eGUBIq_dshmSlide{0%{margin-left:-30%}to{margin-left:100%}}.eGUBIq_irow .eGUBIq_progress{margin-top:8px}.eGUBIq_progress code{text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,Menlo,monospace;font-size:11px;overflow:hidden}.eGUBIq_empty{color:var(--dsw-alias-label-secondary,#9ca3af);text-align:center;padding:32px;font-size:13px}.eGUBIq_err{color:var(--dsw-alias-state-error-primary,#dc2626);white-space:pre-wrap;word-break:break-all;margin:8px 0;font-size:12px}.eGUBIq_cardBlocked{border-color:var(--dsw-alias-state-error-primary,#dc2626)}.eGUBIq_conflictHead{align-items:flex-start;gap:8px;display:flex}.eGUBIq_conflictIcon{color:var(--dsw-alias-state-error-primary,#dc2626);flex-shrink:0;margin-top:1px}.eGUBIq_conflictTitle{color:var(--dsw-alias-state-error-primary,#dc2626);font-size:13px;font-weight:600;line-height:18px}.eGUBIq_conflictBody{margin:0;font-size:12px;line-height:19px}.eGUBIq_roster{background:var(--dsw-alias-border-l2,#e5e7eb);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:8px;flex-direction:column;gap:1px;display:flex;overflow:hidden}.eGUBIq_rosterRow{background:var(--dsw-alias-bg-layer-1,#fff);align-items:center;gap:8px;padding:7px 10px;display:flex}.eGUBIq_rosterMain{flex-direction:column;min-width:0;display:flex}.eGUBIq_rosterName{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:12px;font-weight:600;overflow:hidden}.eGUBIq_rosterAuthor{color:var(--dsw-alias-label-secondary,#9ca3af);text-overflow:ellipsis;white-space:nowrap;font-size:10.5px;overflow:hidden}.eGUBIq_rosterTag{border-radius:4px;flex-shrink:0;margin-left:auto;padding:1px 6px;font-size:10.5px;font-weight:600}.eGUBIq_rosterTagKeep{color:var(--dsw-alias-state-success-primary,#16a34a);background:#16a34a1f}.eGUBIq_rosterTagDrop{color:var(--dsw-alias-state-error-primary,#dc2626);background:#dc26261f}.eGUBIq_rosterRowOut .eGUBIq_rosterName{text-decoration:line-through}.eGUBIq_rosterRowOut{opacity:.62}.eGUBIq_rosterSplit{background:var(--dsw-alias-border-l2,#e5e7eb);height:1px}.eGUBIq_reassure{color:var(--dsw-alias-label-secondary,#6b7280);align-items:center;gap:5px;margin:0;font-size:11.5px;line-height:17px;display:flex}.eGUBIq_reassureOk{color:var(--dsw-alias-state-success-primary,#16a34a);flex-shrink:0}.eGUBIq_conflictWhy{color:var(--dsw-alias-label-tertiary,#8b93a1);overflow-wrap:anywhere;margin-top:2px;font-family:ui-monospace,Menlo,monospace;font-size:11px;line-height:17px}.eGUBIq_conflictWhyText{margin-top:5px;font-family:-apple-system,BlinkMacSystemFont,PingFang SC,sans-serif}.eGUBIq_choices{flex-direction:column;gap:7px;display:flex}.eGUBIq_choice{text-align:left;font:inherit;cursor:pointer;background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l3,#d9dde3);border-radius:9px;align-items:flex-start;gap:9px;padding:9px 11px;display:flex}.eGUBIq_choice:has(input:disabled){cursor:default;opacity:.6}.eGUBIq_choiceOn{border-color:var(--dsw-alias-brand-primary,#4f6ef7);background:var(--dsw-alias-bg-layer-2,#f5f7ff)}.eGUBIq_choiceRadio{width:13px;height:13px;accent-color:var(--dsw-alias-brand-primary,#4f6ef7);flex-shrink:0;margin:2px 0 0}.eGUBIq_choiceMain{flex-direction:column;gap:3px;min-width:0;display:flex}.eGUBIq_choiceTitle{font-size:12px;font-weight:600;line-height:17px}.eGUBIq_choiceNote{color:var(--dsw-alias-label-tertiary,#8b93a1);font-size:11px;line-height:16px}.eGUBIq_choiceSafe{color:var(--dsw-alias-state-success-primary,#16a34a)}.eGUBIq_stateTag{white-space:nowrap;background:var(--dsw-alias-bg-layer-2,#f3f4f6);min-height:20px;color:var(--dsw-alias-label-secondary,#6b7280);border-radius:5px;flex-shrink:0;align-items:center;gap:5px;padding:1px 7px;font-size:11px;line-height:16px;display:inline-flex}.eGUBIq_stateTag[data-on=true]{color:var(--dsw-alias-state-success-primary,#16a34a);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#16a34a) 10%, transparent)}.eGUBIq_stateDot{background:var(--dsw-alias-label-tertiary,#8b93a1);border-radius:999px;flex:none;width:6px;height:6px}.eGUBIq_stateDot[data-on=true]{background:var(--dsw-alias-state-success-primary,#16a34a)}.eGUBIq_metaTag{text-overflow:ellipsis;white-space:nowrap;background:var(--dsw-alias-bg-layer-2,#f3f4f6);min-width:0;max-width:100%;min-height:20px;color:var(--dsw-alias-label-tertiary,#8b93a1);border-radius:5px;flex-shrink:1;padding:1px 7px;font-size:11px;line-height:18px;display:inline-block;overflow:hidden}.eGUBIq_metaTagOk{color:var(--dsw-alias-state-success-primary,#16a34a);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#16a34a) 10%, transparent)}.eGUBIq_nameLink{color:inherit;text-decoration:none}.eGUBIq_irowName{text-overflow:clip;align-items:baseline;gap:6px;min-width:0;display:flex;overflow:visible}.eGUBIq_irowNameText{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.eGUBIq_irowName>.eGUBIq_owner{flex:none}.eGUBIq_nameLink:hover{color:var(--dsw-alias-brand-primary,#4f6ef7);text-decoration:underline}.eGUBIq_opWrap{flex-shrink:0;display:inline-flex;position:relative}.eGUBIq_opEntry{font:inherit;cursor:pointer;white-space:nowrap;color:var(--dsw-alias-label-primary,#1f2328);background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l3,#d9dde3);border-radius:7px;align-items:center;gap:6px;padding:4px 10px;font-size:12px;display:inline-flex;position:relative}.eGUBIq_opEntryQuiet{color:var(--dsw-alias-label-secondary,#6b7280);background:0 0;border-color:#0000}.eGUBIq_opEntryAlert{border-color:var(--dsw-alias-state-error-primary,#dc2626);color:var(--dsw-alias-state-error-primary,#dc2626)}.eGUBIq_opDot{background:var(--dsw-alias-state-error-primary,#dc2626);border-radius:99px;width:8px;height:8px;position:absolute;top:-3px;right:-3px}.eGUBIq_opPanel{z-index:40;background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l3,#d9dde3);border-radius:12px;width:460px;max-width:86vw;max-height:70vh;position:absolute;top:calc(100% + 6px);right:0;overflow-y:auto;box-shadow:0 20px 52px #00000047}.eGUBIq_opHead{border-bottom:1px solid var(--dsw-alias-border-l2,#e5e7eb);align-items:center;gap:8px;padding:9px 14px;display:flex}.eGUBIq_opPanelTitle{font-size:12.5px;font-weight:600}.eGUBIq_opCloseBtn.eGUBIq_opCloseBtn{min-width:0;color:var(--dsw-alias-label-secondary,#6b7280);padding:0 6px}.eGUBIq_opAggregate{border-bottom:1px solid var(--dsw-alias-border-l2,#e5e7eb);background:var(--dsw-alias-bg-layer-2,#f7f8fa);padding:9px 14px}.eGUBIq_opAggregateTop{font-variant-numeric:tabular-nums;font-size:12px;font-weight:600}.eGUBIq_opAggregateHint{color:var(--dsw-alias-label-tertiary,#8b93a1);margin-top:4px;font-size:10.5px}.eGUBIq_opRow{border-bottom:1px solid var(--dsw-alias-border-l2,#e5e7eb);align-items:flex-start;gap:9px;padding:9px 14px;display:flex}.eGUBIq_opRow:last-child{border-bottom:none}.eGUBIq_opRowAlert{background:#dc26260f}.eGUBIq_opIcon{flex-shrink:0;place-items:center;width:14px;margin-top:1px;display:grid}.eGUBIq_opQueuedIcon{color:var(--dsw-alias-label-tertiary,#8b93a1);font-size:12px}.eGUBIq_opMain{flex-direction:column;flex:1;gap:3px;min-width:0;display:flex}.eGUBIq_opTop{align-items:baseline;gap:6px;min-width:0;display:flex}.eGUBIq_opVerb{color:var(--dsw-alias-label-secondary,#6b7280);flex-shrink:0;font-size:12px}.eGUBIq_opName{text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:600;overflow:hidden}.eGUBIq_opStatus{color:var(--dsw-alias-label-tertiary,#8b93a1);overflow-wrap:anywhere;font-size:10.5px;line-height:16px}.eGUBIq_opStatusBad{color:var(--dsw-alias-state-error-primary,#dc2626)}.eGUBIq_opActions{flex-shrink:0;align-items:center;gap:6px;margin-top:1px;display:flex}.eGUBIq_opDecision{border-top:1px dashed var(--dsw-alias-border-l2,#e5e7eb);flex-direction:column;gap:8px;margin-top:8px;padding-top:8px;display:flex}.eGUBIq_opDecisionFoot{align-items:center;gap:8px;display:flex}.eGUBIq_conflictDetailsToggle{font:inherit;cursor:pointer;color:var(--dsw-alias-label-tertiary,#8b93a1);background:0 0;border:none;align-items:center;gap:4px;padding:2px 0;font-size:11px;display:inline-flex}.eGUBIq_conflictDetailsToggle:hover{color:var(--dsw-alias-label-secondary,#6b7280)}.eGUBIq_opEmpty{text-align:center;color:var(--dsw-alias-label-secondary,#6b7280);padding:30px 14px;font-size:12px}.eGUBIq_opEmptyHint{color:var(--dsw-alias-label-tertiary,#8b93a1);margin-top:4px;font-size:11px}.eGUBIq_cardBlockedMark{font:inherit;cursor:pointer;color:var(--dsw-alias-state-error-primary,#dc2626);border:1px solid var(--dsw-alias-state-error-primary,#dc2626);background:#dc262614;border-radius:7px;align-items:center;gap:5px;padding:4px 9px;font-size:11px;display:inline-flex}.eGUBIq_dangerBtn.eGUBIq_dangerBtn{color:var(--dsw-alias-state-error-primary,#dc2626);border-color:var(--dsw-alias-state-error-primary,#dc2626)}.eGUBIq_dangerBtn.eGUBIq_dangerBtn:hover:not(:disabled){background:var(--dsw-alias-state-error-primary,#dc2626);color:#fff}.eGUBIq_dangerArmed.eGUBIq_dangerArmed{background:var(--dsw-alias-state-error-primary,#dc2626);border-color:var(--dsw-alias-state-error-primary,#dc2626);color:#fff}.eGUBIq_retryBtn{margin-top:4px}.eGUBIq_irow{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:10px;flex-direction:column;gap:10px;min-width:0;padding:12px 14px;display:flex}.eGUBIq_irowActions{flex-wrap:wrap;justify-content:flex-start;align-items:center;gap:8px;min-width:0;display:flex}.eGUBIq_irowTrailing{flex-wrap:nowrap;align-items:center;gap:8px;min-width:0;display:inline-flex}.eGUBIq_irowMissing{filter:grayscale();opacity:.5}.eGUBIq_irow>.eGUBIq_src,.eGUBIq_irow>.eGUBIq_owner,.eGUBIq_irow button{white-space:nowrap;flex-shrink:0}.eGUBIq_tabSearchRow{padding:0 4px 6px;display:flex}.eGUBIq_tabSearch{width:100%}.eGUBIq_spec{color:var(--dsw-alias-label-secondary,#9ca3af);overflow-wrap:anywhere;min-width:0;font-family:ui-monospace,Menlo,monospace;font-size:11px}.eGUBIq_specTag{white-space:nowrap;border-radius:4px;flex-shrink:0;align-items:center;height:16px;padding:0 5px;font-size:10px;font-weight:600;display:inline-flex}.eGUBIq_specTagGit{color:#0b7285;background:#12a3c41f}.eGUBIq_specTagFile{color:#b07d1b;background:#f0b42924}.eGUBIq_backupCheckList .eGUBIq_grow{white-space:nowrap;text-overflow:ellipsis;flex:70%;min-width:0;overflow:hidden}.eGUBIq_backupCheckList .eGUBIq_spec{text-align:right;white-space:nowrap;text-overflow:ellipsis;flex:0 30%;max-width:30%;overflow:hidden}.eGUBIq_staleAction{margin-top:8px}.eGUBIq_pct{color:var(--dsw-alias-label-secondary,#6b7280);flex-shrink:0;font-size:11px;font-weight:600}.eGUBIq_pager{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;margin:16px 0 4px;display:flex}.eGUBIq_pagerPages{flex-wrap:wrap;flex:1;justify-content:center;align-items:center;gap:6px;min-width:0;display:flex}.eGUBIq_pageEllipsis{color:var(--dsw-alias-label-secondary,#9ca3af);padding:0 2px;font-size:12px}.eGUBIq_pageInfo{color:var(--dsw-alias-label-secondary,#6b7280);white-space:nowrap;font-size:12px}.eGUBIq_depBadge{border:1px solid var(--dsw-alias-state-warn-primary,#b45309);color:var(--dsw-alias-state-warn-primary,#b45309);white-space:nowrap;border-radius:4px;flex-shrink:0;margin-left:6px;padding:1px 6px;font-size:11px;font-weight:600;line-height:16px}.eGUBIq_deprecate{color:var(--dsw-alias-state-warn-primary,#b45309);background:var(--dsw-alias-bg-layer-2,#fdf3e3);border:1px solid var(--dsw-alias-border-l2,#f3e3c3);border-radius:8px;margin:0;padding:8px 10px;font-size:12px;line-height:18px}.eGUBIq_deprecate a{color:var(--dsw-alias-state-warn-primary,#b45309);text-decoration:underline}.eGUBIq_deprecate .eGUBIq_src{margin-left:8px}.eGUBIq_depLine{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.eGUBIq_switch{border:1px solid var(--dsw-alias-border-l2,#d9dde3);background:var(--dsw-alias-bg-layer-2,#e5e7eb);cursor:pointer;border-radius:99px;flex-shrink:0;width:38px;height:22px;padding:0;transition:background .15s,border-color .15s;position:relative}.eGUBIq_switchOn{background:var(--dsw-alias-state-success-primary,#16a34a);border-color:var(--dsw-alias-state-success-primary,#16a34a)}.eGUBIq_switchMixed{background:var(--dsw-alias-state-warn-primary,#b45309);border-color:var(--dsw-alias-state-warn-primary,#b45309)}.eGUBIq_switchKnob{background:#fff;border-radius:99px;width:16px;height:16px;transition:left .15s;position:absolute;top:2px;left:2px;box-shadow:0 1px 2px #00000040}.eGUBIq_switchOn .eGUBIq_switchKnob,.eGUBIq_switchMixed .eGUBIq_switchKnob{left:18px}.eGUBIq_switch:disabled{opacity:.5;cursor:default}.eGUBIq_viewBar{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:8px;align-items:center;gap:2px;width:fit-content;margin-bottom:12px;padding:2px;display:flex}.eGUBIq_viewBtn{font:inherit;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-radius:6px;padding:4px 10px;font-size:12px;line-height:18px}.eGUBIq_viewBtn:hover{color:var(--dsw-alias-brand-primary,#4f6ef7)}.eGUBIq_viewOn{background:var(--dsw-alias-bg-layer-2,#eef0f4);color:var(--dsw-alias-label-primary,#1f2328);font-weight:600}.eGUBIq_groupRow{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;margin-bottom:10px;padding:12px 14px}.eGUBIq_groupHead{align-items:center;gap:10px;min-width:0;display:flex}.eGUBIq_groupName{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;line-height:20px;overflow:hidden}.eGUBIq_groupActions{flex-shrink:0;align-items:center;gap:6px;display:flex}.eGUBIq_groupMembers{flex-direction:column;gap:6px;margin-top:10px;display:flex}.eGUBIq_groupMember{background:var(--dsw-alias-bg-layer-2,#f7f8fa);border-radius:8px;align-items:center;gap:8px;padding:6px 8px;font-size:12px;line-height:18px;display:flex}.eGUBIq_groupMember .eGUBIq_nm{flex:1;min-width:0;font-size:12px}.eGUBIq_groupAddPanel{border-top:1px dashed var(--dsw-alias-border-l2,#e5e7eb);flex-direction:column;gap:6px;margin-top:10px;padding-top:10px;display:flex}.eGUBIq_groupCreate{align-items:center;gap:8px;margin-bottom:10px;display:flex}.eGUBIq_inlineInput{flex:1;min-width:120px}.eGUBIq_assignRow{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.eGUBIq_assignSelect{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);color:var(--dsw-alias-label-primary,#1f2328);font:inherit;border-radius:6px;padding:3px 6px;font-size:12px;line-height:18px}.eGUBIq_groupHint{color:var(--dsw-alias-label-tertiary,#8b93a1);font-size:11px}.eGUBIq_sectAction{color:var(--dsw-alias-label-secondary,#6b7280);align-items:center;gap:8px;margin:14px 2px 8px;font-size:12px;font-weight:600;display:flex}.eGUBIq_backupGrid{grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:12px;display:grid}.eGUBIq_backupCard{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;flex-direction:column;gap:10px;padding:16px;display:flex}.eGUBIq_backupCard h3{margin:0;font-size:14px}.eGUBIq_backupCard p{color:var(--dsw-alias-label-secondary,#6b7280);margin:0;font-size:12px;line-height:18px}.eGUBIq_backupActions{flex-wrap:wrap;gap:8px;display:flex;position:relative}.eGUBIq_hiddenFile{opacity:0;pointer-events:none;width:1px;height:1px;position:absolute}.eGUBIq_backupInput{box-sizing:border-box;width:100%}.eGUBIq_backupCheck{cursor:pointer;align-items:center;gap:6px;font-size:12px;display:flex}.eGUBIq_backupWarn{margin:0;font-size:12px;line-height:18px;color:var(--dsw-alias-state-warn-primary,#b45309)!important}.eGUBIq_backupMessage{color:var(--dsw-alias-label-secondary,#6b7280);grid-column:1/-1;font-size:12px}.eGUBIq_backupCheckList{flex-direction:column;gap:6px;max-height:260px;margin:10px 0 4px;padding-right:4px;display:flex;overflow-y:auto}.eGUBIq_backupCheckList .eGUBIq_backupCheck{justify-content:space-between;gap:8px}.eGUBIq_diagPage{flex-direction:column;gap:12px;height:100%;min-height:0;display:flex;overflow-y:auto}.eGUBIq_diagSummary{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;flex-wrap:wrap;align-items:center;gap:12px;padding:10px 14px;font-size:12px;display:flex}.eGUBIq_diagSummaryItem{color:var(--dsw-alias-label-secondary,#6b7280);white-space:nowrap;align-items:center;gap:6px;display:inline-flex}.eGUBIq_diagSummaryMeta{color:var(--dsw-alias-label-tertiary,#9ca3af);text-overflow:ellipsis;white-space:nowrap;max-width:320px;font-family:ui-monospace,Menlo,monospace;font-size:11px;overflow:hidden}.eGUBIq_diagSection{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;flex-direction:column;gap:8px;padding:12px 14px;display:flex}.eGUBIq_diagSection h3{color:var(--dsw-alias-label-primary,#1f2328);margin:0;font-size:13px;font-weight:600}.eGUBIq_diagCount{color:var(--dsw-alias-label-tertiary,#9ca3af);font-size:11px;font-weight:400}.eGUBIq_diagEmpty{color:var(--dsw-alias-label-secondary,#9ca3af);padding:8px 0;font-size:12px}.eGUBIq_diagBundle{border-top:1px solid var(--dsw-alias-border-l2,#f0f1f3);flex-direction:column;gap:6px;padding-top:8px;display:flex}.eGUBIq_diagBundle:first-of-type{border-top:none;padding-top:0}.eGUBIq_diagRow{flex-wrap:wrap;align-items:center;gap:8px;min-width:0;font-size:12px;line-height:18px;display:flex}.eGUBIq_diagMeta{align-items:baseline;gap:8px;min-width:0;font-size:12px;display:flex}.eGUBIq_diagKey{color:var(--dsw-alias-label-tertiary,#9ca3af);flex-shrink:0;min-width:64px;font-size:11px}.eGUBIq_diagVal{color:var(--dsw-alias-label-primary,#1f2328);overflow-wrap:anywhere;min-width:0;font-family:ui-monospace,Menlo,monospace;font-size:12px;font-weight:500}.eGUBIq_diagIndex{background:var(--dsw-alias-bg-layer-2,#f3f4f6);min-width:18px;height:18px;color:var(--dsw-alias-label-secondary,#6b7280);border-radius:9px;flex-shrink:0;justify-content:center;align-items:center;font-size:11px;font-weight:600;display:inline-flex}.eGUBIq_diagArrow{color:var(--dsw-alias-label-tertiary,#9ca3af);flex-shrink:0;font-size:12px}.eGUBIq_diagBadgeOfficial{background:var(--dsw-alias-brand-primary,#4f6ef7);color:#fff;border-radius:9px;flex-shrink:0;align-items:center;height:18px;padding:0 8px;font-size:11px;font-weight:600;display:inline-flex}.eGUBIq_diagBadgeCommunity{background:var(--dsw-alias-bg-layer-2,#f3f4f6);height:18px;color:var(--dsw-alias-label-secondary,#6b7280);border-radius:9px;flex-shrink:0;align-items:center;padding:0 8px;font-size:11px;display:inline-flex}.eGUBIq_diagBadgeShadow{background:var(--dsw-alias-state-error-primary,#dc2626);color:#fff;border-radius:9px;flex-shrink:0;align-items:center;height:18px;padding:0 8px;font-size:11px;font-weight:600;display:inline-flex}.eGUBIq_diagBadgeWarn{background:var(--dsw-alias-state-warn-primary,#b45309);color:#fff;white-space:nowrap;border-radius:9px;flex-shrink:0;align-items:center;height:18px;padding:0 8px;font-size:11px;font-weight:600;display:inline-flex}.eGUBIq_diagBadgeInfo{background:var(--dsw-alias-bg-layer-2,#f3f4f6);height:18px;color:var(--dsw-alias-label-secondary,#6b7280);white-space:nowrap;border-radius:9px;flex-shrink:0;align-items:center;padding:0 8px;font-size:11px;display:inline-flex}.eGUBIq_diagList{flex-direction:column;gap:6px;display:flex}.eGUBIq_sectionOverview{color:var(--dsw-alias-label-tertiary,#8b93a1);text-overflow:ellipsis;white-space:nowrap;max-width:100%;padding:2px 0 6px;font-size:12px;line-height:18px;overflow:hidden}.eGUBIq_diagAlert{color:var(--dsw-alias-state-warn-primary,#b45309)}.eGUBIq_ovRow{background:var(--dsw-alias-bg-layer-2,#f7f8fa);border-radius:8px;flex-wrap:wrap;align-items:center;gap:8px;min-width:0;padding:6px 10px;font-size:12px;line-height:18px;display:flex}.eGUBIq_ovArrow{color:var(--dsw-alias-label-tertiary,#9ca3af);flex-shrink:0;font-size:12px}.eGUBIq_ovByTag{background:var(--dsw-alias-brand-primary,#4f6ef7);color:#fff;text-overflow:ellipsis;white-space:nowrap;border-radius:9px;flex-shrink:0;align-items:center;max-width:260px;height:18px;padding:0 8px;font-size:11px;font-weight:600;display:inline-flex;overflow:hidden}.eGUBIq_ovFrom{color:var(--dsw-alias-label-secondary,#6b7280);text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:12px;overflow:hidden}.eGUBIq_orphRow{background:var(--dsw-alias-bg-layer-2,#f7f8fa);border-radius:8px;flex-wrap:wrap;align-items:center;gap:8px;min-width:0;padding:6px 10px;font-size:12px;line-height:18px;display:flex}.eGUBIq_orphBadge{background:var(--dsw-alias-state-warn-primary,#b45309);color:#fff;white-space:nowrap;border-radius:9px;flex-shrink:0;align-items:center;height:18px;padding:0 8px;font-size:11px;font-weight:600;display:inline-flex}.eGUBIq_dragHandle{width:20px;height:20px;color:var(--dsw-alias-label-tertiary,#9ca3af);cursor:grab;-webkit-user-select:none;user-select:none;flex-shrink:0;justify-content:center;align-items:center;font-size:12px;line-height:20px;display:inline-flex}.eGUBIq_dragOver{outline:2px dashed var(--dsw-alias-brand-primary,#4f6ef7);outline-offset:2px;background:var(--dsw-alias-bg-layer-2,#f0f2f8);border-radius:8px}.eGUBIq_dragging{opacity:.45;background:var(--dsw-alias-bg-layer-2,#f3f4f6)}.eGUBIq_collapseHead{font:inherit;color:var(--dsw-alias-label-primary,#1f2328);cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;gap:8px;width:100%;padding:0;font-size:13px;font-weight:600;display:flex}.eGUBIq_collapseIcon{color:var(--dsw-alias-label-secondary,#6b7280);flex-shrink:0;display:inline-flex}.eGUBIq_collapseTitle{flex:1;min-width:0}.eGUBIq_collapseBody{border-top:1px solid var(--dsw-alias-border-l2,#f0f1f3);overflow-wrap:anywhere;flex-direction:column;gap:10px;min-width:0;margin-top:8px;padding-top:10px;display:flex}.eGUBIq_orderPanel{flex-direction:column;gap:10px;min-width:0;display:flex}.eGUBIq_panelNote{color:var(--dsw-alias-label-secondary,#6b7280);margin:0;font-size:12px;line-height:18px}.eGUBIq_panelActions{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.eGUBIq_presetList{flex-direction:column;gap:6px;min-width:0;display:flex}.eGUBIq_presetRow{background:var(--dsw-alias-bg-layer-2,#f7f8fa);border-radius:8px;flex-direction:column;align-items:stretch;gap:6px;min-width:0;max-width:100%;padding:8px 10px;font-size:12px;line-height:18px;display:flex}.eGUBIq_presetName{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:13px;font-weight:600;overflow:hidden}.eGUBIq_snapList{flex-direction:column;gap:6px;min-width:0;display:flex}.eGUBIq_snapRow{background:var(--dsw-alias-bg-layer-2,#f7f8fa);border-radius:8px;flex-direction:column;align-items:stretch;gap:8px;padding:10px 12px;font-size:12px;line-height:18px;display:flex}.eGUBIq_snapMeta{flex-wrap:wrap;align-items:center;gap:8px;min-width:0;display:flex}.eGUBIq_snapConfirmText{color:var(--dsw-alias-state-warn-primary,#b45309);margin:0;font-size:12px;line-height:18px}.eGUBIq_confirmRow{flex-wrap:wrap;align-items:center;gap:6px;display:inline-flex}.eGUBIq_fixFallback{flex-direction:column;gap:6px;margin:8px 0;display:flex}.eGUBIq_fixFallbackText{box-sizing:border-box;width:100%;color:var(--dsw-alias-label-primary,#1f2328);background:var(--dsw-alias-bg-layer-2,#f3f4f6);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);resize:vertical;white-space:pre-wrap;word-break:break-all;border-radius:6px;padding:8px 10px;font-family:ui-monospace,Menlo,monospace;font-size:11px;line-height:16px}.eGUBIq_setCard{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);background:var(--dsw-alias-bg-layer-3,#fff);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.eGUBIq_setCard:hover{border-color:var(--dsw-alias-label-dimmed,#c8ccd4)}.eGUBIq_setCardOpen{background:var(--dsw-alias-bg-layer-2,#f7f8fa);border-color:var(--dsw-alias-label-dimmed,#c8ccd4)}.eGUBIq_setHeader{-webkit-appearance:none;appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.eGUBIq_setHeader:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#4f6ef7);outline-offset:-2px}.eGUBIq_setHeadText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.eGUBIq_setName{color:var(--dsw-alias-label-primary,#1f2328);font-size:15px;font-weight:600;line-height:1.4}.eGUBIq_setDesc{color:var(--dsw-alias-label-tertiary,#8b93a1);font-size:13px;line-height:1.5}.eGUBIq_setChevron{color:var(--dsw-alias-label-tertiary,#8b93a1);flex:none;transition:transform .16s;display:inline-flex}.eGUBIq_setChevronOpen{transform:rotate(180deg)}.eGUBIq_setBody{border-top:1px solid var(--dsw-alias-border-l2,#e5e7eb);margin:0 16px;padding-bottom:8px}.eGUBIq_setRow{align-items:center;gap:12px;padding:12px 0;display:flex}.eGUBIq_setRow+.eGUBIq_setRow{border-top:1px solid var(--dsw-alias-border-l2,#e5e7eb)}.eGUBIq_setLabelBox{flex-direction:column;flex:1;gap:3px;min-width:0;display:flex}.eGUBIq_setLabel{font-size:13px;line-height:20px}.eGUBIq_setHint{color:var(--dsw-alias-label-tertiary,#8b93a1);font-size:12px;line-height:18px}.eGUBIq_setConfirm{border-top:1px solid var(--dsw-alias-border-l2,#e5e7eb);flex-direction:column;gap:8px;padding:12px 0 4px;display:flex}.eGUBIq_setCheck{cursor:pointer;align-items:center;gap:8px;font-size:12px;line-height:18px;display:flex}.eGUBIq_setActions{border-top:1px solid var(--dsw-alias-border-l2,#e5e7eb);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.eGUBIq_setDanger{color:var(--dsw-alias-state-error-primary,#dc2626)}.eGUBIq_setSeg{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:8px;flex-shrink:0;gap:2px;padding:2px;display:inline-flex}.eGUBIq_setSegBtn{font:inherit;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border:none;border-radius:6px;padding:3px 10px;font-size:12px;line-height:18px}.eGUBIq_setSegBtn:disabled{cursor:default;opacity:.5}.eGUBIq_setSegOn{background:var(--dsw-alias-bg-layer-2,#eef0f4);color:var(--dsw-alias-label-primary,#1f2328);font-weight:600}.eGUBIq_setBetaTag{background:var(--dsw-alias-bg-module-platform,#eef0f4);color:var(--dsw-alias-label-secondary,#6b7280);border-radius:9px;margin-left:6px;padding:0 6px;font-size:11px;font-weight:600;line-height:17px}";
|
|
1488
1586
|
const tagId = "dshmarket/Market.module.css";
|
|
1489
1587
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
1490
1588
|
const tag = document.createElement("style");
|
|
@@ -1542,6 +1640,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
1542
1640
|
"collapseHead": "eGUBIq_collapseHead",
|
|
1543
1641
|
"collapseIcon": "eGUBIq_collapseIcon",
|
|
1544
1642
|
"collapseTitle": "eGUBIq_collapseTitle",
|
|
1643
|
+
"confirmRow": "eGUBIq_confirmRow",
|
|
1545
1644
|
"conflictBody": "eGUBIq_conflictBody",
|
|
1546
1645
|
"conflictDetailsToggle": "eGUBIq_conflictDetailsToggle",
|
|
1547
1646
|
"conflictHead": "eGUBIq_conflictHead",
|
|
@@ -1664,6 +1763,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
1664
1763
|
"opTop": "eGUBIq_opTop",
|
|
1665
1764
|
"opVerb": "eGUBIq_opVerb",
|
|
1666
1765
|
"opWrap": "eGUBIq_opWrap",
|
|
1766
|
+
"orderPanel": "eGUBIq_orderPanel",
|
|
1667
1767
|
"orphBadge": "eGUBIq_orphBadge",
|
|
1668
1768
|
"orphRow": "eGUBIq_orphRow",
|
|
1669
1769
|
"ovArrow": "eGUBIq_ovArrow",
|
|
@@ -1675,8 +1775,12 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
1675
1775
|
"pageInfo": "eGUBIq_pageInfo",
|
|
1676
1776
|
"pager": "eGUBIq_pager",
|
|
1677
1777
|
"pagerPages": "eGUBIq_pagerPages",
|
|
1778
|
+
"panelActions": "eGUBIq_panelActions",
|
|
1678
1779
|
"panelNote": "eGUBIq_panelNote",
|
|
1679
1780
|
"pct": "eGUBIq_pct",
|
|
1781
|
+
"presetList": "eGUBIq_presetList",
|
|
1782
|
+
"presetName": "eGUBIq_presetName",
|
|
1783
|
+
"presetRow": "eGUBIq_presetRow",
|
|
1680
1784
|
"progress": "eGUBIq_progress",
|
|
1681
1785
|
"reassure": "eGUBIq_reassure",
|
|
1682
1786
|
"reassureOk": "eGUBIq_reassureOk",
|
|
@@ -1720,6 +1824,10 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
1720
1824
|
"setSegOn": "eGUBIq_setSegOn",
|
|
1721
1825
|
"shot": "eGUBIq_shot",
|
|
1722
1826
|
"shots": "eGUBIq_shots",
|
|
1827
|
+
"snapConfirmText": "eGUBIq_snapConfirmText",
|
|
1828
|
+
"snapList": "eGUBIq_snapList",
|
|
1829
|
+
"snapMeta": "eGUBIq_snapMeta",
|
|
1830
|
+
"snapRow": "eGUBIq_snapRow",
|
|
1723
1831
|
"sp": "eGUBIq_sp",
|
|
1724
1832
|
"spec": "eGUBIq_spec",
|
|
1725
1833
|
"specTag": "eGUBIq_specTag",
|
|
@@ -2253,21 +2361,568 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
2253
2361
|
});
|
|
2254
2362
|
}
|
|
2255
2363
|
//#endregion
|
|
2364
|
+
//#region src/client/preset-panel.tsx
|
|
2365
|
+
/**
|
|
2366
|
+
* Diagnostics sub-panel — issue #98 phase 3 (plugin presets).
|
|
2367
|
+
*
|
|
2368
|
+
* Rendered at the bottom of the Diagnostics tab inside a collapsible section
|
|
2369
|
+
* (the parent keeps it mounted and passes `open`, so it lazy-loads on first
|
|
2370
|
+
* expand and keeps its state across collapses). Lists named presets
|
|
2371
|
+
* (GET /dsh-market/presets), saves the current community bundle order as a
|
|
2372
|
+
* new preset (POST /dsh-market/presets {action:'save', name, bundleOrder,
|
|
2373
|
+
* disabled}), applies one (action:'apply' — the host trial-validates and
|
|
2374
|
+
* auto-snapshots before writing; on success the parent refreshes the check
|
|
2375
|
+
* report) and deletes one after an inline double confirmation
|
|
2376
|
+
* (action:'delete').
|
|
2377
|
+
*
|
|
2378
|
+
* The list payload is read defensively (bare array or {presets: [...]}).
|
|
2379
|
+
*/
|
|
2380
|
+
async function postJson$1(url, body) {
|
|
2381
|
+
let res;
|
|
2382
|
+
try {
|
|
2383
|
+
res = await fetch(url, {
|
|
2384
|
+
method: "POST",
|
|
2385
|
+
headers: { "content-type": "application/json" },
|
|
2386
|
+
body: JSON.stringify(body)
|
|
2387
|
+
});
|
|
2388
|
+
} catch {
|
|
2389
|
+
return {
|
|
2390
|
+
status: 0,
|
|
2391
|
+
body: null
|
|
2392
|
+
};
|
|
2393
|
+
}
|
|
2394
|
+
let payload = null;
|
|
2395
|
+
try {
|
|
2396
|
+
payload = await res.json();
|
|
2397
|
+
} catch {}
|
|
2398
|
+
return {
|
|
2399
|
+
status: res.status,
|
|
2400
|
+
body: payload
|
|
2401
|
+
};
|
|
2402
|
+
}
|
|
2403
|
+
const errorText = (status, body, fallback) => body !== null && typeof body.error === "string" ? body.error : status === 0 ? fallback + "network error" : fallback + `HTTP ${String(status)}`;
|
|
2404
|
+
function PresetPanel(props) {
|
|
2405
|
+
const { t, open, bundleOrder, onRefresh } = props;
|
|
2406
|
+
const [presets, setPresets] = (0, react.useState)(null);
|
|
2407
|
+
const [error, setError] = (0, react.useState)(null);
|
|
2408
|
+
const [msg, setMsg] = (0, react.useState)(null);
|
|
2409
|
+
const [busy, setBusy] = (0, react.useState)(null);
|
|
2410
|
+
const [name, setName] = (0, react.useState)("");
|
|
2411
|
+
/** Preset name awaiting the second confirm click, or null. */
|
|
2412
|
+
const [confirmDelete, setConfirmDelete] = (0, react.useState)(null);
|
|
2413
|
+
/** Hidden <input type="file"> for the import action. */
|
|
2414
|
+
const loaded = (0, react.useRef)(false);
|
|
2415
|
+
const load = (0, react.useCallback)(() => {
|
|
2416
|
+
fetch("/dsh-market/presets", { cache: "no-store" }).then((res) => res.json()).then((body) => {
|
|
2417
|
+
const list = Array.isArray(body) ? body : Array.isArray(body.presets) ? body.presets : [];
|
|
2418
|
+
setPresets(list.map((item) => {
|
|
2419
|
+
const preset = item ?? {};
|
|
2420
|
+
return {
|
|
2421
|
+
name: String(preset.name ?? ""),
|
|
2422
|
+
bundleOrder: Array.isArray(preset.bundleOrder) ? preset.bundleOrder.map(String) : [],
|
|
2423
|
+
disabled: Array.isArray(preset.disabled) ? preset.disabled.map(String) : []
|
|
2424
|
+
};
|
|
2425
|
+
}));
|
|
2426
|
+
setError(null);
|
|
2427
|
+
loaded.current = true;
|
|
2428
|
+
}).catch(() => setError(t("presetListFail") + "network"));
|
|
2429
|
+
}, [t]);
|
|
2430
|
+
(0, react.useEffect)(() => {
|
|
2431
|
+
if (open && !loaded.current) load();
|
|
2432
|
+
}, [open, load]);
|
|
2433
|
+
(0, react.useCallback)(() => {
|
|
2434
|
+
const presetName = name.trim();
|
|
2435
|
+
if (presetName === "") {
|
|
2436
|
+
setError(t("presetNameEmpty"));
|
|
2437
|
+
return;
|
|
2438
|
+
}
|
|
2439
|
+
if (busy !== null) return;
|
|
2440
|
+
setBusy("save");
|
|
2441
|
+
setMsg(null);
|
|
2442
|
+
setError(null);
|
|
2443
|
+
fetch("/dsh-market/installed", { cache: "no-store" }).then((res) => res.json()).then((installed) => postJson$1("/dsh-market/presets", {
|
|
2444
|
+
action: "save",
|
|
2445
|
+
name: presetName,
|
|
2446
|
+
bundleOrder,
|
|
2447
|
+
disabled: Array.isArray(installed.disabled) ? installed.disabled.map(String) : []
|
|
2448
|
+
})).then(({ status, body }) => {
|
|
2449
|
+
if (status >= 200 && status < 300 && body?.ok === true) {
|
|
2450
|
+
setName("");
|
|
2451
|
+
setMsg(t("presetSaved"));
|
|
2452
|
+
load();
|
|
2453
|
+
} else setError(errorText(status, body, t("presetFail")));
|
|
2454
|
+
}).catch(() => setError(t("presetFail") + "network")).finally(() => setBusy(null));
|
|
2455
|
+
}, [
|
|
2456
|
+
busy,
|
|
2457
|
+
bundleOrder,
|
|
2458
|
+
load,
|
|
2459
|
+
name,
|
|
2460
|
+
t
|
|
2461
|
+
]);
|
|
2462
|
+
const apply = (0, react.useCallback)((presetName) => {
|
|
2463
|
+
if (busy !== null) return;
|
|
2464
|
+
setBusy("apply");
|
|
2465
|
+
setMsg(null);
|
|
2466
|
+
setError(null);
|
|
2467
|
+
postJson$1("/dsh-market/presets", {
|
|
2468
|
+
action: "apply",
|
|
2469
|
+
name: presetName
|
|
2470
|
+
}).then(({ status, body }) => {
|
|
2471
|
+
if (status >= 200 && status < 300 && body?.ok === true) {
|
|
2472
|
+
setMsg(t("presetApplied"));
|
|
2473
|
+
onRefresh();
|
|
2474
|
+
} else setError(errorText(status, body, t("presetFail")));
|
|
2475
|
+
}).catch(() => setError(t("presetFail") + "network")).finally(() => setBusy(null));
|
|
2476
|
+
}, [
|
|
2477
|
+
busy,
|
|
2478
|
+
onRefresh,
|
|
2479
|
+
t
|
|
2480
|
+
]);
|
|
2481
|
+
const remove = (0, react.useCallback)((presetName) => {
|
|
2482
|
+
if (busy !== null) return;
|
|
2483
|
+
setBusy("delete");
|
|
2484
|
+
setMsg(null);
|
|
2485
|
+
setError(null);
|
|
2486
|
+
postJson$1("/dsh-market/presets", {
|
|
2487
|
+
action: "delete",
|
|
2488
|
+
name: presetName
|
|
2489
|
+
}).then(({ status, body }) => {
|
|
2490
|
+
if (status >= 200 && status < 300 && body?.ok === true) {
|
|
2491
|
+
setConfirmDelete(null);
|
|
2492
|
+
setMsg(t("presetDeleted"));
|
|
2493
|
+
load();
|
|
2494
|
+
} else setError(errorText(status, body, t("presetFail")));
|
|
2495
|
+
}).catch(() => setError(t("presetFail") + "network")).finally(() => setBusy(null));
|
|
2496
|
+
}, [
|
|
2497
|
+
busy,
|
|
2498
|
+
load,
|
|
2499
|
+
t
|
|
2500
|
+
]);
|
|
2501
|
+
/** Change preview of one preset: {reordered[], enabled[], disabled[], noop}. */
|
|
2502
|
+
const [previewed, setPreviewed] = (0, react.useState)(null);
|
|
2503
|
+
const preview = (0, react.useCallback)((presetName) => {
|
|
2504
|
+
if (busy !== null) return;
|
|
2505
|
+
setBusy("preview");
|
|
2506
|
+
setMsg(null);
|
|
2507
|
+
setError(null);
|
|
2508
|
+
if (previewed?.name === presetName) {
|
|
2509
|
+
setPreviewed(null);
|
|
2510
|
+
setBusy(null);
|
|
2511
|
+
return;
|
|
2512
|
+
}
|
|
2513
|
+
postJson$1("/dsh-market/presets", {
|
|
2514
|
+
action: "preview",
|
|
2515
|
+
name: presetName
|
|
2516
|
+
}).then(({ status, body }) => {
|
|
2517
|
+
if (status >= 200 && status < 300 && body?.ok === true && body.changes !== null && typeof body.changes === "object") {
|
|
2518
|
+
const changes = body.changes;
|
|
2519
|
+
setPreviewed({
|
|
2520
|
+
name: presetName,
|
|
2521
|
+
changes: {
|
|
2522
|
+
reordered: Array.isArray(changes.reordered) ? changes.reordered.map(String) : [],
|
|
2523
|
+
enabled: Array.isArray(changes.enabled) ? changes.enabled.map(String) : [],
|
|
2524
|
+
disabled: Array.isArray(changes.disabled) ? changes.disabled.map(String) : [],
|
|
2525
|
+
noop: changes.noop === true
|
|
2526
|
+
}
|
|
2527
|
+
});
|
|
2528
|
+
} else setError(errorText(status, body, t("presetPreviewFail")));
|
|
2529
|
+
}).catch(() => setError(t("presetPreviewFail") + "network")).finally(() => setBusy(null));
|
|
2530
|
+
}, [
|
|
2531
|
+
busy,
|
|
2532
|
+
previewed,
|
|
2533
|
+
t
|
|
2534
|
+
]);
|
|
2535
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2536
|
+
className: Market_module_css_default.orderPanel,
|
|
2537
|
+
children: [
|
|
2538
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2539
|
+
className: Market_module_css_default.panelNote,
|
|
2540
|
+
children: t("presetHint")
|
|
2541
|
+
}),
|
|
2542
|
+
error !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2543
|
+
className: Market_module_css_default.err,
|
|
2544
|
+
children: error
|
|
2545
|
+
}),
|
|
2546
|
+
presets === null || presets.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2547
|
+
className: Market_module_css_default.diagEmpty,
|
|
2548
|
+
children: t("presetEmpty")
|
|
2549
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2550
|
+
className: Market_module_css_default.presetList,
|
|
2551
|
+
children: presets.map((preset) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2552
|
+
className: Market_module_css_default.presetRow,
|
|
2553
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2554
|
+
className: Market_module_css_default.confirmRow,
|
|
2555
|
+
children: [
|
|
2556
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2557
|
+
className: Market_module_css_default.presetName,
|
|
2558
|
+
children: preset.name
|
|
2559
|
+
}),
|
|
2560
|
+
preset.bundleOrder.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2561
|
+
className: Market_module_css_default.spec,
|
|
2562
|
+
children: t("presetBundleCount").replace("{0}", String(preset.bundleOrder.length))
|
|
2563
|
+
}),
|
|
2564
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: Market_module_css_default.grow }),
|
|
2565
|
+
confirmDelete === preset.name ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2566
|
+
className: Market_module_css_default.confirmRow,
|
|
2567
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2568
|
+
variant: "primary",
|
|
2569
|
+
size: "sm",
|
|
2570
|
+
disabled: busy !== null,
|
|
2571
|
+
onClick: () => remove(preset.name),
|
|
2572
|
+
children: t("presetDelete")
|
|
2573
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2574
|
+
variant: "ghost",
|
|
2575
|
+
size: "sm",
|
|
2576
|
+
disabled: busy !== null,
|
|
2577
|
+
onClick: () => setConfirmDelete(null),
|
|
2578
|
+
children: t("cancel")
|
|
2579
|
+
})]
|
|
2580
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2581
|
+
className: Market_module_css_default.confirmRow,
|
|
2582
|
+
children: [
|
|
2583
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2584
|
+
variant: "outline",
|
|
2585
|
+
size: "sm",
|
|
2586
|
+
disabled: busy !== null,
|
|
2587
|
+
onClick: () => apply(preset.name),
|
|
2588
|
+
children: t("presetApply")
|
|
2589
|
+
}),
|
|
2590
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2591
|
+
variant: "ghost",
|
|
2592
|
+
size: "sm",
|
|
2593
|
+
disabled: busy !== null,
|
|
2594
|
+
onClick: () => preview(preset.name),
|
|
2595
|
+
children: previewed?.name === preset.name ? t("cancel") : t("presetPreview")
|
|
2596
|
+
}),
|
|
2597
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2598
|
+
variant: "ghost",
|
|
2599
|
+
size: "sm",
|
|
2600
|
+
disabled: busy !== null,
|
|
2601
|
+
onClick: () => setConfirmDelete(preset.name),
|
|
2602
|
+
children: t("presetDelete")
|
|
2603
|
+
})
|
|
2604
|
+
]
|
|
2605
|
+
})
|
|
2606
|
+
]
|
|
2607
|
+
}), previewed?.name === preset.name && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2608
|
+
className: Market_module_css_default.diagList,
|
|
2609
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2610
|
+
className: Market_module_css_default.diagKey,
|
|
2611
|
+
children: t("presetPreviewTitle")
|
|
2612
|
+
}), previewed.changes.noop ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2613
|
+
className: Market_module_css_default.spec,
|
|
2614
|
+
children: t("presetNoop")
|
|
2615
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2616
|
+
className: Market_module_css_default.spec,
|
|
2617
|
+
children: [
|
|
2618
|
+
previewed.changes.reordered.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2619
|
+
className: Market_module_css_default.warnLine,
|
|
2620
|
+
children: [
|
|
2621
|
+
t("presetReorder").replace("{0}", String(previewed.changes.reordered.length)),
|
|
2622
|
+
": ",
|
|
2623
|
+
previewed.changes.reordered.join(", ")
|
|
2624
|
+
]
|
|
2625
|
+
}),
|
|
2626
|
+
previewed.changes.enabled.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2627
|
+
className: Market_module_css_default.warnLine,
|
|
2628
|
+
children: [
|
|
2629
|
+
t("presetEnable").replace("{0}", String(previewed.changes.enabled.length)),
|
|
2630
|
+
": ",
|
|
2631
|
+
previewed.changes.enabled.join(", ")
|
|
2632
|
+
]
|
|
2633
|
+
}),
|
|
2634
|
+
previewed.changes.disabled.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2635
|
+
className: Market_module_css_default.warnLine,
|
|
2636
|
+
children: [
|
|
2637
|
+
t("presetDisable").replace("{0}", String(previewed.changes.disabled.length)),
|
|
2638
|
+
": ",
|
|
2639
|
+
previewed.changes.disabled.join(", ")
|
|
2640
|
+
]
|
|
2641
|
+
})
|
|
2642
|
+
]
|
|
2643
|
+
})]
|
|
2644
|
+
})]
|
|
2645
|
+
}, preset.name))
|
|
2646
|
+
}),
|
|
2647
|
+
msg !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2648
|
+
className: Market_module_css_default.okState,
|
|
2649
|
+
children: msg
|
|
2650
|
+
})
|
|
2651
|
+
]
|
|
2652
|
+
});
|
|
2653
|
+
}
|
|
2654
|
+
//#endregion
|
|
2655
|
+
//#region src/client/snapshot-panel.tsx
|
|
2656
|
+
/**
|
|
2657
|
+
* Diagnostics sub-panel — issue #98 phase 3 (snapshots & rollback).
|
|
2658
|
+
*
|
|
2659
|
+
* Rendered at the bottom of the Diagnostics tab inside a collapsible section
|
|
2660
|
+
* (the parent keeps it mounted and passes `open`, so it lazy-loads on first
|
|
2661
|
+
* expand and keeps its state across collapses). Lists profile snapshots
|
|
2662
|
+
* (GET /dsh-market/snapshots), creates one (POST /dsh-market/snapshots) and
|
|
2663
|
+
* restores one after an inline double confirmation
|
|
2664
|
+
* (POST /dsh-market/restore-snapshot {snapshot}).
|
|
2665
|
+
*
|
|
2666
|
+
* The list payload is read defensively (bare array or {snapshots: [...]});
|
|
2667
|
+
* `files` entries are {path, json|lines} objects, from which only `path` is
|
|
2668
|
+
* displayed.
|
|
2669
|
+
*/
|
|
2670
|
+
async function postJson(url, body) {
|
|
2671
|
+
let res;
|
|
2672
|
+
try {
|
|
2673
|
+
res = await fetch(url, {
|
|
2674
|
+
method: "POST",
|
|
2675
|
+
headers: { "content-type": "application/json" },
|
|
2676
|
+
body: JSON.stringify(body)
|
|
2677
|
+
});
|
|
2678
|
+
} catch {
|
|
2679
|
+
return {
|
|
2680
|
+
status: 0,
|
|
2681
|
+
body: null
|
|
2682
|
+
};
|
|
2683
|
+
}
|
|
2684
|
+
let payload = null;
|
|
2685
|
+
try {
|
|
2686
|
+
payload = await res.json();
|
|
2687
|
+
} catch {}
|
|
2688
|
+
return {
|
|
2689
|
+
status: res.status,
|
|
2690
|
+
body: payload
|
|
2691
|
+
};
|
|
2692
|
+
}
|
|
2693
|
+
/** Snapshot file entries may be plain names or {path, json|lines} objects. */
|
|
2694
|
+
function fileNames(files) {
|
|
2695
|
+
if (!Array.isArray(files)) return [];
|
|
2696
|
+
const names = [];
|
|
2697
|
+
for (const file of files) if (typeof file === "string") names.push(file);
|
|
2698
|
+
else if (file !== null && typeof file === "object") {
|
|
2699
|
+
const path = file.path;
|
|
2700
|
+
if (typeof path === "string") names.push(path);
|
|
2701
|
+
}
|
|
2702
|
+
return names;
|
|
2703
|
+
}
|
|
2704
|
+
function snapshotOf(value) {
|
|
2705
|
+
if (value === null || typeof value !== "object") return null;
|
|
2706
|
+
const item = value;
|
|
2707
|
+
if (typeof item.id !== "string" && typeof item.id !== "number") return null;
|
|
2708
|
+
return {
|
|
2709
|
+
id: String(item.id),
|
|
2710
|
+
createdAt: typeof item.createdAt === "string" || typeof item.createdAt === "number" ? item.createdAt : 0,
|
|
2711
|
+
files: fileNames(item.files)
|
|
2712
|
+
};
|
|
2713
|
+
}
|
|
2714
|
+
function formatTime(value) {
|
|
2715
|
+
const date = new Date(value);
|
|
2716
|
+
return Number.isNaN(date.getTime()) ? String(value) : date.toLocaleString();
|
|
2717
|
+
}
|
|
2718
|
+
function SnapshotPanel(props) {
|
|
2719
|
+
const { t, open, onRefresh } = props;
|
|
2720
|
+
const [snapshots, setSnapshots] = (0, react.useState)(null);
|
|
2721
|
+
const [error, setError] = (0, react.useState)(null);
|
|
2722
|
+
const [msg, setMsg] = (0, react.useState)(null);
|
|
2723
|
+
const [busy, setBusy] = (0, react.useState)(null);
|
|
2724
|
+
/** Snapshot id awaiting the second confirm click (restore), or null. */
|
|
2725
|
+
const [confirmId, setConfirmId] = (0, react.useState)(null);
|
|
2726
|
+
/** Snapshot id awaiting the second confirm click (delete), or null. */
|
|
2727
|
+
const [confirmDeleteId, setConfirmDeleteId] = (0, react.useState)(null);
|
|
2728
|
+
const loaded = (0, react.useRef)(false);
|
|
2729
|
+
const load = (0, react.useCallback)(() => {
|
|
2730
|
+
fetch("/dsh-market/snapshots", { cache: "no-store" }).then((res) => res.json()).then((body) => {
|
|
2731
|
+
const list = Array.isArray(body) ? body : Array.isArray(body.snapshots) ? body.snapshots : [];
|
|
2732
|
+
setSnapshots(list.map(snapshotOf).filter((snap) => snap !== null));
|
|
2733
|
+
setError(null);
|
|
2734
|
+
loaded.current = true;
|
|
2735
|
+
}).catch(() => setError(t("snapListFail") + "network"));
|
|
2736
|
+
}, [t]);
|
|
2737
|
+
(0, react.useEffect)(() => {
|
|
2738
|
+
if (open && !loaded.current) load();
|
|
2739
|
+
}, [open, load]);
|
|
2740
|
+
const create = (0, react.useCallback)(() => {
|
|
2741
|
+
if (busy !== null) return;
|
|
2742
|
+
setBusy("create");
|
|
2743
|
+
setMsg(null);
|
|
2744
|
+
setError(null);
|
|
2745
|
+
postJson("/dsh-market/snapshots", {}).then(({ status, body }) => {
|
|
2746
|
+
if (status >= 200 && status < 300 && body?.ok === true) {
|
|
2747
|
+
setMsg(t("snapCreated"));
|
|
2748
|
+
load();
|
|
2749
|
+
} else {
|
|
2750
|
+
const detail = body !== null && typeof body.error === "string" ? body.error : status === 0 ? "network error" : `HTTP ${String(status)}`;
|
|
2751
|
+
setError(t("snapCreateFail") + detail);
|
|
2752
|
+
}
|
|
2753
|
+
}).catch(() => setError(t("snapCreateFail") + "network")).finally(() => setBusy(null));
|
|
2754
|
+
}, [
|
|
2755
|
+
busy,
|
|
2756
|
+
load,
|
|
2757
|
+
t
|
|
2758
|
+
]);
|
|
2759
|
+
const restore = (0, react.useCallback)((id) => {
|
|
2760
|
+
if (busy !== null) return;
|
|
2761
|
+
setBusy("restore");
|
|
2762
|
+
setMsg(null);
|
|
2763
|
+
setError(null);
|
|
2764
|
+
postJson("/dsh-market/restore-snapshot", { snapshot: id }).then(({ status, body }) => {
|
|
2765
|
+
if (status >= 200 && status < 300 && body?.ok === true) {
|
|
2766
|
+
setConfirmId(null);
|
|
2767
|
+
setMsg(t("snapRestored"));
|
|
2768
|
+
onRefresh();
|
|
2769
|
+
} else {
|
|
2770
|
+
const detail = body !== null && typeof body.error === "string" ? body.error : status === 0 ? "network error" : `HTTP ${String(status)}`;
|
|
2771
|
+
setError(t("snapRestoreFail") + detail);
|
|
2772
|
+
}
|
|
2773
|
+
}).catch(() => setError(t("snapRestoreFail") + "network")).finally(() => setBusy(null));
|
|
2774
|
+
}, [
|
|
2775
|
+
busy,
|
|
2776
|
+
onRefresh,
|
|
2777
|
+
t
|
|
2778
|
+
]);
|
|
2779
|
+
/** Delete one snapshot after inline double confirmation. */
|
|
2780
|
+
const remove = (0, react.useCallback)((id) => {
|
|
2781
|
+
if (busy !== null) return;
|
|
2782
|
+
setBusy("delete");
|
|
2783
|
+
setMsg(null);
|
|
2784
|
+
setError(null);
|
|
2785
|
+
postJson("/dsh-market/delete-snapshot", { snapshot: id }).then(({ status, body }) => {
|
|
2786
|
+
if (status >= 200 && status < 300 && body?.ok === true) {
|
|
2787
|
+
setConfirmDeleteId(null);
|
|
2788
|
+
setMsg(t("snapDeleted"));
|
|
2789
|
+
load();
|
|
2790
|
+
} else {
|
|
2791
|
+
const detail = body !== null && typeof body.error === "string" ? body.error : status === 0 ? "network error" : `HTTP ${String(status)}`;
|
|
2792
|
+
setError(t("snapDeleteFail") + detail);
|
|
2793
|
+
}
|
|
2794
|
+
}).catch(() => setError(t("snapDeleteFail") + "network")).finally(() => setBusy(null));
|
|
2795
|
+
}, [
|
|
2796
|
+
busy,
|
|
2797
|
+
load,
|
|
2798
|
+
t
|
|
2799
|
+
]);
|
|
2800
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2801
|
+
className: Market_module_css_default.orderPanel,
|
|
2802
|
+
children: [
|
|
2803
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2804
|
+
className: Market_module_css_default.panelNote,
|
|
2805
|
+
children: t("snapHint")
|
|
2806
|
+
}),
|
|
2807
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2808
|
+
className: Market_module_css_default.panelActions,
|
|
2809
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2810
|
+
variant: "primary",
|
|
2811
|
+
size: "sm",
|
|
2812
|
+
disabled: busy !== null,
|
|
2813
|
+
onClick: create,
|
|
2814
|
+
children: busy === "create" ? t("snapCreating") : t("snapCreate")
|
|
2815
|
+
})
|
|
2816
|
+
}),
|
|
2817
|
+
error !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2818
|
+
className: Market_module_css_default.err,
|
|
2819
|
+
children: error
|
|
2820
|
+
}),
|
|
2821
|
+
snapshots === null || snapshots.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2822
|
+
className: Market_module_css_default.diagEmpty,
|
|
2823
|
+
children: t("snapEmpty")
|
|
2824
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2825
|
+
className: Market_module_css_default.snapList,
|
|
2826
|
+
children: snapshots.map((snap) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2827
|
+
className: Market_module_css_default.snapRow,
|
|
2828
|
+
children: confirmId === snap.id ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2829
|
+
className: Market_module_css_default.snapConfirmText,
|
|
2830
|
+
children: t("snapRestoreConfirmText")
|
|
2831
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2832
|
+
className: Market_module_css_default.confirmRow,
|
|
2833
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2834
|
+
variant: "primary",
|
|
2835
|
+
size: "sm",
|
|
2836
|
+
disabled: busy !== null,
|
|
2837
|
+
onClick: () => restore(snap.id),
|
|
2838
|
+
children: busy === "restore" ? t("snapRestoring") : t("snapRestoreConfirm")
|
|
2839
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2840
|
+
variant: "ghost",
|
|
2841
|
+
size: "sm",
|
|
2842
|
+
disabled: busy !== null,
|
|
2843
|
+
onClick: () => setConfirmId(null),
|
|
2844
|
+
children: t("cancel")
|
|
2845
|
+
})]
|
|
2846
|
+
})] }) : confirmDeleteId === snap.id ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2847
|
+
className: Market_module_css_default.snapConfirmText,
|
|
2848
|
+
children: t("snapDeleteConfirmText")
|
|
2849
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2850
|
+
className: Market_module_css_default.confirmRow,
|
|
2851
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2852
|
+
variant: "primary",
|
|
2853
|
+
size: "sm",
|
|
2854
|
+
disabled: busy !== null,
|
|
2855
|
+
onClick: () => remove(snap.id),
|
|
2856
|
+
children: busy === "delete" ? t("snapDeleting") : t("snapDeleteConfirm")
|
|
2857
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2858
|
+
variant: "ghost",
|
|
2859
|
+
size: "sm",
|
|
2860
|
+
disabled: busy !== null,
|
|
2861
|
+
onClick: () => setConfirmDeleteId(null),
|
|
2862
|
+
children: t("cancel")
|
|
2863
|
+
})]
|
|
2864
|
+
})] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2865
|
+
className: Market_module_css_default.snapMeta,
|
|
2866
|
+
children: [
|
|
2867
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2868
|
+
className: Market_module_css_default.diagVal,
|
|
2869
|
+
children: formatTime(snap.createdAt)
|
|
2870
|
+
}),
|
|
2871
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2872
|
+
className: Market_module_css_default.spec,
|
|
2873
|
+
children: snap.id
|
|
2874
|
+
}),
|
|
2875
|
+
snap.files.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2876
|
+
className: Market_module_css_default.spec,
|
|
2877
|
+
children: [
|
|
2878
|
+
t("snapFiles"),
|
|
2879
|
+
": ",
|
|
2880
|
+
snap.files.join(", ")
|
|
2881
|
+
]
|
|
2882
|
+
})
|
|
2883
|
+
]
|
|
2884
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2885
|
+
className: Market_module_css_default.confirmRow,
|
|
2886
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2887
|
+
variant: "outline",
|
|
2888
|
+
size: "sm",
|
|
2889
|
+
disabled: busy !== null,
|
|
2890
|
+
onClick: () => setConfirmId(snap.id),
|
|
2891
|
+
children: t("snapRestore")
|
|
2892
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2893
|
+
variant: "ghost",
|
|
2894
|
+
size: "sm",
|
|
2895
|
+
disabled: busy !== null,
|
|
2896
|
+
onClick: () => setConfirmDeleteId(snap.id),
|
|
2897
|
+
children: t("snapDelete")
|
|
2898
|
+
})]
|
|
2899
|
+
})] })
|
|
2900
|
+
}, snap.id))
|
|
2901
|
+
}),
|
|
2902
|
+
msg !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2903
|
+
className: Market_module_css_default.okState,
|
|
2904
|
+
children: msg
|
|
2905
|
+
})
|
|
2906
|
+
]
|
|
2907
|
+
});
|
|
2908
|
+
}
|
|
2909
|
+
//#endregion
|
|
2256
2910
|
//#region src/client/Diagnostics.tsx
|
|
2257
2911
|
/**
|
|
2258
2912
|
* Diagnostics tab — issue #98: renders the profile composition check report
|
|
2259
2913
|
* served by the host route /dsh-market/check (see src/check.ts). Below the
|
|
2260
|
-
* report
|
|
2261
|
-
* locally with
|
|
2262
|
-
*
|
|
2263
|
-
*
|
|
2914
|
+
* report sit the phase 2/3 action panels: a community-bundle ordering block
|
|
2915
|
+
* (reorder locally with ↑/↓, POST to /dsh-market/bundle-order) and a
|
|
2916
|
+
* snapshots & rollback panel (snapshot-panel.tsx) — collapsible, default
|
|
2917
|
+
* collapsed, and lazy-fetching on first expand. The plugin presets panel
|
|
2918
|
+
* ships in a later stacked PR.
|
|
2264
2919
|
*
|
|
2265
2920
|
* Read-only view of the loading-layer stack and the conflict surface: bundle
|
|
2266
2921
|
* order (official vs community), duplicate loader entry ids, peer dependency
|
|
2267
2922
|
* mismatches, multi-version core packages, overrides and orphan patches. The
|
|
2268
|
-
* report
|
|
2269
|
-
*
|
|
2270
|
-
* host tree.
|
|
2923
|
+
* report
|
|
2924
|
+
* shape mirrors the CheckReport interface in src/check.ts; it is re-declared
|
|
2925
|
+
* here because the client bundle is built independently of the host tree.
|
|
2271
2926
|
*/
|
|
2272
2927
|
/**
|
|
2273
2928
|
* A collapsible report section: header shows title + count + chevron; the
|
|
@@ -2329,8 +2984,9 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
2329
2984
|
});
|
|
2330
2985
|
}
|
|
2331
2986
|
/** A collapsible section that KEEPS its children mounted (hidden via CSS when
|
|
2332
|
-
* collapsed) so the
|
|
2333
|
-
* in-progress edits across collapses.
|
|
2987
|
+
* collapsed) so the phase 3 panels below retain their loaded data and
|
|
2988
|
+
* in-progress edits across collapses. Children mount from the start, but the
|
|
2989
|
+
* panels only fetch when `open` first becomes true.
|
|
2334
2990
|
*/
|
|
2335
2991
|
function CollapsibleSection(props) {
|
|
2336
2992
|
const { title, count, open, onToggle, children } = props;
|
|
@@ -2389,7 +3045,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
2389
3045
|
/**
|
|
2390
3046
|
* Fetch and render the profile check report. Refetches on every mount, so
|
|
2391
3047
|
* switching tabs away and back re-runs the (cheap, read-only) analysis; the
|
|
2392
|
-
*
|
|
3048
|
+
* phase 3 panels below call `refresh()` after applying changes.
|
|
2393
3049
|
*/
|
|
2394
3050
|
function Diagnostics(props) {
|
|
2395
3051
|
const { t } = props;
|
|
@@ -2397,11 +3053,13 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
2397
3053
|
const [error, setError] = (0, react.useState)(null);
|
|
2398
3054
|
const [orderOpen, setOrderOpen] = (0, react.useState)(false);
|
|
2399
3055
|
const [explainOpen, setExplainOpen] = (0, react.useState)(false);
|
|
3056
|
+
const [snapOpen, setSnapOpen] = (0, react.useState)(false);
|
|
3057
|
+
const [presetOpen, setPresetOpen] = (0, react.useState)(false);
|
|
2400
3058
|
const [fixMsg, setFixMsg] = (0, react.useState)(null);
|
|
2401
3059
|
/** The built AI-fix prompt when the clipboard path failed — rendered as a
|
|
2402
3060
|
* selectable text block so the user can still copy it manually. */
|
|
2403
3061
|
const [fixFallback, setFixFallback] = (0, react.useState)(null);
|
|
2404
|
-
/** Bump to re-run the /dsh-market/check fetch after an order apply. */
|
|
3062
|
+
/** Bump to re-run the /dsh-market/check fetch after an order/snapshot-restore apply. */
|
|
2405
3063
|
const [version, setVersion] = (0, react.useState)(0);
|
|
2406
3064
|
const refresh = (0, react.useCallback)(() => setVersion((v) => v + 1), []);
|
|
2407
3065
|
/** Community bundle names from the report, in declared order. */
|
|
@@ -2419,8 +3077,8 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
2419
3077
|
* refresh() refetch returns a NEW array even when the order is unchanged,
|
|
2420
3078
|
* so a naive `setOrder(communityNames)` effect would wipe the user's
|
|
2421
3079
|
* in-progress drag/↑↓ edits on every unrelated re-check. Only resync when
|
|
2422
|
-
* the report's community order actually CHANGED (apply order
|
|
2423
|
-
* identical refetch keeps the draft (review M2).
|
|
3080
|
+
* the report's community order actually CHANGED (apply order / snapshot
|
|
3081
|
+
* restore) — an identical refetch keeps the draft (review M2).
|
|
2424
3082
|
*/
|
|
2425
3083
|
const syncedOrderRef = (0, react.useRef)(null);
|
|
2426
3084
|
(0, react.useEffect)(() => {
|
|
@@ -3337,6 +3995,27 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
3337
3995
|
}, name))
|
|
3338
3996
|
})
|
|
3339
3997
|
]
|
|
3998
|
+
}),
|
|
3999
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CollapsibleSection, {
|
|
4000
|
+
title: t("presetSection"),
|
|
4001
|
+
open: presetOpen,
|
|
4002
|
+
onToggle: () => setPresetOpen((o) => !o),
|
|
4003
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PresetPanel, {
|
|
4004
|
+
t,
|
|
4005
|
+
open: presetOpen,
|
|
4006
|
+
bundleOrder: order,
|
|
4007
|
+
onRefresh: refresh
|
|
4008
|
+
})
|
|
4009
|
+
}),
|
|
4010
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CollapsibleSection, {
|
|
4011
|
+
title: t("snapSection"),
|
|
4012
|
+
open: snapOpen,
|
|
4013
|
+
onToggle: () => setSnapOpen((o) => !o),
|
|
4014
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SnapshotPanel, {
|
|
4015
|
+
t,
|
|
4016
|
+
open: snapOpen,
|
|
4017
|
+
onRefresh: refresh
|
|
4018
|
+
})
|
|
3340
4019
|
})
|
|
3341
4020
|
]
|
|
3342
4021
|
});
|
|
@@ -4427,6 +5106,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
4427
5106
|
const [updates, setUpdates] = (0, react.useState)({});
|
|
4428
5107
|
const [updatingName, setUpdatingName] = (0, react.useState)(null);
|
|
4429
5108
|
const [staleName, setStaleName] = (0, react.useState)(null);
|
|
5109
|
+
const [restoreName, setRestoreName] = (0, react.useState)(null);
|
|
4430
5110
|
/** Determinate percent parsed from pnpm's Progress line, when available. */
|
|
4431
5111
|
const [progressPct, setProgressPct] = (0, react.useState)(null);
|
|
4432
5112
|
/**
|
|
@@ -5112,10 +5792,11 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
5112
5792
|
body: "{}"
|
|
5113
5793
|
}).catch(() => {});
|
|
5114
5794
|
}, []);
|
|
5115
|
-
const doUpdate = (0, react.useCallback)((name, force = false) => {
|
|
5795
|
+
const doUpdate = (0, react.useCallback)((name, force = false, restore = false) => {
|
|
5116
5796
|
setInstallError(null);
|
|
5117
5797
|
setActivationWarnings([]);
|
|
5118
5798
|
setStaleName((prev) => prev === name ? null : prev);
|
|
5799
|
+
setRestoreName((prev) => prev === name ? null : prev);
|
|
5119
5800
|
setUpdatingName(name);
|
|
5120
5801
|
updateIdleStrikes.current = 0;
|
|
5121
5802
|
sessionStorage.setItem("dshm-updating", JSON.stringify({ name }));
|
|
@@ -5129,10 +5810,11 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
5129
5810
|
return fetch("/dsh-market/update", {
|
|
5130
5811
|
method: "POST",
|
|
5131
5812
|
headers: { "content-type": "application/json" },
|
|
5132
|
-
body: JSON.stringify(
|
|
5813
|
+
body: JSON.stringify({
|
|
5133
5814
|
name,
|
|
5134
|
-
force: true
|
|
5135
|
-
|
|
5815
|
+
...force ? { force: true } : {},
|
|
5816
|
+
...restore ? { restore: true } : {}
|
|
5817
|
+
})
|
|
5136
5818
|
}).then((res) => res.json().then((body) => ({
|
|
5137
5819
|
status: res.status,
|
|
5138
5820
|
body
|
|
@@ -5175,7 +5857,8 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
5175
5857
|
if (body.stale === true) setStaleName(name);
|
|
5176
5858
|
if (Array.isArray(body.ignoredBuilds) && body.ignoredBuilds.length > 0) setBuildsSkipped({
|
|
5177
5859
|
updateName: name,
|
|
5178
|
-
names: body.ignoredBuilds.map(String)
|
|
5860
|
+
names: body.ignoredBuilds.map(String),
|
|
5861
|
+
restore
|
|
5179
5862
|
});
|
|
5180
5863
|
const text = (v) => typeof v === "string" ? v : v && typeof v.text === "string" ? v.text : v == null ? "" : JSON.stringify(v);
|
|
5181
5864
|
const detail = text(body.error) || humanOutput([text(body.stderr), text(body.stdout)].filter(Boolean).join("\n")) || "exit " + body.exitCode;
|
|
@@ -5183,10 +5866,28 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
5183
5866
|
state: "failed",
|
|
5184
5867
|
reason: detail.trim().slice(-600)
|
|
5185
5868
|
}));
|
|
5186
|
-
setInstallError(t("updateFail") + ": " + name + " — " + detail.trim().slice(-600));
|
|
5869
|
+
setInstallError((restore ? t("restoreFail") : t("updateFail")) + ": " + name + " — " + detail.trim().slice(-600));
|
|
5187
5870
|
}
|
|
5188
5871
|
}).catch(() => {});
|
|
5189
5872
|
}, [refreshInstalled, t]);
|
|
5873
|
+
const askRestore = (0, react.useCallback)((name) => {
|
|
5874
|
+
const spec = installed[name];
|
|
5875
|
+
const entry = data === null || spec === void 0 ? void 0 : entryForDep(data.plugins, name, String(spec), repoIdentities[name], repoHints[name]);
|
|
5876
|
+
setStaleName(null);
|
|
5877
|
+
if (entry === void 0) {
|
|
5878
|
+
setRestoreName(null);
|
|
5879
|
+
setInstallError(t("restoreNoCatalog"));
|
|
5880
|
+
return;
|
|
5881
|
+
}
|
|
5882
|
+
setRestoreName(name);
|
|
5883
|
+
setInstallError(t("restoreHint"));
|
|
5884
|
+
}, [
|
|
5885
|
+
data,
|
|
5886
|
+
installed,
|
|
5887
|
+
repoHints,
|
|
5888
|
+
repoIdentities,
|
|
5889
|
+
t
|
|
5890
|
+
]);
|
|
5190
5891
|
const doUseSkin = (0, react.useCallback)((name) => {
|
|
5191
5892
|
setInstallError(null);
|
|
5192
5893
|
fetch("/dsh-market/use-skin", {
|
|
@@ -6447,7 +7148,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
6447
7148
|
size: "sm",
|
|
6448
7149
|
disabled: busyUrl !== null,
|
|
6449
7150
|
onClick: () => {
|
|
6450
|
-
const { plugin, updateName, names } = buildsSkipped;
|
|
7151
|
+
const { plugin, updateName, names, restore } = buildsSkipped;
|
|
6451
7152
|
setBuildsSkipped(null);
|
|
6452
7153
|
fetch("/dsh-market/approve-builds", {
|
|
6453
7154
|
method: "POST",
|
|
@@ -6456,7 +7157,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
6456
7157
|
}).then((res) => res.json()).then((body) => {
|
|
6457
7158
|
if (!body.ok) setInstallError(String(body.error || "approve failed"));
|
|
6458
7159
|
else if (plugin !== void 0) doInstall(plugin);
|
|
6459
|
-
else if (updateName !== void 0) doUpdate(updateName);
|
|
7160
|
+
else if (updateName !== void 0) doUpdate(updateName, false, restore === true);
|
|
6460
7161
|
}).catch((error) => setInstallError(String(error)));
|
|
6461
7162
|
},
|
|
6462
7163
|
children: t("approveBuilds")
|
|
@@ -6507,18 +7208,26 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
6507
7208
|
className: Market_module_css_default.err,
|
|
6508
7209
|
children: [installError, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6509
7210
|
className: Market_module_css_default.staleAction,
|
|
6510
|
-
children: [
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
7211
|
+
children: [
|
|
7212
|
+
staleName !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
7213
|
+
size: "sm",
|
|
7214
|
+
onClick: () => doUpdate(staleName, true),
|
|
7215
|
+
children: t("updateNow")
|
|
7216
|
+
}),
|
|
7217
|
+
restoreName !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
7218
|
+
size: "sm",
|
|
7219
|
+
onClick: () => doUpdate(restoreName, false, true),
|
|
7220
|
+
children: t("restoreContinue")
|
|
7221
|
+
}),
|
|
7222
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
7223
|
+
size: "sm",
|
|
7224
|
+
variant: "outline",
|
|
7225
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDownloadOutline16, { size: 14 }),
|
|
7226
|
+
disabled: exportState === "busy",
|
|
7227
|
+
onClick: doExportLog,
|
|
7228
|
+
children: exportState === "busy" ? t("exportingLog") : t("exportLog")
|
|
7229
|
+
})
|
|
7230
|
+
]
|
|
6522
7231
|
})]
|
|
6523
7232
|
}),
|
|
6524
7233
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -7273,6 +7982,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
7273
7982
|
const missing = pendingBackup !== null && !installedFiles.includes(name);
|
|
7274
7983
|
const entry = data === null ? void 0 : entryForDep(data.plugins, name, String(spec), repoIdentities[name], repoHints[name]);
|
|
7275
7984
|
const status = updates[name];
|
|
7985
|
+
const localDev = /^(?:link|file):/i.test(String(spec)) || status?.kind === "linked";
|
|
7276
7986
|
const act = activations[name];
|
|
7277
7987
|
const meta = act !== void 0 ? activationMeta(act.state, t) : null;
|
|
7278
7988
|
const version = status && status.version ? "v" + status.version : "";
|
|
@@ -7454,7 +8164,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
7454
8164
|
disabled: updatingName !== null,
|
|
7455
8165
|
onClick: () => doUpdate(name),
|
|
7456
8166
|
children: t("update")
|
|
7457
|
-
}) :
|
|
8167
|
+
}) : localDev ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7458
8168
|
className: Market_module_css_default.metaTag,
|
|
7459
8169
|
title: t("linkedDev"),
|
|
7460
8170
|
children: t("linkedDev")
|
|
@@ -7468,14 +8178,20 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
7468
8178
|
className: Market_module_css_default.dangerBtn,
|
|
7469
8179
|
disabled: true,
|
|
7470
8180
|
children: t("uninstalling")
|
|
7471
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
8181
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [localDev && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
8182
|
+
variant: "outline",
|
|
8183
|
+
size: "sm",
|
|
8184
|
+
disabled: removingName !== null || busyUrl !== null || updatingName !== null,
|
|
8185
|
+
onClick: () => askRestore(name),
|
|
8186
|
+
children: t("restore")
|
|
8187
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
7472
8188
|
variant: "outline",
|
|
7473
8189
|
size: "sm",
|
|
7474
8190
|
className: Market_module_css_default.dangerBtn,
|
|
7475
8191
|
disabled: removingName !== null || busyUrl !== null || updatingName !== null,
|
|
7476
8192
|
onClick: () => setRemoveConfirm(name),
|
|
7477
8193
|
children: t("uninstall")
|
|
7478
|
-
}))]
|
|
8194
|
+
})] }))]
|
|
7479
8195
|
})
|
|
7480
8196
|
]
|
|
7481
8197
|
})]
|