zipcalm 0.0.0-stage → 1.0.2

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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +260 -2
  3. package/bin/zipcalm.js +191 -0
  4. package/package.json +67 -4
  5. package/server/app.js +309 -0
  6. package/server/boot.js +145 -0
  7. package/server/config/defaults.js +153 -0
  8. package/server/config/index.js +140 -0
  9. package/server/config/schema.js +244 -0
  10. package/server/core/auth/password.js +89 -0
  11. package/server/core/auth/store.js +261 -0
  12. package/server/core/compress/blacklist.js +236 -0
  13. package/server/core/compress/capRegistry.js +171 -0
  14. package/server/core/compress/deleter.js +285 -0
  15. package/server/core/compress/hardlinkScan.js +67 -0
  16. package/server/core/compress/orchestrator.js +783 -0
  17. package/server/core/compress/preflight.js +376 -0
  18. package/server/core/compress/registry.js +240 -0
  19. package/server/core/compress/sourceWalk.js +84 -0
  20. package/server/core/compress/verify.js +47 -0
  21. package/server/core/engineRunner.js +369 -0
  22. package/server/core/fs/list.js +164 -0
  23. package/server/core/fs/platformProfile.js +167 -0
  24. package/server/core/fs/repairNames.js +150 -0
  25. package/server/core/fs/roots.js +178 -0
  26. package/server/core/fs/safePath.js +173 -0
  27. package/server/core/fs/search.js +108 -0
  28. package/server/core/fs/stat.js +110 -0
  29. package/server/core/fs/systemTrash.js +212 -0
  30. package/server/core/fs/writeOps.js +257 -0
  31. package/server/core/hardlink/executor.js +106 -0
  32. package/server/core/hardlink/scanner.js +193 -0
  33. package/server/core/metrics/collector.js +279 -0
  34. package/server/core/metrics/procfs.js +107 -0
  35. package/server/core/task/events.js +82 -0
  36. package/server/core/task/manager.js +987 -0
  37. package/server/core/task/recovery.js +116 -0
  38. package/server/core/task/store.js +240 -0
  39. package/server/http/middleware/auth.js +130 -0
  40. package/server/http/middleware/error.js +54 -0
  41. package/server/http/middleware/logger.js +27 -0
  42. package/server/http/middleware/pathGuard.js +119 -0
  43. package/server/http/router.js +29 -0
  44. package/server/http/routes/auth.js +115 -0
  45. package/server/http/routes/blacklist.js +97 -0
  46. package/server/http/routes/capabilities.js +21 -0
  47. package/server/http/routes/compress.js +339 -0
  48. package/server/http/routes/fs.js +109 -0
  49. package/server/http/routes/hardlink.js +160 -0
  50. package/server/http/routes/health.js +52 -0
  51. package/server/http/routes/metrics.js +36 -0
  52. package/server/http/routes/tasks.js +304 -0
  53. package/server/lib/atomic-json.js +118 -0
  54. package/server/lib/errors.js +145 -0
  55. package/server/lib/fs-probe.js +25 -0
  56. package/server/lib/logger.js +68 -0
  57. package/server/lib/runtime-guard.js +49 -0
  58. package/server/lib/throttle.js +42 -0
  59. package/server/plugins/capabilities/password/index.js +300 -0
  60. package/server/plugins/capabilities/password/methods/aes256.js +31 -0
  61. package/server/plugins/capabilities/password/methods/zip20.js +29 -0
  62. package/server/plugins/formats/_shared/createGuards.js +26 -0
  63. package/server/plugins/formats/_shared/entrySafety.js +174 -0
  64. package/server/plugins/formats/_shared/nameRepair.js +123 -0
  65. package/server/plugins/formats/_shared/streams.js +18 -0
  66. package/server/plugins/formats/_shared/tar/compression.js +114 -0
  67. package/server/plugins/formats/_shared/tar/reader.js +74 -0
  68. package/server/plugins/formats/_shared/tar/writer.js +206 -0
  69. package/server/plugins/formats/_shared/tarFamily.js +207 -0
  70. package/server/plugins/formats/rar/index.js +354 -0
  71. package/server/plugins/formats/rar/js-engine.js +122 -0
  72. package/server/plugins/formats/rar/js-runner.mjs +129 -0
  73. package/server/plugins/formats/rar/unrar.js +266 -0
  74. package/server/plugins/formats/sevenzip/engine.js +355 -0
  75. package/server/plugins/formats/sevenzip/index.js +461 -0
  76. package/server/plugins/formats/sevenzip/wasm-runner.mjs +72 -0
  77. package/server/plugins/formats/tar/index.js +19 -0
  78. package/server/plugins/formats/targz/index.js +19 -0
  79. package/server/plugins/formats/tarzst/index.js +26 -0
  80. package/server/plugins/formats/zip/index.js +587 -0
  81. package/shared/app-version.js +7 -0
  82. package/shared/capabilities.js +21 -0
  83. package/shared/compress-modes.js +38 -0
  84. package/shared/error-codes.js +117 -0
  85. package/shared/format-list.js +101 -0
  86. package/shared/hardlink-hint.js +21 -0
  87. package/shared/task-phase.js +62 -0
  88. package/shared/task-status.js +84 -0
  89. package/web/dist/assets/index-D3zjq7N2.js +131 -0
  90. package/web/dist/assets/index-D9Vdmrb9.css +1 -0
  91. package/web/dist/index.html +18 -0
