@oj-module/runtime 0.2.6 → 0.2.14

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.
@@ -4,4 +4,5 @@ export declare function useMenu(): {
4
4
  sideNavMenuKeyInSplitMode: string;
5
5
  topNavItems: import("./types").MenuItemType[];
6
6
  sideNavItems: import("./types").MenuItemType[];
7
+ bottomNavItems: import("./types").MenuItemType[];
7
8
  };
@@ -16,6 +16,11 @@ interface Props extends ButtonProps {
16
16
  * 消息列表
17
17
  */
18
18
  notifications?: NotificationItem[];
19
+ /**
20
+ * 弹层开合回调(容器用它做「打开即重拉」:清空可能发生在通知中心页等
21
+ * 别处,铃铛列表不重拉会一直展示已清空的消息)
22
+ */
23
+ onOpenChange?: (open: boolean) => void;
19
24
  }
20
25
  export declare const NotificationPopup: React.FC<Props>;
21
26
  export {};
@@ -6,6 +6,7 @@ import type { ButtonProps } from "antd";
6
6
  * (popup 按 onEventChange 是否存在推导,评审 A3——不加新 prop);
7
7
  * - 写操作成功后重拉刷新;**重拉失败不清空现有列表**(评审 b4);
8
8
  * - 20x 复制残留已删除(评审 b4,同一 id 复制 20 份会让 markRead 语义失真);
9
- * - viewAll 不接线(N3,模板无通知中心页)。
9
+ * - viewAll 由弹层内直接导航到通知中心页(N3 落地,不经过 provider——
10
+ * 本组件的 onEventChange 仍只承载写事件,read-only 推导不受影响)。
10
11
  */
11
12
  export declare function NotificationContainer({ ...restProps }: ButtonProps): import("#node_modules/@types/react").JSX.Element;
@@ -1,5 +1,13 @@
1
1
  import type { AppRouteRecordRaw } from "../types";