@@ -0,0 +1 @@
1
+ :root{--color-bg: #f4f6f8;--color-surface: #ffffff;--color-surface-muted: #f8fafc;--color-border: #e2e8f0;--color-border-strong: #cbd5e1;--color-text: #1f2733;--color-text-muted: #64748b;--color-text-inverse: #ffffff;--color-primary: #2f6fed;--color-primary-soft: #e8f0fe;--color-ok: #16a34a;--color-warn: #d97706;--color-error: #dc2626;--color-hover: rgba(47, 111, 237, .08);--color-active: rgba(47, 111, 237, .14);--radius-sm: 4px;--radius-md: 8px;--radius-lg: 12px;--shadow-card: 0 1px 2px rgba(15, 23, 42, .06), 0 1px 3px rgba(15, 23, 42, .08);--shadow-pop: 0 8px 24px rgba(15, 23, 42, .12);--space-1: 4px;--space-2: 8px;--space-3: 12px;--space-4: 16px;--space-5: 20px;--space-6: 24px;--topbar-height: 56px;--bottombar-height: 52px;--sidebar-width: 232px;--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;--font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Courier New", monospace;--font-size-xs: 12px;--font-size-sm: 13px;--font-size-md: 14px;--font-size-lg: 16px;--font-size-xl: 20px;--hit-target-min: 32px}*,*:before,*:after{box-sizing:border-box}html,body{height:100%}body{margin:0;font-family:var(--font-sans);font-size:var(--font-size-md);line-height:1.5;color:var(--color-text);background:var(--color-bg);-webkit-font-smoothing:antialiased}#app{height:100%}h1,h2,h3,h4,p{margin:0}ul{margin:0;padding:0;list-style:none}a{color:var(--color-primary);text-decoration:none}a:hover{text-decoration:underline}button{font:inherit;color:inherit;background:none;border:1px solid var(--color-border-strong);border-radius:var(--radius-sm);padding:var(--space-1) var(--space-3);min-height:var(--hit-target-min);cursor:pointer}button:hover:not(:disabled){background:var(--color-hover)}button:disabled{cursor:not-allowed;opacity:.5}input,select,textarea{font:inherit;color:inherit;background:var(--color-surface);border:1px solid var(--color-border-strong);border-radius:var(--radius-sm);padding:var(--space-1) var(--space-2);min-height:var(--hit-target-min)}input:focus-visible,button:focus-visible,a:focus-visible{outline:2px solid var(--color-primary);outline-offset:1px}.main-area,.sidebar{touch-action:manipulation}.scroll-area{overflow:auto;scrollbar-width:thin}.scroll-area::-webkit-scrollbar{width:8px;height:8px}.scroll-area::-webkit-scrollbar-thumb{background:var(--color-border-strong);border-radius:var(--radius-sm)}.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.app-shell{display:grid;height:100%;grid-template-columns:var(--sidebar-width) 1fr;grid-template-rows:var(--topbar-height) 1fr var(--bottombar-height);grid-template-areas:"topbar topbar" "sidebar main" "bottombar bottombar"}.topbar{grid-area:topbar;display:flex;align-items:center;gap:var(--space-4);padding:0 var(--space-4);background:var(--color-surface);border-bottom:1px solid var(--color-border)}.sidebar{grid-area:sidebar;display:flex;flex-direction:column;gap:var(--space-4);padding:var(--space-4) var(--space-3);background:var(--color-surface);border-right:1px solid var(--color-border);overflow:auto}.main-area{grid-area:main;display:flex;flex-direction:column;min-width:0;background:var(--color-bg);overflow:hidden}.bottom-task-bar{grid-area:bottombar;display:flex;align-items:center;gap:var(--space-4);padding:0 var(--space-4);background:var(--color-surface);border-top:1px solid var(--color-border)}.topbar__brand{display:flex;align-items:baseline;gap:var(--space-2);font-weight:600;white-space:nowrap}.topbar__brand-sub{font-size:var(--font-size-xs);font-weight:400;color:var(--color-text-muted)}.topbar__crumbs{display:flex;align-items:center;gap:var(--space-1);font-size:var(--font-size-sm);color:var(--color-text-muted);min-width:0;overflow:hidden;white-space:nowrap}.search-results{position:absolute;top:calc(100% + var(--space-1));left:0;z-index:2400;width:min(420px,80vw);max-height:320px;overflow:auto;padding:var(--space-1);background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);box-shadow:0 10px 28px #00000029}.search-results ul{margin:0;padding:0;list-style:none}.search-results__item{display:flex;flex-direction:column;align-items:flex-start;width:100%;min-height:40px;padding:var(--space-1) var(--space-2);border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);text-align:left;cursor:pointer}.search-results__item:hover{background:var(--color-hover)}.search-results__name{font-size:var(--font-size-sm, .875rem)}.search-results__path{color:var(--color-text-muted);font-size:var(--font-size-xs);word-break:break-all}.search-results__hint{margin:var(--space-1) var(--space-2);color:var(--color-text-muted);font-size:var(--font-size-xs)}.file-table__row,.file-card{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}.topbar__search{flex:1 1 auto;max-width:320px}.topbar__search input{width:100%}.topbar__spacer{flex:1 1 auto}.topbar__views{display:flex;gap:var(--space-1)}.view-toggle{padding:var(--space-1) var(--space-3);font-size:var(--font-size-sm);color:var(--color-text-muted)}.view-toggle[aria-pressed=true]{color:var(--color-primary);border-color:var(--color-primary);background:var(--color-primary-soft)}.topbar__user{display:flex;align-items:center;gap:var(--space-2);font-size:var(--font-size-sm);color:var(--color-text-muted);white-space:nowrap}.sidebar__section{display:flex;flex-direction:column;gap:var(--space-2)}.sidebar__title{display:flex;align-items:center;gap:var(--space-1);font-size:var(--font-size-xs);font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--color-text-muted);padding:0 var(--space-2)}.nav-list{display:flex;flex-direction:column;gap:2px}.nav-item{display:flex;align-items:center;gap:var(--space-2);min-height:var(--hit-target-min);padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);color:var(--color-text);font-size:var(--font-size-sm)}.nav-item:hover{background:var(--color-hover);text-decoration:none}.nav-item[aria-current=page]{background:var(--color-primary-soft);color:var(--color-primary);font-weight:600}.nav-item__icon{display:inline-flex;width:16px;height:16px;color:currentColor}.tree{display:flex;flex-direction:column;gap:2px;font-size:var(--font-size-sm)}.tree__item{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);color:var(--color-text-muted)}.tree__item--root{color:var(--color-text);font-weight:600}.main-area__toolbar{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) var(--space-4);background:var(--color-surface);border-bottom:1px solid var(--color-border)}.main-area__toolbar-title{font-size:var(--font-size-lg);font-weight:600}.main-area__toolbar-hint{font-size:var(--font-size-xs);color:var(--color-text-muted)}.main-area__body{flex:1 1 auto;padding:var(--space-4);overflow:auto}.page-outlet{display:flex;flex-direction:column;gap:var(--space-4);min-height:100%}.card{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);box-shadow:var(--shadow-card);padding:var(--space-5)}.card__title{font-size:var(--font-size-lg);font-weight:600;margin-bottom:var(--space-2)}.card__desc{color:var(--color-text-muted);font-size:var(--font-size-sm)}.chart-legend{display:flex;gap:var(--space-4);margin-top:var(--space-1);font-size:var(--font-size-xs)}.chart-legend__item{display:inline-flex;align-items:center;gap:var(--space-1);color:var(--color-text-muted)}.chart-legend__dot{width:8px;height:8px;border-radius:999px;display:inline-block}.metric__value{font-size:var(--font-size-2xl, 1.5rem);font-weight:600;font-variant-numeric:tabular-nums;margin:var(--space-1) 0;line-height:1.2}.context-menu{position:fixed;z-index:3000;min-width:180px;padding:var(--space-1) 0;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);box-shadow:0 8px 24px #0000002e}.context-menu__item{display:flex;align-items:center;justify-content:space-between;gap:var(--space-4);width:100%;min-height:40px;padding:0 var(--space-3);border:0;background:transparent;color:var(--color-text);font-size:var(--font-size-sm, .875rem);text-align:left;cursor:pointer}.context-menu__item:hover:not(:disabled){background:var(--color-hover)}.context-menu__item:disabled{color:var(--color-text-muted);cursor:not-allowed}.context-menu__item--danger{color:var(--color-error, #dc2626)}.context-menu__shortcut{color:var(--color-text-muted);font-size:var(--font-size-xs)}.context-menu__divider{height:1px;margin:var(--space-1) 0;background:var(--color-border)}.dialog-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:3100;display:flex;align-items:center;justify-content:center;padding:var(--space-4);background:#0f172a73}.dialog{width:min(420px,100%);padding:var(--space-4);background:var(--color-surface);border-radius:var(--radius-md);box-shadow:0 16px 40px #00000040}.dialog__title{margin:0 0 var(--space-3);font-size:var(--font-size-lg, 1.125rem)}.dialog__field{display:block;margin-bottom:var(--space-3)}.dialog__field span{display:block;margin-bottom:var(--space-1);color:var(--color-text-muted);font-size:var(--font-size-xs)}.dialog__field input{width:100%;min-height:40px;padding:0 var(--space-3);border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-surface);color:var(--color-text)}.dialog__text{margin:0 0 var(--space-3);color:var(--color-text-muted)}.dialog__footer{display:flex;justify-content:flex-end;gap:var(--space-2)}.dialog__footer button{min-height:40px;padding:0 var(--space-4)}.dialog__primary{border-color:var(--color-primary, #2f6fed);background:var(--color-primary, #2f6fed);color:#fff}.dialog__primary--danger{border-color:var(--color-error, #dc2626);background:var(--color-error, #dc2626)}.file-browser__split{display:grid;grid-template-columns:minmax(160px,220px) minmax(0,1fr);gap:var(--space-4);margin-top:var(--space-3)}.file-browser__tree-pane{overflow:auto;max-height:62vh;border-right:1px solid var(--color-border);padding-right:var(--space-3)}.root-item{display:flex;flex-direction:column;align-items:stretch;gap:2px;width:100%;min-height:44px;padding:var(--space-1) var(--space-2);border:1px solid transparent;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);text-align:left;cursor:pointer}.root-item:hover{background:var(--color-hover)}.root-item--active{background:color-mix(in srgb,var(--color-primary) 12%,transparent);border-color:color-mix(in srgb,var(--color-primary) 35%,transparent);font-weight:600}.root-item__name{font-size:var(--font-size-sm, .875rem);word-break:break-all}.root-item__size{color:var(--color-text-muted);font-size:var(--font-size-xs)}.root-item__bar{display:block;width:100%;height:3px;margin-top:2px;border-radius:999px;background:var(--color-surface-muted);overflow:hidden;pointer-events:none}.root-item__bar-fill{display:block;height:100%;background:var(--color-text-muted);border-radius:inherit;transition:width .2s ease-out}.root-item__bar-fill--warn{background:var(--color-warn)}.root-item__bar-fill--danger{background:var(--color-error)}.dir-tree__caption{margin:0 0 var(--space-2);color:var(--color-text-muted);font-size:var(--font-size-xs)}.dir-tree__node{display:flex;align-items:center;gap:var(--space-1);width:100%;min-height:40px;padding:0 var(--space-2);border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);text-align:left;cursor:pointer}.dir-tree__node:hover{background:var(--color-hover)}.dir-tree__node--active{background:var(--color-hover);font-weight:600}.dir-tree__node[data-drop-active=true]{outline:2px dashed var(--color-primary, #2f6fed);outline-offset:-2px;background:color-mix(in srgb,var(--color-primary, #2f6fed) 12%,transparent)}.dir-tree__list{margin:0;padding:0;list-style:none}.dir-tree__row{display:flex;align-items:center;gap:var(--space-1)}.dir-tree__toggle{width:28px;min-height:40px;border:0;background:transparent;color:var(--color-text-muted);cursor:pointer}.file-table__row--focused{outline:2px solid var(--color-primary, #2f6fed);outline-offset:-2px}.file-table__row--selected{background:color-mix(in srgb,var(--color-primary, #2f6fed) 10%,transparent)}.drop-target{outline:2px dashed var(--color-primary, #2f6fed);outline-offset:2px}@media (max-width: 760px){.file-browser__split{grid-template-columns:minmax(0,1fr)}.file-browser__tree-pane{max-height:30vh;border-right:0;border-bottom:1px solid var(--color-border);padding-right:0;padding-bottom:var(--space-2)}}.topbar__menu,.sidebar__close{display:none}@media (max-width: 760px){.app-shell{grid-template-columns:minmax(0,1fr);grid-template-areas:"topbar" "main" "bottombar"}.topbar__menu{display:inline-flex;align-items:center;justify-content:center;min-width:40px;min-height:40px;border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-surface);color:var(--color-text)}.sidebar{position:fixed;left:0;top:0;bottom:0;z-index:2500;width:min(78vw,300px);transform:translate(-100%);transition:transform .18s ease-out;box-shadow:8px 0 24px #0000002e}.sidebar--open{transform:none}.sidebar__close{display:inline-flex;align-items:center;justify-content:center;align-self:flex-end;min-width:40px;min-height:40px;border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-surface);color:var(--color-text)}}@media (max-width: 760px){.topbar__search,.topbar__crumbs,.topbar__brand-sub{display:none}.topbar{gap:var(--space-2);padding:0 var(--space-2);overflow:hidden}.topbar__brand{flex-shrink:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.file-browser__permission{max-width:62ch;padding:var(--space-2) var(--space-3);border:1px solid var(--color-border);border-left:3px solid var(--color-warn);border-radius:var(--radius-sm);background:var(--color-surface-muted)}.file-browser__permission p{margin:var(--space-1) 0}.file-browser__permission ul{margin:var(--space-1) 0;padding-left:1.25rem;line-height:1.6}.file-browser__permission code{padding:0 .25em;border-radius:3px;background:var(--color-hover);font-size:.92em}.file-browser__toolbar button:disabled{opacity:1;color:var(--color-text-muted);border-color:var(--color-border);background:var(--color-surface-muted);cursor:not-allowed}.file-browser__toolbar{flex-wrap:wrap;row-gap:var(--space-2)}.file-browser__toolbar button,.file-browser__crumb{flex-shrink:0}.bottom-task-bar{flex-wrap:wrap;gap:var(--space-1);padding:var(--space-1) var(--space-2);overflow:hidden}.bottom-task-bar__metrics{display:none}.bottom-task-bar__actions{flex-wrap:wrap;margin-left:auto}.file-browser__toolbar button,.file-browser__crumb,.bottom-task-bar__actions button,.dir-tree__node,.dir-tree__toggle{min-height:44px}.file-browser__toolbar [data-testid=open-compress],.file-browser__toolbar [data-testid=open-extract],.file-browser__toolbar [data-testid=reload],.file-browser__toolbar [data-testid=selection-count]{display:none}}.file-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:var(--space-3);margin-top:var(--space-3)}.file-card{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:var(--space-1);min-height:96px;padding:var(--space-3) var(--space-2);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface);cursor:pointer;text-align:center;overflow:hidden}.file-card--selected{background:color-mix(in srgb,var(--color-primary, #2f6fed) 12%,transparent);outline:2px solid var(--color-primary, #2f6fed);outline-offset:-2px}.file-card--focused{outline:2px dashed var(--color-primary, #2f6fed);outline-offset:-2px}.file-card__icon{color:var(--color-text-muted)}.file-card__name{width:100%;font-size:var(--font-size-xs);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;word-break:break-all}.file-card__meta{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--space-1);color:var(--color-text-muted);font-size:var(--font-size-xs)}.bottom-bar{position:fixed;left:0;right:0;bottom:0;z-index:2000;display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-2) var(--space-3) calc(var(--space-2) + env(safe-area-inset-bottom,0px));background:var(--color-surface);border-top:1px solid var(--color-border);box-shadow:0 -6px 20px #0000001a}.bottom-bar__count{color:var(--color-text-muted);font-size:var(--font-size-xs)}.bottom-bar__actions{display:flex;gap:var(--space-2)}.bottom-bar__actions button{flex:1;min-height:44px;padding:0 var(--space-2)}.bottom-bar__danger{color:var(--color-error, #dc2626);border-color:currentcolor}@media (pointer: coarse){.file-table__row{height:44px}.file-table__row td{padding-top:0;padding-bottom:0}button,.file-browser__crumb,.dir-tree__node{min-height:44px}}@media (max-width: 760px){.file-grid{grid-template-columns:repeat(auto-fill,minmax(104px,1fr))}.file-browser{padding-bottom:96px}.drawer button,.drawer input,.drawer select,.dialog button,.dialog input{min-height:44px}}.placeholder-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:var(--space-4)}.placeholder-block{border:1px dashed var(--color-border-strong);border-radius:var(--radius-md);padding:var(--space-4);color:var(--color-text-muted);font-size:var(--font-size-sm);background:var(--color-surface-muted)}.badge{display:inline-flex;align-items:center;gap:var(--space-1);padding:1px var(--space-2);border-radius:var(--radius-sm);font-size:var(--font-size-xs);background:var(--color-surface-muted);border:1px solid var(--color-border);color:var(--color-text-muted)}.badge--ok{color:var(--color-ok);border-color:color-mix(in srgb,var(--color-ok) 35%,transparent)}.badge--active{color:var(--color-primary);border-color:color-mix(in srgb,var(--color-primary) 35%,transparent)}.badge--warn{color:var(--color-warn);border-color:color-mix(in srgb,var(--color-warn) 35%,transparent)}.badge--error{color:var(--color-error);border-color:color-mix(in srgb,var(--color-error) 35%,transparent)}.bottom-task-bar__summary{display:flex;align-items:center;gap:var(--space-3);font-size:var(--font-size-sm);white-space:nowrap}.bottom-task-bar__current{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text-muted)}.bottom-task-bar__metrics{display:flex;gap:var(--space-3);font-family:var(--font-mono);font-size:var(--font-size-xs);color:var(--color-text-muted);white-space:nowrap}.bottom-task-bar__actions{display:flex;gap:var(--space-2)}.login-page{display:flex;align-items:center;justify-content:center;min-height:60vh}.login-card{width:min(380px,100%)}.login-card__brand{font-size:var(--font-size-xl);font-weight:600;margin-bottom:var(--space-2)}.login-form{display:flex;flex-direction:column;gap:var(--space-2);margin-top:var(--space-4)}.login-form__label{font-size:var(--font-size-sm);color:var(--color-text-muted)}.login-form__error{color:var(--color-error);font-size:var(--font-size-sm)}.login-form__submit{margin-top:var(--space-2);color:var(--color-text-inverse);background:var(--color-primary);border-color:var(--color-primary)}.login-form__submit:hover:not(:disabled){background:color-mix(in srgb,var(--color-primary) 88%,black)}.file-browser{padding:0;overflow:hidden}.file-browser__toolbar{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-3);border-bottom:1px solid var(--color-border);background:var(--color-surface-muted)}.file-browser__crumbs{display:flex;align-items:center;gap:var(--space-1);flex-wrap:wrap;min-width:0}.file-browser__crumb{border:none;min-height:auto;padding:2px var(--space-1);color:var(--color-primary);background:none}.file-browser__crumb[aria-current=page]{color:var(--color-text);font-weight:600;cursor:default}.file-browser__crumb:hover:not([aria-current=page]){text-decoration:underline;background:none}.file-browser__hint{padding:var(--space-3);color:var(--color-text-muted);font-size:var(--font-size-sm)}.file-browser__empty,.file-browser__error{padding:var(--space-5);display:flex;flex-direction:column;gap:var(--space-2);align-items:flex-start}.file-browser__error{color:var(--color-error)}.file-browser__error p{color:var(--color-text)}.file-table{width:100%;border-collapse:collapse;font-size:var(--font-size-sm)}.file-table th,.file-table td{text-align:left;padding:var(--space-2) var(--space-3);border-bottom:1px solid var(--color-border);white-space:nowrap}.file-table thead th{font-weight:600;color:var(--color-text-muted);background:var(--color-surface)}.file-table__sort{border:none;padding:0;min-height:auto;color:inherit;background:none;font-weight:600}.file-table__row{cursor:default}.file-table__row--dir{cursor:pointer}.file-table__row:hover{background:var(--color-hover)}.file-table__name{display:inline-flex;align-items:center;gap:var(--space-2);min-width:0}.file-table__col-type{width:88px;color:var(--color-text-muted)}.file-table__size,.file-table__mtime{color:var(--color-text-muted);font-variant-numeric:tabular-nums}.file-table__col-check{width:32px;text-align:center}.file-table__col-check input{min-height:auto;cursor:pointer}.drawer-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:#0f172a59;display:flex;justify-content:flex-end;z-index:3000}.drawer{width:min(420px,100%);height:100%;background:var(--color-surface);box-shadow:var(--shadow-pop);display:flex;flex-direction:column;padding-bottom:env(safe-area-inset-bottom,0px)}.drawer__header,.drawer__footer{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-3) var(--space-4);border-bottom:1px solid var(--color-border)}.drawer__footer{border-bottom:none;border-top:1px solid var(--color-border);justify-content:flex-end}.drawer__close{margin-left:auto}.drawer__body{padding:var(--space-4);display:flex;flex-direction:column;gap:var(--space-4);overflow:auto;flex:1 1 auto}.field{border:1px solid var(--color-border);border-radius:var(--radius-md);padding:var(--space-3);display:flex;flex-direction:column;gap:var(--space-2)}.field legend{font-size:var(--font-size-xs);color:var(--color-text-muted);padding:0 var(--space-1)}.field__option{display:flex;align-items:center;gap:var(--space-2);font-size:var(--font-size-sm)}.field__option input{min-height:auto}.field__label{font-size:var(--font-size-sm);color:var(--color-text-muted)}.drawer__hardlink-hint{margin:0;padding:var(--space-2) var(--space-3);border:1px solid color-mix(in srgb,var(--color-primary) 32%,var(--color-border));border-left:3px solid var(--color-primary);border-radius:var(--radius-sm);background:color-mix(in srgb,var(--color-primary) 8%,var(--color-surface));color:var(--color-text);font-size:var(--font-size-sm);line-height:1.55;overflow-wrap:anywhere}.drawer__hardlink-hint b{font-weight:600}.drawer__hardlink-hint--ok{border-color:color-mix(in srgb,var(--color-ok) 32%,var(--color-border));border-left-color:var(--color-ok);background:color-mix(in srgb,var(--color-ok) 8%,var(--color-surface))}.field__hint{font-size:var(--font-size-xs);color:var(--color-text-muted)}.progress{height:8px;border-radius:999px;background:var(--color-surface-muted);border:1px solid var(--color-border);overflow:hidden;margin:var(--space-2) 0}.progress__bar{height:100%;background:var(--color-primary);transition:width .2s ease}.task-panel__head{display:flex;align-items:center;gap:var(--space-2)}.task-panel__confirm{display:flex;align-items:center;gap:var(--space-3);margin-top:var(--space-2);padding:var(--space-2) var(--space-3);border:1px solid var(--color-border-strong);border-radius:var(--radius-md);background:var(--color-surface-muted)}.bottom-task-bar__progress{display:inline-block;width:120px;height:6px;border-radius:999px;background:var(--color-surface-muted);border:1px solid var(--color-border);overflow:hidden;vertical-align:middle}.bottom-task-bar__file{color:var(--color-text-muted);max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.drawer--wide{width:min(760px,100%)}.task-drawer__body{display:grid;grid-template-columns:minmax(220px,1fr) minmax(280px,1.4fr);gap:var(--space-4);align-items:start}.task-drawer__list{display:flex;flex-direction:column;gap:var(--space-1);max-height:70vh;overflow:auto}.task-drawer__row{display:flex;align-items:center;gap:var(--space-2);justify-content:flex-start;text-align:left;width:100%}.task-drawer__row--active{outline:2px solid var(--color-primary)}.task-drawer__detail{border-left:1px solid var(--color-border);padding-left:var(--space-4);display:flex;flex-direction:column;gap:var(--space-2)}.task-drawer__kv{display:grid;grid-template-columns:72px 1fr;gap:var(--space-1) var(--space-2);font-size:var(--font-size-sm)}.task-drawer__kv dt{color:var(--color-text-muted)}.task-drawer__actions{display:flex;gap:var(--space-2);flex-wrap:wrap;margin-top:var(--space-2)}.modal-mask[data-v-b8c79d1b]{position:fixed;top:0;right:0;bottom:0;left:0;background:#00000073;display:flex;align-items:center;justify-content:center;z-index:60;padding:16px}.modal-card[data-v-b8c79d1b]{width:min(560px,100%);max-height:82vh;overflow:auto;background:var(--color-surface, #fff);border-radius:12px;padding:18px 20px;box-shadow:0 18px 48px #0000003d}.modal-card__head[data-v-b8c79d1b]{display:flex;align-items:center;justify-content:space-between;gap:12px}.modal-card__head h3[data-v-b8c79d1b]{margin:0;font-size:16px}.modal-card__close[data-v-b8c79d1b]{min-height:40px;min-width:64px;border:1px solid var(--color-border, #d8dde6);border-radius:8px;background:transparent;cursor:pointer}.modal-card__hint[data-v-b8c79d1b]{margin:10px 0;font-size:13px;line-height:1.6;color:var(--color-text-muted, #5b6472)}.modal-card__error[data-v-b8c79d1b]{margin:10px 0;color:var(--color-danger, #d33);font-size:13px}.modal-card__stats[data-v-b8c79d1b]{display:flex;flex-wrap:wrap;gap:8px 16px;padding:0;margin:10px 0;list-style:none;font-size:13px}.modal-card__list[data-v-b8c79d1b]{margin:8px 0;padding:0;list-style:none;font-size:12px;display:grid;gap:6px}.modal-card__list li[data-v-b8c79d1b]{display:flex;flex-wrap:wrap;gap:6px;padding:6px 8px;border-radius:6px;background:var(--color-surface-alt, #f5f7fa);word-break:break-all}.modal-card__list .arrow[data-v-b8c79d1b]{color:var(--color-text-muted, #5b6472)}.modal-card__list .to[data-v-b8c79d1b]{color:var(--color-primary, #2f6fed);font-weight:600}.modal-card__foot[data-v-b8c79d1b]{display:flex;justify-content:flex-end;gap:10px;margin-top:14px}.modal-card__foot .btn[data-v-b8c79d1b]{min-height:40px;min-width:88px;border-radius:8px;border:1px solid var(--color-border, #d8dde6);background:transparent;cursor:pointer}.modal-card__foot .btn--primary[data-v-b8c79d1b]{background:var(--color-primary, #2f6fed);border-color:var(--color-primary, #2f6fed);color:#fff}.modal-card__foot .btn[data-v-b8c79d1b]:disabled{opacity:.5;cursor:not-allowed}.hardlink-form[data-v-a34ec66d]{display:flex;flex-direction:column;gap:10px;margin:12px 0}.hardlink-form__row[data-v-a34ec66d]{display:flex;flex-direction:column;gap:4px}.hardlink-form__row input[data-v-a34ec66d]{padding:8px 10px;border:1px solid var(--color-border, #d0d3d9);border-radius:6px}.hardlink-summary[data-v-a34ec66d]{display:flex;gap:16px;flex-wrap:wrap;padding:8px 0;font-weight:600}.hardlink-groups[data-v-a34ec66d]{display:flex;flex-direction:column;gap:10px}.hardlink-groups__all[data-v-a34ec66d]{display:flex;align-items:center;gap:8px;font-weight:600}.hardlink-group[data-v-a34ec66d]{border:1px solid var(--color-border, #d0d3d9);border-radius:8px;padding:10px}.hardlink-group--selected[data-v-a34ec66d]{border-color:var(--color-primary, #2f6fed)}.hardlink-group__head[data-v-a34ec66d]{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.hardlink-group__paths[data-v-a34ec66d]{margin:8px 0 0;padding-left:28px;word-break:break-all}.hardlink-group__master[data-v-a34ec66d]{font-weight:600}.uplot,.uplot *,.uplot *:before,.uplot *:after{box-sizing:border-box}.uplot{font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5;width:min-content}.u-title{text-align:center;font-size:18px;font-weight:700}.u-wrap{position:relative;-webkit-user-select:none;user-select:none}.u-over,.u-under{position:absolute}.u-under{overflow:hidden}.uplot canvas{display:block;position:relative;width:100%;height:100%}.u-axis{position:absolute}.u-legend{font-size:14px;margin:auto;text-align:center}.u-inline{display:block}.u-inline *{display:inline-block}.u-inline tr{margin-right:16px}.u-legend th{font-weight:600}.u-legend th>*{vertical-align:middle;display:inline-block}.u-legend .u-marker{width:1em;height:1em;margin-right:4px;background-clip:padding-box!important}.u-inline.u-live th:after{content:":";vertical-align:middle}.u-inline:not(.u-live) .u-value{display:none}.u-series>*{padding:4px}.u-series th{cursor:pointer}.u-legend .u-off>*{opacity:.3}.u-select{background:#00000012;position:absolute;pointer-events:none}.u-cursor-x,.u-cursor-y{position:absolute;left:0;top:0;pointer-events:none;will-change:transform}.u-hz .u-cursor-x,.u-vt .u-cursor-y{height:100%;border-right:1px dashed #607D8B}.u-hz .u-cursor-y,.u-vt .u-cursor-x{width:100%;border-bottom:1px dashed #607D8B}.u-cursor-pt{position:absolute;top:0;left:0;border-radius:50%;border:0 solid;pointer-events:none;will-change:transform;background-clip:padding-box!important}.u-axis.u-off,.u-select.u-off,.u-cursor-x.u-off,.u-cursor-y.u-off,.u-cursor-pt.u-off{display:none}.trend-chart[data-v-1e8d3936]{width:100%;overflow:hidden}
@@ -0,0 +1,18 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>ZipCalm 压压惊</title>
7
+ <!--
8
+ F1 前端准备块(Vue 3 版):
9
+ - 只搭骨架(四区布局 + vue-router 占位页 + axios 客户端封装),不接后端。
10
+ - 挂载由 src/main.js 完成:createApp(App).use(pinia).use(router).mount('#app')
11
+ -->
12
+ <script type="module" crossorigin src="/assets/index-D3zjq7N2.js"></script>
13
+ <link rel="stylesheet" crossorigin href="/assets/index-D9Vdmrb9.css">
14
+ </head>
15
+ <body>
16
+ <div id="app"></div>
17
+ </body>
18
+ </html>