2
- /** 按照路由中 order 升序来排序路由 */
2
+ /**
3
+ * 按照路由中 order 升序来排序路由(双段序轴,2026-10-20):
4
+ * - order >= 0:主菜单区,升序在前;
5
+ * - order < 0 :底部固定区,升序在后(-2 在 -1 上面)——渲染层
6
+ * (layout-sidebar / layout-mixed-sidebar 第二列)把这一段 pin 在
7
+ * 侧边栏底部,其余菜单形态按列表末尾回落;
8
+ * - 未声明 order:沿用数组下标兜底(下标 + 2)。order: 0 是合法值,
9
+ * 用 ?? 判定(历史实现用 ||,0 会被误当「未设置」改写成兜底值)。
10
+ */
3
11
  export declare function ascending(arr: AppRouteRecordRaw[]): ({
4
12
  handle: {
5
13
  order: number;
@@ -11,7 +11,9 @@ export type AnnotatedRoute = AppRouteRecordRaw;
11
11
  * - 三值 category 原样落 handle.category(main=常规组、admin=管理组、hidden=不进菜单);
12
12
  * - hidden 与 enabled=0(禁用)复用既有 hideInMenu 通路——只过滤菜单层,路由仍可达
13
13
  * (禁用的路由摘除归装载层三处同写,D12);
14
- * - order 覆写为声明序:框架项保留 100 间隔带、方案项从 200 起编,共用一条序轴;
14
+ * - order 覆写为声明序(2026-10-20 双段序轴):框架常规项 ≥0 升序、管理面负数入
15
+ * 底部固定区(pin 侧边栏底部,ascending 双段排序)、方案项从 200 起编,共用一条序轴;
16
+ * 同 order 按根 path 字母序;
15
17
  * - 未匹配路由(框架/后端)原样保留(同一对象引用),入参不突变;
16
18
  * - solRoutes 为空(端点失败/未登录降级空表)时原样返回——降级不阻断,路由照常。
17
19
  *
package/dist/runtime.js CHANGED
@@ -2,7 +2,7 @@
2
2
  if (typeof document !== "undefined" && !document.querySelector("style[data-ojm-runtime-css]")) {
3
3
  const s = document.createElement("style");
4
4
  s.setAttribute("data-ojm-runtime-css", "");
5
- s.textContent = "\n@layer properties, reset, antd;\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer reset{\n/* stylelint-disable */\nhtml,\nbody {\n width: 100%;\n height: 100%;\n}\ninput::-ms-clear,\ninput::-ms-reveal {\n display: none;\n}\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n -ms-overflow-style: scrollbar;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nbody {\n margin: 0;\n}\n[tabindex='-1']:focus {\n outline: none;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n margin-top: 0;\n margin-bottom: 0.5em;\n font-weight: 500;\n}\np {\n margin-top: 0;\n margin-bottom: 1em;\n}\nabbr[title],\nabbr[data-original-title] {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n border-bottom: 0;\n cursor: help;\n}\naddress {\n margin-bottom: 1em;\n font-style: normal;\n line-height: inherit;\n}\ninput[type='text'],\ninput[type='password'],\ninput[type='number'],\ntextarea {\n -webkit-appearance: none;\n}\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1em;\n}\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\ndt {\n font-weight: 500;\n}\ndd {\n margin-bottom: 0.5em;\n margin-left: 0;\n}\nblockquote {\n margin: 0 0 1em;\n}\ndfn {\n font-style: italic;\n}\nb,\nstrong {\n font-weight: bolder;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\nsub {\n bottom: -0.25em;\n}\nsup {\n top: -0.5em;\n}\npre,\ncode,\nkbd,\nsamp {\n font-size: 1em;\n font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;\n}\npre {\n margin-top: 0;\n margin-bottom: 1em;\n overflow: auto;\n}\nfigure {\n margin: 0 0 1em;\n}\nimg {\n vertical-align: middle;\n border-style: none;\n}\na,\narea,\nbutton,\n[role='button'],\ninput:not([type='range']),\nlabel,\nselect,\nsummary,\ntextarea {\n touch-action: manipulation;\n}\ntable {\n border-collapse: collapse;\n}\ncaption {\n padding-top: 0.75em;\n padding-bottom: 0.3em;\n text-align: left;\n caption-side: bottom;\n}\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n color: inherit;\n font-size: inherit;\n font-family: inherit;\n line-height: inherit;\n}\nbutton,\ninput {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml [type='button'],\n[type='reset'],\n[type='submit'] {\n -webkit-appearance: button;\n}\nbutton::-moz-focus-inner,\n[type='button']::-moz-focus-inner,\n[type='reset']::-moz-focus-inner,\n[type='submit']::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\ninput[type='radio'],\ninput[type='checkbox'] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type='date'],\ninput[type='time'],\ninput[type='datetime-local'],\ninput[type='month'] {\n -webkit-appearance: listbox;\n}\ntextarea {\n overflow: auto;\n resize: vertical;\n}\nfieldset {\n min-width: 0;\n margin: 0;\n padding: 0;\n border: 0;\n}\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n margin-bottom: 0.5em;\n padding: 0;\n color: inherit;\n font-size: 1.5em;\n line-height: inherit;\n white-space: normal;\n}\nprogress {\n vertical-align: baseline;\n}\n[type='number']::-webkit-inner-spin-button,\n[type='number']::-webkit-outer-spin-button {\n height: auto;\n}\n[type='search'] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n[type='search']::-webkit-search-cancel-button,\n[type='search']::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\noutput {\n display: inline-block;\n}\nsummary {\n display: list-item;\n}\ntemplate {\n display: none;\n}\n[hidden] {\n display: none !important;\n}\n}\n@layer simplebar{\n[data-simplebar]{position:relative;flex-direction:column;flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;align-items:flex-start}.simplebar-wrapper{overflow:hidden;width:inherit;height:inherit;max-width:inherit;max-height:inherit}.simplebar-mask{direction:inherit;position:absolute;overflow:hidden;padding:0;margin:0;left:0;top:0;bottom:0;right:0;width:auto!important;height:auto!important;z-index:0}.simplebar-offset{direction:inherit!important;box-sizing:inherit!important;resize:none!important;position:absolute;top:0;left:0;bottom:0;right:0;padding:0;margin:0;-webkit-overflow-scrolling:touch}.simplebar-content-wrapper{direction:inherit;box-sizing:border-box!important;position:relative;display:block;height:100%;width:auto;max-width:100%;max-height:100%;overflow:auto;scrollbar-width:none;-ms-overflow-style:none}.simplebar-content-wrapper::-webkit-scrollbar,.simplebar-hide-scrollbar::-webkit-scrollbar{display:none;width:0;height:0}.simplebar-content:after,.simplebar-content:before{content:' ';display:table}.simplebar-placeholder{max-height:100%;max-width:100%;width:100%;pointer-events:none}.simplebar-height-auto-observer-wrapper{box-sizing:inherit!important;height:100%;width:100%;max-width:1px;position:relative;float:left;max-height:1px;overflow:hidden;z-index:-1;padding:0;margin:0;pointer-events:none;flex-grow:inherit;flex-shrink:0;flex-basis:0}.simplebar-height-auto-observer{box-sizing:inherit;display:block;opacity:0;position:absolute;top:0;left:0;height:1000%;width:1000%;min-height:1px;min-width:1px;overflow:hidden;pointer-events:none;z-index:-1}.simplebar-track{z-index:1;position:absolute;right:0;bottom:0;pointer-events:none;overflow:hidden}[data-simplebar].simplebar-dragging{pointer-events:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}[data-simplebar].simplebar-dragging .simplebar-content{pointer-events:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}[data-simplebar].simplebar-dragging .simplebar-track{pointer-events:all}.simplebar-scrollbar{position:absolute;left:0;right:0;min-height:10px}.simplebar-scrollbar:before{position:absolute;content:'';background:#000;border-radius:7px;left:2px;right:2px;opacity:0;transition:opacity .2s .5s linear}.simplebar-scrollbar.simplebar-visible:before{opacity:.5;transition-delay:0s;transition-duration:0s}.simplebar-track.simplebar-vertical{top:0;width:11px}.simplebar-scrollbar:before{top:2px;bottom:2px;left:2px;right:2px}.simplebar-track.simplebar-horizontal{left:0;height:11px}.simplebar-track.simplebar-horizontal .simplebar-scrollbar{right:auto;left:0;top:0;bottom:0;min-height:0;min-width:10px;width:auto}[data-simplebar-direction=rtl] .simplebar-track.simplebar-vertical{right:auto;left:0}.simplebar-dummy-scrollbar-size{direction:rtl;position:fixed;opacity:0;visibility:hidden;height:500px;width:500px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:scrollbar!important}.simplebar-dummy-scrollbar-size>div{width:200%;height:200%;margin:10px 0}.simplebar-hide-scrollbar{position:fixed;left:0;visibility:hidden;overflow-y:scroll;scrollbar-width:none;-ms-overflow-style:none}\n}\n@layer simplebar {\n .simplebar-scrollbar:before {\n background-color: #909399;\n }\n\n .simplebar-content {\n height: 100%;\n }\n}\n\n#root {\n height: 100vh;\n}\n\nimg {\n max-width: 100%;\n height: auto;\n}\n\nhtml.color-blind-mode {\n --tw-invert: invert(100%);\n filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );\n}\n\nhtml.gray-mode {\n --tw-grayscale: grayscale(100%);\n filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );\n}\n\n@layer theme {\n :root, :host {\n --font-sans: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", \"Noto Sans\", Arial,\n sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --spacing: .25rem;\n --container-md: 28rem;\n --text-xs: .75rem;\n --text-xs--line-height: calc(1 / .75);\n --text-sm: .875rem;\n --text-sm--line-height: calc(1.25 / .875);\n --text-lg: 1.125rem;\n --text-lg--line-height: calc(1.75 / 1.125);\n --text-xl: 1.25rem;\n --text-xl--line-height: calc(1.75 / 1.25);\n --text-2xl: 1.5rem;\n --text-2xl--line-height: calc(2 / 1.5);\n --text-3xl: 1.875rem;\n --text-3xl--line-height: calc(2.25 / 1.875);\n --font-weight-medium: 500;\n --font-weight-semibold: 600;\n --font-weight-bold: 700;\n --tracking-tight: -.025em;\n --radius-sm: .25rem;\n --radius-md: .375rem;\n --radius-xl: .75rem;\n --ease-in: cubic-bezier(.4, 0, 1, 1);\n --animate-spin: spin 1s linear infinite;\n --default-transition-duration: .15s;\n --default-transition-timing-function: cubic-bezier(.4, 0, .2, 1);\n --animate-wiggle: wiggle 1s both;\n --animate-bounce-in-down-out-up: bounce-in-down-out-up 4s ease-in-out 0s infinite;\n }\n}\n\n@layer base, components;\n\n@layer utilities {\n .visible {\n visibility: visible;\n }\n\n .absolute {\n position: absolute;\n }\n\n .fixed {\n position: fixed;\n }\n\n .relative {\n position: relative;\n }\n\n .static {\n position: static;\n }\n\n .top-0 {\n top: 0;\n }\n\n .top-1\\.5 {\n top: calc(var(--spacing) * 1.5);\n }\n\n .top-2 {\n top: calc(var(--spacing) * 2);\n }\n\n .top-3 {\n top: calc(var(--spacing) * 3);\n }\n\n .right-2 {\n right: calc(var(--spacing) * 2);\n }\n\n .right-3 {\n right: calc(var(--spacing) * 3);\n }\n\n .right-4 {\n right: calc(var(--spacing) * 4);\n }\n\n .bottom-0 {\n bottom: 0;\n }\n\n .bottom-3 {\n bottom: calc(var(--spacing) * 3);\n }\n\n .left-0 {\n left: 0;\n }\n\n .left-1\\/2 {\n left: 50%;\n }\n\n .left-3 {\n left: calc(var(--spacing) * 3);\n }\n\n .z-10 {\n z-index: 10;\n }\n\n .container {\n width: 100%;\n }\n\n @media (min-width: 480px) {\n .container {\n max-width: 480px;\n }\n }\n\n @media (min-width: 576px) {\n .container {\n max-width: 576px;\n }\n }\n\n @media (min-width: 768px) {\n .container {\n max-width: 768px;\n }\n }\n\n @media (min-width: 992px) {\n .container {\n max-width: 992px;\n }\n }\n\n @media (min-width: 1200px) {\n .container {\n max-width: 1200px;\n }\n }\n\n @media (min-width: 1600px) {\n .container {\n max-width: 1600px;\n }\n }\n\n .m-0 {\n margin: 0;\n }\n\n .m-152 {\n margin: calc(var(--spacing) * 152);\n }\n\n .mx-3 {\n margin-inline: calc(var(--spacing) * 3);\n }\n\n .mx-4 {\n margin-inline: calc(var(--spacing) * 4);\n }\n\n .mx-auto {\n margin-inline: auto;\n }\n\n .my-0 {\n margin-block: 0;\n }\n\n .my-1 {\n margin-block: var(--spacing);\n }\n\n .my-4 {\n margin-block: calc(var(--spacing) * 4);\n }\n\n .my-8 {\n margin-block: calc(var(--spacing) * 8);\n }\n\n .mt-2 {\n margin-top: calc(var(--spacing) * 2);\n }\n\n .mt-2\\.5 {\n margin-top: calc(var(--spacing) * 2.5);\n }\n\n .mt-4 {\n margin-top: calc(var(--spacing) * 4);\n }\n\n .mt-6 {\n margin-top: calc(var(--spacing) * 6);\n }\n\n .mr-2 {\n margin-right: calc(var(--spacing) * 2);\n }\n\n .mr-3 {\n margin-right: calc(var(--spacing) * 3);\n }\n\n .mr-8 {\n margin-right: calc(var(--spacing) * 8);\n }\n\n .mr-17 {\n margin-right: calc(var(--spacing) * 17);\n }\n\n .mb-0 {\n margin-bottom: 0;\n }\n\n .mb-2 {\n margin-bottom: calc(var(--spacing) * 2);\n }\n\n .mb-3 {\n margin-bottom: calc(var(--spacing) * 3);\n }\n\n .mb-6 {\n margin-bottom: calc(var(--spacing) * 6);\n }\n\n .ml-2 {\n margin-left: calc(var(--spacing) * 2);\n }\n\n .ml-4 {\n margin-left: calc(var(--spacing) * 4);\n }\n\n .box-border {\n box-sizing: border-box;\n }\n\n .line-clamp-2 {\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n display: -webkit-box;\n overflow: hidden;\n }\n\n .block {\n display: block;\n }\n\n .flex {\n display: flex;\n }\n\n .hidden {\n display: none;\n }\n\n .inline {\n display: inline;\n }\n\n .inline-block {\n display: inline-block;\n }\n\n .table {\n display: table;\n }\n\n .aspect-square {\n aspect-ratio: 1;\n }\n\n .size-5 {\n width: calc(var(--spacing) * 5);\n height: calc(var(--spacing) * 5);\n }\n\n .h-2 {\n height: calc(var(--spacing) * 2);\n }\n\n .h-5 {\n height: calc(var(--spacing) * 5);\n }\n\n .h-10 {\n height: calc(var(--spacing) * 10);\n }\n\n .h-64 {\n height: calc(var(--spacing) * 64);\n }\n\n .h-\\[0\\.63em\\] {\n height: .63em;\n }\n\n .h-full {\n height: 100%;\n }\n\n .h-screen {\n height: 100vh;\n }\n\n .w-1\\/3 {\n width: 33.3333%;\n }\n\n .w-2 {\n width: calc(var(--spacing) * 2);\n }\n\n .w-2\\/5 {\n width: 40%;\n }\n\n .w-7\\/12 {\n width: 58.3333%;\n }\n\n .w-10 {\n width: calc(var(--spacing) * 10);\n }\n\n .w-11 {\n width: calc(var(--spacing) * 11);\n }\n\n .w-12 {\n width: calc(var(--spacing) * 12);\n }\n\n .w-40 {\n width: calc(var(--spacing) * 40);\n }\n\n .w-72 {\n width: calc(var(--spacing) * 72);\n }\n\n .w-full {\n width: 100%;\n }\n\n .max-w-90 {\n max-width: calc(var(--spacing) * 90);\n }\n\n .min-w-0 {\n min-width: 0;\n }\n\n .flex-1 {\n flex: 1;\n }\n\n .flex-auto {\n flex: auto;\n }\n\n .flex-shrink-0, .shrink-0 {\n flex-shrink: 0;\n }\n\n .grow {\n flex-grow: 1;\n }\n\n .-translate-x-1\\/2 {\n --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n\n .scale-75 {\n --tw-scale-x: 75%;\n --tw-scale-y: 75%;\n --tw-scale-z: 75%;\n scale: var(--tw-scale-x) var(--tw-scale-y);\n }\n\n .transform {\n transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, );\n }\n\n .animate-spin {\n animation: var(--animate-spin);\n }\n\n .cursor-help {\n cursor: help;\n }\n\n .cursor-pointer {\n cursor: pointer;\n }\n\n .list-none {\n list-style-type: none;\n }\n\n .flex-col {\n flex-direction: column;\n }\n\n .flex-row-reverse {\n flex-direction: row-reverse;\n }\n\n .flex-wrap {\n flex-wrap: wrap;\n }\n\n .items-center {\n align-items: center;\n }\n\n .justify-between {\n justify-content: space-between;\n }\n\n .justify-center {\n justify-content: center;\n }\n\n .justify-start {\n justify-content: flex-start;\n }\n\n .gap-1 {\n gap: var(--spacing);\n }\n\n .gap-2 {\n gap: calc(var(--spacing) * 2);\n }\n\n .gap-3 {\n gap: calc(var(--spacing) * 3);\n }\n\n .gap-5 {\n gap: calc(var(--spacing) * 5);\n }\n\n .gap-x-3 {\n column-gap: calc(var(--spacing) * 3);\n }\n\n .gap-y-5 {\n row-gap: calc(var(--spacing) * 5);\n }\n\n .overflow-hidden {\n overflow: hidden;\n }\n\n .overflow-x-auto {\n overflow-x: auto;\n }\n\n .overflow-x-hidden {\n overflow-x: hidden;\n }\n\n .overflow-y-auto {\n overflow-y: auto;\n }\n\n .rounded {\n border-radius: .25rem;\n }\n\n .rounded-full {\n border-radius: 3.40282e38px;\n }\n\n .rounded-md {\n border-radius: var(--radius-md);\n }\n\n .rounded-none {\n border-radius: 0;\n }\n\n .rounded-sm {\n border-radius: var(--radius-sm);\n }\n\n .rounded-r-xl {\n border-top-right-radius: var(--radius-xl);\n border-bottom-right-radius: var(--radius-xl);\n }\n\n .border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n\n .border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n }\n\n .border-r {\n border-right-style: var(--tw-border-style);\n border-right-width: 1px;\n }\n\n .border-l {\n border-left-style: var(--tw-border-style);\n border-left-width: 1px;\n }\n\n .\\!border-none {\n --tw-border-style: none !important;\n border-style: none !important;\n }\n\n .border-t-\\[\\#303030\\] {\n border-top-color: #303030;\n }\n\n .border-t-colorBorderSecondary {\n border-top-color: var(--oo-colorBorderSecondary);\n }\n\n .border-r-\\[\\#303030\\] {\n border-right-color: #303030;\n }\n\n .border-r-colorBorderSecondary {\n border-right-color: var(--oo-colorBorderSecondary);\n }\n\n .border-l-colorBorderSecondary {\n border-left-color: var(--oo-colorBorderSecondary);\n }\n\n .bg-\\[\\#F3F4F5\\] {\n background-color: #f3f4f5;\n }\n\n .bg-blue-500\\/20 {\n background-color: rgb(var(--oo-blue-5));\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n .bg-blue-500\\/20 {\n background-color: color-mix(in oklab, rgb(var(--oo-blue-5)) 20%, transparent);\n }\n }\n\n .bg-blue-600 {\n background-color: rgb(var(--oo-blue-6));\n }\n\n .bg-colorBgContainer {\n background-color: var(--oo-colorBgContainer);\n }\n\n .bg-colorBgLayout {\n background-color: var(--oo-colorBgLayout);\n }\n\n .bg-gray-100 {\n background-color: #f5f5f5;\n }\n\n .bg-primary {\n background-color: rgb(var(--oo-colorPrimary));\n }\n\n .bg-primaryActive {\n background-color: rgb(var(--oo-colorPrimaryActive));\n }\n\n .object-cover {\n object-fit: cover;\n }\n\n .p-0 {\n padding: 0;\n }\n\n .p-1 {\n padding: var(--spacing);\n }\n\n .p-2 {\n padding: calc(var(--spacing) * 2);\n }\n\n .p-4 {\n padding: calc(var(--spacing) * 4);\n }\n\n .px-0 {\n padding-inline: 0;\n }\n\n .px-1 {\n padding-inline: var(--spacing);\n }\n\n .px-1\\.5 {\n padding-inline: calc(var(--spacing) * 1.5);\n }\n\n .px-2 {\n padding-inline: calc(var(--spacing) * 2);\n }\n\n .px-2\\.75 {\n padding-inline: calc(var(--spacing) * 2.75);\n }\n\n .px-3 {\n padding-inline: calc(var(--spacing) * 3);\n }\n\n .px-4 {\n padding-inline: calc(var(--spacing) * 4);\n }\n\n .px-6 {\n padding-inline: calc(var(--spacing) * 6);\n }\n\n .px-9 {\n padding-inline: calc(var(--spacing) * 9);\n }\n\n .px-10 {\n padding-inline: calc(var(--spacing) * 10);\n }\n\n .px-\\[11px\\] {\n padding-inline: 11px;\n }\n\n .py-1 {\n padding-block: var(--spacing);\n }\n\n .py-1\\.5 {\n padding-block: calc(var(--spacing) * 1.5);\n }\n\n .py-2 {\n padding-block: calc(var(--spacing) * 2);\n }\n\n .py-2\\.5 {\n padding-block: calc(var(--spacing) * 2.5);\n }\n\n .py-4 {\n padding-block: calc(var(--spacing) * 4);\n }\n\n .py-10 {\n padding-block: calc(var(--spacing) * 10);\n }\n\n .pb-4 {\n padding-bottom: calc(var(--spacing) * 4);\n }\n\n .pl-2 {\n padding-left: calc(var(--spacing) * 2);\n }\n\n .text-center {\n text-align: center;\n }\n\n .font-sans {\n font-family: var(--font-sans);\n }\n\n .text-3xl {\n font-size: var(--text-3xl);\n line-height: var(--tw-leading, var(--text-3xl--line-height));\n }\n\n .text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n\n .text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n\n .text-xl {\n font-size: var(--text-xl);\n line-height: var(--tw-leading, var(--text-xl--line-height));\n }\n\n .text-xs {\n font-size: var(--text-xs);\n line-height: var(--tw-leading, var(--text-xs--line-height));\n }\n\n .text-\\[4rem\\] {\n font-size: 4rem;\n }\n\n .leading-none {\n --tw-leading: 1;\n line-height: 1;\n }\n\n .font-bold {\n --tw-font-weight: var(--font-weight-bold);\n font-weight: var(--font-weight-bold);\n }\n\n .font-medium {\n --tw-font-weight: var(--font-weight-medium);\n font-weight: var(--font-weight-medium);\n }\n\n .font-semibold {\n --tw-font-weight: var(--font-weight-semibold);\n font-weight: var(--font-weight-semibold);\n }\n\n .tracking-tight {\n --tw-tracking: var(--tracking-tight);\n letter-spacing: var(--tracking-tight);\n }\n\n .text-colorBgContainer {\n color: var(--oo-colorBgContainer);\n }\n\n .text-colorBgContainer\\! {\n color: var(--oo-colorBgContainer) !important;\n }\n\n .text-colorText {\n color: var(--oo-colorText);\n }\n\n .text-colorText\\! {\n color: var(--oo-colorText) !important;\n }\n\n .text-colorTextSecondary {\n color: var(--oo-colorTextSecondary);\n }\n\n .text-colorTextTertiary {\n color: var(--oo-colorTextTertiary);\n }\n\n .opacity-50 {\n opacity: .5;\n }\n\n .opacity-90 {\n opacity: .9;\n }\n\n .outline, .outline-1 {\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n }\n\n .outline-2 {\n outline-style: var(--tw-outline-style);\n outline-width: 2px;\n }\n\n .outline-blue-600 {\n outline-color: rgb(var(--oo-blue-6));\n }\n\n .outline-gray-300 {\n outline-color: #d9d9d9;\n }\n\n .filter {\n filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );\n }\n\n .transition {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n\n .transition-all {\n transition-property: all;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n\n .duration-300 {\n --tw-duration: .3s;\n transition-duration: .3s;\n }\n\n .ease-in {\n --tw-ease: var(--ease-in);\n transition-timing-function: var(--ease-in);\n }\n\n @media (hover: hover) {\n .group-hover\\:animate-wiggle:is(:where(.group):hover *) {\n animation: var(--animate-wiggle);\n }\n\n .group-hover\\:opacity-100:is(:where(.group):hover *) {\n opacity: 1;\n }\n }\n\n .before\\:absolute:before {\n content: var(--tw-content);\n position: absolute;\n }\n\n .before\\:top-1\\/2:before {\n content: var(--tw-content);\n top: 50%;\n }\n\n .before\\:left-1\\/2:before {\n content: var(--tw-content);\n left: 50%;\n }\n\n .before\\:h-0:before {\n content: var(--tw-content);\n height: 0;\n }\n\n .before\\:w-0:before {\n content: var(--tw-content);\n width: 0;\n }\n\n .before\\:rounded-sm:before {\n content: var(--tw-content);\n border-radius: var(--radius-sm);\n }\n\n .before\\:opacity-0:before {\n content: var(--tw-content);\n opacity: 0;\n }\n\n .before\\:outline:before {\n content: var(--tw-content);\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n }\n\n .before\\:outline-2:before {\n content: var(--tw-content);\n outline-style: var(--tw-outline-style);\n outline-width: 2px;\n }\n\n .before\\:outline-transparent:before {\n content: var(--tw-content);\n outline-color: #0000;\n }\n\n .before\\:transition-all:before {\n content: var(--tw-content);\n transition-property: all;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n\n .before\\:duration-300:before {\n content: var(--tw-content);\n --tw-duration: .3s;\n transition-duration: .3s;\n }\n\n .before\\:content-\\[\\'\\'\\]:before {\n --tw-content: \"\";\n content: var(--tw-content);\n }\n\n .last\\:mr-auto:last-child {\n margin-right: auto;\n }\n\n @media (hover: hover) {\n .hover\\:bg-gray-100:hover {\n background-color: #f5f5f5;\n }\n\n .hover\\:text-colorText:hover {\n color: var(--oo-colorText);\n }\n }\n\n .before\\:hover\\:top-0:before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .before\\:hover\\:top-0:before:hover {\n top: 0;\n }\n }\n\n .before\\:hover\\:left-0:before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .before\\:hover\\:left-0:before:hover {\n left: 0;\n }\n }\n\n .before\\:hover\\:h-full:before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .before\\:hover\\:h-full:before:hover {\n height: 100%;\n }\n }\n\n .before\\:hover\\:w-full:before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .before\\:hover\\:w-full:before:hover {\n width: 100%;\n }\n }\n\n .before\\:hover\\:p-1:before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .before\\:hover\\:p-1:before:hover {\n padding: var(--spacing);\n }\n }\n\n .before\\:hover\\:opacity-100:before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .before\\:hover\\:opacity-100:before:hover {\n opacity: 1;\n }\n }\n\n .before\\:hover\\:outline-blue-600:before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .before\\:hover\\:outline-blue-600:before:hover {\n outline-color: rgb(var(--oo-blue-6));\n }\n }\n\n @media (prefers-reduced-motion: no-preference) {\n .motion-safe\\:animate-bounce-in-down-out-up {\n animation: var(--animate-bounce-in-down-out-up);\n }\n }\n\n @media (min-width: 576px) {\n .sm\\:mx-auto {\n margin-inline: auto;\n }\n }\n\n @media (min-width: 768px) {\n .md\\:mr-2\\.5 {\n margin-right: calc(var(--spacing) * 2.5);\n }\n\n .md\\:block {\n display: block;\n }\n\n .md\\:w-3\\/12 {\n width: 25%;\n }\n\n .md\\:w-96 {\n width: calc(var(--spacing) * 96);\n }\n\n .md\\:max-w-md {\n max-width: var(--container-md);\n }\n\n .md\\:bg-colorBgLayout {\n background-color: var(--oo-colorBgLayout);\n }\n\n .md\\:px-4 {\n padding-inline: calc(var(--spacing) * 4);\n }\n\n .md\\:pb-0 {\n padding-bottom: 0;\n }\n\n .md\\:text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n }\n\n @media (min-width: 992px) {\n .lg\\:text-2xl {\n font-size: var(--text-2xl);\n line-height: var(--tw-leading, var(--text-2xl--line-height));\n }\n }\n\n @media (min-width: 1200px) {\n .xl\\:w-2\\/12 {\n width: 16.6667%;\n }\n\n .xl\\:px-8 {\n padding-inline: calc(var(--spacing) * 8);\n }\n }\n\n .dark\\:bg-\\[\\#26313C\\]:where(.dark, .dark *) {\n background-color: #26313c;\n }\n\n .dark\\:bg-black:where(.dark, .dark *) {\n background-color: #000;\n }\n\n .dark\\:bg-gray-700:where(.dark, .dark *) {\n background-color: #434343;\n }\n\n .dark\\:outline-blue-700:where(.dark, .dark *) {\n outline-color: rgb(var(--oo-blue-7));\n }\n\n .dark\\:outline-gray-700:where(.dark, .dark *) {\n outline-color: #434343;\n }\n\n @media (hover: hover) {\n .dark\\:hover\\:bg-gray-700:where(.dark, .dark *):hover {\n background-color: #434343;\n }\n }\n\n .dark\\:before\\:hover\\:outline-blue-700:where(.dark, .dark *):before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .dark\\:before\\:hover\\:outline-blue-700:where(.dark, .dark *):before:hover {\n outline-color: rgb(var(--oo-blue-7));\n }\n }\n\n .en-US\\:gap-y-3:where(:lang(en-US)) {\n row-gap: calc(var(--spacing) * 3);\n }\n\n .en-US\\:text-\\[9rem\\]:where(:lang(en-US)) {\n font-size: 9rem;\n }\n\n .zh-CN\\:hidden:where(:lang(zh-CN)) {\n display: none;\n }\n}\n\n@keyframes fade-in {\n from {\n opacity: 0;\n }\n\n to {\n opacity: 1;\n }\n}\n\n@keyframes fade-out {\n from {\n opacity: 1;\n }\n\n to {\n opacity: 0;\n }\n}\n\n@keyframes slide-in {\n from {\n transform: translateX(-30px);\n }\n\n to {\n transform: translateX(0);\n }\n}\n\n@keyframes slide-out {\n from {\n transform: translateX(0);\n }\n\n to {\n transform: translateX(30px);\n }\n}\n\n@keyframes slide-top-in {\n from {\n transform: translateY(-10%);\n }\n\n to {\n transform: translateY(0);\n }\n}\n\n@keyframes slide-top-out {\n from {\n transform: translateY(0);\n }\n\n to {\n transform: translateY(-10%);\n }\n}\n\n@keyframes slide-bottom-in {\n from {\n transform: translateY(10%);\n }\n\n to {\n transform: translateY(0);\n }\n}\n\n@keyframes slide-bottom-out {\n from {\n transform: translateY(0);\n }\n\n to {\n transform: translateY(10%);\n }\n}\n\n@keyframes fade-slide {\n 0% {\n opacity: 0;\n transform: translate(-30px);\n }\n\n 50% {\n opacity: 1;\n }\n\n 100% {\n opacity: 0;\n transform: translate(30px);\n }\n}\n\n@keyframes fade-up {\n 0% {\n opacity: 0;\n transform: translateY(10%);\n }\n\n 50% {\n opacity: 1;\n }\n\n 100% {\n opacity: 0;\n transform: translateY(-10%);\n }\n}\n\n@keyframes fade-down {\n 0% {\n opacity: 0;\n transform: translateY(-10%);\n }\n\n 50% {\n opacity: 1;\n }\n\n 100% {\n opacity: 0;\n transform: translateY(10%);\n }\n}\n\n.fade-slide {\n animation: 3s linear infinite fade-slide;\n}\n\n.fade {\n animation: 3s linear infinite alternate fade-in;\n}\n\n.fade-up {\n animation: 3s infinite fade-up;\n}\n\n.fade-down {\n animation: 3s infinite fade-down;\n}\n\n@keyframes zoom-in {\n 0% {\n transform: scale(.8);\n }\n\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes zoom-out {\n 0% {\n transform: scale(1);\n }\n\n 100% {\n opacity: 1;\n transform: scale(1.25);\n }\n}\n\n@keyframes fade-zoom {\n 0% {\n opacity: 0;\n transform: scale(.8);\n }\n\n 50% {\n opacity: 1;\n transform: scale(1);\n }\n\n 100% {\n opacity: 0;\n transform: scale(1.25);\n }\n}\n\n.fade-zoom {\n animation: 3s infinite fade-zoom;\n}\n\n.keepalive-fade.active {\n animation: .3s ease-in-out fade-in;\n}\n\n.keepalive-fade.inactive {\n animation: .3s ease-in-out fade-out;\n}\n\n.keepalive-fade-slide.active {\n animation: .3s ease-in-out fade-in, .3s ease-in-out slide-in;\n}\n\n.keepalive-fade-slide.inactive {\n animation: .3s ease-in-out fade-out, .3s ease-in-out slide-out;\n}\n\n.keepalive-fade-up.active {\n animation: .3s ease-in-out fade-in, .3s ease-in-out slide-bottom-in;\n}\n\n.keepalive-fade-up.inactive {\n animation: .3s ease-in-out fade-out, .3s ease-in-out slide-top-out;\n}\n\n.keepalive-fade-down.active {\n animation: .3s ease-in-out fade-in, .3s ease-in-out slide-top-in;\n}\n\n.keepalive-fade-down.inactive {\n animation: .3s ease-in-out fade-out, .3s ease-in-out slide-bottom-out;\n}\n\n.keepalive-fade-zoom.active {\n animation: .3s ease-in-out zoom-in, .3s ease-in-out zoom-in;\n}\n\n.keepalive-fade-zoom.inactive {\n animation: .3s ease-in-out zoom-out, .3s ease-in-out fade-out;\n}\n\n@property --tw-blur {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-brightness {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-contrast {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-grayscale {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-hue-rotate {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-invert {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-opacity {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-saturate {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-sepia {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-drop-shadow {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-drop-shadow-color {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-drop-shadow-alpha {\n syntax: \"<percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n\n@property --tw-drop-shadow-size {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-translate-x {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-translate-y {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-translate-z {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-scale-x {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n\n@property --tw-scale-y {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n\n@property --tw-scale-z {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n\n@property --tw-rotate-x {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-rotate-y {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-rotate-z {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-skew-x {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-skew-y {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-border-style {\n syntax: \"*\";\n inherits: false;\n initial-value: solid;\n}\n\n@property --tw-leading {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-font-weight {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-tracking {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-outline-style {\n syntax: \"*\";\n inherits: false;\n initial-value: solid;\n}\n\n@property --tw-duration {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-ease {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-content {\n syntax: \"*\";\n inherits: false;\n initial-value: \"\";\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@keyframes wiggle {\n 0%, 100% {\n transform-origin: top;\n }\n\n 15% {\n transform: rotateZ(10deg);\n }\n\n 30% {\n transform: rotateZ(-10deg);\n }\n\n 45% {\n transform: rotateZ(5deg);\n }\n\n 60% {\n transform: rotateZ(-5deg);\n }\n\n 75% {\n transform: rotateZ(2deg);\n }\n}\n\n@keyframes bounce-in-down-out-up {\n 0% {\n transform: translateY(0);\n }\n\n 50% {\n transform: translateY(-20px);\n }\n\n 100% {\n transform: translateY(0);\n }\n}\n\n@layer properties {\n @supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) {\n *, :before, :after, ::backdrop {\n --tw-blur: initial;\n --tw-brightness: initial;\n --tw-contrast: initial;\n --tw-grayscale: initial;\n --tw-hue-rotate: initial;\n --tw-invert: initial;\n --tw-opacity: initial;\n --tw-saturate: initial;\n --tw-sepia: initial;\n --tw-drop-shadow: initial;\n --tw-drop-shadow-color: initial;\n --tw-drop-shadow-alpha: 100%;\n --tw-drop-shadow-size: initial;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-scale-z: 1;\n --tw-rotate-x: initial;\n --tw-rotate-y: initial;\n --tw-rotate-z: initial;\n --tw-skew-x: initial;\n --tw-skew-y: initial;\n --tw-border-style: solid;\n --tw-leading: initial;\n --tw-font-weight: initial;\n --tw-tracking: initial;\n --tw-outline-style: solid;\n --tw-duration: initial;\n --tw-ease: initial;\n --tw-content: \"\";\n }\n }\n}\n/*$vite$:1*/";
5
+ s.textContent = "\n@layer properties, reset, antd;\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer reset{\n/* stylelint-disable */\nhtml,\nbody {\n width: 100%;\n height: 100%;\n}\ninput::-ms-clear,\ninput::-ms-reveal {\n display: none;\n}\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n -ms-overflow-style: scrollbar;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nbody {\n margin: 0;\n}\n[tabindex='-1']:focus {\n outline: none;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n margin-top: 0;\n margin-bottom: 0.5em;\n font-weight: 500;\n}\np {\n margin-top: 0;\n margin-bottom: 1em;\n}\nabbr[title],\nabbr[data-original-title] {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n border-bottom: 0;\n cursor: help;\n}\naddress {\n margin-bottom: 1em;\n font-style: normal;\n line-height: inherit;\n}\ninput[type='text'],\ninput[type='password'],\ninput[type='number'],\ntextarea {\n -webkit-appearance: none;\n}\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1em;\n}\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\ndt {\n font-weight: 500;\n}\ndd {\n margin-bottom: 0.5em;\n margin-left: 0;\n}\nblockquote {\n margin: 0 0 1em;\n}\ndfn {\n font-style: italic;\n}\nb,\nstrong {\n font-weight: bolder;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\nsub {\n bottom: -0.25em;\n}\nsup {\n top: -0.5em;\n}\npre,\ncode,\nkbd,\nsamp {\n font-size: 1em;\n font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;\n}\npre {\n margin-top: 0;\n margin-bottom: 1em;\n overflow: auto;\n}\nfigure {\n margin: 0 0 1em;\n}\nimg {\n vertical-align: middle;\n border-style: none;\n}\na,\narea,\nbutton,\n[role='button'],\ninput:not([type='range']),\nlabel,\nselect,\nsummary,\ntextarea {\n touch-action: manipulation;\n}\ntable {\n border-collapse: collapse;\n}\ncaption {\n padding-top: 0.75em;\n padding-bottom: 0.3em;\n text-align: left;\n caption-side: bottom;\n}\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n color: inherit;\n font-size: inherit;\n font-family: inherit;\n line-height: inherit;\n}\nbutton,\ninput {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml [type='button'],\n[type='reset'],\n[type='submit'] {\n -webkit-appearance: button;\n}\nbutton::-moz-focus-inner,\n[type='button']::-moz-focus-inner,\n[type='reset']::-moz-focus-inner,\n[type='submit']::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\ninput[type='radio'],\ninput[type='checkbox'] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type='date'],\ninput[type='time'],\ninput[type='datetime-local'],\ninput[type='month'] {\n -webkit-appearance: listbox;\n}\ntextarea {\n overflow: auto;\n resize: vertical;\n}\nfieldset {\n min-width: 0;\n margin: 0;\n padding: 0;\n border: 0;\n}\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n margin-bottom: 0.5em;\n padding: 0;\n color: inherit;\n font-size: 1.5em;\n line-height: inherit;\n white-space: normal;\n}\nprogress {\n vertical-align: baseline;\n}\n[type='number']::-webkit-inner-spin-button,\n[type='number']::-webkit-outer-spin-button {\n height: auto;\n}\n[type='search'] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n[type='search']::-webkit-search-cancel-button,\n[type='search']::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\noutput {\n display: inline-block;\n}\nsummary {\n display: list-item;\n}\ntemplate {\n display: none;\n}\n[hidden] {\n display: none !important;\n}\n}\n@layer simplebar{\n[data-simplebar]{position:relative;flex-direction:column;flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;align-items:flex-start}.simplebar-wrapper{overflow:hidden;width:inherit;height:inherit;max-width:inherit;max-height:inherit}.simplebar-mask{direction:inherit;position:absolute;overflow:hidden;padding:0;margin:0;left:0;top:0;bottom:0;right:0;width:auto!important;height:auto!important;z-index:0}.simplebar-offset{direction:inherit!important;box-sizing:inherit!important;resize:none!important;position:absolute;top:0;left:0;bottom:0;right:0;padding:0;margin:0;-webkit-overflow-scrolling:touch}.simplebar-content-wrapper{direction:inherit;box-sizing:border-box!important;position:relative;display:block;height:100%;width:auto;max-width:100%;max-height:100%;overflow:auto;scrollbar-width:none;-ms-overflow-style:none}.simplebar-content-wrapper::-webkit-scrollbar,.simplebar-hide-scrollbar::-webkit-scrollbar{display:none;width:0;height:0}.simplebar-content:after,.simplebar-content:before{content:' ';display:table}.simplebar-placeholder{max-height:100%;max-width:100%;width:100%;pointer-events:none}.simplebar-height-auto-observer-wrapper{box-sizing:inherit!important;height:100%;width:100%;max-width:1px;position:relative;float:left;max-height:1px;overflow:hidden;z-index:-1;padding:0;margin:0;pointer-events:none;flex-grow:inherit;flex-shrink:0;flex-basis:0}.simplebar-height-auto-observer{box-sizing:inherit;display:block;opacity:0;position:absolute;top:0;left:0;height:1000%;width:1000%;min-height:1px;min-width:1px;overflow:hidden;pointer-events:none;z-index:-1}.simplebar-track{z-index:1;position:absolute;right:0;bottom:0;pointer-events:none;overflow:hidden}[data-simplebar].simplebar-dragging{pointer-events:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}[data-simplebar].simplebar-dragging .simplebar-content{pointer-events:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}[data-simplebar].simplebar-dragging .simplebar-track{pointer-events:all}.simplebar-scrollbar{position:absolute;left:0;right:0;min-height:10px}.simplebar-scrollbar:before{position:absolute;content:'';background:#000;border-radius:7px;left:2px;right:2px;opacity:0;transition:opacity .2s .5s linear}.simplebar-scrollbar.simplebar-visible:before{opacity:.5;transition-delay:0s;transition-duration:0s}.simplebar-track.simplebar-vertical{top:0;width:11px}.simplebar-scrollbar:before{top:2px;bottom:2px;left:2px;right:2px}.simplebar-track.simplebar-horizontal{left:0;height:11px}.simplebar-track.simplebar-horizontal .simplebar-scrollbar{right:auto;left:0;top:0;bottom:0;min-height:0;min-width:10px;width:auto}[data-simplebar-direction=rtl] .simplebar-track.simplebar-vertical{right:auto;left:0}.simplebar-dummy-scrollbar-size{direction:rtl;position:fixed;opacity:0;visibility:hidden;height:500px;width:500px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:scrollbar!important}.simplebar-dummy-scrollbar-size>div{width:200%;height:200%;margin:10px 0}.simplebar-hide-scrollbar{position:fixed;left:0;visibility:hidden;overflow-y:scroll;scrollbar-width:none;-ms-overflow-style:none}\n}\n@layer simplebar {\n .simplebar-scrollbar:before {\n background-color: #909399;\n }\n\n .simplebar-content {\n height: 100%;\n }\n}\n\n#root {\n height: 100vh;\n}\n\nimg {\n max-width: 100%;\n height: auto;\n}\n\nhtml.color-blind-mode {\n --tw-invert: invert(100%);\n filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );\n}\n\nhtml.gray-mode {\n --tw-grayscale: grayscale(100%);\n filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );\n}\n\n@layer theme {\n :root, :host {\n --font-sans: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", \"Noto Sans\", Arial,\n sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --spacing: .25rem;\n --container-md: 28rem;\n --text-xs: .75rem;\n --text-xs--line-height: calc(1 / .75);\n --text-sm: .875rem;\n --text-sm--line-height: calc(1.25 / .875);\n --text-lg: 1.125rem;\n --text-lg--line-height: calc(1.75 / 1.125);\n --text-xl: 1.25rem;\n --text-xl--line-height: calc(1.75 / 1.25);\n --text-2xl: 1.5rem;\n --text-2xl--line-height: calc(2 / 1.5);\n --text-3xl: 1.875rem;\n --text-3xl--line-height: calc(2.25 / 1.875);\n --font-weight-medium: 500;\n --font-weight-semibold: 600;\n --font-weight-bold: 700;\n --tracking-tight: -.025em;\n --radius-sm: .25rem;\n --radius-md: .375rem;\n --radius-xl: .75rem;\n --ease-in: cubic-bezier(.4, 0, 1, 1);\n --animate-spin: spin 1s linear infinite;\n --default-transition-duration: .15s;\n --default-transition-timing-function: cubic-bezier(.4, 0, .2, 1);\n --animate-wiggle: wiggle 1s both;\n --animate-bounce-in-down-out-up: bounce-in-down-out-up 4s ease-in-out 0s infinite;\n }\n}\n\n@layer base, components;\n\n@layer utilities {\n .visible {\n visibility: visible;\n }\n\n .absolute {\n position: absolute;\n }\n\n .fixed {\n position: fixed;\n }\n\n .relative {\n position: relative;\n }\n\n .static {\n position: static;\n }\n\n .top-0 {\n top: 0;\n }\n\n .top-1\\.5 {\n top: calc(var(--spacing) * 1.5);\n }\n\n .top-2 {\n top: calc(var(--spacing) * 2);\n }\n\n .top-3 {\n top: calc(var(--spacing) * 3);\n }\n\n .right-2 {\n right: calc(var(--spacing) * 2);\n }\n\n .right-3 {\n right: calc(var(--spacing) * 3);\n }\n\n .right-4 {\n right: calc(var(--spacing) * 4);\n }\n\n .bottom-0 {\n bottom: 0;\n }\n\n .bottom-3 {\n bottom: calc(var(--spacing) * 3);\n }\n\n .left-0 {\n left: 0;\n }\n\n .left-1\\/2 {\n left: 50%;\n }\n\n .left-3 {\n left: calc(var(--spacing) * 3);\n }\n\n .z-10 {\n z-index: 10;\n }\n\n .container {\n width: 100%;\n }\n\n @media (min-width: 480px) {\n .container {\n max-width: 480px;\n }\n }\n\n @media (min-width: 576px) {\n .container {\n max-width: 576px;\n }\n }\n\n @media (min-width: 768px) {\n .container {\n max-width: 768px;\n }\n }\n\n @media (min-width: 992px) {\n .container {\n max-width: 992px;\n }\n }\n\n @media (min-width: 1200px) {\n .container {\n max-width: 1200px;\n }\n }\n\n @media (min-width: 1600px) {\n .container {\n max-width: 1600px;\n }\n }\n\n .m-0 {\n margin: 0;\n }\n\n .m-152 {\n margin: calc(var(--spacing) * 152);\n }\n\n .mx-3 {\n margin-inline: calc(var(--spacing) * 3);\n }\n\n .mx-4 {\n margin-inline: calc(var(--spacing) * 4);\n }\n\n .mx-auto {\n margin-inline: auto;\n }\n\n .my-0 {\n margin-block: 0;\n }\n\n .my-1 {\n margin-block: var(--spacing);\n }\n\n .my-4 {\n margin-block: calc(var(--spacing) * 4);\n }\n\n .my-8 {\n margin-block: calc(var(--spacing) * 8);\n }\n\n .mt-2 {\n margin-top: calc(var(--spacing) * 2);\n }\n\n .mt-2\\.5 {\n margin-top: calc(var(--spacing) * 2.5);\n }\n\n .mt-4 {\n margin-top: calc(var(--spacing) * 4);\n }\n\n .mt-6 {\n margin-top: calc(var(--spacing) * 6);\n }\n\n .mr-2 {\n margin-right: calc(var(--spacing) * 2);\n }\n\n .mr-3 {\n margin-right: calc(var(--spacing) * 3);\n }\n\n .mr-8 {\n margin-right: calc(var(--spacing) * 8);\n }\n\n .mr-17 {\n margin-right: calc(var(--spacing) * 17);\n }\n\n .mb-0 {\n margin-bottom: 0;\n }\n\n .mb-2 {\n margin-bottom: calc(var(--spacing) * 2);\n }\n\n .mb-3 {\n margin-bottom: calc(var(--spacing) * 3);\n }\n\n .mb-6 {\n margin-bottom: calc(var(--spacing) * 6);\n }\n\n .ml-1 {\n margin-left: var(--spacing);\n }\n\n .ml-2 {\n margin-left: calc(var(--spacing) * 2);\n }\n\n .ml-4 {\n margin-left: calc(var(--spacing) * 4);\n }\n\n .box-border {\n box-sizing: border-box;\n }\n\n .line-clamp-2 {\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n display: -webkit-box;\n overflow: hidden;\n }\n\n .block {\n display: block;\n }\n\n .flex {\n display: flex;\n }\n\n .hidden {\n display: none;\n }\n\n .inline {\n display: inline;\n }\n\n .inline-block {\n display: inline-block;\n }\n\n .table {\n display: table;\n }\n\n .aspect-square {\n aspect-ratio: 1;\n }\n\n .size-5 {\n width: calc(var(--spacing) * 5);\n height: calc(var(--spacing) * 5);\n }\n\n .h-2 {\n height: calc(var(--spacing) * 2);\n }\n\n .h-5 {\n height: calc(var(--spacing) * 5);\n }\n\n .h-10 {\n height: calc(var(--spacing) * 10);\n }\n\n .h-64 {\n height: calc(var(--spacing) * 64);\n }\n\n .h-\\[0\\.63em\\] {\n height: .63em;\n }\n\n .h-full {\n height: 100%;\n }\n\n .h-screen {\n height: 100vh;\n }\n\n .min-h-0 {\n min-height: 0;\n }\n\n .w-1\\/3 {\n width: 33.3333%;\n }\n\n .w-2 {\n width: calc(var(--spacing) * 2);\n }\n\n .w-2\\/5 {\n width: 40%;\n }\n\n .w-7\\/12 {\n width: 58.3333%;\n }\n\n .w-10 {\n width: calc(var(--spacing) * 10);\n }\n\n .w-11 {\n width: calc(var(--spacing) * 11);\n }\n\n .w-12 {\n width: calc(var(--spacing) * 12);\n }\n\n .w-40 {\n width: calc(var(--spacing) * 40);\n }\n\n .w-72 {\n width: calc(var(--spacing) * 72);\n }\n\n .w-full {\n width: 100%;\n }\n\n .max-w-90 {\n max-width: calc(var(--spacing) * 90);\n }\n\n .min-w-0 {\n min-width: 0;\n }\n\n .flex-1 {\n flex: 1;\n }\n\n .flex-auto {\n flex: auto;\n }\n\n .flex-shrink-0, .shrink-0 {\n flex-shrink: 0;\n }\n\n .grow {\n flex-grow: 1;\n }\n\n .-translate-x-1\\/2 {\n --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n\n .scale-75 {\n --tw-scale-x: 75%;\n --tw-scale-y: 75%;\n --tw-scale-z: 75%;\n scale: var(--tw-scale-x) var(--tw-scale-y);\n }\n\n .transform {\n transform: var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, );\n }\n\n .animate-spin {\n animation: var(--animate-spin);\n }\n\n .cursor-help {\n cursor: help;\n }\n\n .cursor-pointer {\n cursor: pointer;\n }\n\n .list-none {\n list-style-type: none;\n }\n\n .flex-col {\n flex-direction: column;\n }\n\n .flex-row-reverse {\n flex-direction: row-reverse;\n }\n\n .flex-wrap {\n flex-wrap: wrap;\n }\n\n .items-center {\n align-items: center;\n }\n\n .justify-between {\n justify-content: space-between;\n }\n\n .justify-center {\n justify-content: center;\n }\n\n .justify-start {\n justify-content: flex-start;\n }\n\n .gap-1 {\n gap: var(--spacing);\n }\n\n .gap-2 {\n gap: calc(var(--spacing) * 2);\n }\n\n .gap-3 {\n gap: calc(var(--spacing) * 3);\n }\n\n .gap-5 {\n gap: calc(var(--spacing) * 5);\n }\n\n .gap-x-3 {\n column-gap: calc(var(--spacing) * 3);\n }\n\n .gap-y-5 {\n row-gap: calc(var(--spacing) * 5);\n }\n\n .overflow-hidden {\n overflow: hidden;\n }\n\n .overflow-x-auto {\n overflow-x: auto;\n }\n\n .overflow-x-hidden {\n overflow-x: hidden;\n }\n\n .overflow-y-auto {\n overflow-y: auto;\n }\n\n .rounded {\n border-radius: .25rem;\n }\n\n .rounded-full {\n border-radius: 3.40282e38px;\n }\n\n .rounded-md {\n border-radius: var(--radius-md);\n }\n\n .rounded-none {\n border-radius: 0;\n }\n\n .rounded-sm {\n border-radius: var(--radius-sm);\n }\n\n .rounded-r-xl {\n border-top-right-radius: var(--radius-xl);\n border-bottom-right-radius: var(--radius-xl);\n }\n\n .border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n\n .border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n }\n\n .border-r {\n border-right-style: var(--tw-border-style);\n border-right-width: 1px;\n }\n\n .border-l {\n border-left-style: var(--tw-border-style);\n border-left-width: 1px;\n }\n\n .\\!border-none {\n --tw-border-style: none !important;\n border-style: none !important;\n }\n\n .border-t-\\[\\#303030\\] {\n border-top-color: #303030;\n }\n\n .border-t-colorBorderSecondary {\n border-top-color: var(--oo-colorBorderSecondary);\n }\n\n .border-r-\\[\\#303030\\] {\n border-right-color: #303030;\n }\n\n .border-r-colorBorderSecondary {\n border-right-color: var(--oo-colorBorderSecondary);\n }\n\n .border-l-colorBorderSecondary {\n border-left-color: var(--oo-colorBorderSecondary);\n }\n\n .bg-\\[\\#F3F4F5\\] {\n background-color: #f3f4f5;\n }\n\n .bg-blue-500\\/20 {\n background-color: rgb(var(--oo-blue-5));\n }\n\n @supports (color: color-mix(in lab, red, red)) {\n .bg-blue-500\\/20 {\n background-color: color-mix(in oklab, rgb(var(--oo-blue-5)) 20%, transparent);\n }\n }\n\n .bg-blue-600 {\n background-color: rgb(var(--oo-blue-6));\n }\n\n .bg-colorBgContainer {\n background-color: var(--oo-colorBgContainer);\n }\n\n .bg-colorBgLayout {\n background-color: var(--oo-colorBgLayout);\n }\n\n .bg-gray-100 {\n background-color: #f5f5f5;\n }\n\n .bg-gray-200 {\n background-color: #f0f0f0;\n }\n\n .bg-primary {\n background-color: rgb(var(--oo-colorPrimary));\n }\n\n .bg-primaryActive {\n background-color: rgb(var(--oo-colorPrimaryActive));\n }\n\n .object-cover {\n object-fit: cover;\n }\n\n .p-0 {\n padding: 0;\n }\n\n .p-1 {\n padding: var(--spacing);\n }\n\n .p-2 {\n padding: calc(var(--spacing) * 2);\n }\n\n .p-4 {\n padding: calc(var(--spacing) * 4);\n }\n\n .px-0 {\n padding-inline: 0;\n }\n\n .px-1 {\n padding-inline: var(--spacing);\n }\n\n .px-1\\.5 {\n padding-inline: calc(var(--spacing) * 1.5);\n }\n\n .px-2 {\n padding-inline: calc(var(--spacing) * 2);\n }\n\n .px-2\\.75 {\n padding-inline: calc(var(--spacing) * 2.75);\n }\n\n .px-3 {\n padding-inline: calc(var(--spacing) * 3);\n }\n\n .px-4 {\n padding-inline: calc(var(--spacing) * 4);\n }\n\n .px-6 {\n padding-inline: calc(var(--spacing) * 6);\n }\n\n .px-9 {\n padding-inline: calc(var(--spacing) * 9);\n }\n\n .px-10 {\n padding-inline: calc(var(--spacing) * 10);\n }\n\n .px-\\[11px\\] {\n padding-inline: 11px;\n }\n\n .py-1 {\n padding-block: var(--spacing);\n }\n\n .py-1\\.5 {\n padding-block: calc(var(--spacing) * 1.5);\n }\n\n .py-2 {\n padding-block: calc(var(--spacing) * 2);\n }\n\n .py-2\\.5 {\n padding-block: calc(var(--spacing) * 2.5);\n }\n\n .py-4 {\n padding-block: calc(var(--spacing) * 4);\n }\n\n .py-10 {\n padding-block: calc(var(--spacing) * 10);\n }\n\n .pb-4 {\n padding-bottom: calc(var(--spacing) * 4);\n }\n\n .pl-2 {\n padding-left: calc(var(--spacing) * 2);\n }\n\n .text-center {\n text-align: center;\n }\n\n .font-sans {\n font-family: var(--font-sans);\n }\n\n .text-3xl {\n font-size: var(--text-3xl);\n line-height: var(--tw-leading, var(--text-3xl--line-height));\n }\n\n .text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n\n .text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n\n .text-xl {\n font-size: var(--text-xl);\n line-height: var(--tw-leading, var(--text-xl--line-height));\n }\n\n .text-xs {\n font-size: var(--text-xs);\n line-height: var(--tw-leading, var(--text-xs--line-height));\n }\n\n .text-\\[4rem\\] {\n font-size: 4rem;\n }\n\n .leading-none {\n --tw-leading: 1;\n line-height: 1;\n }\n\n .font-bold {\n --tw-font-weight: var(--font-weight-bold);\n font-weight: var(--font-weight-bold);\n }\n\n .font-medium {\n --tw-font-weight: var(--font-weight-medium);\n font-weight: var(--font-weight-medium);\n }\n\n .font-semibold {\n --tw-font-weight: var(--font-weight-semibold);\n font-weight: var(--font-weight-semibold);\n }\n\n .tracking-tight {\n --tw-tracking: var(--tracking-tight);\n letter-spacing: var(--tracking-tight);\n }\n\n .text-colorBgContainer {\n color: var(--oo-colorBgContainer);\n }\n\n .text-colorBgContainer\\! {\n color: var(--oo-colorBgContainer) !important;\n }\n\n .text-colorText {\n color: var(--oo-colorText);\n }\n\n .text-colorText\\! {\n color: var(--oo-colorText) !important;\n }\n\n .text-colorTextSecondary {\n color: var(--oo-colorTextSecondary);\n }\n\n .text-colorTextTertiary {\n color: var(--oo-colorTextTertiary);\n }\n\n .text-gray-500 {\n color: #8c8c8c;\n }\n\n .opacity-50 {\n opacity: .5;\n }\n\n .opacity-90 {\n opacity: .9;\n }\n\n .outline, .outline-1 {\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n }\n\n .outline-2 {\n outline-style: var(--tw-outline-style);\n outline-width: 2px;\n }\n\n .outline-blue-600 {\n outline-color: rgb(var(--oo-blue-6));\n }\n\n .outline-gray-300 {\n outline-color: #d9d9d9;\n }\n\n .filter {\n filter: var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, );\n }\n\n .transition {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n\n .transition-all {\n transition-property: all;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n\n .duration-300 {\n --tw-duration: .3s;\n transition-duration: .3s;\n }\n\n .ease-in {\n --tw-ease: var(--ease-in);\n transition-timing-function: var(--ease-in);\n }\n\n @media (hover: hover) {\n .group-hover\\:animate-wiggle:is(:where(.group):hover *) {\n animation: var(--animate-wiggle);\n }\n\n .group-hover\\:opacity-100:is(:where(.group):hover *) {\n opacity: 1;\n }\n }\n\n .before\\:absolute:before {\n content: var(--tw-content);\n position: absolute;\n }\n\n .before\\:top-1\\/2:before {\n content: var(--tw-content);\n top: 50%;\n }\n\n .before\\:left-1\\/2:before {\n content: var(--tw-content);\n left: 50%;\n }\n\n .before\\:h-0:before {\n content: var(--tw-content);\n height: 0;\n }\n\n .before\\:w-0:before {\n content: var(--tw-content);\n width: 0;\n }\n\n .before\\:rounded-sm:before {\n content: var(--tw-content);\n border-radius: var(--radius-sm);\n }\n\n .before\\:opacity-0:before {\n content: var(--tw-content);\n opacity: 0;\n }\n\n .before\\:outline:before {\n content: var(--tw-content);\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n }\n\n .before\\:outline-2:before {\n content: var(--tw-content);\n outline-style: var(--tw-outline-style);\n outline-width: 2px;\n }\n\n .before\\:outline-transparent:before {\n content: var(--tw-content);\n outline-color: #0000;\n }\n\n .before\\:transition-all:before {\n content: var(--tw-content);\n transition-property: all;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n\n .before\\:duration-300:before {\n content: var(--tw-content);\n --tw-duration: .3s;\n transition-duration: .3s;\n }\n\n .before\\:content-\\[\\'\\'\\]:before {\n --tw-content: \"\";\n content: var(--tw-content);\n }\n\n .last\\:mr-auto:last-child {\n margin-right: auto;\n }\n\n @media (hover: hover) {\n .hover\\:bg-gray-100:hover {\n background-color: #f5f5f5;\n }\n\n .hover\\:text-colorText:hover {\n color: var(--oo-colorText);\n }\n }\n\n .before\\:hover\\:top-0:before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .before\\:hover\\:top-0:before:hover {\n top: 0;\n }\n }\n\n .before\\:hover\\:left-0:before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .before\\:hover\\:left-0:before:hover {\n left: 0;\n }\n }\n\n .before\\:hover\\:h-full:before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .before\\:hover\\:h-full:before:hover {\n height: 100%;\n }\n }\n\n .before\\:hover\\:w-full:before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .before\\:hover\\:w-full:before:hover {\n width: 100%;\n }\n }\n\n .before\\:hover\\:p-1:before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .before\\:hover\\:p-1:before:hover {\n padding: var(--spacing);\n }\n }\n\n .before\\:hover\\:opacity-100:before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .before\\:hover\\:opacity-100:before:hover {\n opacity: 1;\n }\n }\n\n .before\\:hover\\:outline-blue-600:before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .before\\:hover\\:outline-blue-600:before:hover {\n outline-color: rgb(var(--oo-blue-6));\n }\n }\n\n @media (prefers-reduced-motion: no-preference) {\n .motion-safe\\:animate-bounce-in-down-out-up {\n animation: var(--animate-bounce-in-down-out-up);\n }\n }\n\n @media (min-width: 576px) {\n .sm\\:mx-auto {\n margin-inline: auto;\n }\n }\n\n @media (min-width: 768px) {\n .md\\:mr-2\\.5 {\n margin-right: calc(var(--spacing) * 2.5);\n }\n\n .md\\:block {\n display: block;\n }\n\n .md\\:w-3\\/12 {\n width: 25%;\n }\n\n .md\\:w-96 {\n width: calc(var(--spacing) * 96);\n }\n\n .md\\:max-w-md {\n max-width: var(--container-md);\n }\n\n .md\\:bg-colorBgLayout {\n background-color: var(--oo-colorBgLayout);\n }\n\n .md\\:px-4 {\n padding-inline: calc(var(--spacing) * 4);\n }\n\n .md\\:pb-0 {\n padding-bottom: 0;\n }\n\n .md\\:text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n }\n\n @media (min-width: 992px) {\n .lg\\:text-2xl {\n font-size: var(--text-2xl);\n line-height: var(--tw-leading, var(--text-2xl--line-height));\n }\n }\n\n @media (min-width: 1200px) {\n .xl\\:w-2\\/12 {\n width: 16.6667%;\n }\n\n .xl\\:px-8 {\n padding-inline: calc(var(--spacing) * 8);\n }\n }\n\n .dark\\:bg-\\[\\#26313C\\]:where(.dark, .dark *) {\n background-color: #26313c;\n }\n\n .dark\\:bg-black:where(.dark, .dark *) {\n background-color: #000;\n }\n\n .dark\\:bg-gray-700:where(.dark, .dark *) {\n background-color: #434343;\n }\n\n .dark\\:outline-blue-700:where(.dark, .dark *) {\n outline-color: rgb(var(--oo-blue-7));\n }\n\n .dark\\:outline-gray-700:where(.dark, .dark *) {\n outline-color: #434343;\n }\n\n @media (hover: hover) {\n .dark\\:hover\\:bg-gray-700:where(.dark, .dark *):hover {\n background-color: #434343;\n }\n }\n\n .dark\\:before\\:hover\\:outline-blue-700:where(.dark, .dark *):before {\n content: var(--tw-content);\n }\n\n @media (hover: hover) {\n .dark\\:before\\:hover\\:outline-blue-700:where(.dark, .dark *):before:hover {\n outline-color: rgb(var(--oo-blue-7));\n }\n }\n\n .en-US\\:gap-y-3:where(:lang(en-US)) {\n row-gap: calc(var(--spacing) * 3);\n }\n\n .en-US\\:text-\\[9rem\\]:where(:lang(en-US)) {\n font-size: 9rem;\n }\n\n .zh-CN\\:hidden:where(:lang(zh-CN)) {\n display: none;\n }\n}\n\n@keyframes fade-in {\n from {\n opacity: 0;\n }\n\n to {\n opacity: 1;\n }\n}\n\n@keyframes fade-out {\n from {\n opacity: 1;\n }\n\n to {\n opacity: 0;\n }\n}\n\n@keyframes slide-in {\n from {\n transform: translateX(-30px);\n }\n\n to {\n transform: translateX(0);\n }\n}\n\n@keyframes slide-out {\n from {\n transform: translateX(0);\n }\n\n to {\n transform: translateX(30px);\n }\n}\n\n@keyframes slide-top-in {\n from {\n transform: translateY(-10%);\n }\n\n to {\n transform: translateY(0);\n }\n}\n\n@keyframes slide-top-out {\n from {\n transform: translateY(0);\n }\n\n to {\n transform: translateY(-10%);\n }\n}\n\n@keyframes slide-bottom-in {\n from {\n transform: translateY(10%);\n }\n\n to {\n transform: translateY(0);\n }\n}\n\n@keyframes slide-bottom-out {\n from {\n transform: translateY(0);\n }\n\n to {\n transform: translateY(10%);\n }\n}\n\n@keyframes fade-slide {\n 0% {\n opacity: 0;\n transform: translate(-30px);\n }\n\n 50% {\n opacity: 1;\n }\n\n 100% {\n opacity: 0;\n transform: translate(30px);\n }\n}\n\n@keyframes fade-up {\n 0% {\n opacity: 0;\n transform: translateY(10%);\n }\n\n 50% {\n opacity: 1;\n }\n\n 100% {\n opacity: 0;\n transform: translateY(-10%);\n }\n}\n\n@keyframes fade-down {\n 0% {\n opacity: 0;\n transform: translateY(-10%);\n }\n\n 50% {\n opacity: 1;\n }\n\n 100% {\n opacity: 0;\n transform: translateY(10%);\n }\n}\n\n.fade-slide {\n animation: 3s linear infinite fade-slide;\n}\n\n.fade {\n animation: 3s linear infinite alternate fade-in;\n}\n\n.fade-up {\n animation: 3s infinite fade-up;\n}\n\n.fade-down {\n animation: 3s infinite fade-down;\n}\n\n@keyframes zoom-in {\n 0% {\n transform: scale(.8);\n }\n\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes zoom-out {\n 0% {\n transform: scale(1);\n }\n\n 100% {\n opacity: 1;\n transform: scale(1.25);\n }\n}\n\n@keyframes fade-zoom {\n 0% {\n opacity: 0;\n transform: scale(.8);\n }\n\n 50% {\n opacity: 1;\n transform: scale(1);\n }\n\n 100% {\n opacity: 0;\n transform: scale(1.25);\n }\n}\n\n.fade-zoom {\n animation: 3s infinite fade-zoom;\n}\n\n.keepalive-fade.active {\n animation: .3s ease-in-out fade-in;\n}\n\n.keepalive-fade.inactive {\n animation: .3s ease-in-out fade-out;\n}\n\n.keepalive-fade-slide.active {\n animation: .3s ease-in-out fade-in, .3s ease-in-out slide-in;\n}\n\n.keepalive-fade-slide.inactive {\n animation: .3s ease-in-out fade-out, .3s ease-in-out slide-out;\n}\n\n.keepalive-fade-up.active {\n animation: .3s ease-in-out fade-in, .3s ease-in-out slide-bottom-in;\n}\n\n.keepalive-fade-up.inactive {\n animation: .3s ease-in-out fade-out, .3s ease-in-out slide-top-out;\n}\n\n.keepalive-fade-down.active {\n animation: .3s ease-in-out fade-in, .3s ease-in-out slide-top-in;\n}\n\n.keepalive-fade-down.inactive {\n animation: .3s ease-in-out fade-out, .3s ease-in-out slide-bottom-out;\n}\n\n.keepalive-fade-zoom.active {\n animation: .3s ease-in-out zoom-in, .3s ease-in-out zoom-in;\n}\n\n.keepalive-fade-zoom.inactive {\n animation: .3s ease-in-out zoom-out, .3s ease-in-out fade-out;\n}\n\n@property --tw-blur {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-brightness {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-contrast {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-grayscale {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-hue-rotate {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-invert {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-opacity {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-saturate {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-sepia {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-drop-shadow {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-drop-shadow-color {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-drop-shadow-alpha {\n syntax: \"<percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n\n@property --tw-drop-shadow-size {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-translate-x {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-translate-y {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-translate-z {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n\n@property --tw-scale-x {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n\n@property --tw-scale-y {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n\n@property --tw-scale-z {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n\n@property --tw-rotate-x {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-rotate-y {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-rotate-z {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-skew-x {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-skew-y {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-border-style {\n syntax: \"*\";\n inherits: false;\n initial-value: solid;\n}\n\n@property --tw-leading {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-font-weight {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-tracking {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-outline-style {\n syntax: \"*\";\n inherits: false;\n initial-value: solid;\n}\n\n@property --tw-duration {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-ease {\n syntax: \"*\";\n inherits: false\n}\n\n@property --tw-content {\n syntax: \"*\";\n inherits: false;\n initial-value: \"\";\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@keyframes wiggle {\n 0%, 100% {\n transform-origin: top;\n }\n\n 15% {\n transform: rotateZ(10deg);\n }\n\n 30% {\n transform: rotateZ(-10deg);\n }\n\n 45% {\n transform: rotateZ(5deg);\n }\n\n 60% {\n transform: rotateZ(-5deg);\n }\n\n 75% {\n transform: rotateZ(2deg);\n }\n}\n\n@keyframes bounce-in-down-out-up {\n 0% {\n transform: translateY(0);\n }\n\n 50% {\n transform: translateY(-20px);\n }\n\n 100% {\n transform: translateY(0);\n }\n}\n\n@layer properties {\n @supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) {\n *, :before, :after, ::backdrop {\n --tw-blur: initial;\n --tw-brightness: initial;\n --tw-contrast: initial;\n --tw-grayscale: initial;\n --tw-hue-rotate: initial;\n --tw-invert: initial;\n --tw-opacity: initial;\n --tw-saturate: initial;\n --tw-sepia: initial;\n --tw-drop-shadow: initial;\n --tw-drop-shadow-color: initial;\n --tw-drop-shadow-alpha: 100%;\n --tw-drop-shadow-size: initial;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-scale-z: 1;\n --tw-rotate-x: initial;\n --tw-rotate-y: initial;\n --tw-rotate-z: initial;\n --tw-skew-x: initial;\n --tw-skew-y: initial;\n --tw-border-style: solid;\n --tw-leading: initial;\n --tw-font-weight: initial;\n --tw-tracking: initial;\n --tw-outline-style: solid;\n --tw-duration: initial;\n --tw-ease: initial;\n --tw-content: \"\";\n }\n }\n}\n/*$vite$:1*/";
6
6
  document.head.appendChild(s);
7
7
  }
8
8
  import ky from "ky";
@@ -11,7 +11,7 @@ import { persist } from "zustand/middleware";
11
11
  import { Link, Navigate, Outlet, createBrowserRouter, matchRoutes, useLocation, useMatches, useNavigate, useOutlet, useSearchParams } from "react-router";
12
12
  import { ErrorBoundary, ErrorBoundary as ErrorBoundary$1 } from "react-error-boundary";
13
13
  import { AntDesignOutlined, ApartmentOutlined, AppstoreOutlined, ArrowDownOutlined, ArrowLeftOutlined, ArrowUpOutlined, BellOutlined, CloseOutlined, CloudOutlined, ContainerOutlined, CopyOutlined, CopyrightOutlined, DownOutlined, EnterOutlined, ExclamationCircleFilled, EyeOutlined, FileTextOutlined, FullscreenExitOutlined, FullscreenOutlined, HomeOutlined, LoadingOutlined, LockOutlined, LogoutOutlined, MenuFoldOutlined, MenuOutlined, MenuUnfoldOutlined, NodeExpandOutlined, QuestionCircleOutlined, RedoOutlined, ReloadOutlined, RocketOutlined, SafetyOutlined, SearchOutlined, SettingOutlined, SisternodeOutlined, SubnodeOutlined, SwapOutlined, TeamOutlined, TranslationOutlined, UploadOutlined, UserOutlined, VerticalAlignBottomOutlined, VerticalAlignMiddleOutlined, VerticalAlignTopOutlined } from "@ant-design/icons";
14
- import { App, Avatar, Badge, Breadcrumb, Button, Checkbox, Col, ColorPicker, ConfigProvider, Divider, Drawer, Dropdown, Empty, FloatButton, Form, Grid, Input, InputNumber, List, Menu, Modal, Popover, Result, Row, Select, Slider, Space, Spin, Switch, Tabs, Tooltip, Tree, Typography, Upload, Watermark, message, notification, theme } from "antd";
14
+ import { App, Avatar, Badge, Breadcrumb, Button, Checkbox, Col, ColorPicker, ConfigProvider, Divider, Drawer, Dropdown, Empty, FloatButton, Form, Grid, Input, InputNumber, List, Menu, Modal, Popover, Result, Row, Select, Slider, Space, Spin, Switch, Tabs, Tag, Tooltip, Tree, Typography, Upload, Watermark, message, notification, theme } from "antd";
15
15
  import { Children, Suspense, cloneElement, createElement, forwardRef, isValidElement, lazy, use, useCallback, useEffect, useMemo, useRef, useState } from "react";
16
16
  import { initReactI18next, useTranslation } from "react-i18next";
17
17
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -256,10 +256,10 @@ function getAppInfo() {
256
256
  return {
257
257
  "pkg": {
258
258
  "name": "@oj-module/runtime",
259
- "version": "0.2.6",
259
+ "version": "0.2.14",
260
260
  "license": "MIT"
261
261
  },
262
- "lastBuildTime": "2026-10-19 12:08:59"
262
+ "lastBuildTime": "2026-10-21 09:05:39"
263
263
  };
264
264
  }
265
265
  var init_get_app_info = __esmMin((() => {}));
@@ -875,7 +875,7 @@ var init_preferences$2 = __esmMin((() => {
875
875
  }));
876
876
  //#endregion
877
877
  //#region src/locales/zh-CN/widgets.json
878
- var document$2, qa$1, setting$1, logoutTip$1, viewAll$1, notifications$1, markAllAsRead$1, clearNotifications$1, versionMonitorTitle$1, versionMonitorContent$1, versionMonitorConfirm$1, versionMonitorCancel$1, search$2, widgets_default$1;
878
+ var document$2, qa$1, setting$1, logoutTip$1, viewAll$1, notifications$1, notiCategory$1, markAllAsRead$1, clearNotifications$1, versionMonitorTitle$1, versionMonitorContent$1, versionMonitorConfirm$1, versionMonitorCancel$1, search$2, widgets_default$1;
879
879
  var init_widgets$1 = __esmMin((() => {
880
880
  document$2 = "文档";
881
881
  qa$1 = "问题 & 帮助";
@@ -883,6 +883,11 @@ var init_widgets$1 = __esmMin((() => {
883
883
  logoutTip$1 = "是否退出登录?";
884
884
  viewAll$1 = "查看所有消息";
885
885
  notifications$1 = "通知";
886
+ notiCategory$1 = {
887
+ "notice": "通知",
888
+ "pm": "私信",
889
+ "mention": "@我"
890
+ };
886
891
  markAllAsRead$1 = "全部标记为已读";
887
892
  clearNotifications$1 = "清空";
888
893
  versionMonitorTitle$1 = "系统版本更新通知";
@@ -906,6 +911,7 @@ var init_widgets$1 = __esmMin((() => {
906
911
  logoutTip: logoutTip$1,
907
912
  viewAll: viewAll$1,
908
913
  notifications: notifications$1,
914
+ notiCategory: notiCategory$1,
909
915
  markAllAsRead: markAllAsRead$1,
910
916
  clearNotifications: clearNotifications$1,
911
917
  versionMonitorTitle: versionMonitorTitle$1,
@@ -1309,13 +1315,18 @@ var init_preferences$1 = __esmMin((() => {
1309
1315
  general,
1310
1316
  footer
1311
1317
  };
1312
- })), document$1, setting, logoutTip, viewAll, notifications, markAllAsRead, clearNotifications, versionMonitorTitle, versionMonitorContent, versionMonitorConfirm, versionMonitorCancel, search, widgets_default;
1318
+ })), document$1, setting, logoutTip, viewAll, notifications, notiCategory, markAllAsRead, clearNotifications, versionMonitorTitle, versionMonitorContent, versionMonitorConfirm, versionMonitorCancel, search, widgets_default;
1313
1319
  var init_widgets = __esmMin((() => {
1314
1320
  document$1 = "Document";
1315
1321
  setting = "Settings";
1316
1322
  logoutTip = "Do you want to logout?";
1317
1323
  viewAll = "View All Messages";
1318
1324
  notifications = "Notifications";
1325
+ notiCategory = {
1326
+ "notice": "Notice",
1327
+ "pm": "Direct",
1328
+ "mention": "Mentions"
1329
+ };
1319
1330
  markAllAsRead = "Make All as Read";
1320
1331
  clearNotifications = "Clear";
1321
1332
  versionMonitorTitle = "System Version Update Notification";
@@ -1339,6 +1350,7 @@ var init_widgets = __esmMin((() => {
1339
1350
  logoutTip,
1340
1351
  viewAll,
1341
1352
  notifications,
1353
+ notiCategory,
1342
1354
  markAllAsRead,
1343
1355
  clearNotifications,
1344
1356
  versionMonitorTitle,
@@ -1511,17 +1523,29 @@ var init_terms_of_service = __esmMin((() => {
1511
1523
  }));
1512
1524
  //#endregion
1513
1525
  //#region src/router/utils/ascending.ts
1514
- /** 按照路由中 order 升序来排序路由 */
1526
+ /**
1527
+ * 按照路由中 order 升序来排序路由(双段序轴,2026-10-20):
1528
+ * - order >= 0:主菜单区,升序在前;
1529
+ * - order < 0 :底部固定区,升序在后(-2 在 -1 上面)——渲染层
1530
+ * (layout-sidebar / layout-mixed-sidebar 第二列)把这一段 pin 在
1531
+ * 侧边栏底部,其余菜单形态按列表末尾回落;
1532
+ * - 未声明 order:沿用数组下标兜底(下标 + 2)。order: 0 是合法值,
1533
+ * 用 ?? 判定(历史实现用 ||,0 会被误当「未设置」改写成兜底值)。
1534
+ */
1515
1535
  function ascending(arr) {
1516
- return arr.map((routeItem, routeIndex) => ({
1536
+ const normalized = arr.map((routeItem, routeIndex) => ({
1517
1537
  ...routeItem,
1518
1538
  handle: {
1519
1539
  ...routeItem.handle,
1520
- order: routeItem?.handle?.order || routeIndex + 2
1540
+ order: routeItem?.handle?.order ?? routeIndex + 2
1521
1541
  }
1522
- })).sort((a, b) => {
1523
- return a?.handle?.order - b?.handle?.order;
1524
- });
1542
+ }));
1543
+ const byOrder = (a, b) => {
1544
+ const delta = (a.handle.order ?? 0) - (b.handle.order ?? 0);
1545
+ if (delta !== 0) return delta;
1546
+ return (a.path ?? "").localeCompare(b.path ?? "");
1547
+ };
1548
+ return [...normalized.filter((routeItem) => (routeItem.handle.order ?? 0) >= 0).sort(byOrder), ...normalized.filter((routeItem) => (routeItem.handle.order ?? 0) < 0).sort(byOrder)];
1525
1549
  }
1526
1550
  var init_ascending = __esmMin((() => {}));
1527
1551
  //#endregion
@@ -4273,6 +4297,7 @@ function transformMenuToFlatMenu(menus, flatMap = []) {
4273
4297
  }
4274
4298
  function GlobalSearch() {
4275
4299
  const wholeMenus = useAccessStore((state) => state.wholeMenus);
4300
+ const bottomMenus = useAccessStore((state) => state.bottomMenus);
4276
4301
  const { isMobile } = useDeviceType();
4277
4302
  const [open, setOpen] = useState(false);
4278
4303
  const navigate = useNavigate();
@@ -4283,7 +4308,7 @@ function GlobalSearch() {
4283
4308
  const inputRef = useRef(null);
4284
4309
  const listRef = useRef(null);
4285
4310
  const [searchHistory = [], setSearchHistory] = useLocalStorageState(searchHistoryLocalStorageKey, { defaultValue: [] });
4286
- const searchMenuList = useMemo(() => transformMenuToFlatMenu(wholeMenus), [wholeMenus]);
4311
+ const searchMenuList = useMemo(() => transformMenuToFlatMenu([...wholeMenus, ...bottomMenus]), [wholeMenus, bottomMenus]);
4287
4312
  function onClose() {
4288
4313
  setOpen(false);
4289
4314
  }
@@ -4491,11 +4516,12 @@ var init_notifications = __esmMin((() => {
4491
4516
  }));
4492
4517
  //#endregion
4493
4518
  //#region src/layout/widgets/notification/index.tsx
4494
- var useStyles$5, NotificationPopup;
4519
+ var NOTIFICATION_CENTER_PATH, useStyles$5, NotificationPopup;
4495
4520
  var init_notification = __esmMin((() => {
4496
4521
  init_basic_button();
4497
4522
  init_icons();
4498
4523
  init_cn();
4524
+ NOTIFICATION_CENTER_PATH = "/notification-center";
4499
4525
  useStyles$5 = createUseStyles(({ token }) => ({ notification: {
4500
4526
  "& .ant-popover-inner": { padding: 0 },
4501
4527
  "& .ant-list-footer": { borderTop: `1px solid ${token.colorBorder}` },
@@ -4504,16 +4530,17 @@ var init_notification = __esmMin((() => {
4504
4530
  overflowY: "auto"
4505
4531
  }
4506
4532
  } }));
4507
- NotificationPopup = ({ dot, notifications, onEventChange, ...restProps }) => {
4533
+ NotificationPopup = ({ dot, notifications, onEventChange, onOpenChange, ...restProps }) => {
4508
4534
  const [open, action] = useToggle();
4509
4535
  const classes = useStyles$5();
4510
4536
  const { t } = useTranslation();
4511
4537
  const readOnly = !onEventChange;
4538
+ const navigate = useNavigate();
4512
4539
  const close = () => {
4513
4540
  action.set(false);
4514
4541
  };
4515
4542
  const handleViewAll = () => {
4516
- onEventChange && onEventChange("viewAll");
4543
+ navigate(NOTIFICATION_CENTER_PATH);
4517
4544
  close();
4518
4545
  };
4519
4546
  const handleMakeAll = () => {
@@ -4529,6 +4556,15 @@ var init_notification = __esmMin((() => {
4529
4556
  onEventChange && onEventChange("read", item);
4530
4557
  if (item.link) window.open(item.link, "_blank", "noopener");
4531
4558
  };
4559
+ const categoryTag = (item) => {
4560
+ if (!item.category) return null;
4561
+ const color = item.category === "pm" ? "magenta" : item.category === "mention" ? "orange" : "blue";
4562
+ return /* @__PURE__ */ jsx(Tag, {
4563
+ color,
4564
+ className: "ml-1 text-xs",
4565
+ children: t(`widgets.notiCategory.${item.category}`)
4566
+ });
4567
+ };
4532
4568
  dot = useMemo(() => {
4533
4569
  return !!notifications?.filter((item) => !item?.isRead).length;
4534
4570
  }, [notifications]);
@@ -4538,7 +4574,10 @@ var init_notification = __esmMin((() => {
4538
4574
  open,
4539
4575
  arrow: false,
4540
4576
  trigger: "click",
4541
- onOpenChange: action.set,
4577
+ onOpenChange: (o) => {
4578
+ action.set(o);
4579
+ onOpenChange?.(o);
4580
+ },
4542
4581
  content: /* @__PURE__ */ jsx(List, {
4543
4582
  size: "small",
4544
4583
  bordered: true,
@@ -4574,18 +4613,21 @@ var init_notification = __esmMin((() => {
4574
4613
  !item.isRead && /* @__PURE__ */ jsx("span", { className: "absolute w-2 h-2 rounded bg-primary right-2 top-2" }),
4575
4614
  /* @__PURE__ */ jsx("span", {
4576
4615
  className: "relative flex w-10 h-10 overflow-hidden rounded-full shrink-0",
4577
- children: /* @__PURE__ */ jsx("img", {
4616
+ children: item.avatar ? /* @__PURE__ */ jsx("img", {
4578
4617
  src: item.avatar,
4579
4618
  className: "object-cover w-full h-full aspect-square",
4580
4619
  role: "img"
4620
+ }) : /* @__PURE__ */ jsx("span", {
4621
+ className: "flex w-full h-full items-center justify-center bg-gray-200 dark:bg-gray-700 text-gray-500",
4622
+ children: /* @__PURE__ */ jsx(BellOutlined, {})
4581
4623
  })
4582
4624
  }),
4583
4625
  /* @__PURE__ */ jsxs("div", {
4584
4626
  className: "flex flex-col gap-1 leading-none",
4585
4627
  children: [
4586
- /* @__PURE__ */ jsx("p", {
4587
- className: "font-semibold",
4588
- children: item.title
4628
+ /* @__PURE__ */ jsxs("p", {
4629
+ className: "font-semibold flex items-center",
4630
+ children: [item.title, categoryTag(item)]
4589
4631
  }),
4590
4632
  /* @__PURE__ */ jsx("p", {
4591
4633
  className: "my-1 text-xs text-muted-foreground line-clamp-2",
@@ -4620,7 +4662,8 @@ var init_notification = __esmMin((() => {
4620
4662
  * (popup 按 onEventChange 是否存在推导,评审 A3——不加新 prop);
4621
4663
  * - 写操作成功后重拉刷新;**重拉失败不清空现有列表**(评审 b4);
4622
4664
  * - 20x 复制残留已删除(评审 b4,同一 id 复制 20 份会让 markRead 语义失真);
4623
- * - viewAll 不接线(N3,模板无通知中心页)。
4665
+ * - viewAll 由弹层内直接导航到通知中心页(N3 落地,不经过 provider——
4666
+ * 本组件的 onEventChange 仍只承载写事件,read-only 推导不受影响)。
4624
4667
  */
4625
4668
  function NotificationContainer({ ...restProps }) {
4626
4669
  const [notifications, setNotifications] = useState([]);
@@ -4646,6 +4689,7 @@ function NotificationContainer({ ...restProps }) {
4646
4689
  if (!p) return;
4647
4690
  (event === "read" ? () => p.markRead(item.id) : event === "makeAll" ? () => p.markAllRead() : event === "clear" ? () => p.clearAll() : void 0)?.().then(reload).catch(() => {});
4648
4691
  } : void 0,
4692
+ onOpenChange: (open) => open && reload(),
4649
4693
  ...restProps
4650
4694
  });
4651
4695
  }
@@ -5853,12 +5897,13 @@ function LayoutMenu({ mode = "inline", autoExpandCurrentMenu, handleMenuSelect,
5853
5897
  const classes = useStyles$4();
5854
5898
  const matches = useMatches();
5855
5899
  const wholeMenus = useAccessStore((state) => state.wholeMenus);
5900
+ const bottomMenus = useAccessStore((state) => state.bottomMenus);
5856
5901
  const { sidebarCollapsed, sidebarTheme, isDark, accordion } = usePreferences();
5857
5902
  const [openKeys, setOpenKeys] = useState([]);
5858
5903
  const { isMobile } = useDeviceType();
5859
5904
  const menuParentKeys = useMemo(() => {
5860
- return getParentKeys(wholeMenus);
5861
- }, [wholeMenus]);
5905
+ return getParentKeys([...wholeMenus, ...bottomMenus]);
5906
+ }, [wholeMenus, bottomMenus]);
5862
5907
  const getSelectedKeys = useMemo(() => {
5863
5908
  const currentActiveMatch = matches.findLast((routeItem) => routeItem.handle?.currentActiveMenu);
5864
5909
  if (currentActiveMatch?.handle?.currentActiveMenu) {
@@ -5969,10 +6014,13 @@ var init_layout_menu = __esmMin((() => {
5969
6014
  //#region src/layout/layout-menu/use-menu.ts
5970
6015
  function useMenu() {
5971
6016
  const wholeMenus = useAccessStore((state) => state.wholeMenus);
6017
+ const bottomMenus = useAccessStore((state) => state.bottomMenus);
5972
6018
  const { isMixedNav, isTwoColumnNav } = useLayout();
5973
6019
  const navigate = useNavigate();
5974
6020
  const { t } = useTranslation();
5975
6021
  const translatedMenus = translateMenus(wholeMenus, t);
6022
+ const translatedBottomMenus = translateMenus(bottomMenus, t);
6023
+ const bottomBandMenuItems = useMemo(() => [...translatedMenus, ...translatedBottomMenus], [translatedMenus, translatedBottomMenus]);
5976
6024
  const { pathname } = useCurrentRoute();
5977
6025
  const matches = useMatches();
5978
6026
  /**
@@ -5986,32 +6034,33 @@ function useMenu() {
5986
6034
  if (!shouldSplitMenuItems) return "";
5987
6035
  const activeMenuPath = matches.findLast((routeItem) => routeItem.handle?.currentActiveMenu)?.handle?.currentActiveMenu;
5988
6036
  const targetPath = activeMenuPath ? removeTrailingSlash(activeMenuPath) : removeTrailingSlash(pathname);
5989
- const { rootMenuPath } = findRootMenuByPath(translatedMenus, targetPath);
6037
+ const { rootMenuPath } = findRootMenuByPath(bottomBandMenuItems, targetPath);
5990
6038
  return rootMenuPath ?? "";
5991
6039
  }, [
5992
6040
  shouldSplitMenuItems,
5993
6041
  pathname,
5994
- matches
6042
+ matches,
6043
+ bottomBandMenuItems
5995
6044
  ]);
5996
6045
  const splitSideNavItems = useMemo(() => {
5997
- const foundMenu = translatedMenus.find((item) => item?.key === sideNavMenuKeyInSplitMode);
6046
+ const foundMenu = bottomBandMenuItems.find((item) => item?.key === sideNavMenuKeyInSplitMode);
5998
6047
  if (!foundMenu) return [];
5999
6048
  return foundMenu?.children ?? [foundMenu];
6000
- }, [sideNavMenuKeyInSplitMode, translatedMenus]);
6049
+ }, [sideNavMenuKeyInSplitMode, bottomBandMenuItems]);
6001
6050
  /**
6002
- * 头部菜单
6051
+ * 头部菜单(含底部区条目回落到末尾:顶部导航/双列第一列无底槽)
6003
6052
  */
6004
6053
  const topNavItems = useMemo(() => {
6005
- if (!shouldSplitMenuItems) return translatedMenus;
6006
- return translatedMenus.map((item) => {
6054
+ if (!shouldSplitMenuItems) return bottomBandMenuItems;
6055
+ return bottomBandMenuItems.map((item) => {
6007
6056
  return {
6008
6057
  ...item,
6009
6058
  children: void 0
6010
6059
  };
6011
6060
  });
6012
- }, [shouldSplitMenuItems, translatedMenus]);
6061
+ }, [shouldSplitMenuItems, bottomBandMenuItems]);
6013
6062
  /**
6014
- * 侧边菜单
6063
+ * 侧边菜单(仅主区:底部固定区由侧边栏底槽单独渲染)
6015
6064
  */
6016
6065
  const sideNavItems = useMemo(() => {
6017
6066
  return shouldSplitMenuItems ? splitSideNavItems : translatedMenus;
@@ -6021,6 +6070,10 @@ function useMenu() {
6021
6070
  translatedMenus
6022
6071
  ]);
6023
6072
  /**
6073
+ * 底部固定区菜单(主区之后、SiderTrigger 之上渲染)
6074
+ */
6075
+ const bottomNavItems = translatedBottomMenus;
6076
+ /**
6024
6077
  * 菜单点击事件处理
6025
6078
  */
6026
6079
  const handleMenuSelect = (key, mode) => {
@@ -6029,7 +6082,7 @@ function useMenu() {
6029
6082
  if (/http(s)?:/.test(key)) window.open(key);
6030
6083
  else navigate(key);
6031
6084
  } else {
6032
- const targetMenu = findDeepestFirstItem(translatedMenus.find((item) => item?.key === key)?.children ?? []);
6085
+ const targetMenu = findDeepestFirstItem(bottomBandMenuItems.find((item) => item?.key === key)?.children ?? []);
6033
6086
  if (!targetMenu) navigate(key);
6034
6087
  else navigate(targetMenu.key);
6035
6088
  }
@@ -6038,7 +6091,8 @@ function useMenu() {
6038
6091
  handleMenuSelect,
6039
6092
  sideNavMenuKeyInSplitMode,
6040
6093
  topNavItems,
6041
- sideNavItems
6094
+ sideNavItems,
6095
+ bottomNavItems
6042
6096
  };
6043
6097
  }
6044
6098
  var init_use_menu = __esmMin((() => {
@@ -6222,7 +6276,8 @@ function LayoutMobileMenu() {
6222
6276
  const { token: { Menu } } = theme.useToken();
6223
6277
  const { sidebarCollapsed, setPreferences, isDark, sidebarTheme } = usePreferences();
6224
6278
  const { isMobile } = useDeviceType();
6225
- const { sideNavItems, handleMenuSelect } = useMenu();
6279
+ const { sideNavItems, bottomNavItems, handleMenuSelect } = useMenu();
6280
+ const menuItems = useMemo(() => [...sideNavItems, ...bottomNavItems], [sideNavItems, bottomNavItems]);
6226
6281
  return isMobile ? /* @__PURE__ */ jsx(Drawer, {
6227
6282
  styles: { body: { backgroundColor: isDark || sidebarTheme === "dark" ? Menu?.darkItemBg : Menu?.itemBg } },
6228
6283
  open: sidebarCollapsed,
@@ -6232,7 +6287,7 @@ function LayoutMobileMenu() {
6232
6287
  onClose: () => setPreferences("sidebarCollapsed", false),
6233
6288
  children: /* @__PURE__ */ jsx(Scrollbar, { children: /* @__PURE__ */ jsx(LayoutMenu, {
6234
6289
  autoExpandCurrentMenu: true,
6235
- menus: sideNavItems,
6290
+ menus: menuItems,
6236
6291
  handleMenuSelect
6237
6292
  }) })
6238
6293
  }) : null;
@@ -6257,6 +6312,7 @@ var init_layout_mobile_menu = __esmMin((() => {
6257
6312
  //#region src/layout/layout-sidebar/index.tsx
6258
6313
  function LayoutSidebar({ children, computedSidebarWidth }) {
6259
6314
  const { sidebarCollapsed, sidebarTheme, isDark } = usePreferences();
6315
+ const { bottomNavItems, handleMenuSelect } = useMenu();
6260
6316
  const { token: { Menu } } = theme.useToken();
6261
6317
  const isFixedDarkTheme = isDark || sidebarTheme === "dark";
6262
6318
  return /* @__PURE__ */ jsx(ConfigProvider, {
@@ -6267,14 +6323,21 @@ function LayoutSidebar({ children, computedSidebarWidth }) {
6267
6323
  backgroundColor: isFixedDarkTheme ? Menu?.darkItemBg : Menu?.itemBg,
6268
6324
  boxShadow: "3px 0 5px 0 rgb(29, 35, 41, 0.05)"
6269
6325
  },
6270
- className: "fixed top-0 bottom-0 left-0 overflow-x-hidden overflow-y-auto transition-all border-r border-r-colorBorderSecondary",
6326
+ className: "fixed top-0 bottom-0 left-0 flex flex-col overflow-x-hidden overflow-y-auto transition-all border-r border-r-colorBorderSecondary",
6271
6327
  children: [
6272
6328
  /* @__PURE__ */ jsx(Logo, { sidebarCollapsed }),
6273
6329
  /* @__PURE__ */ jsx("div", {
6274
- className: "overflow-hidden",
6275
- style: { height: `calc(100% - 48px - 40px)` },
6330
+ className: "flex-1 min-h-0 overflow-hidden",
6276
6331
  children: /* @__PURE__ */ jsx(Scrollbar, { children })
6277
6332
  }),
6333
+ bottomNavItems.length > 0 ? /* @__PURE__ */ jsx("div", {
6334
+ className: "shrink-0",
6335
+ children: /* @__PURE__ */ jsx(LayoutMenu, {
6336
+ autoExpandCurrentMenu: true,
6337
+ menus: bottomNavItems,
6338
+ handleMenuSelect
6339
+ })
6340
+ }) : null,
6278
6341
  /* @__PURE__ */ jsx(SiderTrigger, {})
6279
6342
  ]
6280
6343
  })
@@ -6283,7 +6346,8 @@ function LayoutSidebar({ children, computedSidebarWidth }) {
6283
6346
  var init_layout_sidebar = __esmMin((() => {
6284
6347
  init_scrollbar();
6285
6348
  init_use_preferences();
6286
- init_constants$1();
6349
+ init_layout_menu();
6350
+ init_use_menu();
6287
6351
  init_logo();
6288
6352
  init_sider_trigger();
6289
6353
  }));
@@ -8329,7 +8393,9 @@ var init_generate_menu_items_from_routes = __esmMin((() => {}));
8329
8393
  * - 三值 category 原样落 handle.category(main=常规组、admin=管理组、hidden=不进菜单);
8330
8394
  * - hidden 与 enabled=0(禁用)复用既有 hideInMenu 通路——只过滤菜单层,路由仍可达
8331
8395
  * (禁用的路由摘除归装载层三处同写,D12);
8332
- * - order 覆写为声明序:框架项保留 100 间隔带、方案项从 200 起编,共用一条序轴;
8396
+ * - order 覆写为声明序(2026-10-20 双段序轴):框架常规项 ≥0 升序、管理面负数入
8397
+ * 底部固定区(pin 侧边栏底部,ascending 双段排序)、方案项从 200 起编,共用一条序轴;
8398
+ * 同 order 按根 path 字母序;
8333
8399
  * - 未匹配路由(框架/后端)原样保留(同一对象引用),入参不突变;
8334
8400
  * - solRoutes 为空(端点失败/未登录降级空表)时原样返回——降级不阻断,路由照常。
8335
8401
  *
@@ -8406,7 +8472,22 @@ var init_resolve_login_route = __esmMin((() => {
8406
8472
  }));
8407
8473
  //#endregion
8408
8474
  //#region src/store/access.ts
8409
- var initialState$1, lastRegisteredRoutes, useAccessStore;
8475
+ /**
8476
+ * 切分主区/底部固定区路由(ascending 已双段排序:负 order 段整体在后)。
8477
+ * 按首个负 order 找边界一次切分,两段各自保持升序。
8478
+ */
8479
+ function splitMenuRoutes(routes) {
8480
+ const boundary = routes.findIndex((route) => (route.handle.order ?? 0) < 0);
8481
+ if (boundary === -1) return {
8482
+ top: routes,
8483
+ bottom: []
8484
+ };
8485
+ return {
8486
+ top: routes.slice(0, boundary),
8487
+ bottom: routes.slice(boundary)
8488
+ };
8489
+ }
8490
+ var baseMenuRoutes, initialState$1, lastRegisteredRoutes, useAccessStore;
8410
8491
  var init_access = __esmMin((() => {
8411
8492
  init_router();
8412
8493
  init_constants();
@@ -8416,8 +8497,10 @@ var init_access = __esmMin((() => {
8416
8497
  init_generate_menu_items_from_routes();
8417
8498
  init_merge_solution_categories();
8418
8499
  init_resolve_login_route();
8500
+ baseMenuRoutes = splitMenuRoutes(baseRoutes);
8419
8501
  initialState$1 = {
8420
- wholeMenus: generateMenuItemsFromRoutes(baseRoutes),
8502
+ wholeMenus: generateMenuItemsFromRoutes(baseMenuRoutes.top),
8503
+ bottomMenus: generateMenuItemsFromRoutes(baseMenuRoutes.bottom),
8421
8504
  routeList: baseRoutes,
8422
8505
  flatRouteList: flattenRoutes(baseRoutes),
8423
8506
  isAccessChecked: false,
@@ -8430,8 +8513,10 @@ var init_access = __esmMin((() => {
8430
8513
  const newRoutes = ascending([...resolveLoginRoute(baseRoutes, routes, router, rootRoute), ...mergeSolutionCategories(routes, get().solutionRoutes)]);
8431
8514
  router.patchRoutes(ROOT_ROUTE_ID, routes);
8432
8515
  const flatRouteList = flattenRoutes(newRoutes);
8516
+ const { top, bottom } = splitMenuRoutes(newRoutes);
8433
8517
  const newState = {
8434
- wholeMenus: generateMenuItemsFromRoutes(newRoutes),
8518
+ wholeMenus: generateMenuItemsFromRoutes(top),
8519
+ bottomMenus: generateMenuItemsFromRoutes(bottom),
8435
8520
  routeList: newRoutes,
8436
8521
  flatRouteList,
8437
8522
  isAccessChecked: true
@@ -3,6 +3,7 @@ import type { MenuItemType } from "../layout/layout-menu/types";
3
3
  import type { AppRouteRecordRaw } from "../router/types";
4
4
  interface AccessState {
5
5
  wholeMenus: MenuItemType[];
6
+ bottomMenus: MenuItemType[];
6
7
  routeList: AppRouteRecordRaw[];
7
8
  flatRouteList: Record<string, AppRouteRecordRaw>;
8
9
  isAccessChecked: boolean;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oj-module/runtime",
3
3
  "type": "module",
4
- "version": "0.2.6",
4
+ "version": "0.2.14",
5
5
  "description": "React Antd Admin 框架运行时,供模块工程消费",
6
6
  "license": "MIT",
7
7
  "imports": {