dsh-key-usage 0.1.2 → 0.1.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["useState","useCallback","useRef","styles","useMemo","styles","shared","styles","overviewStyles","styles","detailStyles","styles","styles","hitRateOf","styles","Fragment","detailStyles","styles","detailStyles","useState","useMemo","styles","listStyles","quotaStyles","styles","typed","useState","useMemo","styles","listStyles","Fragment","useState","useCallback","useMemo","styles","styles","h"],"sources":["../src/client/UsageIcon.tsx","../src/client/api.ts","../src/client/format.ts","../src/client/tooltip.tsx","../src/client/channels.ts","../src/client/components/Heatmap.tsx","../src/client/tabs/OverviewTab.tsx","../src/client/components/ShareBar.tsx","../src/client/components/StatCard.tsx","../src/client/components/TokenBars.tsx","../src/client/components/DailyDetailTable.tsx","../src/client/tabs/DetailTab.tsx","../src/client/tabs/ProjectsTab.tsx","../src/client/tabs/QuotaTab.tsx","../src/client/tabs/SessionsTab.tsx","../src/client/KeyUsageSection.tsx","../src/client/UsagePage.tsx","../src/client/index.tsx"],"sourcesContent":["/**\n * 侧边栏导航图标(`sidebar.panellist`)。\n * 该 slot 由宿主自持整行(标签、hover/active 配色),插件只提供字形,\n * 因此用 currentColor 让宿主的行样式直接染上图标。\n */\nimport type { ReactNode } from 'react'\n\nexport function UsageIcon({ size = 18 }: { size?: number }): ReactNode {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n style={{ display: 'block' }}\n >\n <rect x=\"2.6\" y=\"8.8\" width=\"2.6\" height=\"4.2\" rx=\"0.7\" fill=\"currentColor\" />\n <rect x=\"6.7\" y=\"5.6\" width=\"2.6\" height=\"7.4\" rx=\"0.7\" fill=\"currentColor\" />\n <rect x=\"10.8\" y=\"2.8\" width=\"2.6\" height=\"10.2\" rx=\"0.7\" fill=\"currentColor\" />\n </svg>\n )\n}\n","/** 同源只读端点的取数封装:任何失败都返回 null,由调用方决定空态。 */\nimport type {\n Channel,\n HeatmapDay,\n ProjectsResponse,\n QuotaProvider,\n SessionsResponse,\n SummaryResponse,\n UsageResponse,\n} from './types.ts'\n\nasync function fetchJson<T>(path: string): Promise<T | null> {\n try {\n const response = await fetch(path, { headers: { Accept: 'application/json' } })\n if (!response.ok) return null\n return await response.json() as T\n } catch {\n return null\n }\n}\n\nexport async function loadChannels(): Promise<Channel[] | null> {\n const result = await fetchJson<{ channels: Channel[] }>('/dsh-key-usage/channels')\n return result === null ? null : result.channels\n}\n\nexport async function loadUsage(from: string, to: string, provider: string): Promise<UsageResponse | null> {\n const params = new URLSearchParams({ from, to })\n if (provider !== 'ALL') params.set('provider', provider)\n return fetchJson<UsageResponse>('/dsh-key-usage/usage?' + params.toString())\n}\n\nexport async function loadHeatmap(): Promise<HeatmapDay[] | null> {\n const result = await fetchJson<{ days: HeatmapDay[] }>('/dsh-key-usage/heatmap')\n return result === null ? null : result.days\n}\n\n/**\n * 余额与订阅窗口:服务端实时优先、失败回落本机快照。\n * @param fresh - 用户手动刷新时传 true,强制重新查一次官方接口\n */\nexport async function loadQuota(fresh = false): Promise<QuotaProvider[] | null> {\n const query = fresh ? '?fresh=1' : ''\n const result = await fetchJson<{ providers: QuotaProvider[] }>('/dsh-key-usage/quota' + query)\n return result === null ? null : result.providers\n}\n\nexport function loadSummary(): Promise<SummaryResponse | null> {\n return fetchJson<SummaryResponse>('/dsh-key-usage/summary')\n}\n\nexport function loadSessions(limit = 300): Promise<SessionsResponse | null> {\n return fetchJson<SessionsResponse>('/dsh-key-usage/sessions?limit=' + String(limit))\n}\n\nexport function loadProjects(limit = 200): Promise<ProjectsResponse | null> {\n return fetchJson<ProjectsResponse>('/dsh-key-usage/projects?limit=' + String(limit))\n}\n","/** 展示层格式化:全部与统计口径无关,只负责把数字变成界面文本。 */\n\n/** 本地日历 `YYYY-MM-DD`。 */\nexport function isoDate(date: Date): string {\n const month = String(date.getMonth() + 1).padStart(2, '0')\n const day = String(date.getDate()).padStart(2, '0')\n return `${date.getFullYear()}-${month}-${day}`\n}\n\nexport function shiftedIsoDate(offsetDays: number): string {\n return isoDate(new Date(Date.now() + offsetDays * 86400000))\n}\n\nexport function fmtTokens(count: number): string {\n if (count >= 1e9) return (count / 1e9).toFixed(2) + 'B'\n if (count >= 1e6) return (count / 1e6).toFixed(1) + 'M'\n if (count >= 1e3) return (count / 1e3).toFixed(0) + 'K'\n return String(count)\n}\n\nexport function fmtCost(amount: number): string {\n return '¥' + amount.toFixed(2)\n}\n\nexport function fmtCalls(count: number): string {\n return count.toLocaleString('en-US').replace(/,/g, ' ')\n}\n\n/** `MM-DD`(图表坐标轴与范围文案用)。 */\nexport function fmtShortDate(dateKey: string): string {\n return dateKey.slice(5)\n}\n\n/** 毫秒时间戳 → `YYYY-MM-DD HH:mm`(本地时区)。 */\nexport function fmtDateTime(timeMs: number | null): string {\n if (timeMs === null) return '—'\n const date = new Date(timeMs)\n const hours = String(date.getHours()).padStart(2, '0')\n const minutes = String(date.getMinutes()).padStart(2, '0')\n return `${isoDate(date)} ${hours}:${minutes}`\n}\n\n/** 毫秒时间戳 → `HH:mm`。 */\nexport function fmtTime(timeMs: number | null): string {\n if (timeMs === null) return '—'\n const date = new Date(timeMs)\n return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`\n}\n\n/** 时长(毫秒)→ `2h 15m` / `43m` / `—`。 */\nexport function fmtDuration(milliseconds: number | null): string {\n if (milliseconds === null || milliseconds <= 0) return '—'\n const minutes = Math.max(1, Math.round(milliseconds / 60000))\n if (minutes < 60) return `${minutes}m`\n return `${Math.floor(minutes / 60)}h ${minutes % 60}m`\n}\n\n/** 最近活跃:刚刚 / N 分钟前 / N 小时前 / N 天前。 */\nexport function fmtRelative(timeMs: number | null, nowMs: number): string {\n if (timeMs === null) return '—'\n const minutes = Math.round((nowMs - timeMs) / 60000)\n if (minutes < 1) return '刚刚'\n if (minutes < 60) return `${minutes} 分钟前`\n if (minutes < 60 * 24) return `${Math.round(minutes / 60)} 小时前`\n return `${Math.round(minutes / (60 * 24))} 天前`\n}\n\n/** 命中率:一位小数百分数,无提示侧 token 时返回 —。 */\nexport function fmtHitRate(cacheReadTokens: number, promptTokens: number): string {\n if (promptTokens <= 0) return '—'\n return (cacheReadTokens / promptTokens * 100).toFixed(1) + '%'\n}\n","/** 共享浮层:跟随鼠标的 fixed 层,内容用 React 节点渲染(不再拼接 innerHTML)。 */\nimport { useCallback, useLayoutEffect, useRef, useState, type ReactNode } from 'react'\nimport styles from './styles/shared.module.css'\n\nexport interface TooltipContent {\n x: number\n y: number\n node: ReactNode\n}\n\nexport interface TooltipApi {\n tooltip: TooltipContent | null\n show: (event: React.MouseEvent, node: ReactNode) => void\n hide: () => void\n}\n\nexport function useTooltip(): TooltipApi {\n const [tooltip, setTooltip] = useState<TooltipContent | null>(null)\n const show = useCallback((event: React.MouseEvent, node: ReactNode) => {\n setTooltip({ x: event.clientX, y: event.clientY, node })\n }, [])\n const hide = useCallback(() => setTooltip(null), [])\n return { tooltip, show, hide }\n}\n\nexport function TooltipView({ tooltip }: { tooltip: TooltipContent | null }): ReactNode {\n const elementRef = useRef<HTMLDivElement | null>(null)\n useLayoutEffect(() => {\n const element = elementRef.current\n if (element === null || tooltip === null) return\n const maxX = window.innerWidth - element.offsetWidth - 12\n const maxY = window.innerHeight - element.offsetHeight - 12\n element.style.left = Math.max(8, Math.min(tooltip.x + 14, maxX)) + 'px'\n element.style.top = Math.max(8, Math.min(tooltip.y + 14, maxY)) + 'px'\n }, [tooltip])\n if (tooltip === null) return null\n return <div ref={elementRef} className={styles.tooltip}>{tooltip.node}</div>\n}\n\nexport function TipTitle({ children }: { children: ReactNode }): ReactNode {\n return <div className={styles.tipTitle}>{children}</div>\n}\n\nexport function TipSub({ children }: { children: ReactNode }): ReactNode {\n return <div className={styles.tipSub}>{children}</div>\n}\n\nexport function TipRow(props: { color?: string; label: ReactNode; amount?: ReactNode; rate?: ReactNode }): ReactNode {\n return (\n <div className={styles.tipRow}>\n {props.color !== undefined && <i style={{ background: props.color }} />}\n <span className={styles.tipName}>{props.label}</span>\n {props.amount !== undefined && <span className={styles.tipAmount}>{props.amount}</span>}\n {props.rate !== undefined && <span className={styles.tipRate}>{props.rate}</span>}\n </div>\n )\n}\n\nexport function TipBar({ percent, color }: { percent: number; color: string }): ReactNode {\n return <div className={styles.tipBar}><i style={{ width: Math.max(2, percent) + '%', background: color }} /></div>\n}\n\nexport function TipDivider({ children }: { children: ReactNode }): ReactNode {\n return <div className={styles.tipDivider}>{children}</div>\n}\n","/** 通道展示工具:颜色、显示名、状态与计费模式文案。 */\nimport type { Channel, ChannelCostMode, ChannelStatus } from './types.ts'\n\nconst CHANNEL_COLORS = ['#5b8cff', '#9a7bff', '#3fb96f', '#e0a13c', '#e05a5a', '#38bdc8']\n\nexport const STATUS_LABELS: Record<ChannelStatus, string> = {\n ok: '正常',\n warn: '偏高',\n danger: '告警',\n off: '未配置',\n}\n\nexport function channelIndexOf(channels: Channel[], provider: string): number {\n return channels.findIndex((channel) => channel.provider === provider)\n}\n\nexport function channelColorOf(channels: Channel[], provider: string): string {\n const index = channelIndexOf(channels, provider)\n return CHANNEL_COLORS[(index >= 0 ? index : 0) % CHANNEL_COLORS.length]\n}\n\nexport function displayNameOf(channels: Channel[], provider: string): string {\n return channels.find((channel) => channel.provider === provider)?.displayName ?? provider\n}\n\nexport function channelOf(channels: Channel[], provider: string | null): Channel | null {\n if (provider === null) return null\n return channels.find((channel) => channel.provider === provider) ?? null\n}\n\n/** 成本单元格:按计费模式给出文案,无法判定时回落金额或 —。 */\nexport function costCellText(channel: Channel | null, cost: number): { text: string; dim: boolean } {\n if (channel === null) return cost > 0 ? { text: '¥' + cost.toFixed(2), dim: false } : { text: '—', dim: true }\n if (channel.costMode === 'sub') return { text: '订阅内', dim: true }\n if (channel.costMode === 'free') return { text: '¥0.00', dim: true }\n if (channel.costMode === 'none') return { text: '无计费', dim: true }\n return cost > 0 ? { text: '¥' + cost.toFixed(2), dim: false } : { text: '—', dim: true }\n}\n\n/** 状态点的颜色(走宿主告警/成功令牌)。 */\nexport function statusColorOf(status: ChannelStatus): string {\n if (status === 'ok') return 'var(--dsw-alias-state-success-primary, #3fb96f)'\n if (status === 'warn') return 'var(--dsw-alias-state-warning-primary, #e0a13c)'\n if (status === 'danger') return 'var(--dsw-alias-state-danger-primary, #e05a5a)'\n return 'var(--dsw-alias-label-tertiary, #67676f)'\n}\n\n/** 窗口占用进度条颜色:≥90 危险、≥60 警告,其余正常。 */\nexport function quotaBarColor(percent: number): string {\n if (percent >= 90) return 'var(--dsw-alias-state-danger-primary, #e05a5a)'\n if (percent >= 60) return 'var(--dsw-alias-state-warning-primary, #e0a13c)'\n return 'var(--dsw-alias-state-success-primary, #3fb96f)'\n}\n\nexport const COST_MODE_LABELS: Record<ChannelCostMode, string> = {\n sub: '订阅制',\n perToken: '按量计费',\n free: '免费额度',\n none: '本地端点',\n unknown: '未查询',\n}\n","/**\n * 活跃热力图:最近约 9 个月的滚动窗口(含未来格占位)。\n * 强度分档取活跃日的三分位(p33 / p67),阈值随可见区间自动变化,\n * 具体数值并入页面底部的口径说明,不再单独占一行。\n * 格子用固定方形尺寸 + 横向滚动,保证「有数据 / 无数据 / 无用量」三类格子完全等大。\n */\nimport { useMemo, type ReactNode } from 'react'\nimport { channelColorOf, displayNameOf } from '../channels.ts'\nimport { fmtTokens, isoDate } from '../format.ts'\nimport type { Channel, HeatmapDay } from '../types.ts'\nimport { TipBar, TipRow, TipSub, TipTitle, type TooltipApi } from '../tooltip.tsx'\nimport styles from '../styles/overview.module.css'\nimport shared from '../styles/shared.module.css'\n\n/** 9 个月 ≈ 39 周;配合 18px 方形格子,窄窗口下横向滚动。 */\nconst WEEK_COUNT = 39\nconst DAY_MS = 86400000\n\ninterface HeatCell {\n date: string\n state: 'future' | 'empty' | 'idle' | 'active'\n level: number\n}\n\nfunction levelThresholds(days: HeatmapDay[]): [number, number] {\n const active = days.map((day) => day.totalTokens).filter((tokens) => tokens > 0).sort((first, second) => first - second)\n if (active.length < 3) return [5e7, 2e8]\n const pick = (fraction: number): number => active[Math.min(active.length - 1, Math.floor(active.length * fraction))]\n return [pick(0.33), pick(0.67)]\n}\n\nfunction levelOf(tokens: number, thresholds: [number, number]): number {\n if (tokens <= 0) return 0\n if (tokens < thresholds[0]) return 1\n if (tokens < thresholds[1]) return 2\n return 3\n}\n\nconst LEVEL_COLORS = ['rgba(128,128,140,.22)', 'rgba(91,140,255,.25)', 'rgba(91,140,255,.55)', '#5b8cff']\n\nexport function Heatmap(props: { days: HeatmapDay[]; channels: Channel[]; tooltip: TooltipApi }): ReactNode {\n const { days, channels, tooltip } = props\n const heatmapByDate = useMemo(() => new Map(days.map((day) => [day.date, day])), [days])\n const thresholds = useMemo(() => levelThresholds(days), [days])\n\n const { columns, monthLabels } = useMemo(() => {\n const today = new Date()\n today.setHours(0, 0, 0, 0)\n const endSaturday = new Date(today.getTime() + (6 - today.getDay()) * DAY_MS)\n const start = new Date(endSaturday.getTime() - (WEEK_COUNT * 7 - 1) * DAY_MS)\n const dataStart = days.length > 0 ? days[0].date : null\n const cells: HeatCell[] = []\n for (let offset = 0; offset < WEEK_COUNT * 7; offset += 1) {\n const date = new Date(start.getTime() + offset * DAY_MS)\n const dateKey = isoDate(date)\n if (date.getTime() > today.getTime()) {\n cells.push({ date: dateKey, state: 'future', level: 0 })\n continue\n }\n // 台账覆盖之前的日子用 ghost 占位,与「无用量」的灰区分开\n if (dataStart === null || dateKey < dataStart) {\n cells.push({ date: dateKey, state: 'empty', level: 0 })\n continue\n }\n const day = heatmapByDate.get(dateKey)\n if (day === undefined || day.totalTokens <= 0) {\n cells.push({ date: dateKey, state: 'idle', level: 0 })\n continue\n }\n cells.push({ date: dateKey, state: 'active', level: levelOf(day.totalTokens, thresholds) })\n }\n const weeks: HeatCell[][] = []\n for (let index = 0; index < cells.length; index += 7) weeks.push(cells.slice(index, index + 7))\n const labels: string[] = []\n let previousMonth = -1\n for (const week of weeks) {\n const month = Number(week[0].date.slice(5, 7))\n labels.push(month !== previousMonth ? month + '月' : '')\n previousMonth = month\n }\n return { columns: weeks, monthLabels: labels }\n }, [days, heatmapByDate])\n\n return (\n <div className={styles.heatmapCard}>\n <div className={styles.heatmapHead}>\n <span className={styles.heatmapTitle}>活跃热力图 · 近 9 个月 · 按当日 Tokens 总量 · 悬停查看当日各模型占比</span>\n <span className={shared.legend}>\n <span><i className=\"ghost\" />无数据</span>\n <span><i style={{ background: LEVEL_COLORS[0] }} />无用量</span>\n <span><i style={{ background: LEVEL_COLORS[1] }} />少</span>\n <span><i style={{ background: LEVEL_COLORS[2] }} />中</span>\n <span><i style={{ background: LEVEL_COLORS[3] }} />高</span>\n </span>\n </div>\n <div className={styles.heatmapScroll}>\n <div className={styles.heatmapBody}>\n <div className={styles.heatWeekdays}>\n <span>日</span><span>一</span><span>二</span><span>三</span><span>四</span><span>五</span><span>六</span>\n </div>\n <div className={styles.heatGridCol}>\n <div className={styles.heatGrid}>\n {columns.map((week, weekIndex) => (\n <div className={styles.heatWeek} key={weekIndex}>\n {week.map((cell) => {\n const day = cell.state === 'active' ? heatmapByDate.get(cell.date) : undefined\n const className = cell.state === 'active'\n ? styles.heatCell\n : cell.state === 'idle' ? styles.heatCell + ' ' + styles.idle : styles.heatCell + ' ' + styles.empty\n return (\n <div\n key={cell.date}\n className={className}\n style={cell.state === 'active' ? { background: LEVEL_COLORS[cell.level] } : undefined}\n onMouseMove={(event) => tooltip.show(event, tipOf(cell, day, channels))}\n onMouseLeave={tooltip.hide}\n />\n )\n })}\n </div>\n ))}\n </div>\n <div className={styles.heatMonths}>\n {monthLabels.map((label, index) => <span key={index}>{label}</span>)}\n </div>\n </div>\n </div>\n </div>\n </div>\n )\n}\n\nfunction tipOf(cell: HeatCell, day: HeatmapDay | undefined, channels: Channel[]): ReactNode {\n if (cell.state !== 'active' || day === undefined) {\n return (\n <>\n <TipTitle>{cell.date}</TipTitle>\n <TipSub>{cell.state === 'idle' ? '当日无用量记录' : '台账尚未覆盖'}</TipSub>\n </>\n )\n }\n return (\n <>\n <TipTitle>{cell.date}</TipTitle>\n <TipSub>合计 <b>{fmtTokens(day.totalTokens)}</b> tokens</TipSub>\n {day.models.map((model) => {\n const percent = day.totalTokens > 0 ? Math.round(model.totalTokens / day.totalTokens * 100) : 0\n const color = channelColorOf(channels, model.provider)\n return (\n <div key={model.provider + '|' + model.model}>\n <TipRow\n color={color}\n label={<>{model.model}<span className={shared.dim}> · {displayNameOf(channels, model.provider)}</span></>}\n amount={fmtTokens(model.totalTokens)}\n rate={percent + '%'}\n />\n <TipBar percent={percent} color={color} />\n </div>\n )\n })}\n </>\n )\n}\n","/** 总览:Key 清单表(原型列结构)+ 年度热力图。 */\nimport type { ReactNode } from 'react'\nimport { costCellText, statusColorOf } from '../channels.ts'\nimport { fmtCalls, fmtTokens } from '../format.ts'\nimport type { Channel, HeatmapDay, QuotaProvider, SummaryResponse } from '../types.ts'\nimport type { TooltipApi } from '../tooltip.tsx'\nimport { Heatmap } from '../components/Heatmap.tsx'\nimport styles from '../styles/shared.module.css'\nimport overviewStyles from '../styles/overview.module.css'\n\nexport function OverviewTab(props: {\n channels: Channel[]\n summary: SummaryResponse | null\n quotas: QuotaProvider[]\n heatmap: HeatmapDay[]\n tooltip: TooltipApi\n onOpenDetail: (provider: string) => void\n}): ReactNode {\n const { channels, summary } = props\n return (\n <div>\n <div className={styles.groupLabel}>Key 清单</div>\n <table className={overviewStyles.keyTable}>\n <thead>\n <tr>\n <th>通道</th><th>类型</th><th>今日</th><th>近 30 天</th><th>余额 / 窗口</th><th>30 天成本</th><th></th>\n </tr>\n </thead>\n <tbody>\n {channels.map((channel) => {\n const row = summary?.channels.find((item) => item.provider === channel.provider) ?? null\n const todayTokens = row === null ? 0 : row.today.tokens\n const monthTokens = row === null ? 0 : row.month.tokens\n const monthCost = row === null ? 0 : row.month.cost\n const costCell = costCellText(channel, monthCost)\n const disabled = channel.status === 'off'\n return (\n <tr\n key={channel.provider}\n className={disabled ? overviewStyles.disabledRow : overviewStyles.clickable}\n onClick={disabled ? undefined : () => props.onOpenDetail(channel.provider)}\n >\n <td>\n <div className={overviewStyles.cellKey}>\n <span className={styles.statusDot} style={{ background: statusColorOf(channel.status) }} />\n <div className={overviewStyles.keyDisplay}>{channel.displayName}</div>\n </div>\n </td>\n <td><span className={tagClassOf(channel)}>{channel.status === 'off' ? '未配置' : channel.costLabel}</span></td>\n <td>{todayTokens > 0 ? fmtTokens(todayTokens) : <span className={styles.dim}>—</span>}</td>\n <td>{monthTokens > 0 ? fmtTokens(monthTokens) : <span className={styles.dim}>—</span>}</td>\n <td>{quotaCellOf(channel)}</td>\n <td>{costCell.dim ? <span className={styles.dim}>{costCell.text}</span> : costCell.text}</td>\n <td>{disabled ? null : <span className={overviewStyles.rowLink}>明细 →</span>}</td>\n </tr>\n )\n })}\n {channels.length === 0 && <tr><td colSpan={7} className={styles.empty}>未读取到通道配置</td></tr>}\n </tbody>\n </table>\n\n <Heatmap days={props.heatmap} channels={channels} tooltip={props.tooltip} />\n\n {summary === null && (\n <div className={styles.empty}>台账读取中或不可用,今日 / 近 30 天列为空</div>\n )}\n {props.quotas.length === 0 && channels.length > 0 && (\n <div className={styles.empty}>未读取到余额快照,余额 / 窗口列显示为 —</div>\n )}\n </div>\n )\n}\n\nfunction tagClassOf(channel: Channel): string {\n const base = overviewStyles.tag\n if (channel.status === 'off') return base + ' ' + overviewStyles.off\n if (channel.costMode === 'free') return base + ' ' + overviewStyles.free\n if (channel.costMode === 'sub') return base + ' ' + overviewStyles.sub\n return base\n}\n\nfunction quotaCellOf(channel: Channel): ReactNode {\n if (channel.costMode === 'sub' && channel.quotaPercent !== null) {\n const percent = channel.quotaPercent\n const levelClass = percent >= 90 ? overviewStyles.danger : percent >= 60 ? overviewStyles.warn : ''\n const windowLabel = channel.quotaWindowLabel ?? channel.quotaWindowKey ?? ''\n return (\n <span className={overviewStyles.quotaCell}>\n <span className={overviewStyles.miniBar}>\n <i style={{ width: Math.max(2, percent) + '%', background: percent >= 60 ? 'var(--dsw-alias-state-warning-primary, #e0a13c)' : 'var(--dsw-alias-state-success-primary, #3fb96f)' }} />\n </span>\n <span className={[overviewStyles.quotaText, levelClass].join(' ').trim()}>{windowLabel} {percent}%</span>\n </span>\n )\n }\n if (channel.balanceText !== null) {\n const levelClass = channel.status === 'danger' ? overviewStyles.danger : channel.status === 'warn' ? overviewStyles.warn : ''\n return (\n <span className={overviewStyles.quotaCell}>\n <span className={[overviewStyles.quotaText, levelClass].join(' ').trim()}>{channel.balanceText}</span>\n </span>\n )\n }\n const fallback = channel.costMode === 'none' ? '无计费' : channel.costMode === 'free' ? '—' : '未查询'\n return <span className={[overviewStyles.quotaText, overviewStyles.dim].join(' ')}>{fallback}</span>\n}\n\n/** 供标题行使用的调用汇总(占位保持导出面稳定)。 */\nexport function overviewCaptionOf(summary: SummaryResponse | null): string {\n if (summary === null) return '台账不可用'\n const calls = summary.channels.reduce((total, row) => total + row.month.calls, 0)\n return fmtCalls(calls) + ' 次调用'\n}\n","/**\n * 占比条:全部通道→通道占比;单通道→模型占比。\n * 只有一条堆叠横条,名字与百分比走悬停 tip(不再列表展示)。\n */\nimport type { ReactNode } from 'react'\nimport { channelColorOf, displayNameOf } from '../channels.ts'\nimport { fmtTokens } from '../format.ts'\nimport type { Channel, UsageResponse } from '../types.ts'\nimport { TipRow, TipSub, TipTitle, type TooltipApi } from '../tooltip.tsx'\nimport styles from '../styles/shared.module.css'\nimport detailStyles from '../styles/detail.module.css'\n\ninterface ShareRow {\n key: string\n label: string\n tokens: number\n color: string\n}\n\nexport function ShareBar(props: {\n usage: UsageResponse | null\n totalTokens: number\n channelFilter: string\n channels: Channel[]\n tooltip: TooltipApi\n}): ReactNode {\n const { usage, totalTokens, channels } = props\n if (usage === null || totalTokens <= 0) {\n return (\n <div className={styles.card}>\n <div className={styles.statLabel}>占比 · 按 Tokens</div>\n <div className={styles.empty} style={{ padding: '8px 0' }}>所选范围内无用量记录</div>\n </div>\n )\n }\n let rows: ShareRow[] = []\n let title = '通道占比 · 按 Tokens'\n if (props.channelFilter === 'ALL') {\n const byProvider = new Map<string, number>()\n for (const day of usage.days) {\n for (const model of day.models) {\n byProvider.set(model.provider, (byProvider.get(model.provider) ?? 0) + model.inputTokens + model.outputTokens + model.cacheReadTokens)\n }\n }\n rows = [...byProvider.entries()].map(([provider, tokens]) => ({\n key: provider, label: displayNameOf(channels, provider), tokens, color: channelColorOf(channels, provider),\n }))\n } else {\n title = '模型占比 · 按 Tokens'\n const byModel = new Map<string, { tokens: number; provider: string }>()\n for (const day of usage.days) {\n for (const model of day.models) {\n const bucket = byModel.get(model.model)\n const tokens = model.inputTokens + model.outputTokens + model.cacheReadTokens\n if (bucket === undefined) byModel.set(model.model, { tokens, provider: model.provider })\n else bucket.tokens += tokens\n }\n }\n rows = [...byModel.entries()].map(([model, value]) => ({\n key: model, label: model, tokens: value.tokens, color: channelColorOf(channels, value.provider),\n }))\n }\n rows.sort((first, second) => second.tokens - first.tokens)\n return (\n <div className={styles.card}>\n <div className={styles.statLabel}>{title}</div>\n <div className={detailStyles.shareBar}>\n {rows.map((row) => {\n const percent = totalTokens > 0 ? Math.round(row.tokens / totalTokens * 100) : 0\n return (\n <i\n key={row.key}\n style={{ width: (row.tokens / totalTokens * 100) + '%', background: row.color }}\n onMouseMove={(event) => props.tooltip.show(event, (\n <>\n <TipTitle>{row.label}</TipTitle>\n <TipSub>占比 <b>{percent}%</b></TipSub>\n <TipRow color={row.color} label=\"Tokens\" amount={fmtTokens(row.tokens)} rate={percent + '%'} />\n </>\n ))}\n onMouseLeave={props.tooltip.hide}\n />\n )\n })}\n </div>\n </div>\n )\n}\n","/** 统计卡:标签 + 主数值 + 副文案(原型 .stat-card)。 */\nimport type { ReactNode } from 'react'\nimport styles from '../styles/shared.module.css'\n\nexport function StatCard(props: { label: string; value: ReactNode; extra?: ReactNode }): ReactNode {\n return (\n <div className={styles.card}>\n <div className={styles.statLabel}>{props.label}</div>\n <div className={styles.statValue}>{props.value}</div>\n {props.extra !== undefined && <div className={styles.statExtra}>{props.extra}</div>}\n </div>\n )\n}\n","/** 堆叠柱状图:按天或按小时,含 x 轴标签(原型 .bars/.bar-labels)。 */\nimport type { ReactNode } from 'react'\nimport type { TooltipApi } from '../tooltip.tsx'\nimport styles from '../styles/detail.module.css'\n\nexport interface TokenBarRow {\n key: string\n axisLabel: string\n cacheReadTokens: number\n inputTokens: number\n outputTokens: number\n tip: ReactNode\n}\n\nexport function TokenBars(props: {\n rows: TokenBarRow[]\n tooltip: TooltipApi\n hidden?: boolean\n}): ReactNode {\n const { rows, tooltip } = props\n if (props.hidden === true || rows.length === 0) return null\n const peak = Math.max(1, ...rows.map((row) => row.cacheReadTokens + row.inputTokens + row.outputTokens))\n const heightOf = (value: number): string => (peak > 0 ? Math.max(1, Math.round(value / peak * 100)) : 1) + '%'\n // 标签抽稀:列数多时每列都写会糊成一片,只保留首列、末列与等距采样\n const labelEvery = Math.max(1, Math.ceil(rows.length / 14))\n return (\n <>\n <div className={rows.length > 20 ? styles.bars + ' ' + styles.barsDense : styles.bars}>\n {rows.map((row) => {\n const rowTotal = row.cacheReadTokens + row.inputTokens + row.outputTokens\n return (\n <div\n key={row.key}\n className={styles.barColumn}\n onMouseMove={(event) => tooltip.show(event, row.tip)}\n onMouseLeave={tooltip.hide}\n >\n {rowTotal > 0 && (\n <>\n <span className={styles.segCache} style={{ height: heightOf(row.cacheReadTokens) }} />\n <span className={styles.segIn} style={{ height: heightOf(row.inputTokens) }} />\n <span className={styles.segOut} style={{ height: heightOf(row.outputTokens) }} />\n </>\n )}\n </div>\n )\n })}\n </div>\n <div className={styles.barLabels}>\n {rows.map((row, index) => (\n <span key={row.key}>{index % labelEvery === 0 || index === rows.length - 1 ? row.axisLabel : ''}</span>\n ))}\n </div>\n </>\n )\n}\n","/**\n * 每日细目:以「天」为折叠单位,展开行用原型子表格展示模型维度\n * (模型 + 调用 / 输入 / 输出 / 缓存读 / 命中率,不占主表列)。\n */\nimport { Fragment, type ReactNode } from 'react'\nimport { displayNameOf } from '../channels.ts'\nimport { fmtCalls, fmtTokens } from '../format.ts'\nimport type { Channel, UsageResponse } from '../types.ts'\nimport styles from '../styles/shared.module.css'\nimport detailStyles from '../styles/detail.module.css'\n\nexport interface DetailSortState {\n key: string\n dir: 'asc' | 'desc'\n}\n\ninterface ModelRow {\n period: string\n model: string\n provider: string\n calls: number\n inputTokens: number\n outputTokens: number\n cacheReadTokens: number\n cost: number\n totalTokens: number\n}\n\ninterface PeriodRow {\n period: string\n calls: number\n inputTokens: number\n outputTokens: number\n cacheReadTokens: number\n cost: number\n totalTokens: number\n}\n\nfunction hitRateOf(cacheReadTokens: number, inputTokens: number, outputTokens: number): string {\n const total = inputTokens + outputTokens + cacheReadTokens\n if (total <= 0) return '—'\n return (cacheReadTokens / total * 100).toFixed(1) + '%'\n}\n\nconst COMPARERS: Record<string, (first: PeriodRow, second: PeriodRow) => number> = {\n period: (first, second) => (first.period < second.period ? -1 : first.period > second.period ? 1 : 0),\n total: (first, second) => first.totalTokens - second.totalTokens,\n calls: (first, second) => first.calls - second.calls,\n input: (first, second) => first.inputTokens - second.inputTokens,\n output: (first, second) => first.outputTokens - second.outputTokens,\n cacheRead: (first, second) => first.cacheReadTokens - second.cacheReadTokens,\n hit: (first, second) => {\n const firstTotal = first.inputTokens + first.outputTokens + first.cacheReadTokens\n const secondTotal = second.inputTokens + second.outputTokens + second.cacheReadTokens\n return (firstTotal > 0 ? first.cacheReadTokens / firstTotal : -1) - (secondTotal > 0 ? second.cacheReadTokens / secondTotal : -1)\n },\n cost: (first, second) => first.cost - second.cost,\n}\n\nexport function DailyDetailTable(props: {\n usage: UsageResponse\n channels: Channel[]\n channelFilter: string\n expandedPeriods: Record<string, boolean>\n onTogglePeriod: (periodKey: string) => void\n sort: DetailSortState\n onSort: (sort: DetailSortState) => void\n}): ReactNode {\n const { usage, channels, channelFilter, expandedPeriods, onTogglePeriod, sort, onSort } = props\n const modelRows: ModelRow[] = []\n for (const day of usage.days) {\n for (const model of day.models) {\n const totalTokens = model.inputTokens + model.outputTokens + model.cacheReadTokens\n modelRows.push({\n period: day.date, model: model.model, provider: model.provider, calls: model.calls,\n inputTokens: model.inputTokens, outputTokens: model.outputTokens, cacheReadTokens: model.cacheReadTokens,\n cost: model.cost, totalTokens,\n })\n }\n }\n const aggregates = new Map<string, PeriodRow>()\n for (const row of modelRows) {\n const bucket = aggregates.get(row.period)\n if (bucket === undefined) {\n aggregates.set(row.period, {\n period: row.period, calls: row.calls, inputTokens: row.inputTokens, outputTokens: row.outputTokens,\n cacheReadTokens: row.cacheReadTokens, cost: row.cost, totalTokens: row.totalTokens,\n })\n } else {\n bucket.calls += row.calls\n bucket.inputTokens += row.inputTokens\n bucket.outputTokens += row.outputTokens\n bucket.cacheReadTokens += row.cacheReadTokens\n bucket.cost += row.cost\n bucket.totalTokens += row.totalTokens\n }\n }\n const comparer = COMPARERS[sort.key] ?? COMPARERS.period\n const ordered = [...aggregates.values()].sort((first, second) => {\n const compared = comparer(first, second)\n return sort.dir === 'asc' ? compared : -compared\n })\n\n const header = (key: string, label: string): ReactNode => {\n const isActive = sort.key === key\n return (\n <th\n className={isActive ? styles.sortActive : styles.sortable}\n onClick={() => onSort(isActive ? { key, dir: sort.dir === 'asc' ? 'desc' : 'asc' } : { key, dir: 'desc' })}\n >\n {label}<span className={styles.sortArrow}>{isActive ? (sort.dir === 'asc' ? '▲' : '▼') : '↕'}</span>\n </th>\n )\n }\n\n const totals = usage.totals\n const totalTokens = totals === null ? 0 : totals.inputTokens + totals.outputTokens + totals.cacheReadTokens\n const periodCount = ordered.length\n\n if (periodCount === 0) {\n return (\n <div>\n <div className={styles.blockLabel}>每日细目</div>\n <div className={styles.empty}>所选范围内无用量记录</div>\n </div>\n )\n }\n\n return (\n <div>\n <div className={styles.blockLabel}>每日细目</div>\n <table className={styles.table}>\n <thead>\n <tr>\n {header('period', '日期')}\n {header('total', '总计')}\n {header('calls', '调用')}\n {header('input', '输入')}\n {header('output', '输出')}\n {header('cacheRead', '缓存读')}\n {header('hit', '命中率')}\n </tr>\n </thead>\n <tbody>\n {ordered.map((period) => {\n const modelsInPeriod = modelRows\n .filter((row) => row.period === period.period)\n .sort((first, second) => second.totalTokens - first.totalTokens)\n const expandable = modelsInPeriod.length > 1\n const isOpen = expandable && expandedPeriods[period.period] === true\n return (\n <Fragment key={period.period}>\n <tr\n className={expandable ? styles.clickable : ''}\n onClick={expandable ? () => onTogglePeriod(period.period) : undefined}\n >\n <td>\n {expandable && <span className={detailStyles.toggleArrow}>{isOpen ? '▼' : '▶'}</span>}\n {period.period}\n </td>\n <td>{fmtTokens(period.totalTokens)}</td>\n <td>{fmtCalls(period.calls)}</td>\n <td>{fmtTokens(period.inputTokens)}</td>\n <td>{fmtTokens(period.outputTokens)}</td>\n <td>{fmtTokens(period.cacheReadTokens)}</td>\n <td>{hitRateOf(period.cacheReadTokens, period.inputTokens, period.outputTokens)}</td>\n </tr>\n {isOpen && (\n <tr>\n <td className={detailStyles.subRowCell} colSpan={7}>\n <div className={detailStyles.subHead}>\n <span />\n <span className={detailStyles.subNumber}>调用</span>\n <span className={detailStyles.subNumber}>输入</span>\n <span className={detailStyles.subNumber}>输出</span>\n <span className={detailStyles.subNumber}>缓存读</span>\n <span className={detailStyles.subNumber}>命中率</span>\n </div>\n {modelsInPeriod.map((row) => (\n <div className={detailStyles.subRow} key={row.period + '|' + row.model + '|' + row.provider}>\n <span className={detailStyles.subName}>\n <span className={detailStyles.subModel}>{row.model}</span>\n {channelFilter === 'ALL' && <span className={detailStyles.subChannel}>{displayNameOf(channels, row.provider)}</span>}\n </span>\n <span className={detailStyles.subNumber}>{fmtCalls(row.calls)}</span>\n <span className={detailStyles.subNumber}>{fmtTokens(row.inputTokens)}</span>\n <span className={detailStyles.subNumber}>{fmtTokens(row.outputTokens)}</span>\n <span className={detailStyles.subNumber}>{fmtTokens(row.cacheReadTokens)}</span>\n <span className={detailStyles.subNumber}>{hitRateOf(row.cacheReadTokens, row.inputTokens, row.outputTokens)}</span>\n </div>\n ))}\n </td>\n </tr>\n )}\n </Fragment>\n )\n })}\n <tr className={styles.total}>\n <td>合计</td>\n <td>{fmtTokens(totalTokens)}</td>\n <td>{fmtCalls(totals?.calls ?? 0)}</td>\n <td>{fmtTokens(totals?.inputTokens ?? 0)}</td>\n <td>{fmtTokens(totals?.outputTokens ?? 0)}</td>\n <td>{fmtTokens(totals?.cacheReadTokens ?? 0)}</td>\n <td>{hitRateOf(totals?.cacheReadTokens ?? 0, totals?.inputTokens ?? 0, totals?.outputTokens ?? 0)}</td>\n </tr>\n </tbody>\n </table>\n </div>\n )\n}\n","/** 使用明细:范围切换 + 三张统计卡 + 占比条 + 通道筛选 + 按天/按小时图表 + 每日细目。 */\nimport type { ReactNode } from 'react'\nimport { channelColorOf, channelOf, costCellText, displayNameOf, statusColorOf } from '../channels.ts'\nimport { fmtCalls, fmtCost, fmtShortDate, fmtTokens, isoDate } from '../format.ts'\nimport type { Channel, ChannelDailySummary, UsageResponse } from '../types.ts'\nimport { TipDivider, TipRow, TipSub, TipTitle, type TooltipApi } from '../tooltip.tsx'\nimport { ShareBar } from '../components/ShareBar.tsx'\nimport { StatCard } from '../components/StatCard.tsx'\nimport { TokenBars, type TokenBarRow } from '../components/TokenBars.tsx'\nimport { DailyDetailTable, type DetailSortState } from '../components/DailyDetailTable.tsx'\nimport styles from '../styles/shared.module.css'\nimport detailStyles from '../styles/detail.module.css'\n\nexport type RangeKey = 'today' | 'week' | 'month' | 'total' | 'custom'\n\nconst RANGE_TABS: Array<[RangeKey, string]> = [\n ['today', '今日'], ['week', '周'], ['month', '月'], ['total', '总计'], ['custom', '自定义'],\n]\n\n/** 图表最多铺开的列数:超过这个跨度的范围按天全画会挤成一团。 */\nconst MAX_AXIS_DAYS = 366\n\nfunction hitRateOf(cacheReadTokens: number, inputTokens: number, outputTokens: number): string {\n const total = inputTokens + outputTokens + cacheReadTokens\n return total > 0 ? (cacheReadTokens / total * 100).toFixed(1) + '%' : '—'\n}\n\nfunction daysBetween(from: string, to: string): number {\n const fromTime = new Date(from + 'T00:00:00').getTime()\n const toTime = new Date(to + 'T00:00:00').getTime()\n return Math.max(1, Math.round((toTime - fromTime) / 86400000) + 1)\n}\n\n/** 范围内每一天的日期键(无数据的日子也要出现在横轴上)。 */\nfunction dateKeysOfRange(from: string, to: string): string[] {\n const start = new Date(from + 'T00:00:00').getTime()\n const total = Math.min(daysBetween(from, to), MAX_AXIS_DAYS)\n const keys: string[] = []\n for (let offset = 0; offset < total; offset += 1) keys.push(isoDate(new Date(start + offset * 86400000)))\n return keys\n}\n\nexport function DetailTab(props: {\n usage: UsageResponse | null\n channels: Channel[]\n range: RangeKey\n onRange: (value: RangeKey) => void\n customFrom: string\n onCustomFrom: (value: string) => void\n customTo: string\n onCustomTo: (value: string) => void\n channelFilter: string\n onChannelFilter: (value: string) => void\n expandedPeriods: Record<string, boolean>\n onTogglePeriod: (periodKey: string) => void\n sort: DetailSortState\n onSort: (sort: DetailSortState) => void\n bounds: { from: string; to: string }\n tooltip: TooltipApi\n}): ReactNode {\n const { usage, channels, bounds, tooltip, channelFilter } = props\n if (usage === null) return <div className={styles.empty}>台账读取中或不可用…</div>\n\n const totals = usage.totals\n const safeTotals = totals ?? { date: '', calls: 0, inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, reasoningTokens: 0, cost: 0 }\n const totalTokens = safeTotals.inputTokens + safeTotals.outputTokens + safeTotals.cacheReadTokens\n const hitRate = hitRateOf(safeTotals.cacheReadTokens, safeTotals.inputTokens, safeTotals.outputTokens)\n const singleChannel = channelFilter === 'ALL' ? null : channelOf(channels, channelFilter)\n const costCell = costCellText(singleChannel, safeTotals.cost)\n const singleDay = bounds.from === bounds.to\n const rangeDays = Math.min(daysBetween(bounds.from, bounds.to), MAX_AXIS_DAYS)\n\n const activeProviders = new Set<string>()\n for (const day of usage.days) {\n for (const model of day.models) {\n if (model.inputTokens + model.outputTokens + model.cacheReadTokens > 0) activeProviders.add(model.provider)\n }\n }\n\n const hourlyRows: TokenBarRow[] = []\n if (singleDay && usage.hours !== null) {\n usage.hours.forEach((slot, hour) => {\n const slotTokens = slot.buckets.inputTokens + slot.buckets.outputTokens + slot.buckets.cacheReadTokens\n hourlyRows.push({\n key: String(hour),\n axisLabel: String(hour).padStart(2, '0') + ':00',\n cacheReadTokens: slot.buckets.cacheReadTokens,\n inputTokens: slot.buckets.inputTokens,\n outputTokens: slot.buckets.outputTokens,\n tip: (\n <>\n <TipTitle>{bounds.from + ' ' + String(hour).padStart(2, '0') + ':00'}</TipTitle>\n {slot.calls === 0 && slotTokens === 0\n ? <TipSub>该小时无用量记录</TipSub>\n : (\n <>\n <TipSub>调用 <b>{fmtCalls(slot.calls)}</b> · Tokens <b>{fmtTokens(slotTokens)}</b></TipSub>\n <TipRow color=\"var(--dsw-alias-state-accent-primary, #5b8cff)\" label=\"输入\" amount={fmtTokens(slot.buckets.inputTokens)} />\n <TipRow color=\"var(--dsw-alias-state-business-primary, #9a7bff)\" label=\"输出\" amount={fmtTokens(slot.buckets.outputTokens)} />\n <TipRow\n color=\"var(--dsw-alias-state-accent-tertiary, rgba(91,140,255,.28))\"\n label=\"缓存读\"\n amount={fmtTokens(slot.buckets.cacheReadTokens)}\n rate={hitRateOf(slot.buckets.cacheReadTokens, slot.buckets.inputTokens, slot.buckets.outputTokens)}\n />\n </>\n )}\n </>\n ),\n })\n })\n }\n\n // 横轴铺满所选范围:没有调用的日子留空位(不画柱子)\n const sessionDates = new Set(usage.sessionDates ?? [])\n const dayByDate = new Map<string, ChannelDailySummary>(usage.days.map((day) => [day.date, day]))\n const dailyRows: TokenBarRow[] = dateKeysOfRange(bounds.from, bounds.to).map((dateKey) => {\n const day = dayByDate.get(dateKey)\n if (day === undefined) {\n return {\n key: dateKey,\n axisLabel: fmtShortDate(dateKey),\n cacheReadTokens: 0,\n inputTokens: 0,\n outputTokens: 0,\n tip: (\n <>\n <TipTitle>{dateKey}</TipTitle>\n <TipSub>当日无用量记录</TipSub>\n </>\n ),\n }\n }\n const dayTotal = day.inputTokens + day.outputTokens + day.cacheReadTokens\n const fromSession = sessionDates.has(day.date)\n const topModels = [...day.models]\n .sort((first, second) => (second.inputTokens + second.outputTokens + second.cacheReadTokens) - (first.inputTokens + first.outputTokens + first.cacheReadTokens))\n .slice(0, 5)\n return {\n key: day.date,\n axisLabel: fmtShortDate(day.date),\n cacheReadTokens: day.cacheReadTokens,\n inputTokens: day.inputTokens,\n outputTokens: day.outputTokens,\n tip: (\n <>\n <TipTitle>{day.date}</TipTitle>\n <TipSub>调用 <b>{fmtCalls(day.calls)}</b> · Tokens <b>{fmtTokens(dayTotal)}</b></TipSub>\n <TipRow color=\"var(--dsw-alias-state-accent-primary, #5b8cff)\" label=\"输入\" amount={fmtTokens(day.inputTokens)} />\n <TipRow color=\"var(--dsw-alias-state-business-primary, #9a7bff)\" label=\"输出\" amount={fmtTokens(day.outputTokens)} />\n <TipRow\n color=\"var(--dsw-alias-state-accent-tertiary, rgba(91,140,255,.28))\"\n label=\"缓存读\"\n amount={fmtTokens(day.cacheReadTokens)}\n rate={hitRateOf(day.cacheReadTokens, day.inputTokens, day.outputTokens)}\n />\n <TipDivider>\n <span>成本</span>\n <b>{day.cost > 0 ? fmtCost(day.cost) : '—'}</b>\n </TipDivider>\n {fromSession && <TipSub>来源:会话事件(该日台账无记录,不含官方成本)</TipSub>}\n {topModels.map((model) => (\n <TipRow\n key={model.provider + '|' + model.model}\n label={<>{model.model}<span className={styles.dim}> · {displayNameOf(channels, model.provider)}</span></>}\n amount={fmtTokens(model.inputTokens + model.outputTokens + model.cacheReadTokens)}\n />\n ))}\n </>\n ),\n }\n })\n\n const useHourAxis = singleDay && usage.hours !== null\n const chartRows = useHourAxis ? hourlyRows : dailyRows\n const chartTitle = useHourAxis ? '按小时 Tokens(' + bounds.from + ')' : '按天 Tokens(' + rangeDays + ' 天)'\n\n return (\n <div>\n <div className={detailStyles.rangeBar}>\n <div className={detailStyles.rangeLeft}>\n <div className={detailStyles.rangeTabs}>\n {RANGE_TABS.map(([key, label]) => (\n <button key={key} className={props.range === key ? detailStyles.active : ''} onClick={() => props.onRange(key)}>{label}</button>\n ))}\n </div>\n {props.range === 'custom' && (\n <>\n <input type=\"date\" className={detailStyles.rangeInput} value={props.customFrom} onChange={(event) => props.onCustomFrom(event.target.value)} />\n <span className={styles.dim}>至</span>\n <input type=\"date\" className={detailStyles.rangeInput} value={props.customTo} onChange={(event) => props.onCustomTo(event.target.value)} />\n </>\n )}\n </div>\n </div>\n\n <div className={styles.cardGrid3}>\n <StatCard label=\"调用次数\" value={fmtCalls(safeTotals.calls)} extra={activeProviders.size + ' 个通道有用量'} />\n <StatCard label=\"Tokens\" value={fmtTokens(totalTokens)} extra={'缓存读 ' + fmtTokens(safeTotals.cacheReadTokens) + ' · 命中率 ' + hitRate} />\n <StatCard\n label=\"成本\"\n value={costCell.dim ? <span className={styles.dim}>{costCell.text}</span> : costCell.text}\n extra=\"按所选范围与筛选聚合\"\n />\n </div>\n\n <ShareBar usage={usage} totalTokens={totalTokens} channelFilter={channelFilter} channels={channels} tooltip={tooltip} />\n\n <div className={styles.chipRow} style={{ marginTop: 14 }}>\n <button className={channelFilter === 'ALL' ? styles.chip + ' ' + styles.active : styles.chip} onClick={() => props.onChannelFilter('ALL')}>\n <span className={styles.statusDot} style={{ background: 'var(--dsw-alias-state-accent-primary, #5b8cff)' }} />全部通道\n </button>\n {channels.map((channel) => (\n <button\n key={channel.provider}\n className={channelFilter === channel.provider ? styles.chip + ' ' + styles.active : styles.chip}\n onClick={() => props.onChannelFilter(channel.provider)}\n >\n <span className={styles.statusDot} style={{ background: statusColorOf(channel.status) }} />{channel.displayName}\n </button>\n ))}\n </div>\n\n <div className={styles.card}>\n <div className={detailStyles.chartTitle}>\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>\n {singleChannel === null\n ? <b>全部通道</b>\n : (\n <>\n <span className={styles.statusDot} style={{ background: statusColorOf(singleChannel.status) }} />\n <b>{singleChannel.displayName}</b>\n </>\n )}\n </span>\n <span className={styles.dim} style={{ fontSize: 11.5 }}>{bounds.from} ~ {bounds.to}</span>\n </div>\n <div className={detailStyles.chartTitle} style={{ marginTop: 10 }}>\n <span className={styles.statLabel}>{chartTitle}</span>\n <span className={styles.legend}>\n <span><i style={{ background: 'rgba(91,140,255,.28)' }} />缓存读</span>\n <span><i style={{ background: 'var(--dsw-alias-state-accent-primary, #5b8cff)' }} />输入</span>\n <span><i style={{ background: 'var(--dsw-alias-state-business-primary, #9a7bff)' }} />输出</span>\n </span>\n </div>\n {chartRows.length === 0\n ? <div className={styles.empty}>所选范围内无用量记录</div>\n : <TokenBars rows={chartRows} tooltip={tooltip} />}\n {useHourAxis && <div className={styles.statExtra}>按小时数据来自本地会话事件,不含成本</div>}\n </div>\n\n <DailyDetailTable\n usage={usage}\n channels={channels}\n channelFilter={channelFilter}\n expandedPeriods={props.expandedPeriods}\n onTogglePeriod={props.onTogglePeriod}\n sort={props.sort}\n onSort={props.onSort}\n />\n </div>\n )\n}\n\n/** 通道颜色(供外部复用,避免各 Tab 重复实现)。 */\nexport { channelColorOf }\n","/** 项目用量:按会话工作目录聚合(数据来自宿主会话事件折叠)。 */\nimport { useMemo, useState, type ReactNode } from 'react'\nimport { channelColorOf, channelOf, costCellText, displayNameOf } from '../channels.ts'\nimport { fmtCalls, fmtRelative, fmtTokens } from '../format.ts'\nimport type { Channel, ProjectRow, ProjectsResponse } from '../types.ts'\nimport styles from '../styles/shared.module.css'\nimport listStyles from '../styles/lists.module.css'\n\ntype SortKey = 'recent' | 'tokensDesc' | 'tokensAsc' | 'callsDesc'\n\nexport function ProjectsTab(props: { data: ProjectsResponse | null; channels: Channel[] }): ReactNode {\n const [query, setQuery] = useState('')\n const [channelFilter, setChannelFilter] = useState('ALL')\n const [sortKey, setSortKey] = useState<SortKey>('recent')\n const [nowMs] = useState(() => Date.now())\n const rows = props.data?.rows ?? []\n\n const visible = useMemo(() => {\n const keyword = query.trim().toLowerCase()\n const filtered = rows.filter((row) => {\n const matchesQuery = keyword === '' || row.workspace.toLowerCase().includes(keyword)\n const matchesChannel = channelFilter === 'ALL' || row.providers[channelFilter] !== undefined\n return matchesQuery && matchesChannel\n })\n const sorters: Record<SortKey, (first: ProjectRow, second: ProjectRow) => number> = {\n recent: (first, second) => (second.lastTime ?? 0) - (first.lastTime ?? 0),\n tokensDesc: (first, second) => second.tokens - first.tokens,\n tokensAsc: (first, second) => first.tokens - second.tokens,\n callsDesc: (first, second) => second.calls - first.calls,\n }\n return [...filtered].sort(sorters[sortKey])\n }, [rows, query, channelFilter, sortKey])\n\n const totalTokens = rows.reduce((total, row) => total + row.tokens, 0)\n\n if (props.data === null) return <div className={styles.empty}>会话数据读取中或不可用…</div>\n\n return (\n <div>\n {props.data.coverage.status !== 'complete' && (\n <div className={styles.warning}>{coverageText(props.data.coverage.status, props.data.coverage.skippedSessions)}</div>\n )}\n <div className={listStyles.filterBar}>\n <input className={listStyles.searchInput} placeholder=\"搜索项目路径…\" value={query} onChange={(event) => setQuery(event.target.value)} />\n <select className={listStyles.filterSelect} value={channelFilter} onChange={(event) => setChannelFilter(event.target.value)}>\n <option value=\"ALL\">全部通道</option>\n {props.channels.map((channel) => <option key={channel.provider} value={channel.provider}>{channel.displayName}</option>)}\n </select>\n <select className={listStyles.filterSelect} value={sortKey} onChange={(event) => setSortKey(event.target.value as SortKey)}>\n <option value=\"recent\">最近活跃</option>\n <option value=\"tokensDesc\">Tokens 最多</option>\n <option value=\"tokensAsc\">Tokens 最少</option>\n <option value=\"callsDesc\">调用最多</option>\n </select>\n </div>\n\n <table className={styles.table}>\n <thead>\n <tr><th>项目</th><th>调用</th><th>Tokens</th><th>占比</th><th>成本</th><th>最近活跃</th></tr>\n </thead>\n <tbody>\n {visible.map((row) => {\n const percent = totalTokens > 0 ? Math.round(row.tokens / totalTokens * 100) : 0\n const dominant = row.dominantProvider\n const channel = channelOf(props.channels, dominant)\n const costCell = costCellText(channel, row.cost ?? 0)\n return (\n <tr key={row.workspace}>\n <td>\n <div className={listStyles.listTitle}>\n <div>\n <div className={listStyles.listMain}>{baseNameOf(row.workspace)}</div>\n <div className={listStyles.listSub}>\n {row.workspace} · {row.sessionCount} 个会话\n {row.archivedSessionCount > 0 ? '(含 ' + row.archivedSessionCount + ' 个已归档,仍计入)' : ''}\n </div>\n </div>\n </div>\n </td>\n <td>{fmtCalls(row.calls)}</td>\n <td>{fmtTokens(row.tokens)}</td>\n <td>\n <span className={listStyles.listBar}>\n <i style={{ width: Math.max(2, percent) + '%', background: channelColorOf(props.channels, dominant ?? '') }} />\n </span> {percent}%\n </td>\n <td>{row.cost === null || channel?.costMode === 'sub' || channel?.costMode === 'free' || channel?.costMode === 'none'\n ? <span className={styles.dim}>{costCell.text}</span>\n : costCell.text}</td>\n <td>{fmtRelative(row.lastTime, nowMs)}</td>\n </tr>\n )\n })}\n {visible.length === 0 && <tr><td colSpan={6} className={styles.empty}>没有符合条件的项目</td></tr>}\n </tbody>\n </table>\n <div className={styles.statExtra}>\n 成本按台账模型中位均价估算{props.data.priced ? '' : '(台账无成本数据,暂不可估)'};命中率 = 缓存读 /(输入 + 输出 + 缓存读)\n </div>\n </div>\n )\n}\n\nfunction coverageText(status: string, skipped: number): string {\n if (status === 'unavailable') return '会话数据不可用(宿主未提供会话服务或全部读取失败)'\n return '会话数据不完整:' + String(skipped) + ' 个会话读取失败,未计入统计'\n}\n\nexport function baseNameOf(path: string): string {\n const normalized = path.replace(/[\\\\/]+$/, '')\n const parts = normalized.split(/[\\\\/]/)\n return parts[parts.length - 1] === '' ? path : parts[parts.length - 1]\n}\n\n/** 通道显示名(列表里复用)。 */\nexport { displayNameOf }\n","/** 余额与配额:按通道展示官方余额快照与订阅窗口(原样数据,不换算不建议)。 */\nimport type { ReactNode } from 'react'\nimport { quotaBarColor, statusColorOf } from '../channels.ts'\nimport { fmtDateTime } from '../format.ts'\nimport type { Channel, QuotaProvider } from '../types.ts'\nimport styles from '../styles/shared.module.css'\nimport quotaStyles from '../styles/quota.module.css'\n\n/** 余额字段展示顺序(原型顺序);未收录字段按原键名追加在后。 */\nconst BALANCE_ORDER = ['totalBalance', 'topUpBalance', 'giftBalance', 'balance', 'currency']\nconst BALANCE_LABELS: Record<string, string> = {\n totalBalance: '总余额', topUpBalance: '充值余额', giftBalance: '赠送余额', balance: '余额', currency: '币种',\n}\n/** 订阅窗口固定展示顺序。 */\nconst WINDOW_ORDER = ['5h', 'week', 'month', 'day']\nconst WINDOW_LABELS: Record<string, string> = { '5h': '5 小时窗口', week: '本周窗口', month: '本月窗口', day: '当日窗口' }\n\nfunction resetTextOf(value: unknown): string {\n if (typeof value !== 'string' || value === '') return '重置时间 —'\n const time = new Date(value)\n if (Number.isNaN(time.getTime())) return '重置于 ' + value\n return '重置于 ' + fmtDateTime(time.getTime())\n}\n\nexport function QuotaTab(props: { channels: Channel[]; quotas: QuotaProvider[] }): ReactNode {\n const snapshotOf = (provider: string): QuotaProvider | null => props.quotas.find((item) => item.provider === provider) ?? null\n return (\n <div className={quotaStyles.quotaList}>\n {props.channels.map((channel) => {\n const snapshot = snapshotOf(channel.provider)\n const balance = snapshot?.balance ?? null\n const plan = snapshot?.plan ?? null\n const isLive = snapshot?.source === 'live'\n const windows = plan !== null && Array.isArray((plan as { windows?: unknown }).windows)\n ? (plan as { windows: Array<{ key?: unknown; percent?: unknown; resetsAt?: unknown }> }).windows\n : null\n return (\n <div className={quotaStyles.quotaCard} key={channel.provider}>\n <div className={quotaStyles.quotaHead}>\n <span className={styles.statusDot} style={{ background: statusColorOf(channel.status) }} />\n <span className={quotaStyles.quotaTitle}>{channel.displayName}</span>\n {isLive && <span className={quotaStyles.liveChip}>实时</span>}\n <span className={quotaStyles.quotaProvider}>{channel.provider} · {channel.costLabel}</span>\n </div>\n\n {balance !== null && (\n <div className={quotaStyles.balanceStrip}>\n {orderedBalanceEntries(balance).map(([key, value]) => (\n <div className={quotaStyles.balanceItem} key={key}>\n <div className={quotaStyles.bsLabel}>{BALANCE_LABELS[key] ?? key}</div>\n <div className={quotaStyles.bsValue}>{String(value)}</div>\n </div>\n ))}\n </div>\n )}\n\n {balance === null && windows !== null && windows.length > 0 && (\n <div className={quotaStyles.windowRow}>\n {orderedWindows(windows).map((window) => {\n const percent = typeof window.percent === 'number' ? window.percent : 0\n const key = typeof window.key === 'string' ? window.key : 'window'\n return (\n <div className={quotaStyles.windowItem} key={key}>\n <div className={quotaStyles.windowHead}>\n <span className={quotaStyles.windowName}>{WINDOW_LABELS[key] ?? key}</span>\n <span className={quotaStyles.windowValue}>{percent}%</span>\n </div>\n <div className={quotaStyles.windowBar}>\n <i style={{ width: Math.max(percent, 0) + '%', background: quotaBarColor(percent) }} />\n </div>\n <div className={quotaStyles.windowReset}>{resetTextOf(window.resetsAt)}</div>\n </div>\n )\n })}\n </div>\n )}\n\n {balance === null && (windows === null || windows.length === 0) && (\n <div className={styles.dim}>{emptyReasonOf(channel, snapshot)}</div>\n )}\n\n {isLive && (\n <div className={quotaStyles.snapshotHint}>\n 实时查询于 {freshTextOf(snapshot?.fetchedAt ?? null)}(来自官方接口,最多缓存 1 分钟)\n </div>\n )}\n {snapshot !== null && !isLive && (\n <div className={staleDaysOf(snapshot.updatedAt) >= 1 ? quotaStyles.snapshotStale : quotaStyles.snapshotHint}>\n 实时查询未成功({errorTextOf(snapshot.error)}),显示本机快照\n {snapshot.updatedAt === null ? '' : ' · 快照时间 ' + fmtDateTime(snapshot.updatedAt) + (staleDaysOf(snapshot.updatedAt) >= 1 ? ',已 ' + staleDaysOf(snapshot.updatedAt) + ' 天未更新' : '')}\n </div>\n )}\n </div>\n )\n })}\n {props.channels.length === 0 && <div className={styles.empty}>未读取到通道配置</div>}\n </div>\n )\n}\n\n/** 实时结果的相对时间文案。 */\nfunction freshTextOf(fetchedAt: number | null): string {\n if (fetchedAt === null) return '刚刚'\n const seconds = Math.max(0, Math.floor((Date.now() - fetchedAt) / 1000))\n if (seconds < 60) return '刚刚'\n const minutes = Math.floor(seconds / 60)\n if (minutes < 60) return minutes + ' 分钟前'\n return Math.floor(minutes / 60) + ' 小时前'\n}\n\n/** 实时查询失败原因的展示文案。 */\nfunction errorTextOf(error: string | null): string {\n if (error === null) return '未启用实时查询'\n if (error === 'no-key') return '该通道未配置 API Key'\n if (error === 'no-snapshot') return '没有快照可用'\n if (error === 'network') return '网络不可达'\n if (error === 'timeout') return '请求超时'\n if (error === 'unauthorized') return '凭据被拒绝(401/403)'\n if (error === 'bad-json') return '接口响应无法解析'\n if (error === 'too-large') return '接口响应异常大'\n if (error.startsWith('http-')) return '接口返回 HTTP ' + error.slice(5)\n return error\n}\n\n/** 快照距今天数(向下取整);用于把「宿主很久没刷新」显式标出来。 */\nfunction staleDaysOf(updatedAt: number | null): number {\n if (updatedAt === null) return 0\n return Math.floor((Date.now() - updatedAt) / 86400000)\n}\n\nfunction orderedBalanceEntries(balance: Record<string, unknown>): Array<[string, unknown]> {\n const entries = Object.entries(balance).filter(([key]) => key !== 'updatedAt')\n const ordered: Array<[string, unknown]> = []\n for (const key of BALANCE_ORDER) {\n const found = entries.find(([entryKey]) => entryKey === key)\n if (found !== undefined) ordered.push(found)\n }\n for (const entry of entries) {\n if (!BALANCE_ORDER.includes(entry[0])) ordered.push(entry)\n }\n return ordered\n}\n\nfunction orderedWindows(windows: Array<{ key?: unknown }>): Array<{ key?: unknown; percent?: unknown; resetsAt?: unknown }> {\n const typed = windows as Array<{ key?: unknown; percent?: unknown; resetsAt?: unknown }>\n return [...typed].sort((first, second) => {\n const firstIndex = WINDOW_ORDER.indexOf(typeof first.key === 'string' ? first.key : '')\n const secondIndex = WINDOW_ORDER.indexOf(typeof second.key === 'string' ? second.key : '')\n return (firstIndex < 0 ? 99 : firstIndex) - (secondIndex < 0 ? 99 : secondIndex)\n })\n}\n\n/** 无数据时的分档说明:区分未配置凭据 / 免费额度 / 本地端点 / 无查询能力。 */\nfunction emptyReasonOf(channel: Channel, snapshot: QuotaProvider | null): string {\n if (snapshot?.source === 'snapshot' && snapshot.error === 'no-key') return '该通道未配置 API Key,无法查询余额'\n if (snapshot?.source === 'snapshot' && snapshot.error === 'unauthorized') return '凭据被通道拒绝,无法查询余额'\n if (channel.status === 'off') return '凭据引用存在,Key 未填写'\n if (channel.costMode === 'none') return '本地端点,无余额查询接口'\n if (channel.costMode === 'free') return '该通道无余额查询接口(免费额度)'\n return '该通道暂无可查询的余额 / 配额接口'\n}\n","/** 会话用量:按会话列出 tokens / 命中率 / 时长,按最近活跃时按日分组。 */\nimport { Fragment, useMemo, useState, type ReactNode } from 'react'\nimport { channelOf, costCellText, displayNameOf } from '../channels.ts'\nimport { fmtCalls, fmtDuration, fmtTime, fmtTokens, isoDate } from '../format.ts'\nimport type { Channel, SessionRow, SessionsResponse } from '../types.ts'\nimport styles from '../styles/shared.module.css'\nimport listStyles from '../styles/lists.module.css'\n\ntype SortKey = 'recent' | 'tokensDesc' | 'tokensAsc' | 'durationDesc'\n/** 会话归档筛选:与宿主原生「筛选会话」菜单同三档。 */\ntype ArchiveFilter = 'hide' | 'all' | 'only'\n\nexport function SessionsTab(props: { data: SessionsResponse | null; channels: Channel[] }): ReactNode {\n const [query, setQuery] = useState('')\n const [channelFilter, setChannelFilter] = useState('ALL')\n const [daysFilter, setDaysFilter] = useState('30')\n const [sortKey, setSortKey] = useState<SortKey>('recent')\n const [archiveFilter, setArchiveFilter] = useState<ArchiveFilter>('hide')\n const [nowMs] = useState(() => Date.now())\n const rows = props.data?.rows ?? []\n const archivedCount = rows.filter((row) => row.archived).length\n\n const visible = useMemo(() => {\n const keyword = query.trim().toLowerCase()\n const maxAgeDays = Number(daysFilter)\n const filtered = rows.filter((row) => {\n const title = (row.title ?? '') + ' ' + row.id + ' ' + (row.workspace ?? '')\n const matchesQuery = keyword === '' || title.toLowerCase().includes(keyword)\n const matchesChannel = channelFilter === 'ALL' || row.provider === channelFilter\n const matchesAge = maxAgeDays === 0 || row.lastTime === null\n || (nowMs - row.lastTime) <= maxAgeDays * 86400000\n const matchesArchive = archiveFilter === 'all' || (archiveFilter === 'only' ? row.archived : !row.archived)\n return matchesQuery && matchesChannel && matchesAge && matchesArchive\n })\n const sorters: Record<SortKey, (first: SessionRow, second: SessionRow) => number> = {\n recent: (first, second) => (second.lastTime ?? 0) - (first.lastTime ?? 0),\n tokensDesc: (first, second) => second.tokens - first.tokens,\n tokensAsc: (first, second) => first.tokens - second.tokens,\n durationDesc: (first, second) => durationOf(second) - durationOf(first),\n }\n return [...filtered].sort(sorters[sortKey])\n }, [rows, query, channelFilter, daysFilter, sortKey, nowMs, archiveFilter])\n\n if (props.data === null) return <div className={styles.empty}>会话数据读取中或不可用…</div>\n\n const groups: Array<{ label: string; rows: SessionRow[] }> = []\n if (sortKey === 'recent') {\n for (const row of visible) {\n const label = dayLabelOf(row.lastTime, nowMs)\n const last = groups[groups.length - 1]\n if (last === undefined || last.label !== label) groups.push({ label, rows: [row] })\n else last.rows.push(row)\n }\n }\n\n return (\n <div>\n {props.data.coverage.status !== 'complete' && (\n <div className={styles.warning}>\n {props.data.coverage.status === 'unavailable'\n ? '会话数据不可用(宿主未提供会话服务或全部读取失败)'\n : '会话数据不完整:' + String(props.data.coverage.skippedSessions) + ' 个会话读取失败,未计入统计'}\n </div>\n )}\n <div className={listStyles.filterBar}>\n <input className={listStyles.searchInput} placeholder=\"搜索会话标题、session id、工作区…\" value={query} onChange={(event) => setQuery(event.target.value)} />\n <select className={listStyles.filterSelect} value={channelFilter} onChange={(event) => setChannelFilter(event.target.value)}>\n <option value=\"ALL\">全部通道</option>\n {props.channels.map((channel) => <option key={channel.provider} value={channel.provider}>{channel.displayName}</option>)}\n </select>\n <select className={listStyles.filterSelect} value={daysFilter} onChange={(event) => setDaysFilter(event.target.value)}>\n <option value=\"7\">近 7 天</option>\n <option value=\"30\">近 30 天</option>\n <option value=\"0\">全部</option>\n </select>\n <select className={listStyles.filterSelect} value={sortKey} onChange={(event) => setSortKey(event.target.value as SortKey)}>\n <option value=\"recent\">最新会话</option>\n <option value=\"tokensDesc\">Tokens 最多</option>\n <option value=\"tokensAsc\">Tokens 最少</option>\n <option value=\"durationDesc\">时长最长</option>\n </select>\n <select\n className={listStyles.filterSelect}\n value={archiveFilter}\n onChange={(event) => setArchiveFilter(event.target.value as ArchiveFilter)}\n title=\"已归档会话只做标记,仍然计入统计\"\n >\n <option value=\"hide\">隐藏已归档</option>\n <option value=\"all\">全部对话(显示已归档)</option>\n <option value=\"only\">仅显示已归档</option>\n </select>\n </div>\n {archiveFilter === 'hide' && archivedCount > 0 && (\n <div className={styles.statExtra}>\n 另有 {archivedCount} 个已归档会话未显示(归档只是标记,用量仍计入上方统计)\n </div>\n )}\n\n <table className={styles.table}>\n <thead>\n <tr><th>会话</th><th>通道</th><th>时间 / 时长</th><th>Tokens</th><th>命中率</th><th>成本</th></tr>\n </thead>\n <tbody>\n {groups.map((group) => {\n const groupTokens = group.rows.reduce((total, row) => total + row.tokens, 0)\n return (\n <Fragment key={'group-' + group.label}>\n <tr className={listStyles.sessionDay}>\n <td colSpan={6}>\n {group.label}\n <span className={listStyles.dayCount}>{group.rows.length} 个会话 · {fmtTokens(groupTokens)}</span>\n </td>\n </tr>\n {group.rows.map((row) => sessionRowOf(row, props.channels))}\n </Fragment>\n )\n })}\n {sortKey !== 'recent' && visible.map((row) => sessionRowOf(row, props.channels))}\n {visible.length === 0 && <tr><td colSpan={6} className={styles.empty}>没有符合条件的会话</td></tr>}\n </tbody>\n </table>\n <div className={styles.statExtra}>\n 会话用量按宿主会话事件折叠(每个结算样本计一次调用);成本按台账模型均价估算\n {props.data.priced ? '' : '(台账无成本数据,暂不可估)'}\n </div>\n </div>\n )\n}\n\nfunction sessionRowOf(row: SessionRow, channels: Channel[]): ReactNode {\n const channel = channelOf(channels, row.provider)\n const costCell = costCellText(channel, row.cost ?? 0)\n return (\n <tr key={row.id} className={row.archived ? listStyles.rowArchived : undefined}>\n <td>\n <div className={listStyles.listMain}>\n {row.title ?? '会话 ' + shortIdOf(row.id)}\n {row.archived && <span className={listStyles.archivedTag}>已归档</span>}\n </div>\n <div className={listStyles.listSub}>{row.workspace ?? '未归属工作区'}</div>\n </td>\n <td>{row.providerLabel ?? displayNameOf(channels, row.provider ?? '')}</td>\n <td>\n <div>{row.lastTime === null ? '—' : dayLabelOf(row.lastTime, Date.now()) + ' ' + fmtTime(row.lastTime)}</div>\n <div className={listStyles.listSub}>时长 {fmtDuration(durationOf(row))}</div>\n </td>\n <td>{fmtTokens(row.tokens)}</td>\n <td>{row.cacheHitRate === null ? '—' : row.cacheHitRate.toFixed(1) + '%'}</td>\n <td>{row.cost === null || channel === null || channel.costMode !== 'perToken'\n ? <span className={styles.dim}>{costCell.text}</span>\n : costCell.text}</td>\n </tr>\n )\n}\n\nfunction durationOf(row: SessionRow): number {\n if (row.firstTime === null || row.lastTime === null) return 0\n return Math.max(0, row.lastTime - row.firstTime)\n}\n\n/** 会话头通常不带标题,用 id 的短片段做可读标识。 */\nfunction shortIdOf(id: string): string {\n const stripped = id.replace(/^session-/, '')\n return stripped.slice(0, 8)\n}\n\nfunction dayLabelOf(timeMs: number | null, nowMs: number): string {\n if (timeMs === null) return '未知日期'\n const dateKey = isoDate(new Date(timeMs))\n if (dateKey === isoDate(new Date(nowMs))) return '今日'\n if (dateKey === isoDate(new Date(nowMs - 86400000))) return '昨日'\n return dateKey\n}\n\n/** 保留调用计数格式,避免各 Tab 各写一份。 */\nexport { fmtCalls }\n","/**\n * 「使用情况」设置页外壳:Tab 路由、范围 / 通道筛选状态与取数。\n * 台账类数据(通道 / 台账 / 热力图 / 汇总 / 快照)来自本地文件端点;\n * 项目与会话数据来自宿主会话事件折叠,切到对应 Tab 时才首次拉取。\n */\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport { loadChannels, loadHeatmap, loadProjects, loadQuota, loadSessions, loadSummary, loadUsage } from './api.ts'\nimport { isoDate, shiftedIsoDate } from './format.ts'\nimport { TooltipView, useTooltip } from './tooltip.tsx'\nimport { OverviewTab } from './tabs/OverviewTab.tsx'\nimport { DetailTab, type RangeKey } from './tabs/DetailTab.tsx'\nimport { ProjectsTab } from './tabs/ProjectsTab.tsx'\nimport { QuotaTab } from './tabs/QuotaTab.tsx'\nimport { SessionsTab } from './tabs/SessionsTab.tsx'\nimport type { DetailSortState } from './components/DailyDetailTable.tsx'\nimport type {\n Channel,\n HeatmapDay,\n ProjectsResponse,\n QuotaProvider,\n SessionsResponse,\n SummaryResponse,\n UsageResponse,\n} from './types.ts'\nimport styles from './styles/shared.module.css'\n\ntype TabId = 'overview' | 'detail' | 'projects' | 'sessions' | 'quota'\n\nconst TABS: Array<[TabId, string]> = [\n ['overview', '总览'],\n ['detail', '使用明细'],\n ['projects', '项目用量'],\n ['sessions', '会话用量'],\n ['quota', '余额与配额'],\n]\n\nexport function KeyUsageSection() {\n const [activeTab, setActiveTab] = useState<TabId>('overview')\n const [range, setRange] = useState<RangeKey>('month')\n const [customFrom, setCustomFrom] = useState(() => shiftedIsoDate(-29))\n const [customTo, setCustomTo] = useState(() => isoDate(new Date()))\n const [channelFilter, setChannelFilter] = useState('ALL')\n const [expandedPeriods, setExpandedPeriods] = useState<Record<string, boolean>>({})\n const [detailSort, setDetailSort] = useState<DetailSortState>({ key: 'period', dir: 'desc' })\n\n const [channels, setChannels] = useState<Channel[]>([])\n const [quotas, setQuotas] = useState<QuotaProvider[]>([])\n const [summary, setSummary] = useState<SummaryResponse | null>(null)\n const [heatmap, setHeatmap] = useState<HeatmapDay[]>([])\n const [usage, setUsage] = useState<UsageResponse | null>(null)\n const [sessions, setSessions] = useState<SessionsResponse | null>(null)\n const [projects, setProjects] = useState<ProjectsResponse | null>(null)\n const [available, setAvailable] = useState<{ from: string; to: string } | null>(null)\n const [loading, setLoading] = useState(false)\n const tooltip = useTooltip()\n\n const reload = useCallback(async (includeSessionData: boolean, forceQuota = false) => {\n setLoading(true)\n // 先查余额:服务端会借这次调用预热实时结果,随后 /channels 的状态判定就能用上\n const quotaResult = await loadQuota(forceQuota)\n const [channelResult, summaryResult, heatmapResult] = await Promise.all([\n loadChannels(), loadSummary(), loadHeatmap(),\n ])\n setChannels(channelResult ?? [])\n setQuotas(quotaResult ?? [])\n setSummary(summaryResult)\n setHeatmap(heatmapResult ?? [])\n if (includeSessionData) {\n const [sessionResult, projectResult] = await Promise.all([loadSessions(), loadProjects()])\n setSessions(sessionResult)\n setProjects(projectResult)\n }\n setLoading(false)\n }, [])\n\n useEffect(() => { void reload(false) }, [reload])\n\n // 项目 / 会话数据按需加载(首次切到对应 Tab 时)\n useEffect(() => {\n if (activeTab === 'sessions' && sessions === null) void loadSessions().then(setSessions)\n if (activeTab === 'projects' && projects === null) void loadProjects().then(setProjects)\n }, [activeTab, sessions, projects])\n\n const bounds = useMemo(() => {\n const today = isoDate(new Date())\n if (range === 'today') return { from: today, to: today }\n if (range === 'week') return { from: shiftedIsoDate(-6), to: today }\n if (range === 'month') return { from: shiftedIsoDate(-29), to: today }\n if (range === 'custom') return { from: customFrom, to: customTo < customFrom ? customFrom : customTo }\n return { from: available?.from ?? today, to: available?.to ?? today }\n }, [range, customFrom, customTo, available])\n\n useEffect(() => {\n let cancelled = false\n void loadUsage(bounds.from, bounds.to, channelFilter).then((result) => {\n if (cancelled || result === null) return\n setUsage(result)\n if (result.availableFrom !== null && result.availableTo !== null) {\n setAvailable({ from: result.availableFrom, to: result.availableTo })\n }\n })\n return () => { cancelled = true }\n }, [bounds.from, bounds.to, channelFilter])\n\n const refresh = useCallback(() => {\n void reload(activeTab === 'sessions' || activeTab === 'projects' || sessions !== null || projects !== null, true)\n void loadUsage(bounds.from, bounds.to, channelFilter).then((result) => { if (result !== null) setUsage(result) })\n }, [reload, activeTab, sessions, projects, bounds.from, bounds.to, channelFilter])\n\n return (\n <div className={styles.section}>\n <div className={styles.title}>\n <span>使用情况</span>\n <span className={styles.titleActions}>\n <button className={styles.refreshBtn} disabled={loading} onClick={refresh}>\n {loading ? '刷新中…' : '↻ 刷新'}\n </button>\n </span>\n </div>\n\n <div className={styles.tabBar}>\n {TABS.map(([tabId, label]) => (\n <button key={tabId} className={activeTab === tabId ? styles.active : ''} onClick={() => setActiveTab(tabId)}>{label}</button>\n ))}\n </div>\n\n {activeTab === 'overview' && (\n <OverviewTab\n channels={channels}\n summary={summary}\n quotas={quotas}\n heatmap={heatmap}\n tooltip={tooltip}\n onOpenDetail={(provider) => { setChannelFilter(provider); setActiveTab('detail') }}\n />\n )}\n {activeTab === 'detail' && (\n <DetailTab\n usage={usage}\n channels={channels}\n range={range}\n onRange={setRange}\n customFrom={customFrom}\n onCustomFrom={setCustomFrom}\n customTo={customTo}\n onCustomTo={setCustomTo}\n channelFilter={channelFilter}\n onChannelFilter={setChannelFilter}\n expandedPeriods={expandedPeriods}\n onTogglePeriod={(periodKey) => setExpandedPeriods((previous) => ({ ...previous, [periodKey]: previous[periodKey] !== true }))}\n sort={detailSort}\n onSort={setDetailSort}\n bounds={bounds}\n tooltip={tooltip}\n />\n )}\n {activeTab === 'projects' && <ProjectsTab data={projects} channels={channels} />}\n {activeTab === 'sessions' && <SessionsTab data={sessions} channels={channels} />}\n {activeTab === 'quota' && <QuotaTab channels={channels} quotas={quotas} />}\n\n <div className={styles.footnote}>\n <b>口径说明</b>\n <ul className={styles.footnoteList}>\n <li>\n 按天数据优先取宿主用量台账(含官方成本);台账无记录的日期回退本地会话事件折叠,那些天没有官方成本\n {summary !== null && summary.todaySource === 'session' ? '(当前有 ' + summary.sessionDates.length + ' 天由会话补位)' : ''}\n 。两套来源按天取舍、不相加。\n </li>\n <li>热力图按可见区间内活跃日的三分位分档(少 / 中 / 高)。</li>\n <li>项目用量、会话用量与单日「按小时」均来自会话事件,每个结算样本计一次调用(不计成本)。</li>\n <li>已归档会话只是标记:用量照常计入,会话列表默认隐藏、可切换显示(显示时淡化并标注)。</li>\n <li>命中率 = 缓存读 ÷(输入 + 输出 + 缓存读)。</li>\n <li>余额与订阅窗口实时查询官方接口(失败回落本机快照),原样展示,不做换算与建议。</li>\n </ul>\n </div>\n\n <TooltipView tooltip={tooltip.tooltip} />\n </div>\n )\n}\n","/**\n * 「使用情况」主区域页面(`main` slot,与 sidebar.panellist 的 id 同名配对)。\n * 点击侧边栏导航项后由宿主在主内容区内联渲染 —— 不是弹窗、不占设置页。\n * 滚动由本容器负责:宿主主内容区不会滚动,长表格必须靠自己滚。\n */\nimport type { ReactNode } from 'react'\nimport { KeyUsageSection } from './KeyUsageSection.tsx'\nimport styles from './styles/page.module.css'\n\n/** 宿主会传入根作用域的标准 kit 与绑定的 `t`;本页面当前不需要它们。 */\nexport function UsagePage(_props: Record<string, unknown>): ReactNode {\n return (\n <div className={styles.page}>\n <div className={styles.inner}>\n <KeyUsageSection />\n </div>\n </div>\n )\n}\n","/**\n * dsh-key-usage 客户端入口:注册「使用情况」侧边栏导航项 + 主区域页面。\n * UI 逻辑在 UsagePage / KeyUsageSection 里;本文件只做 cordis apply 接线。\n *\n * slot 契约(对齐已装的 dsh-context「上下文洞察」写法):\n * - `sidebar.panellist`:宿主自持整行(标签 / hover / active),插件只提供图标,`id` 是面板标识;\n * - `main`:同一标识放在 `key` 上,宿主在主内容区按它渲染整页 —— 因此不是弹窗、也不占设置页。\n */\nimport { createElement as h } from 'react'\nimport type { SectionContext } from './types.ts'\nimport { UsageIcon } from './UsageIcon.tsx'\nimport { UsagePage } from './UsagePage.tsx'\n\nconst NS = 'dsh-key-usage'\n/** 侧边栏条目与 main 页面共用的面板标识(宿主 MainPanelId 域,命名空间化避免撞车)。 */\nconst PANEL_ID = NS\n\nexport const name = NS\nexport const inject = ['slots']\n\nexport function apply(ctx: SectionContext): void {\n ctx.slots.inject('main', () => ctx.slots.register({\n name: 'main',\n key: PANEL_ID,\n }, UsagePage))\n\n ctx.slots.inject('sidebar.panellist', () => ctx.slots.register({\n name: 'sidebar.panellist',\n id: PANEL_ID,\n order: 30,\n label: () => '使用情况',\n }, (props: { size?: number }) => h(UsageIcon, { size: props.size })))\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["useState","useCallback","useRef","styles","DAY_MS","useMemo","useRef","styles","shared","styles","styles","overviewStyles","styles","detailStyles","styles","styles","hitRateOf","trendStyles","useMemo","useState","useSyncExternalStore","styles","styles","hitRateOf","Fragment","detailStyles","EXPORT_COLUMNS","daysBetween","styles","detailStyles","exportStyles","EXPORT_COLUMNS","useState","useMemo","styles","coverageText","listStyles","exportStyles","EXPORT_COLUMNS","useState","useMemo","styles","listStyles","exportStyles","useState","useRef","useMemo","pricingStyles","styles","quotaStyles","styles","typed","useState","useMemo","styles","listStyles","exportStyles","Fragment","useState","useSyncExternalStore","useCallback","useMemo","styles","styles","useSyncExternalStore","useState","h"],"sources":["../src/client/pricing.ts","../src/client/pricingSettings.ts","../src/client/UsageIcon.tsx","../src/client/api.ts","../src/client/format.ts","../src/client/tooltip.tsx","../src/client/channels.ts","../src/client/components/Heatmap.tsx","../src/client/components/CostSourceChip.tsx","../src/client/tabs/OverviewTab.tsx","../src/client/export.ts","../src/client/components/ShareBar.tsx","../src/client/components/StatCard.tsx","../src/client/components/TokenBars.tsx","../src/client/components/TrendPanel.tsx","../src/client/rows.ts","../src/client/components/DailyDetailTable.tsx","../src/client/tabs/DetailTab.tsx","../src/client/tabs/ModelsTab.tsx","../src/client/tabs/ProjectsTab.tsx","../src/client/components/PricingRulesPanel.tsx","../src/client/tabs/QuotaTab.tsx","../src/client/tabs/SessionsTab.tsx","../src/client/KeyUsageSection.tsx","../src/client/UsagePage.tsx","../src/client/components/PricingCard.tsx","../src/client/index.tsx"],"sourcesContent":["/**\n * 客户端计费规则视图模型:类型、文案、编辑器用的规则构造与导入解析。\n *\n * 规则本体存在宿主设置服务里(命名空间 = profile 条目 id),客户端只经 `configForms` 读写;\n * 定价算法在服务端(src/server/pricing.ts),界面不重复实现,只做展示与编辑。\n */\n\nexport type PricingUnit = 'perMillionTokens' | 'perThousandTokens' | 'perCall'\n\n/** 成本来源角标:与服务端 `costSource` 字段一一对应。 */\nexport type CostSource = 'official' | 'rule' | 'catalog' | 'estimate' | 'none'\n\nexport interface OffPeakWindow {\n from: string\n to: string\n /** ISO 星期 1=周一 … 7=周日;缺省 = 每天都适用(与服务端同义)。 */\n days?: number[]\n}\n\nexport interface PricingRates {\n input: number\n cacheRead: number\n cacheWrite: number\n output: number\n}\n\nexport interface OffPeakPricing extends PricingRates {\n windows: OffPeakWindow[]\n}\n\nexport interface PricingRule extends PricingRates {\n provider: string\n model: string\n unit: PricingUnit\n currency: string\n offPeak: OffPeakPricing | null\n note: string\n}\n\nexport interface PricingConfig {\n version: number\n currency: string\n rules: PricingRule[]\n}\n\nexport interface PricingTemplate {\n id: string\n label: string\n note: string\n rules: PricingRule[]\n}\n\n/** 内置官方价目的一个来源(计费面板展示「已内置 N 条,来源见 …」)。 */\nexport interface CatalogSourceSummary {\n source: string\n fetchedAt: string\n providers: string[]\n count: number\n}\n\nexport interface PricingCoverage {\n from: string\n to: string\n ruleModels: number\n /** 命中内置官方价目的模型数(未配规则时自动生效的那一层)。 */\n catalogModels: number\n averagedModels: number\n unpricedModels: number\n /** 近 30 天按规则口径算出的金额(仅作参照,界面成本按「官方 > 规则 > 内置 > 均价」逐格取值)。 */\n ruleCostByCurrency: Record<string, number>\n savingsByCurrency: Record<string, number>\n savingsDetail: Array<{ provider: string; model: string; currency: string; cacheReadTokens: number; amount: number }>\n}\n\nexport interface PricingResponse {\n rules: PricingRule[]\n currency: string\n /** 宿主设置服务是否可用:false 时只能导入 / 导出,保存会失败。 */\n writable: boolean\n revision: number | null\n templates: PricingTemplate[]\n /** 内置官方价目:条数 + 各来源(含抓取日期),无需用户套用即自动生效。 */\n catalog: { entries: number; sources: CatalogSourceSummary[] }\n /** 与 rules 等长:该条规则此刻是否处于错峰时段(按本地时间判定,服务端算)。 */\n offPeakNow: boolean[]\n coverage: PricingCoverage\n}\n\nexport const COST_SOURCE_LABELS: Record<CostSource, string> = {\n official: '官方',\n rule: '自定',\n catalog: '官方价',\n estimate: '估算',\n none: '—',\n}\n\n/** 角标的悬浮说明:让「估算」不会被当成账单金额用。 */\nexport const COST_SOURCE_HINTS: Record<CostSource, string> = {\n official: '官方:台账记录的厂商账单金额',\n rule: '自定:按你维护的计费规则算出',\n catalog: '官方价:按插件内置的厂商官方价目算出(可查来源;你的规则优先于它)',\n estimate: '估算:按台账反推的均价推算',\n none: '没有价格依据(未配置规则,台账也无成本数据)',\n}\n\nexport const UNIT_LABELS: Record<PricingUnit, string> = {\n perMillionTokens: '每百万 tokens',\n perThousandTokens: '每千 tokens',\n perCall: '每次调用',\n}\n\nexport const UNIT_OPTIONS: PricingUnit[] = ['perMillionTokens', 'perThousandTokens', 'perCall']\nexport const CURRENCY_OPTIONS = ['CNY', 'USD']\n\nexport const EMPTY_CONFIG: PricingConfig = { version: 1, currency: 'CNY', rules: [] }\n\n/** 币种符号;未知币种保留代码前缀,避免把 USD 当 CNY 渲染。 */\nexport function currencySymbolOf(currency: string): string {\n if (currency === 'CNY') return '¥'\n if (currency === 'USD') return '$'\n return currency + ' '\n}\n\nexport function ruleKeyOf(rule: PricingRule): string {\n return rule.provider + '|' + rule.model\n}\n\nexport function ruleLabelOf(rule: PricingRule): string {\n const model = rule.model === '*' ? '全部模型' : rule.model\n return (rule.provider === '*' ? '任意通道' : rule.provider) + ' · ' + model\n}\n\n/** 错峰窗口文案:`09:00–12:00、14:00–18:00`;带 `days` 的窗口补一个「(工作日)」之类的后缀。 */\nexport function offPeakWindowsText(rule: PricingRule): string {\n if (rule.offPeak === null || rule.offPeak.windows.length === 0) return ''\n return rule.offPeak.windows.map((window) => {\n const base = window.from + '–' + window.to\n const suffix = dayScopeSuffixOf(window.days)\n return suffix === '' ? base : base + '(' + suffix + ')'\n }).join('、')\n}\n\n/** 编辑器里的星期范围三选一;与服务端 `days` 的映射见 DAY_SCOPE_DAYS。 */\nexport type DayScope = 'every' | 'weekday' | 'weekend'\n\nexport const DAY_SCOPE_OPTIONS: DayScope[] = ['every', 'weekday', 'weekend']\n\nexport const DAY_SCOPE_LABELS: Record<DayScope, string> = {\n every: '每天',\n weekday: '仅工作日',\n weekend: '仅周末',\n}\n\n/** 「每天」刻意映射成 `days` 缺省(而不是 [1..7]),保证升级前的规则原样往返。 */\nexport const DAY_SCOPE_DAYS: Record<DayScope, number[] | undefined> = {\n every: undefined,\n weekday: [1, 2, 3, 4, 5],\n weekend: [6, 7],\n}\n\n/** 已保存的 `days` → 编辑器取值;非法值一律当「每天」(与服务端容错口径一致)。 */\nexport function dayScopeOf(days: number[] | undefined): DayScope {\n const normalized = normalizeDays(days)\n if (normalized === undefined) return 'every'\n const key = normalized.join(',')\n if (key === '1,2,3,4,5') return 'weekday'\n if (key === '6,7') return 'weekend'\n // 三选一表达不了自定义组合(手改 JSON 才可能出现):保守显示「每天」,不改写数值\n return 'every'\n}\n\n/** `days` 的简短说明;缺省或非三名组合返回空串(表示「每天」)。 */\nexport function dayScopeSuffixOf(days: number[] | undefined): string {\n const scope = dayScopeOf(days)\n return scope === 'every' ? '' : DAY_SCOPE_LABELS[scope]\n}\n\n/**\n * `days` 归一:只接受 1–7 的整数、去重排序;非法值返回 undefined = 每天适用。\n * 与服务端 normalizeDays 同一口径:非法值不整段作废,避免金额突然变高。\n */\nexport function normalizeDays(raw: unknown): number[] | undefined {\n if (!Array.isArray(raw)) return undefined\n const days = new Set<number>()\n for (const entry of raw) {\n if (typeof entry !== 'number' || !Number.isInteger(entry) || entry < 1 || entry > 7) continue\n days.add(entry)\n }\n if (days.size === 0) return undefined\n return [...days].sort((first, second) => first - second)\n}\n\nfunction toNumber(value: unknown, fallback: number): number {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : fallback\n}\n\nfunction toText(value: unknown, fallback: string): string {\n return typeof value === 'string' && value.trim() !== '' ? value.trim() : fallback\n}\n\nfunction ratesOf(raw: Record<string, unknown>, fallback: PricingRates): PricingRates {\n return {\n input: toNumber(raw.input, fallback.input),\n cacheRead: toNumber(raw.cacheRead, fallback.cacheRead),\n cacheWrite: toNumber(raw.cacheWrite, fallback.cacheWrite),\n output: toNumber(raw.output, fallback.output),\n }\n}\n\nfunction windowsOf(raw: unknown): OffPeakWindow[] {\n if (!Array.isArray(raw)) return []\n const windows: OffPeakWindow[] = []\n for (const entry of raw) {\n if (typeof entry !== 'object' || entry === null) continue\n const from = (entry as { from?: unknown }).from\n const to = (entry as { to?: unknown }).to\n if (typeof from !== 'string' || typeof to !== 'string') continue\n if (!/^\\d{1,2}:\\d{2}$/.test(from.trim()) || !/^\\d{1,2}:\\d{2}$/.test(to.trim())) continue\n const days = normalizeDays((entry as { days?: unknown }).days)\n windows.push({ from: from.trim(), to: to.trim(), ...(days === undefined ? {} : { days }) })\n }\n return windows\n}\n\n/**\n * 设置服务返回的值做一次防御式归一:\n * 宿主 schema 会把缺省的 `offPeak` 补成 `{windows: [], …}`,那种空壳要还原成「无错峰」。\n */\nexport function normalizeClientPricing(value: unknown): PricingConfig {\n if (typeof value !== 'object' || value === null) return EMPTY_CONFIG\n const record = value as Record<string, unknown>\n const currency = toText(record.currency, EMPTY_CONFIG.currency)\n const rules: PricingRule[] = []\n for (const entry of Array.isArray(record.rules) ? record.rules : []) {\n if (typeof entry !== 'object' || entry === null) continue\n const raw = entry as Record<string, unknown>\n const base = ratesOf(raw, { input: 0, cacheRead: 0, cacheWrite: 0, output: 0 })\n let offPeak: OffPeakPricing | null = null\n if (typeof raw.offPeak === 'object' && raw.offPeak !== null) {\n const offPeakRaw = raw.offPeak as Record<string, unknown>\n const windows = windowsOf(offPeakRaw.windows)\n if (windows.length > 0) offPeak = { ...ratesOf(offPeakRaw, base), windows }\n }\n rules.push({\n provider: toText(raw.provider, '*'),\n model: toText(raw.model, '*'),\n unit: UNIT_OPTIONS.includes(raw.unit as PricingUnit) ? raw.unit as PricingUnit : 'perMillionTokens',\n currency: toText(raw.currency, currency),\n ...base,\n offPeak,\n note: typeof raw.note === 'string' ? raw.note : '',\n })\n }\n return {\n version: typeof record.version === 'number' ? record.version : 1,\n currency,\n rules,\n }\n}\n\n/** 编辑器产出的规则必须只含 JSON 形状:写盘走宿主,`undefined` 会被拒绝。 */\nexport function cleanRuleForWrite(rule: PricingRule): Record<string, unknown> {\n const values: Record<string, unknown> = {\n provider: rule.provider.trim() === '' ? '*' : rule.provider.trim(),\n model: rule.model.trim() === '' ? '*' : rule.model.trim(),\n unit: rule.unit,\n currency: rule.currency,\n input: rule.input,\n cacheRead: rule.cacheRead,\n cacheWrite: rule.cacheWrite,\n output: rule.output,\n note: rule.note,\n }\n if (rule.offPeak !== null && rule.offPeak.windows.length > 0) {\n values.offPeak = {\n // `days` 缺省时**不写这个字段**:保持与升级前的 JSON 形状一致,旧版本读到也还是「每天」\n windows: rule.offPeak.windows.map((window) => {\n const days = normalizeDays(window.days)\n return days === undefined\n ? { from: window.from, to: window.to }\n : { from: window.from, to: window.to, days }\n }),\n input: rule.offPeak.input,\n cacheRead: rule.offPeak.cacheRead,\n cacheWrite: rule.offPeak.cacheWrite,\n output: rule.offPeak.output,\n }\n }\n return values\n}\n\nexport function configForWrite(config: PricingConfig): Record<string, unknown> {\n return {\n version: config.version,\n currency: config.currency,\n rules: config.rules.map(cleanRuleForWrite),\n }\n}\n\n/** 新增规则的初始值:全 0 单价会算成免费,因此先挡在保存之前(见编辑器校验)。 */\nexport function blankRule(config: PricingConfig): PricingRule {\n return {\n provider: '*', model: '*', unit: 'perMillionTokens', currency: config.currency,\n input: 0, cacheRead: 0, cacheWrite: 0, output: 0, offPeak: null, note: '',\n }\n}\n\nexport interface ImportResult {\n config: PricingConfig | null\n error: string | null\n}\n\n/** 导入:接受整份配置(`{version,currency,rules}`)或裸规则数组;解析失败给出中文原因。 */\nexport function parseImportedPricing(text: string): ImportResult {\n let parsed: unknown\n try {\n parsed = JSON.parse(text)\n } catch (error) {\n return { config: null, error: '不是合法 JSON:' + (error instanceof Error ? error.message : String(error)) }\n }\n const candidate = Array.isArray(parsed) ? { version: 1, currency: EMPTY_CONFIG.currency, rules: parsed } : parsed\n if (typeof candidate !== 'object' || candidate === null) {\n return { config: null, error: '顶层必须是对象或规则数组' }\n }\n const config = normalizeClientPricing(candidate)\n if (config.rules.length === 0) return { config: null, error: '没有解析出任何规则(检查 provider / model / 单价字段)' }\n return { config, error: null }\n}\n\n/** 单价全为 0 的规则会把成本算成免费,保存前必须拦住。 */\nexport function ruleProblemOf(rule: PricingRule): string | null {\n const values = [rule.input, rule.cacheRead, rule.cacheWrite, rule.output]\n if (values.every((value) => value === 0)) return '四档单价全为 0 会算成免费,至少填一个'\n if (values.some((value) => !Number.isFinite(value) || value < 0)) return '单价必须是不小于 0 的数字'\n if (rule.offPeak !== null && rule.offPeak.windows.length === 0) return '错峰时段至少要有一个窗口,或整段留空'\n return null\n}\n","/**\n * 计费规则的读写通道:把宿主的配置表单服务(`ctx.configForms`)包成一个 React 可订阅的 store。\n *\n * 为什么不用自己的 HTTP 路由写文件:插件只允许写 `quota-snapshots.json` 一个文件。\n * 规则的命名空间就是本插件在 profile 里的条目 id(`dsh-key-usage`),\n * 写入由宿主的 config-editor 落到当前 profile 的 cordis patch 上,插件全程不碰文件系统。\n */\nimport { EMPTY_CONFIG, configForWrite, normalizeClientPricing, type PricingConfig } from './pricing.ts'\n\n/** `configForms.get(entryId)` 返回的表单控制器(宿主 dsh-client-ui-settings 提供)。 */\nexport interface PricingForm {\n getSnapshot(): { status?: string; value?: unknown; revision?: number; writable?: boolean }\n subscribe(listener: () => void): () => void\n mutate(ops: Array<{ op: 'set' | 'unset'; path: string[]; value?: unknown }>, expectedRevision?: number): Promise<boolean>\n}\n\nexport interface ConfigFormsService {\n get(entryId: string): PricingForm\n whileServed(namespaces: string[], register: (served: Set<string>) => () => void): () => void\n}\n\nexport interface PricingSettingsState {\n /** loading = 宿主还没回;ready = 已拿到值;unavailable = 宿主没有这个命名空间。 */\n status: 'loading' | 'ready' | 'unavailable'\n writable: boolean\n config: PricingConfig\n /** 写入失败的中文原因(乐观锁冲突 / 命名空间未服务 / 宿主拒绝)。 */\n error: string | null\n}\n\nexport interface PricingSettingsStore {\n store: {\n subscribe(listener: () => void): () => void\n getSnapshot(): PricingSettingsState\n }\n /** 绑定表单控制器;返回解绑函数。宿主没提供 configForms 时传 null。 */\n attach(form: PricingForm | null): () => void\n /** 整份规则写回;成功返回 true。 */\n save(config: PricingConfig): Promise<boolean>\n /** 设置命名空间是否由宿主服务(决定要不要注册插件页卡片)。 */\n isServed(): boolean\n noteError(message: string): void\n}\n\nexport function createPricingSettings(): PricingSettingsStore {\n let state: PricingSettingsState = {\n status: 'loading',\n writable: false,\n config: EMPTY_CONFIG,\n error: null,\n }\n let form: PricingForm | null = null\n let unsubscribe: (() => void) | null = null\n const listeners = new Set<() => void>()\n\n const publish = (next: PricingSettingsState): void => {\n if (\n next.status === state.status && next.writable === state.writable\n && next.error === state.error && next.config === state.config\n ) return\n state = next\n for (const listener of listeners) listener()\n }\n\n const sync = (): void => {\n if (form === null) {\n publish({ status: 'unavailable', writable: false, config: state.config, error: state.error })\n return\n }\n const snapshot = form.getSnapshot()\n const ready = snapshot.status === 'ready' && snapshot.value !== undefined\n publish({\n status: ready ? 'ready' : snapshot.status === 'unavailable' ? 'unavailable' : 'loading',\n writable: snapshot.writable === true,\n config: ready ? normalizeClientPricing(snapshot.value) : state.config,\n error: state.error,\n })\n }\n\n return {\n store: {\n subscribe(listener) {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n },\n getSnapshot: () => state,\n },\n attach(next) {\n unsubscribe?.()\n unsubscribe = null\n form = next\n if (form !== null) {\n unsubscribe = form.subscribe(sync)\n publish({ ...state, error: null })\n }\n sync()\n return () => {\n unsubscribe?.()\n unsubscribe = null\n form = null\n }\n },\n async save(config) {\n if (form === null) {\n publish({ ...state, error: '宿主没有提供配置表单服务,规则只能导出 / 导入,无法保存' })\n return false\n }\n publish({ ...state, error: null })\n let accepted = false\n try {\n // 整段替换而非逐条改数组:宿主的数组层是整体覆盖语义,逐条改很容易留下旧元素\n accepted = await form.mutate([{ op: 'set', path: ['pricing'], value: configForWrite(config) }])\n } catch (error) {\n publish({ ...state, error: '写入失败:' + (error instanceof Error ? error.message : String(error)) })\n return false\n }\n if (!accepted) publish({ ...state, error: '写入被宿主拒绝(可能是规则在别处被同时修改,请重试)' })\n return accepted\n },\n isServed: () => state.status !== 'unavailable',\n noteError(message) {\n publish({ ...state, error: message })\n },\n }\n}\n\n/**\n * 进程内单例:插件在页面里只有一个实例,index.tsx 在 apply 时把它接到 `configForms` 上,\n * 组件用 useSyncExternalStore 订阅即可(避免把服务对象一层层透传进 React 树)。\n */\nexport const pricingSettings = createPricingSettings()\n","/**\n * 侧边栏导航图标(`sidebar.panellist`)。\n * 该 slot 由宿主自持整行(标签、hover/active 配色),插件只提供字形,\n * 因此用 currentColor 让宿主的行样式直接染上图标。\n */\nimport type { ReactNode } from 'react'\n\nexport function UsageIcon({ size = 18 }: { size?: number }): ReactNode {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n focusable=\"false\"\n style={{ display: 'block' }}\n >\n <rect x=\"2.6\" y=\"8.8\" width=\"2.6\" height=\"4.2\" rx=\"0.7\" fill=\"currentColor\" />\n <rect x=\"6.7\" y=\"5.6\" width=\"2.6\" height=\"7.4\" rx=\"0.7\" fill=\"currentColor\" />\n <rect x=\"10.8\" y=\"2.8\" width=\"2.6\" height=\"10.2\" rx=\"0.7\" fill=\"currentColor\" />\n </svg>\n )\n}\n","/** 同源只读端点的取数封装:任何失败都返回 null,由调用方决定空态。 */\n\nimport type {\n Channel,\n HeatmapDay,\n ModelsResponse,\n PricingResponse,\n ProjectsResponse,\n QuotaProvider,\n SessionsResponse,\n SummaryResponse,\n UsageResponse,\n} from './types.ts'\n\n/**\n * 最近一次请求失败的原因,按路径记住。\n * 空态文案需要能指向「怎么做」——最常见的失败是新端点 404(服务端代码要重启宿主才生效)。\n */\nconst failureReasons = new Map<string, string>()\n\nexport function failureReasonOf(path: string): string | null {\n return failureReasons.get(path) ?? null\n}\n\nasync function fetchJson<T>(path: string): Promise<T | null> {\n try {\n const response = await fetch(path, { headers: { Accept: 'application/json' } })\n if (!response.ok) {\n failureReasons.set(path, response.status === 404\n ? 'HTTP 404:宿主没有这个端点 —— 服务端改动需要退出重开 DSH(刷新页面不够)'\n : 'HTTP ' + String(response.status))\n return null\n }\n failureReasons.delete(path)\n return await response.json() as T\n } catch (error) {\n failureReasons.set(path, '请求失败:' + (error instanceof Error ? error.message : String(error)))\n return null\n }\n}\n\nexport async function loadChannels(): Promise<Channel[] | null> {\n const result = await fetchJson<{ channels: Channel[] }>('/dsh-key-usage/channels')\n return result === null ? null : result.channels\n}\n\nexport async function loadUsage(from: string, to: string, provider: string): Promise<UsageResponse | null> {\n const params = new URLSearchParams({ from, to })\n if (provider !== 'ALL') params.set('provider', provider)\n return fetchJson<UsageResponse>('/dsh-key-usage/usage?' + params.toString())\n}\n\nexport async function loadHeatmap(): Promise<HeatmapDay[] | null> {\n const result = await fetchJson<{ days: HeatmapDay[] }>('/dsh-key-usage/heatmap')\n return result === null ? null : result.days\n}\n\n/**\n * 余额与订阅窗口:服务端实时优先、失败回落本机快照。\n * @param fresh - 用户手动刷新时传 true,强制重新查一次官方接口\n */\nexport async function loadQuota(fresh = false): Promise<QuotaProvider[] | null> {\n const query = fresh ? '?fresh=1' : ''\n const result = await fetchJson<{ providers: QuotaProvider[] }>('/dsh-key-usage/quota' + query)\n return result === null ? null : result.providers\n}\n\nexport function loadSummary(): Promise<SummaryResponse | null> {\n return fetchJson<SummaryResponse>('/dsh-key-usage/summary')\n}\n\nexport function loadSessions(limit = 300): Promise<SessionsResponse | null> {\n return fetchJson<SessionsResponse>('/dsh-key-usage/sessions?limit=' + String(limit))\n}\n\nexport function loadProjects(limit = 200): Promise<ProjectsResponse | null> {\n return fetchJson<ProjectsResponse>('/dsh-key-usage/projects?limit=' + String(limit))\n}\n\nexport function loadModels(limit = 200): Promise<ModelsResponse | null> {\n return fetchJson<ModelsResponse>('/dsh-key-usage/models?limit=' + String(limit))\n}\n\n/** 计费规则面板的服务端对照:内置模板、错峰状态与近 30 天覆盖度。 */\nexport function loadPricing(): Promise<PricingResponse | null> {\n return fetchJson<PricingResponse>('/dsh-key-usage/pricing')\n}\n","/** 展示层格式化:全部与统计口径无关,只负责把数字变成界面文本。 */\n\n/** 本地日历 `YYYY-MM-DD`。 */\nexport function isoDate(date: Date): string {\n const month = String(date.getMonth() + 1).padStart(2, '0')\n const day = String(date.getDate()).padStart(2, '0')\n return `${date.getFullYear()}-${month}-${day}`\n}\n\nexport function shiftedIsoDate(offsetDays: number): string {\n return isoDate(new Date(Date.now() + offsetDays * 86400000))\n}\n\nexport function fmtTokens(count: number): string {\n if (count >= 1e9) return (count / 1e9).toFixed(2) + 'B'\n if (count >= 1e6) return (count / 1e6).toFixed(1) + 'M'\n if (count >= 1e3) return (count / 1e3).toFixed(0) + 'K'\n return String(count)\n}\n\nexport function fmtCost(amount: number): string {\n return '¥' + amount.toFixed(2)\n}\n\nexport function fmtCalls(count: number): string {\n return count.toLocaleString('en-US').replace(/,/g, ' ')\n}\n\n/** `MM-DD`(图表坐标轴与范围文案用)。 */\nexport function fmtShortDate(dateKey: string): string {\n return dateKey.slice(5)\n}\n\n/** 毫秒时间戳 → `YYYY-MM-DD HH:mm`(本地时区)。 */\nexport function fmtDateTime(timeMs: number | null): string {\n if (timeMs === null) return '—'\n const date = new Date(timeMs)\n const hours = String(date.getHours()).padStart(2, '0')\n const minutes = String(date.getMinutes()).padStart(2, '0')\n return `${isoDate(date)} ${hours}:${minutes}`\n}\n\n/** 毫秒时间戳 → `HH:mm`。 */\nexport function fmtTime(timeMs: number | null): string {\n if (timeMs === null) return '—'\n const date = new Date(timeMs)\n return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`\n}\n\n/** 时长(毫秒)→ `2h 15m` / `43m` / `—`。 */\nexport function fmtDuration(milliseconds: number | null): string {\n if (milliseconds === null || milliseconds <= 0) return '—'\n const minutes = Math.max(1, Math.round(milliseconds / 60000))\n if (minutes < 60) return `${minutes}m`\n return `${Math.floor(minutes / 60)}h ${minutes % 60}m`\n}\n\n/** 最近活跃:刚刚 / N 分钟前 / N 小时前 / N 天前。 */\nexport function fmtRelative(timeMs: number | null, nowMs: number): string {\n if (timeMs === null) return '—'\n const minutes = Math.round((nowMs - timeMs) / 60000)\n if (minutes < 1) return '刚刚'\n if (minutes < 60) return `${minutes} 分钟前`\n if (minutes < 60 * 24) return `${Math.round(minutes / 60)} 小时前`\n return `${Math.round(minutes / (60 * 24))} 天前`\n}\n\n/** 命中率:一位小数百分数,无提示侧 token 时返回 —。 */\nexport function fmtHitRate(cacheReadTokens: number, promptTokens: number): string {\n if (promptTokens <= 0) return '—'\n return (cacheReadTokens / promptTokens * 100).toFixed(1) + '%'\n}\n","/** 共享浮层:跟随鼠标的 fixed 层,内容用 React 节点渲染(不再拼接 innerHTML)。 */\nimport { useCallback, useLayoutEffect, useRef, useState, type ReactNode } from 'react'\nimport styles from './styles/shared.module.css'\n\nexport interface TooltipContent {\n x: number\n y: number\n node: ReactNode\n}\n\nexport interface TooltipApi {\n tooltip: TooltipContent | null\n show: (event: React.MouseEvent, node: ReactNode) => void\n hide: () => void\n}\n\nexport function useTooltip(): TooltipApi {\n const [tooltip, setTooltip] = useState<TooltipContent | null>(null)\n const show = useCallback((event: React.MouseEvent, node: ReactNode) => {\n setTooltip({ x: event.clientX, y: event.clientY, node })\n }, [])\n const hide = useCallback(() => setTooltip(null), [])\n return { tooltip, show, hide }\n}\n\nexport function TooltipView({ tooltip }: { tooltip: TooltipContent | null }): ReactNode {\n const elementRef = useRef<HTMLDivElement | null>(null)\n useLayoutEffect(() => {\n const element = elementRef.current\n if (element === null || tooltip === null) return\n const maxX = window.innerWidth - element.offsetWidth - 12\n const maxY = window.innerHeight - element.offsetHeight - 12\n element.style.left = Math.max(8, Math.min(tooltip.x + 14, maxX)) + 'px'\n element.style.top = Math.max(8, Math.min(tooltip.y + 14, maxY)) + 'px'\n }, [tooltip])\n if (tooltip === null) return null\n return <div ref={elementRef} className={styles.tooltip}>{tooltip.node}</div>\n}\n\nexport function TipTitle({ children }: { children: ReactNode }): ReactNode {\n return <div className={styles.tipTitle}>{children}</div>\n}\n\nexport function TipSub({ children }: { children: ReactNode }): ReactNode {\n return <div className={styles.tipSub}>{children}</div>\n}\n\nexport function TipRow(props: { color?: string; label: ReactNode; amount?: ReactNode; rate?: ReactNode }): ReactNode {\n return (\n <div className={styles.tipRow}>\n {props.color !== undefined && <i style={{ background: props.color }} />}\n <span className={styles.tipName}>{props.label}</span>\n {props.amount !== undefined && <span className={styles.tipAmount}>{props.amount}</span>}\n {props.rate !== undefined && <span className={styles.tipRate}>{props.rate}</span>}\n </div>\n )\n}\n\nexport function TipBar({ percent, color }: { percent: number; color: string }): ReactNode {\n return <div className={styles.tipBar}><i style={{ width: Math.max(2, percent) + '%', background: color }} /></div>\n}\n\nexport function TipDivider({ children }: { children: ReactNode }): ReactNode {\n return <div className={styles.tipDivider}>{children}</div>\n}\n","/** 通道展示工具:颜色、显示名、状态与计费模式文案。 */\nimport type { Channel, ChannelCostMode, ChannelStatus } from './types.ts'\n\nconst CHANNEL_COLORS = ['#5b8cff', '#9a7bff', '#3fb96f', '#e0a13c', '#e05a5a', '#38bdc8']\n\nexport const STATUS_LABELS: Record<ChannelStatus, string> = {\n ok: '正常',\n warn: '偏高',\n danger: '告警',\n off: '未配置',\n}\n\nexport function channelIndexOf(channels: Channel[], provider: string): number {\n return channels.findIndex((channel) => channel.provider === provider)\n}\n\nexport function channelColorOf(channels: Channel[], provider: string): string {\n const index = channelIndexOf(channels, provider)\n return CHANNEL_COLORS[(index >= 0 ? index : 0) % CHANNEL_COLORS.length]\n}\n\nexport function displayNameOf(channels: Channel[], provider: string): string {\n return channels.find((channel) => channel.provider === provider)?.displayName ?? provider\n}\n\nexport function channelOf(channels: Channel[], provider: string | null): Channel | null {\n if (provider === null) return null\n return channels.find((channel) => channel.provider === provider) ?? null\n}\n\n/** 成本单元格:按计费模式给出文案,无法判定时回落金额或 —。 */\nexport function costCellText(channel: Channel | null, cost: number): { text: string; dim: boolean } {\n if (channel === null) return cost > 0 ? { text: '¥' + cost.toFixed(2), dim: false } : { text: '—', dim: true }\n if (channel.costMode === 'sub') return { text: '订阅内', dim: true }\n if (channel.costMode === 'free') return { text: '¥0.00', dim: true }\n if (channel.costMode === 'none') return { text: '无计费', dim: true }\n return cost > 0 ? { text: '¥' + cost.toFixed(2), dim: false } : { text: '—', dim: true }\n}\n\n/**\n * 单元格是否该挂来源角标:只有真的显示了金额(`¥…`)时才挂,\n * `订阅内` / `免费` / `无计费` / `—` 都是占位文案,挂角标只是噪音。\n */\nexport function showsAmount(cell: { text: string }): boolean {\n return cell.text.startsWith('¥')\n}\n\n/** 状态点的颜色(走宿主告警/成功令牌)。 */\nexport function statusColorOf(status: ChannelStatus): string {\n if (status === 'ok') return 'var(--dsw-alias-state-success-primary, #3fb96f)'\n if (status === 'warn') return 'var(--dsw-alias-state-warning-primary, #e0a13c)'\n if (status === 'danger') return 'var(--dsw-alias-state-danger-primary, #e05a5a)'\n return 'var(--dsw-alias-label-tertiary, #67676f)'\n}\n\n/** 窗口占用进度条颜色:≥90 危险、≥60 警告,其余正常。 */\nexport function quotaBarColor(percent: number): string {\n if (percent >= 90) return 'var(--dsw-alias-state-danger-primary, #e05a5a)'\n if (percent >= 60) return 'var(--dsw-alias-state-warning-primary, #e0a13c)'\n return 'var(--dsw-alias-state-success-primary, #3fb96f)'\n}\n\nexport const COST_MODE_LABELS: Record<ChannelCostMode, string> = {\n sub: '订阅制',\n perToken: '按量计费',\n free: '免费额度',\n none: '本地端点',\n unknown: '未查询',\n}\n","/**\n * 活跃热力图:最近约 9 个月的滚动窗口(含未来格占位)。\n * 强度分档取活跃日的三分位(p33 / p67),阈值随可见区间自动变化,\n * 具体数值并入页面底部的口径说明,不再单独占一行。\n * 格子用固定方形尺寸 + 横向滚动,保证「有数据 / 无数据 / 无用量」三类格子完全等大。\n */\nimport { useEffect, useMemo, useRef, type ReactNode } from 'react'\nimport { channelColorOf, displayNameOf } from '../channels.ts'\nimport { fmtTokens, isoDate } from '../format.ts'\nimport type { Channel, HeatmapDay } from '../types.ts'\nimport { TipBar, TipRow, TipSub, TipTitle, type TooltipApi } from '../tooltip.tsx'\nimport styles from '../styles/overview.module.css'\nimport shared from '../styles/shared.module.css'\n\n/** 9 个月 ≈ 39 周;配合 18px 方形格子,窄窗口下横向滚动。 */\nconst WEEK_COUNT = 39\nconst DAY_MS = 86400000\n\ninterface HeatCell {\n date: string\n state: 'future' | 'empty' | 'idle' | 'active'\n level: number\n}\n\nfunction levelThresholds(days: HeatmapDay[]): [number, number] {\n const active = days.map((day) => day.totalTokens).filter((tokens) => tokens > 0).sort((first, second) => first - second)\n if (active.length < 3) return [5e7, 2e8]\n const pick = (fraction: number): number => active[Math.min(active.length - 1, Math.floor(active.length * fraction))]\n return [pick(0.33), pick(0.67)]\n}\n\nfunction levelOf(tokens: number, thresholds: [number, number]): number {\n if (tokens <= 0) return 0\n if (tokens < thresholds[0]) return 1\n if (tokens < thresholds[1]) return 2\n return 3\n}\n\nconst LEVEL_COLORS = ['rgba(128,128,140,.22)', 'rgba(91,140,255,.25)', 'rgba(91,140,255,.55)', '#5b8cff']\n\nexport function Heatmap(props: { days: HeatmapDay[]; channels: Channel[]; tooltip: TooltipApi }): ReactNode {\n const { days, channels, tooltip } = props\n const heatmapByDate = useMemo(() => new Map(days.map((day) => [day.date, day])), [days])\n const thresholds = useMemo(() => levelThresholds(days), [days])\n\n const { columns, monthLabels } = useMemo(() => {\n const today = new Date()\n today.setHours(0, 0, 0, 0)\n const endSaturday = new Date(today.getTime() + (6 - today.getDay()) * DAY_MS)\n const start = new Date(endSaturday.getTime() - (WEEK_COUNT * 7 - 1) * DAY_MS)\n const dataStart = days.length > 0 ? days[0].date : null\n const cells: HeatCell[] = []\n for (let offset = 0; offset < WEEK_COUNT * 7; offset += 1) {\n const date = new Date(start.getTime() + offset * DAY_MS)\n const dateKey = isoDate(date)\n if (date.getTime() > today.getTime()) {\n cells.push({ date: dateKey, state: 'future', level: 0 })\n continue\n }\n // 台账覆盖之前的日子用 ghost 占位,与「无用量」的灰区分开\n if (dataStart === null || dateKey < dataStart) {\n cells.push({ date: dateKey, state: 'empty', level: 0 })\n continue\n }\n const day = heatmapByDate.get(dateKey)\n if (day === undefined || day.totalTokens <= 0) {\n cells.push({ date: dateKey, state: 'idle', level: 0 })\n continue\n }\n cells.push({ date: dateKey, state: 'active', level: levelOf(day.totalTokens, thresholds) })\n }\n const weeks: HeatCell[][] = []\n for (let index = 0; index < cells.length; index += 7) weeks.push(cells.slice(index, index + 7))\n const labels: string[] = []\n let previousMonth = -1\n for (const week of weeks) {\n const month = Number(week[0].date.slice(5, 7))\n labels.push(month !== previousMonth ? month + '月' : '')\n previousMonth = month\n }\n return { columns: weeks, monthLabels: labels }\n }, [days, heatmapByDate])\n\n // 默认贴最右侧:右边是最新的日期,左边是 9 个月前的历史(每次筛选都跳回去反而烦人,所以只在挂载时定位一次)\n const scrollRef = useRef<HTMLDivElement | null>(null)\n useEffect(() => {\n const node = scrollRef.current\n if (node === null) return\n node.scrollLeft = node.scrollWidth - node.clientWidth\n }, [])\n\n return (\n <div className={styles.heatmapCard}>\n <div className={styles.heatmapHead}>\n <span className={styles.heatmapTitle}>活跃热力图 · 近 9 个月 · 按当日 Tokens 总量 · 悬停查看当日各模型占比</span>\n <span className={shared.legend}>\n <span><i className=\"ghost\" />无数据</span>\n <span><i style={{ background: LEVEL_COLORS[0] }} />无用量</span>\n <span><i style={{ background: LEVEL_COLORS[1] }} />少</span>\n <span><i style={{ background: LEVEL_COLORS[2] }} />中</span>\n <span><i style={{ background: LEVEL_COLORS[3] }} />高</span>\n </span>\n </div>\n <div className={styles.heatmapScroll} ref={scrollRef}>\n <div className={styles.heatmapBody}>\n <div className={styles.heatWeekdays}>\n <span>日</span><span>一</span><span>二</span><span>三</span><span>四</span><span>五</span><span>六</span>\n </div>\n <div className={styles.heatGridCol}>\n <div className={styles.heatGrid}>\n {columns.map((week, weekIndex) => (\n <div className={styles.heatWeek} key={weekIndex}>\n {week.map((cell) => {\n const day = cell.state === 'active' ? heatmapByDate.get(cell.date) : undefined\n const className = cell.state === 'active'\n ? styles.heatCell\n : cell.state === 'idle' ? styles.heatCell + ' ' + styles.idle : styles.heatCell + ' ' + styles.empty\n return (\n <div\n key={cell.date}\n className={className}\n style={cell.state === 'active' ? { background: LEVEL_COLORS[cell.level] } : undefined}\n onMouseMove={(event) => tooltip.show(event, tipOf(cell, day, channels))}\n onMouseLeave={tooltip.hide}\n />\n )\n })}\n </div>\n ))}\n </div>\n <div className={styles.heatMonths}>\n {monthLabels.map((label, index) => <span key={index}>{label}</span>)}\n </div>\n </div>\n </div>\n </div>\n </div>\n )\n}\n\nfunction tipOf(cell: HeatCell, day: HeatmapDay | undefined, channels: Channel[]): ReactNode {\n if (cell.state !== 'active' || day === undefined) {\n return (\n <>\n <TipTitle>{cell.date}</TipTitle>\n <TipSub>{cell.state === 'idle' ? '当日无用量记录' : '台账尚未覆盖'}</TipSub>\n </>\n )\n }\n return (\n <>\n <TipTitle>{cell.date}</TipTitle>\n <TipSub>合计 <b>{fmtTokens(day.totalTokens)}</b> tokens</TipSub>\n {day.models.map((model) => {\n const percent = day.totalTokens > 0 ? Math.round(model.totalTokens / day.totalTokens * 100) : 0\n const color = channelColorOf(channels, model.provider)\n return (\n <div key={model.provider + '|' + model.model}>\n <TipRow\n color={color}\n label={<>{model.model}<span className={shared.dim}> · {displayNameOf(channels, model.provider)}</span></>}\n amount={fmtTokens(model.totalTokens)}\n rate={percent + '%'}\n />\n <TipBar percent={percent} color={color} />\n </div>\n )\n })}\n </>\n )\n}\n","/**\n * 成本来源角标:官方(台账账单)/ 官方价(内置官方价目)/ 自定(你的规则)/ 估算(台账均价)\n * —— 避免把估算当成账单金额用。\n * 只在真的显示了金额时挂;`订阅内` / `免费` / `—` 这类占位文案不带角标。\n */\nimport type { ReactNode } from 'react'\nimport { COST_SOURCE_HINTS, COST_SOURCE_LABELS, type CostSource } from '../pricing.ts'\nimport styles from '../styles/pricing.module.css'\n\nexport function CostSourceChip(props: { source: CostSource | null | undefined; compact?: boolean }): ReactNode {\n const source = props.source ?? 'none'\n if (source === 'none') return null\n return (\n <span className={styles.sourceChip + ' ' + sourceClass(source)} title={COST_SOURCE_HINTS[source]}>\n {COST_SOURCE_LABELS[source]}\n </span>\n )\n}\n\nfunction sourceClass(source: CostSource): string {\n if (source === 'official') return styles.sourceOfficial\n if (source === 'rule') return styles.sourceRule\n if (source === 'catalog') return styles.sourceCatalog\n return styles.sourceEstimate\n}\n","/** 总览:Key 清单表(原型列结构)+ 年度热力图。 */\nimport type { ReactNode } from 'react'\nimport { costCellText, showsAmount, statusColorOf } from '../channels.ts'\nimport { fmtCalls, fmtTokens } from '../format.ts'\nimport type { Channel, HeatmapDay, QuotaProvider, SummaryResponse } from '../types.ts'\nimport type { TooltipApi } from '../tooltip.tsx'\nimport { Heatmap } from '../components/Heatmap.tsx'\nimport { CostSourceChip } from '../components/CostSourceChip.tsx'\nimport styles from '../styles/shared.module.css'\nimport overviewStyles from '../styles/overview.module.css'\n\nexport function OverviewTab(props: {\n channels: Channel[]\n summary: SummaryResponse | null\n quotas: QuotaProvider[]\n heatmap: HeatmapDay[]\n tooltip: TooltipApi\n onOpenDetail: (provider: string) => void\n}): ReactNode {\n const { channels, summary } = props\n return (\n <div>\n <div className={styles.groupLabel}>Key 清单</div>\n <table className={overviewStyles.keyTable}>\n <thead>\n <tr>\n <th>通道</th><th>类型</th><th>今日</th><th>近 30 天</th><th>余额 / 窗口</th><th>30 天成本</th><th></th>\n </tr>\n </thead>\n <tbody>\n {channels.map((channel) => {\n const row = summary?.channels.find((item) => item.provider === channel.provider) ?? null\n const todayTokens = row === null ? 0 : row.today.tokens\n const monthTokens = row === null ? 0 : row.month.tokens\n const monthCost = row === null ? 0 : row.month.cost\n const costCell = costCellText(channel, monthCost)\n const disabled = channel.status === 'off'\n return (\n <tr\n key={channel.provider}\n className={disabled ? overviewStyles.disabledRow : overviewStyles.clickable}\n onClick={disabled ? undefined : () => props.onOpenDetail(channel.provider)}\n >\n <td>\n <div className={overviewStyles.cellKey}>\n <span className={styles.statusDot} style={{ background: statusColorOf(channel.status) }} />\n <div className={overviewStyles.keyDisplay}>{channel.displayName}</div>\n </div>\n </td>\n <td><span className={tagClassOf(channel)}>{channel.status === 'off' ? '未配置' : channel.costLabel}</span></td>\n <td>{todayTokens > 0 ? fmtTokens(todayTokens) : <span className={styles.dim}>—</span>}</td>\n <td>{monthTokens > 0 ? fmtTokens(monthTokens) : <span className={styles.dim}>—</span>}</td>\n <td>{quotaCellOf(channel)}</td>\n <td>{costCell.dim ? <span className={styles.dim}>{costCell.text}</span> : <>{costCell.text}{showsAmount(costCell) && <CostSourceChip source={row?.month.costSource} />}</>}</td>\n <td>{disabled ? null : <span className={overviewStyles.rowLink}>明细 →</span>}</td>\n </tr>\n )\n })}\n {channels.length === 0 && <tr><td colSpan={7} className={styles.empty}>未读取到通道配置</td></tr>}\n </tbody>\n </table>\n\n <Heatmap days={props.heatmap} channels={channels} tooltip={props.tooltip} />\n\n {summary === null && (\n <div className={styles.empty}>台账读取中或不可用,今日 / 近 30 天列为空</div>\n )}\n {props.quotas.length === 0 && channels.length > 0 && (\n <div className={styles.empty}>未读取到余额快照,余额 / 窗口列显示为 —</div>\n )}\n </div>\n )\n}\n\nfunction tagClassOf(channel: Channel): string {\n const base = overviewStyles.tag\n if (channel.status === 'off') return base + ' ' + overviewStyles.off\n if (channel.costMode === 'free') return base + ' ' + overviewStyles.free\n if (channel.costMode === 'sub') return base + ' ' + overviewStyles.sub\n return base\n}\n\nfunction quotaCellOf(channel: Channel): ReactNode {\n if (channel.costMode === 'sub' && channel.quotaPercent !== null) {\n const percent = channel.quotaPercent\n const levelClass = percent >= 90 ? overviewStyles.danger : percent >= 60 ? overviewStyles.warn : ''\n const windowLabel = channel.quotaWindowLabel ?? channel.quotaWindowKey ?? ''\n return (\n <span className={overviewStyles.quotaCell}>\n <span className={overviewStyles.miniBar}>\n <i style={{ width: Math.max(2, percent) + '%', background: percent >= 60 ? 'var(--dsw-alias-state-warning-primary, #e0a13c)' : 'var(--dsw-alias-state-success-primary, #3fb96f)' }} />\n </span>\n <span className={[overviewStyles.quotaText, levelClass].join(' ').trim()}>{windowLabel} {percent}%</span>\n </span>\n )\n }\n if (channel.balanceText !== null) {\n const levelClass = channel.status === 'danger' ? overviewStyles.danger : channel.status === 'warn' ? overviewStyles.warn : ''\n return (\n <span className={overviewStyles.quotaCell}>\n <span className={[overviewStyles.quotaText, levelClass].join(' ').trim()}>{channel.balanceText}</span>\n </span>\n )\n }\n const fallback = channel.costMode === 'none' ? '无计费' : channel.costMode === 'free' ? '—' : '未查询'\n return <span className={[overviewStyles.quotaText, overviewStyles.dim].join(' ')}>{fallback}</span>\n}\n\n/** 供标题行使用的调用汇总(占位保持导出面稳定)。 */\nexport function overviewCaptionOf(summary: SummaryResponse | null): string {\n if (summary === null) return '台账不可用'\n const calls = summary.channels.reduce((total, row) => total + row.month.calls, 0)\n return fmtCalls(calls) + ' 次调用'\n}\n","/**\n * 导出工具:纯函数生成 CSV / JSON 文本 + 用 Blob 触发浏览器下载。\n * 零依赖、零服务端往返,导出的永远是**客户端当前筛选后**的数据。\n *\n * 两条口径约束:\n * - CSV 必须带 UTF-8 BOM:Excel 默认按本地代码页解码,没有 BOM 中文会变乱码;\n * - JSON 不能带 BOM:`JSON.parse` 遇到 BOM 会直接抛错。\n */\nimport { isoDate } from './format.ts'\n\n/** 列定义。`value` 取原始值(数字保持数字),避免把界面文本再解析回数字。 */\nexport interface ExportColumn<Row> {\n key: string\n label: string\n value: (row: Row) => string | number | null\n}\n\nconst UTF8_BOM = '\\ufeff'\n\nexport const CSV_MIME = 'text/csv;charset=utf-8'\nexport const JSON_MIME = 'application/json;charset=utf-8'\n\n/** 表头 + 数据行 → CSV 文本(转义见 `csvCell`,换行用 RFC 4180 的 CRLF)。 */\nexport function toCsv<Row>(rows: Row[], columns: Array<ExportColumn<Row>>): string {\n const lines = [columns.map((column) => csvCell(column.label)).join(',')]\n for (const row of rows) {\n lines.push(columns.map((column) => csvCell(column.value(row))).join(','))\n }\n return UTF8_BOM + lines.join('\\r\\n') + '\\r\\n'\n}\n\nexport function toJson(value: unknown): string {\n return JSON.stringify(value, null, 2) + '\\n'\n}\n\n/** 下载文件名:`dsh-usage-<主题>-<当天>.<扩展名>`,主题用英文短名避免跨端中文文件名乱码。 */\nexport function exportFileName(topic: string, extension: 'csv' | 'json'): string {\n return 'dsh-usage-' + topic + '-' + isoDate(new Date()) + '.' + extension\n}\n\nexport function downloadFile(name: string, text: string, mime: string): void {\n const objectUrl = URL.createObjectURL(new Blob([text], { type: mime }))\n const anchor = document.createElement('a')\n anchor.href = objectUrl\n anchor.download = name\n document.body.appendChild(anchor)\n anchor.click()\n anchor.remove()\n // 立刻 revoke 会有浏览器来不及取数据,推到下一轮事件循环再释放\n window.setTimeout(() => URL.revokeObjectURL(objectUrl), 0)\n}\n\n/** 逗号、引号、换行都必须包引号并把内部引号翻倍,否则标题里的逗号会撑破列。 */\nfunction csvCell(value: string | number | null): string {\n if (value === null) return ''\n const text = String(value)\n return /[\",\\r\\n]/.test(text) ? '\"' + text.replace(/\"/g, '\"\"') + '\"' : text\n}\n","/**\n * 占比条:全部通道→通道占比;单通道→模型占比。\n * 只有一条堆叠横条,名字与百分比走悬停 tip(不再列表展示)。\n */\nimport type { ReactNode } from 'react'\nimport { channelColorOf, displayNameOf } from '../channels.ts'\nimport { fmtTokens } from '../format.ts'\nimport type { Channel, UsageResponse } from '../types.ts'\nimport { TipRow, TipSub, TipTitle, type TooltipApi } from '../tooltip.tsx'\nimport styles from '../styles/shared.module.css'\nimport detailStyles from '../styles/detail.module.css'\n\ninterface ShareRow {\n key: string\n label: string\n tokens: number\n color: string\n}\n\nexport function ShareBar(props: {\n usage: UsageResponse | null\n totalTokens: number\n channelFilter: string\n channels: Channel[]\n tooltip: TooltipApi\n}): ReactNode {\n const { usage, totalTokens, channels } = props\n if (usage === null || totalTokens <= 0) {\n return (\n <div className={styles.card}>\n <div className={styles.statLabel}>占比 · 按 Tokens</div>\n <div className={styles.empty} style={{ padding: '8px 0' }}>所选范围内无用量记录</div>\n </div>\n )\n }\n let rows: ShareRow[] = []\n let title = '通道占比 · 按 Tokens'\n if (props.channelFilter === 'ALL') {\n const byProvider = new Map<string, number>()\n for (const day of usage.days) {\n for (const model of day.models) {\n byProvider.set(model.provider, (byProvider.get(model.provider) ?? 0) + model.inputTokens + model.outputTokens + model.cacheReadTokens)\n }\n }\n rows = [...byProvider.entries()].map(([provider, tokens]) => ({\n key: provider, label: displayNameOf(channels, provider), tokens, color: channelColorOf(channels, provider),\n }))\n } else {\n title = '模型占比 · 按 Tokens'\n const byModel = new Map<string, { tokens: number; provider: string }>()\n for (const day of usage.days) {\n for (const model of day.models) {\n const bucket = byModel.get(model.model)\n const tokens = model.inputTokens + model.outputTokens + model.cacheReadTokens\n if (bucket === undefined) byModel.set(model.model, { tokens, provider: model.provider })\n else bucket.tokens += tokens\n }\n }\n rows = [...byModel.entries()].map(([model, value]) => ({\n key: model, label: model, tokens: value.tokens, color: channelColorOf(channels, value.provider),\n }))\n }\n rows.sort((first, second) => second.tokens - first.tokens)\n return (\n <div className={styles.card}>\n <div className={styles.statLabel}>{title}</div>\n <div className={detailStyles.shareBar}>\n {rows.map((row) => {\n const percent = totalTokens > 0 ? Math.round(row.tokens / totalTokens * 100) : 0\n return (\n <i\n key={row.key}\n style={{ width: (row.tokens / totalTokens * 100) + '%', background: row.color }}\n onMouseMove={(event) => props.tooltip.show(event, (\n <>\n <TipTitle>{row.label}</TipTitle>\n <TipSub>占比 <b>{percent}%</b></TipSub>\n <TipRow color={row.color} label=\"Tokens\" amount={fmtTokens(row.tokens)} rate={percent + '%'} />\n </>\n ))}\n onMouseLeave={props.tooltip.hide}\n />\n )\n })}\n </div>\n </div>\n )\n}\n","/** 统计卡:标签 + 主数值 + 副文案(原型 .stat-card)。 */\nimport type { ReactNode } from 'react'\nimport styles from '../styles/shared.module.css'\n\nexport function StatCard(props: { label: string; value: ReactNode; extra?: ReactNode }): ReactNode {\n return (\n <div className={styles.card}>\n <div className={styles.statLabel}>{props.label}</div>\n <div className={styles.statValue}>{props.value}</div>\n {props.extra !== undefined && <div className={styles.statExtra}>{props.extra}</div>}\n </div>\n )\n}\n","/** 堆叠柱状图:按天或按小时,含 x 轴标签(原型 .bars/.bar-labels)。 */\nimport type { ReactNode } from 'react'\nimport type { TooltipApi } from '../tooltip.tsx'\nimport styles from '../styles/detail.module.css'\n\nexport interface TokenBarRow {\n key: string\n axisLabel: string\n cacheReadTokens: number\n inputTokens: number\n outputTokens: number\n tip: ReactNode\n}\n\nexport function TokenBars(props: {\n rows: TokenBarRow[]\n tooltip: TooltipApi\n hidden?: boolean\n}): ReactNode {\n const { rows, tooltip } = props\n if (props.hidden === true || rows.length === 0) return null\n const peak = Math.max(1, ...rows.map((row) => row.cacheReadTokens + row.inputTokens + row.outputTokens))\n const heightOf = (value: number): string => (peak > 0 ? Math.max(1, Math.round(value / peak * 100)) : 1) + '%'\n // 标签抽稀:列数多时每列都写会糊成一片,只保留首列、末列与等距采样\n const labelEvery = Math.max(1, Math.ceil(rows.length / 14))\n return (\n <>\n <div className={rows.length > 20 ? styles.bars + ' ' + styles.barsDense : styles.bars}>\n {rows.map((row) => {\n const rowTotal = row.cacheReadTokens + row.inputTokens + row.outputTokens\n return (\n <div\n key={row.key}\n className={styles.barColumn}\n onMouseMove={(event) => tooltip.show(event, row.tip)}\n onMouseLeave={tooltip.hide}\n >\n {rowTotal > 0 && (\n <>\n <span className={styles.segCache} style={{ height: heightOf(row.cacheReadTokens) }} />\n <span className={styles.segIn} style={{ height: heightOf(row.inputTokens) }} />\n <span className={styles.segOut} style={{ height: heightOf(row.outputTokens) }} />\n </>\n )}\n </div>\n )\n })}\n </div>\n <div className={styles.barLabels}>\n {rows.map((row, index) => (\n <span key={row.key}>{index % labelEvery === 0 || index === rows.length - 1 ? row.axisLabel : ''}</span>\n ))}\n </div>\n </>\n )\n}\n","/**\n * 环比对比:当前范围 vs 上一段等长范围。\n * 纯客户端实现 —— 复用同一个 /usage 端点按上期范围再请求一次,服务端不感知「环比」。\n * 涨跌只用中性色 + 上下箭头:用量涨不代表好、成本涨也不代表错,不引入红绿对错语义。\n */\nimport { useEffect, useMemo, useState, useSyncExternalStore } from 'react'\nimport type { ReactNode } from 'react'\nimport { loadUsage } from '../api.ts'\nimport { channelOf, costCellText } from '../channels.ts'\nimport { fmtCalls, fmtCost, fmtTokens, isoDate } from '../format.ts'\nimport { COST_SOURCE_LABELS } from '../pricing.ts'\nimport { pricingSettings } from '../pricingSettings.ts'\nimport type { Channel, DaySummary, UsageResponse } from '../types.ts'\nimport styles from '../styles/shared.module.css'\nimport trendStyles from '../styles/trend.module.css'\n\n/** 与 DetailTab 的 `RangeKey` 同形:单独声明,避免两个模块互相 import 类型。 */\nexport type TrendRangeKey = 'today' | 'week' | 'month' | 'total' | 'custom'\n\nconst DAY_MS = 86400000\n\ninterface ChangeView {\n text: string\n kind: 'up' | 'down' | 'flat' | 'none'\n /** 成本上升时用中性提示色标注(不是错误语义)。 */\n warn: boolean\n}\n\ninterface TrendRow {\n key: string\n label: string\n current: ReactNode\n previous: ReactNode\n change: ReactNode\n}\n\nconst FLAT: ChangeView = { text: '持平', kind: 'flat', warn: false }\nconst UNAVAILABLE: ChangeView = { text: '—', kind: 'none', warn: false }\n\n/** 闭区间天数,至少 1(日期键按本地日历算,与 DetailTab 的横轴口径一致)。 */\nfunction spanDaysOf(from: string, to: string): number {\n const fromTime = new Date(from + 'T00:00:00').getTime()\n const toTime = new Date(to + 'T00:00:00').getTime()\n return Math.max(1, Math.round((toTime - fromTime) / DAY_MS) + 1)\n}\n\n/** 上一段等长范围:本期首日的前一天往前推同样天数(10-07~10-13 → 09-30~10-06)。 */\nfunction previousWindowOf(from: string, to: string): { from: string; to: string } {\n const startTime = new Date(from + 'T00:00:00').getTime()\n const span = spanDaysOf(from, to)\n return { from: isoDate(new Date(startTime - span * DAY_MS)), to: isoDate(new Date(startTime - DAY_MS)) }\n}\n\n/** 展示口径 Tokens:输入 + 输出 + 缓存读(与三张统计卡、命中率公式同一口径)。 */\nfunction displayTokensOf(totals: DaySummary): number {\n return totals.inputTokens + totals.outputTokens + totals.cacheReadTokens\n}\n\n/** 命中率(%);分母为 0 时返回 null,界面显示 — 而不是 NaN。 */\nfunction hitRateOf(totals: DaySummary): number | null {\n const total = displayTokensOf(totals)\n return total > 0 ? totals.cacheReadTokens / total * 100 : null\n}\n\n/** 该期是否有任何用量:全 0 视为「无数据」,据此显示「上期无数据」而不是 0 与 −100%。 */\nfunction hasAnyData(totals: DaySummary | null): boolean {\n return totals !== null && (totals.calls > 0 || displayTokensOf(totals) > 0 || totals.cost > 0)\n}\n\n/** 环比百分比;上期为 0 时不给百分比(Infinity / NaN 不进界面)。 */\nfunction percentChangeOf(current: number, previous: number, warnOnUp: boolean): ChangeView {\n if (previous <= 0) return current <= 0 ? FLAT : { text: '上期为 0', kind: 'none', warn: false }\n const percent = (current - previous) / previous * 100\n if (Math.abs(percent) < 0.05) return FLAT\n return {\n text: (percent > 0 ? '+' : '') + percent.toFixed(1) + '%',\n kind: percent > 0 ? 'up' : 'down',\n warn: warnOnUp && percent > 0,\n }\n}\n\n/** 命中率本身是比值,涨跌按百分点(pp)计,避免「96.2% 比 94.0% 涨 2.3%」这类误读。 */\nfunction pointChangeOf(current: number, previous: number): ChangeView {\n const difference = current - previous\n if (Math.abs(difference) < 0.05) return FLAT\n return {\n text: (difference > 0 ? '+' : '') + difference.toFixed(1) + 'pp',\n kind: difference > 0 ? 'up' : 'down',\n warn: false,\n }\n}\n\n/**\n * 成本文案:订阅 / 免费 / 本地端点没有可比金额,沿用 `costCellText` 的占位文案;\n * 其余情况一律给金额(含 ¥0.00),否则「本期降到 0」会被当成不可比而丢掉 −100%。\n */\nfunction costTextOf(channel: Channel | null, cost: number): { text: string; dim: boolean; amount: boolean } {\n if (channel !== null && channel.costMode !== 'perToken' && channel.costMode !== 'unknown') {\n const cell = costCellText(channel, cost)\n return { text: cell.text, dim: cell.dim, amount: false }\n }\n return { text: fmtCost(cost), dim: false, amount: true }\n}\n\nfunction changeNodeOf(change: ChangeView): ReactNode {\n if (change.kind === 'none') return <span className={trendStyles.muted}>{change.text}</span>\n const arrow = change.kind === 'up' ? '↑' : change.kind === 'down' ? '↓' : '→'\n const tone = change.warn ? trendStyles.warn : change.kind === 'flat' ? trendStyles.flat : ''\n return <span className={tone === '' ? trendStyles.change : trendStyles.change + ' ' + tone}>{arrow} {change.text}</span>\n}\n\nexport function TrendPanel(props: {\n usage: UsageResponse\n channels: Channel[]\n range: TrendRangeKey\n bounds: { from: string; to: string }\n channelFilter: string\n}): ReactNode {\n const { usage, bounds, channelFilter } = props\n const comparable = props.range !== 'total'\n const previousWindow = useMemo(() => previousWindowOf(bounds.from, bounds.to), [bounds.from, bounds.to])\n const [previousUsage, setPreviousUsage] = useState<UsageResponse | null>(null)\n const [status, setStatus] = useState<'loading' | 'ready'>('loading')\n // 成本由服务端按计费规则算,规则一改两期就不是同一套口径,所以跟着规则重取上期\n const pricingState = useSyncExternalStore(pricingSettings.store.subscribe, pricingSettings.store.getSnapshot)\n const pricingSignature = JSON.stringify(pricingState.config)\n\n useEffect(() => {\n if (!comparable) return\n let cancelled = false\n setStatus('loading')\n void loadUsage(previousWindow.from, previousWindow.to, channelFilter).then((result) => {\n if (cancelled) return\n setPreviousUsage(result)\n setStatus('ready')\n })\n return () => { cancelled = true }\n }, [comparable, previousWindow.from, previousWindow.to, channelFilter, pricingSignature])\n\n const header = (\n <div className={trendStyles.head}>\n <span className={styles.statLabel}>环比对比 · 与上一段等长范围</span>\n <span className={trendStyles.span}>\n 本期 {bounds.from} ~ {bounds.to}\n {comparable ? ' · 上期 ' + previousWindow.from + ' ~ ' + previousWindow.to : ''}\n </span>\n </div>\n )\n\n if (!comparable) {\n return (\n <div className={styles.card + ' ' + trendStyles.panel}>\n {header}\n <div className={trendStyles.placeholder}>总计范围没有可对比的上一段</div>\n </div>\n )\n }\n\n const currentTotals = usage.totals\n const previousTotals = previousUsage?.totals ?? null\n const previousHasData = status === 'ready' && hasAnyData(previousTotals)\n const currentHasData = hasAnyData(currentTotals)\n const previousPlaceholder = status === 'loading' ? '读取中…' : previousUsage === null ? '无法获取' : '上期无数据'\n\n const currentValue = (text: string): ReactNode => <span className={trendStyles.current}>{text}</span>\n const previousValue = (text: string): ReactNode => previousHasData\n ? <span className={trendStyles.previous}>{text}</span>\n : <span className={trendStyles.muted}>{previousPlaceholder}</span>\n const changeValue = (change: ChangeView): ReactNode => previousHasData\n ? changeNodeOf(change)\n : <span className={trendStyles.muted}>—</span>\n\n const currentCalls = currentTotals?.calls ?? 0\n const previousCalls = previousTotals?.calls ?? 0\n const currentTokens = currentTotals === null ? 0 : displayTokensOf(currentTotals)\n const previousTokens = previousTotals === null ? 0 : displayTokensOf(previousTotals)\n const currentHitRate = currentTotals === null ? null : hitRateOf(currentTotals)\n const previousHitRate = previousTotals === null ? null : hitRateOf(previousTotals)\n const currentCost = currentTotals?.cost ?? 0\n const previousCost = previousTotals?.cost ?? 0\n const singleChannel = channelFilter === 'ALL' ? null : channelOf(props.channels, channelFilter)\n const currentCostText = costTextOf(singleChannel, currentCost)\n const previousCostText = costTextOf(singleChannel, previousCost)\n const costComparable = currentCostText.amount && previousCostText.amount\n\n const rows: TrendRow[] = [\n {\n key: 'calls',\n label: '调用次数',\n current: currentValue(fmtCalls(currentCalls)),\n previous: previousValue(fmtCalls(previousCalls)),\n change: changeValue(percentChangeOf(currentCalls, previousCalls, false)),\n },\n {\n key: 'tokens',\n label: 'Tokens',\n current: currentValue(fmtTokens(currentTokens)),\n previous: previousValue(fmtTokens(previousTokens)),\n change: changeValue(percentChangeOf(currentTokens, previousTokens, false)),\n },\n {\n key: 'cost',\n label: '成本',\n current: currentCostText.amount\n ? currentValue(currentCostText.text)\n : <span className={trendStyles.muted}>{currentCostText.text}</span>,\n previous: previousValue(previousCostText.text),\n change: costComparable\n ? changeValue(percentChangeOf(currentCost, previousCost, true))\n : <span className={trendStyles.muted}>不可比</span>,\n },\n {\n key: 'hitRate',\n label: '缓存命中率',\n current: currentValue(currentHitRate === null ? '—' : currentHitRate.toFixed(1) + '%'),\n previous: previousValue(previousHitRate === null ? '—' : previousHitRate.toFixed(1) + '%'),\n change: changeValue(currentHitRate !== null && previousHitRate !== null\n ? pointChangeOf(currentHitRate, previousHitRate)\n : UNAVAILABLE),\n },\n ]\n\n const notes: string[] = []\n if ((usage.sessionDates ?? []).length > 0 || (previousUsage?.sessionDates ?? []).length > 0) {\n notes.push('含会话补位数据,与台账口径不完全可比')\n }\n if (previousHasData && costComparable) {\n const currentSource = currentTotals?.costSource ?? 'none'\n const previousSource = previousTotals?.costSource ?? 'none'\n if (currentSource !== previousSource) {\n notes.push('两期成本来源不同(本期 ' + COST_SOURCE_LABELS[currentSource] + ' / 上期 ' + COST_SOURCE_LABELS[previousSource] + '),口径不完全可比')\n }\n }\n if (status === 'ready' && previousUsage === null) notes.push('上一段范围读取失败,无法对比')\n if (!currentHasData) notes.push('本期范围内无用量记录')\n notes.push('命中率的变化按百分点(pp)计,其余指标为环比百分比')\n\n return (\n <div className={styles.card + ' ' + trendStyles.panel}>\n {header}\n <table className={styles.table}>\n <thead>\n <tr>\n <th>指标</th>\n <th>本期</th>\n <th>上期</th>\n <th>变化</th>\n </tr>\n </thead>\n <tbody>\n {rows.map((row) => (\n <tr key={row.key}>\n <td>{row.label}</td>\n <td>{row.current}</td>\n <td>{row.previous}</td>\n <td>{row.change}</td>\n </tr>\n ))}\n </tbody>\n </table>\n <div className={trendStyles.notes}>\n {notes.map((note) => <div key={note} className={trendStyles.note}>{note}</div>)}\n </div>\n </div>\n )\n}\n","/**\n * 零 Token 行的统一处理。\n *\n * 只有调用次数、Token 全是 0 的行,基本都是**调用失败 / 未产生用量**的记录(本机实测:\n * key 失效的模型只有调用数、没有任何 Token),列在用量表里全是噪音 —— 总计 0、命中率 —、成本 —。\n * 四处列表(使用明细的每日细目 / 按模型 / 项目用量 / 会话用量)统一用 `dropEmptyRows` 过滤,\n * 并把隐藏条数如实告诉用户,避免「数字怎么少了」的困惑。\n */\nexport interface EmptyRowFilter<Row> {\n rows: Row[]\n /** 被隐藏的行数(Token 为 0)。 */\n hidden: number\n}\n\nexport function dropEmptyRows<Row>(rows: Row[], tokensOf: (row: Row) => number): EmptyRowFilter<Row> {\n const kept = rows.filter((row) => tokensOf(row) > 0)\n return { rows: kept, hidden: rows.length - kept.length }\n}\n\n/** 列表底部的一行小字:说明隐藏了什么、为什么。 */\nexport function hiddenEmptyRowsText(hidden: number): string {\n return '已隐藏 ' + String(hidden) + ' 行无 Token 记录(调用失败或未产生用量;调用次数仍计入合计)'\n}\n","/**\n * 每日细目:以「天」为折叠单位,展开行用原型子表格展示模型维度\n * (模型 + 调用 / 输入 / 输出 / 缓存读 / 命中率,不占主表列)。\n */\nimport { Fragment, type ReactNode } from 'react'\nimport { displayNameOf } from '../channels.ts'\nimport { fmtCalls, fmtTokens } from '../format.ts'\nimport { hiddenEmptyRowsText } from '../rows.ts'\nimport type { Channel, UsageResponse } from '../types.ts'\nimport styles from '../styles/shared.module.css'\nimport detailStyles from '../styles/detail.module.css'\n\nexport interface DetailSortState {\n key: string\n dir: 'asc' | 'desc'\n}\n\n/** 输入/输出为 0 时不再显示 `0`(全缓存命中或纯输出模型的 0 是噪音),改显示淡化的 `—`。 */\nfunction tokenCellOf(value: number): ReactNode {\n return value === 0 ? <span className={styles.dim}>—</span> : fmtTokens(value)\n}\n\ninterface ModelRow {\n period: string\n model: string\n provider: string\n calls: number\n inputTokens: number\n outputTokens: number\n cacheReadTokens: number\n cost: number\n totalTokens: number\n}\n\ninterface PeriodRow {\n period: string\n calls: number\n inputTokens: number\n outputTokens: number\n cacheReadTokens: number\n cost: number\n totalTokens: number\n}\n\nfunction hitRateOf(cacheReadTokens: number, inputTokens: number, outputTokens: number): string {\n const total = inputTokens + outputTokens + cacheReadTokens\n if (total <= 0) return '—'\n return (cacheReadTokens / total * 100).toFixed(1) + '%'\n}\n\nconst COMPARERS: Record<string, (first: PeriodRow, second: PeriodRow) => number> = {\n period: (first, second) => (first.period < second.period ? -1 : first.period > second.period ? 1 : 0),\n total: (first, second) => first.totalTokens - second.totalTokens,\n calls: (first, second) => first.calls - second.calls,\n input: (first, second) => first.inputTokens - second.inputTokens,\n output: (first, second) => first.outputTokens - second.outputTokens,\n cacheRead: (first, second) => first.cacheReadTokens - second.cacheReadTokens,\n hit: (first, second) => {\n const firstTotal = first.inputTokens + first.outputTokens + first.cacheReadTokens\n const secondTotal = second.inputTokens + second.outputTokens + second.cacheReadTokens\n return (firstTotal > 0 ? first.cacheReadTokens / firstTotal : -1) - (secondTotal > 0 ? second.cacheReadTokens / secondTotal : -1)\n },\n cost: (first, second) => first.cost - second.cost,\n}\n\nexport function DailyDetailTable(props: {\n usage: UsageResponse\n channels: Channel[]\n channelFilter: string\n expandedPeriods: Record<string, boolean>\n onTogglePeriod: (periodKey: string) => void\n sort: DetailSortState\n onSort: (sort: DetailSortState) => void\n}): ReactNode {\n const { usage, channels, channelFilter, expandedPeriods, onTogglePeriod, sort, onSort } = props\n const modelRows: ModelRow[] = []\n for (const day of usage.days) {\n for (const model of day.models) {\n const totalTokens = model.inputTokens + model.outputTokens + model.cacheReadTokens\n modelRows.push({\n period: day.date, model: model.model, provider: model.provider, calls: model.calls,\n inputTokens: model.inputTokens, outputTokens: model.outputTokens, cacheReadTokens: model.cacheReadTokens,\n cost: model.cost, totalTokens,\n })\n }\n }\n const aggregates = new Map<string, PeriodRow>()\n for (const row of modelRows) {\n const bucket = aggregates.get(row.period)\n if (bucket === undefined) {\n aggregates.set(row.period, {\n period: row.period, calls: row.calls, inputTokens: row.inputTokens, outputTokens: row.outputTokens,\n cacheReadTokens: row.cacheReadTokens, cost: row.cost, totalTokens: row.totalTokens,\n })\n } else {\n bucket.calls += row.calls\n bucket.inputTokens += row.inputTokens\n bucket.outputTokens += row.outputTokens\n bucket.cacheReadTokens += row.cacheReadTokens\n bucket.cost += row.cost\n bucket.totalTokens += row.totalTokens\n }\n }\n const comparer = COMPARERS[sort.key] ?? COMPARERS.period\n // 全天零 Token(只有失败调用)的日子不展示:总计划 0、命中率与成本都是空值,只是噪音\n const nonEmpty = [...aggregates.values()].filter((entry) => entry.totalTokens > 0)\n const hiddenEmpty = aggregates.size - nonEmpty.length\n const ordered = nonEmpty.sort((first, second) => {\n const compared = comparer(first, second)\n return sort.dir === 'asc' ? compared : -compared\n })\n\n const header = (key: string, label: string): ReactNode => {\n const isActive = sort.key === key\n return (\n <th\n className={isActive ? styles.sortActive : styles.sortable}\n onClick={() => onSort(isActive ? { key, dir: sort.dir === 'asc' ? 'desc' : 'asc' } : { key, dir: 'desc' })}\n >\n {label}<span className={styles.sortArrow}>{isActive ? (sort.dir === 'asc' ? '▲' : '▼') : '↕'}</span>\n </th>\n )\n }\n\n const totals = usage.totals\n const totalTokens = totals === null ? 0 : totals.inputTokens + totals.outputTokens + totals.cacheReadTokens\n const periodCount = ordered.length\n\n if (periodCount === 0) {\n return (\n <div>\n <div className={styles.blockLabel}>每日细目</div>\n <div className={styles.empty}>所选范围内无用量记录</div>\n </div>\n )\n }\n\n return (\n <div>\n <div className={styles.blockLabel}>每日细目</div>\n <table className={styles.table}>\n <thead>\n <tr>\n {header('period', '日期')}\n {header('total', '总计')}\n {header('calls', '调用')}\n {header('input', '输入')}\n {header('output', '输出')}\n {header('cacheRead', '缓存读')}\n {header('hit', '命中率')}\n </tr>\n </thead>\n <tbody>\n {ordered.map((period) => {\n const modelsInPeriod = modelRows\n .filter((row) => row.period === period.period)\n .filter((row) => row.totalTokens > 0)\n .sort((first, second) => second.totalTokens - first.totalTokens)\n const expandable = modelsInPeriod.length > 1\n const isOpen = expandable && expandedPeriods[period.period] === true\n return (\n <Fragment key={period.period}>\n <tr\n className={expandable ? styles.clickable : ''}\n onClick={expandable ? () => onTogglePeriod(period.period) : undefined}\n >\n <td>\n {expandable && <span className={detailStyles.toggleArrow}>{isOpen ? '▼' : '▶'}</span>}\n {period.period}\n </td>\n <td>{fmtTokens(period.totalTokens)}</td>\n <td>{fmtCalls(period.calls)}</td>\n <td>{tokenCellOf(period.inputTokens)}</td>\n <td>{tokenCellOf(period.outputTokens)}</td>\n <td>{fmtTokens(period.cacheReadTokens)}</td>\n <td>{hitRateOf(period.cacheReadTokens, period.inputTokens, period.outputTokens)}</td>\n </tr>\n {isOpen && (\n <tr>\n <td className={detailStyles.subRowCell} colSpan={7}>\n <div className={detailStyles.subHead}>\n <span />\n <span className={detailStyles.subNumber}>调用</span>\n <span className={detailStyles.subNumber}>输入</span>\n <span className={detailStyles.subNumber}>输出</span>\n <span className={detailStyles.subNumber}>缓存读</span>\n <span className={detailStyles.subNumber}>命中率</span>\n </div>\n {modelsInPeriod.map((row) => (\n <div className={detailStyles.subRow} key={row.period + '|' + row.model + '|' + row.provider}>\n <span className={detailStyles.subName}>\n <span className={detailStyles.subModel}>{row.model}</span>\n {channelFilter === 'ALL' && <span className={detailStyles.subChannel}>{displayNameOf(channels, row.provider)}</span>}\n </span>\n <span className={detailStyles.subNumber}>{fmtCalls(row.calls)}</span>\n <span className={detailStyles.subNumber}>{tokenCellOf(row.inputTokens)}</span>\n <span className={detailStyles.subNumber}>{tokenCellOf(row.outputTokens)}</span>\n <span className={detailStyles.subNumber}>{fmtTokens(row.cacheReadTokens)}</span>\n <span className={detailStyles.subNumber}>{hitRateOf(row.cacheReadTokens, row.inputTokens, row.outputTokens)}</span>\n </div>\n ))}\n </td>\n </tr>\n )}\n </Fragment>\n )\n })}\n <tr className={styles.total}>\n <td>合计</td>\n <td>{fmtTokens(totalTokens)}</td>\n <td>{fmtCalls(totals?.calls ?? 0)}</td>\n <td>{fmtTokens(totals?.inputTokens ?? 0)}</td>\n <td>{fmtTokens(totals?.outputTokens ?? 0)}</td>\n <td>{fmtTokens(totals?.cacheReadTokens ?? 0)}</td>\n <td>{hitRateOf(totals?.cacheReadTokens ?? 0, totals?.inputTokens ?? 0, totals?.outputTokens ?? 0)}</td>\n </tr>\n </tbody>\n </table>\n {hiddenEmpty > 0 && <div className={styles.statExtra}>{hiddenEmptyRowsText(hiddenEmpty)}</div>}\n </div>\n )\n}\n","/** 使用明细:范围切换 + 三张统计卡 + 占比条 + 通道筛选 + 按天/按小时图表 + 每日细目。 */\nimport type { ReactNode } from 'react'\nimport { channelColorOf, channelOf, costCellText, displayNameOf, showsAmount, statusColorOf } from '../channels.ts'\nimport { fmtCalls, fmtCost, fmtShortDate, fmtTokens, isoDate } from '../format.ts'\nimport { CSV_MIME, JSON_MIME, downloadFile, exportFileName, toCsv, toJson, type ExportColumn } from '../export.ts'\nimport type { Channel, ChannelDailySummary, DaySummary, UsageResponse } from '../types.ts'\nimport { TipDivider, TipRow, TipSub, TipTitle, type TooltipApi } from '../tooltip.tsx'\nimport { ShareBar } from '../components/ShareBar.tsx'\nimport { CostSourceChip } from '../components/CostSourceChip.tsx'\nimport { StatCard } from '../components/StatCard.tsx'\nimport { TokenBars, type TokenBarRow } from '../components/TokenBars.tsx'\nimport { TrendPanel } from '../components/TrendPanel.tsx'\nimport { DailyDetailTable, type DetailSortState } from '../components/DailyDetailTable.tsx'\nimport styles from '../styles/shared.module.css'\nimport detailStyles from '../styles/detail.module.css'\nimport exportStyles from '../styles/export.module.css'\n\nexport type RangeKey = 'today' | 'week' | 'month' | 'total' | 'custom'\n\nconst RANGE_TABS: Array<[RangeKey, string]> = [\n ['today', '今日'], ['week', '周'], ['month', '月'], ['total', '总计'], ['custom', '自定义'],\n]\n\n/** 图表最多铺开的列数:超过这个跨度的范围按天全画会挤成一团。 */\nconst MAX_AXIS_DAYS = 366\n\n/** 导出列:命中率与成本给数值(不带单位),方便在表格里继续算。 */\nconst EXPORT_COLUMNS: Array<ExportColumn<ChannelDailySummary>> = [\n { key: 'date', label: '日期', value: (row) => row.date },\n { key: 'calls', label: '调用', value: (row) => row.calls },\n { key: 'inputTokens', label: '输入', value: (row) => row.inputTokens },\n { key: 'outputTokens', label: '输出', value: (row) => row.outputTokens },\n { key: 'cacheReadTokens', label: '缓存读', value: (row) => row.cacheReadTokens },\n { key: 'cacheHitRate', label: '命中率(%)', value: (row) => hitRateValueOf(row) },\n { key: 'cost', label: '成本(元)', value: (row) => row.cost },\n]\n\n/** 命中率数值(导出用;界面上的带 % 文本由 `hitRateOf` 生成)。 */\nfunction hitRateValueOf(row: ChannelDailySummary): number | null {\n const total = row.inputTokens + row.outputTokens + row.cacheReadTokens\n return total > 0 ? Math.round(row.cacheReadTokens / total * 1000) / 10 : null\n}\n\nfunction hitRateOf(cacheReadTokens: number, inputTokens: number, outputTokens: number): string {\n const total = inputTokens + outputTokens + cacheReadTokens\n return total > 0 ? (cacheReadTokens / total * 100).toFixed(1) + '%' : '—'\n}\n\nfunction daysBetween(from: string, to: string): number {\n const fromTime = new Date(from + 'T00:00:00').getTime()\n const toTime = new Date(to + 'T00:00:00').getTime()\n return Math.max(1, Math.round((toTime - fromTime) / 86400000) + 1)\n}\n\n/** 范围内每一天的日期键(无数据的日子也要出现在横轴上)。 */\nfunction dateKeysOfRange(from: string, to: string): string[] {\n const start = new Date(from + 'T00:00:00').getTime()\n const total = Math.min(daysBetween(from, to), MAX_AXIS_DAYS)\n const keys: string[] = []\n for (let offset = 0; offset < total; offset += 1) keys.push(isoDate(new Date(start + offset * 86400000)))\n return keys\n}\n\nexport function DetailTab(props: {\n usage: UsageResponse | null\n channels: Channel[]\n range: RangeKey\n onRange: (value: RangeKey) => void\n customFrom: string\n onCustomFrom: (value: string) => void\n customTo: string\n onCustomTo: (value: string) => void\n channelFilter: string\n onChannelFilter: (value: string) => void\n expandedPeriods: Record<string, boolean>\n onTogglePeriod: (periodKey: string) => void\n sort: DetailSortState\n onSort: (sort: DetailSortState) => void\n bounds: { from: string; to: string }\n tooltip: TooltipApi\n}): ReactNode {\n const { usage, channels, bounds, tooltip, channelFilter } = props\n if (usage === null) return <div className={styles.empty}>台账读取中或不可用…</div>\n\n const totals = usage.totals\n const safeTotals: DaySummary = totals ?? {\n date: '', calls: 0, inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, reasoningTokens: 0, cost: 0,\n }\n const totalTokens = safeTotals.inputTokens + safeTotals.outputTokens + safeTotals.cacheReadTokens\n const hitRate = hitRateOf(safeTotals.cacheReadTokens, safeTotals.inputTokens, safeTotals.outputTokens)\n /** 缓存读在展示口径 Tokens 里的占比;分母为 0 时不给数字(避免显示 0% 误导)。 */\n const cacheReadShare = totalTokens > 0 ? (safeTotals.cacheReadTokens / totalTokens * 100).toFixed(1) + '%' : null\n /** 范围内「有用量」的天数:日均 Tokens 的分母(拿日历天数去除会把空闲日算成用量偏低)。 */\n const activeDays = usage.days.filter((day) => day.inputTokens + day.outputTokens + day.cacheReadTokens > 0).length\n const singleChannel = channelFilter === 'ALL' ? null : channelOf(channels, channelFilter)\n const costCell = costCellText(singleChannel, safeTotals.cost)\n const singleDay = bounds.from === bounds.to\n const rangeDays = Math.min(daysBetween(bounds.from, bounds.to), MAX_AXIS_DAYS)\n\n /** 导出当前范围与通道筛选后的每日明细(按日期升序,不跟随表格排序)。 */\n const exportDaily = (format: 'csv' | 'json'): void => {\n if (format === 'csv') downloadFile(exportFileName('daily', 'csv'), toCsv(usage.days, EXPORT_COLUMNS), CSV_MIME)\n else downloadFile(exportFileName('daily', 'json'), toJson(usage.days), JSON_MIME)\n }\n\n const activeProviders = new Set<string>()\n for (const day of usage.days) {\n for (const model of day.models) {\n if (model.inputTokens + model.outputTokens + model.cacheReadTokens > 0) activeProviders.add(model.provider)\n }\n }\n\n const hourlyRows: TokenBarRow[] = []\n if (singleDay && usage.hours !== null) {\n usage.hours.forEach((slot, hour) => {\n const slotTokens = slot.buckets.inputTokens + slot.buckets.outputTokens + slot.buckets.cacheReadTokens\n hourlyRows.push({\n key: String(hour),\n axisLabel: String(hour).padStart(2, '0') + ':00',\n cacheReadTokens: slot.buckets.cacheReadTokens,\n inputTokens: slot.buckets.inputTokens,\n outputTokens: slot.buckets.outputTokens,\n tip: (\n <>\n <TipTitle>{bounds.from + ' ' + String(hour).padStart(2, '0') + ':00'}</TipTitle>\n {slot.calls === 0 && slotTokens === 0\n ? <TipSub>该小时无用量记录</TipSub>\n : (\n <>\n <TipSub>调用 <b>{fmtCalls(slot.calls)}</b> · Tokens <b>{fmtTokens(slotTokens)}</b></TipSub>\n <TipRow color=\"var(--dsw-alias-state-accent-primary, #5b8cff)\" label=\"输入\" amount={fmtTokens(slot.buckets.inputTokens)} />\n <TipRow color=\"var(--dsw-alias-state-business-primary, #9a7bff)\" label=\"输出\" amount={fmtTokens(slot.buckets.outputTokens)} />\n <TipRow\n color=\"var(--dsw-alias-state-accent-tertiary, rgba(91,140,255,.28))\"\n label=\"缓存读\"\n amount={fmtTokens(slot.buckets.cacheReadTokens)}\n rate={hitRateOf(slot.buckets.cacheReadTokens, slot.buckets.inputTokens, slot.buckets.outputTokens)}\n />\n </>\n )}\n </>\n ),\n })\n })\n }\n\n // 横轴铺满所选范围:没有调用的日子留空位(不画柱子)\n const sessionDates = new Set(usage.sessionDates ?? [])\n const dayByDate = new Map<string, ChannelDailySummary>(usage.days.map((day) => [day.date, day]))\n const dailyRows: TokenBarRow[] = dateKeysOfRange(bounds.from, bounds.to).map((dateKey) => {\n const day = dayByDate.get(dateKey)\n if (day === undefined) {\n return {\n key: dateKey,\n axisLabel: fmtShortDate(dateKey),\n cacheReadTokens: 0,\n inputTokens: 0,\n outputTokens: 0,\n tip: (\n <>\n <TipTitle>{dateKey}</TipTitle>\n <TipSub>当日无用量记录</TipSub>\n </>\n ),\n }\n }\n const dayTotal = day.inputTokens + day.outputTokens + day.cacheReadTokens\n const fromSession = sessionDates.has(day.date)\n const topModels = [...day.models]\n .sort((first, second) => (second.inputTokens + second.outputTokens + second.cacheReadTokens) - (first.inputTokens + first.outputTokens + first.cacheReadTokens))\n .slice(0, 5)\n return {\n key: day.date,\n axisLabel: fmtShortDate(day.date),\n cacheReadTokens: day.cacheReadTokens,\n inputTokens: day.inputTokens,\n outputTokens: day.outputTokens,\n tip: (\n <>\n <TipTitle>{day.date}</TipTitle>\n <TipSub>调用 <b>{fmtCalls(day.calls)}</b> · Tokens <b>{fmtTokens(dayTotal)}</b></TipSub>\n <TipRow color=\"var(--dsw-alias-state-accent-primary, #5b8cff)\" label=\"输入\" amount={fmtTokens(day.inputTokens)} />\n <TipRow color=\"var(--dsw-alias-state-business-primary, #9a7bff)\" label=\"输出\" amount={fmtTokens(day.outputTokens)} />\n <TipRow\n color=\"var(--dsw-alias-state-accent-tertiary, rgba(91,140,255,.28))\"\n label=\"缓存读\"\n amount={fmtTokens(day.cacheReadTokens)}\n rate={hitRateOf(day.cacheReadTokens, day.inputTokens, day.outputTokens)}\n />\n <TipDivider>\n <span>成本</span>\n <b>{day.cost > 0 ? fmtCost(day.cost) : '—'}</b>\n </TipDivider>\n {fromSession && <TipSub>来源:会话事件(该日台账无记录,不含官方成本)</TipSub>}\n {topModels.map((model) => (\n <TipRow\n key={model.provider + '|' + model.model}\n label={<>{model.model}<span className={styles.dim}> · {displayNameOf(channels, model.provider)}</span></>}\n amount={fmtTokens(model.inputTokens + model.outputTokens + model.cacheReadTokens)}\n />\n ))}\n </>\n ),\n }\n })\n\n const useHourAxis = singleDay && usage.hours !== null\n const chartRows = useHourAxis ? hourlyRows : dailyRows\n const chartTitle = useHourAxis ? '按小时 Tokens(' + bounds.from + ')' : '按天 Tokens(' + rangeDays + ' 天)'\n\n return (\n <div>\n <div className={detailStyles.rangeBar}>\n <div className={detailStyles.rangeLeft}>\n <div className={detailStyles.rangeTabs}>\n {RANGE_TABS.map(([key, label]) => (\n <button key={key} className={props.range === key ? detailStyles.active : ''} onClick={() => props.onRange(key)}>{label}</button>\n ))}\n </div>\n {props.range === 'custom' && (\n <>\n <input type=\"date\" className={detailStyles.rangeInput} value={props.customFrom} onChange={(event) => props.onCustomFrom(event.target.value)} />\n <span className={styles.dim}>至</span>\n <input type=\"date\" className={detailStyles.rangeInput} value={props.customTo} onChange={(event) => props.onCustomTo(event.target.value)} />\n </>\n )}\n </div>\n <span className={exportStyles.exportGroup}>\n <button className={exportStyles.exportBtn} disabled={usage.days.length === 0} onClick={() => exportDaily('csv')}>导出 CSV</button>\n <button className={exportStyles.exportBtn} disabled={usage.days.length === 0} onClick={() => exportDaily('json')}>导出 JSON</button>\n </span>\n </div>\n\n <div className={styles.cardGrid6}>\n <StatCard label=\"调用次数\" value={fmtCalls(safeTotals.calls)} extra={activeProviders.size + ' 个通道有用量'} />\n <StatCard\n label=\"Tokens\"\n value={fmtTokens(totalTokens)}\n extra={'输入 ' + fmtTokens(safeTotals.inputTokens) + ' · 输出 ' + fmtTokens(safeTotals.outputTokens)}\n />\n <StatCard\n label=\"缓存读\"\n value={fmtTokens(safeTotals.cacheReadTokens)}\n extra={cacheReadShare === null ? '与上方 Tokens 同口径' : '占 Tokens 的 ' + cacheReadShare}\n />\n <StatCard label=\"缓存命中率\" value={hitRate} extra=\"缓存读 ÷(输入 + 输出 + 缓存读)\" />\n <StatCard\n label=\"日均 Tokens\"\n value={activeDays === 0 ? '—' : fmtTokens(Math.round(totalTokens / activeDays))}\n extra={'范围内 ' + String(activeDays) + ' 天有用量'}\n />\n <StatCard\n label=\"成本\"\n value={costCell.dim\n ? <span className={styles.dim}>{costCell.text}</span>\n : <>{costCell.text}{showsAmount(costCell) && <CostSourceChip source={safeTotals.costSource} />}</>}\n extra=\"按所选范围与筛选聚合\"\n />\n </div>\n\n <TrendPanel usage={usage} channels={channels} range={props.range} bounds={bounds} channelFilter={channelFilter} />\n\n <ShareBar usage={usage} totalTokens={totalTokens} channelFilter={channelFilter} channels={channels} tooltip={tooltip} />\n\n <div className={styles.chipRow} style={{ marginTop: 14 }}>\n <button className={channelFilter === 'ALL' ? styles.chip + ' ' + styles.active : styles.chip} onClick={() => props.onChannelFilter('ALL')}>\n <span className={styles.statusDot} style={{ background: 'var(--dsw-alias-state-accent-primary, #5b8cff)' }} />全部通道\n </button>\n {channels.map((channel) => (\n <button\n key={channel.provider}\n className={channelFilter === channel.provider ? styles.chip + ' ' + styles.active : styles.chip}\n onClick={() => props.onChannelFilter(channel.provider)}\n >\n <span className={styles.statusDot} style={{ background: statusColorOf(channel.status) }} />{channel.displayName}\n </button>\n ))}\n </div>\n\n <div className={styles.card}>\n <div className={detailStyles.chartTitle}>\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>\n {singleChannel === null\n ? <b>全部通道</b>\n : (\n <>\n <span className={styles.statusDot} style={{ background: statusColorOf(singleChannel.status) }} />\n <b>{singleChannel.displayName}</b>\n </>\n )}\n </span>\n <span className={styles.dim} style={{ fontSize: 11.5 }}>{bounds.from} ~ {bounds.to}</span>\n </div>\n <div className={detailStyles.chartTitle} style={{ marginTop: 10 }}>\n <span className={styles.statLabel}>{chartTitle}</span>\n <span className={styles.legend}>\n <span><i style={{ background: 'rgba(91,140,255,.28)' }} />缓存读</span>\n <span><i style={{ background: 'var(--dsw-alias-state-accent-primary, #5b8cff)' }} />输入</span>\n <span><i style={{ background: 'var(--dsw-alias-state-business-primary, #9a7bff)' }} />输出</span>\n </span>\n </div>\n {chartRows.length === 0\n ? <div className={styles.empty}>所选范围内无用量记录</div>\n : <TokenBars rows={chartRows} tooltip={tooltip} />}\n {useHourAxis && <div className={styles.statExtra}>按小时数据来自本地会话事件,不含成本</div>}\n </div>\n\n <DailyDetailTable\n usage={usage}\n channels={channels}\n channelFilter={channelFilter}\n expandedPeriods={props.expandedPeriods}\n onTogglePeriod={props.onTogglePeriod}\n sort={props.sort}\n onSort={props.onSort}\n />\n </div>\n )\n}\n\n/** 通道颜色(供外部复用,避免各 Tab 重复实现)。 */\nexport { channelColorOf }\n","/** 按模型:`provider + model` 聚合的用量与估算成本(数据来自宿主会话事件折叠)。 */\nimport { useMemo, useState, type ReactNode } from 'react'\nimport { failureReasonOf } from '../api.ts'\nimport { channelColorOf, channelOf, costCellText, showsAmount } from '../channels.ts'\nimport { fmtCalls, fmtDateTime, fmtRelative, fmtTokens } from '../format.ts'\nimport { CSV_MIME, JSON_MIME, downloadFile, exportFileName, toCsv, toJson, type ExportColumn } from '../export.ts'\nimport { dropEmptyRows, hiddenEmptyRowsText } from '../rows.ts'\nimport { CostSourceChip } from '../components/CostSourceChip.tsx'\nimport { COST_SOURCE_LABELS } from '../pricing.ts'\nimport type { Channel, ModelAggregateRow, ModelsResponse } from '../types.ts'\nimport styles from '../styles/shared.module.css'\nimport listStyles from '../styles/lists.module.css'\nimport exportStyles from '../styles/export.module.css'\n\nconst MODELS_PATH = '/dsh-key-usage/models'\n\ntype SortKey = 'tokensDesc' | 'callsDesc' | 'costDesc' | 'recent'\n\n/** 导出列:取原始数值(金额、命中率不带单位),方便直接进表格做计算。 */\nconst EXPORT_COLUMNS: Array<ExportColumn<ModelAggregateRow>> = [\n { key: 'provider', label: '通道 id', value: (row) => row.provider },\n { key: 'providerLabel', label: '通道', value: (row) => row.providerLabel },\n { key: 'model', label: '模型', value: (row) => row.model },\n { key: 'calls', label: '调用', value: (row) => row.calls },\n { key: 'tokens', label: 'Tokens', value: (row) => row.tokens },\n { key: 'inputTokens', label: '输入', value: (row) => row.buckets.inputTokens },\n { key: 'outputTokens', label: '输出', value: (row) => row.buckets.outputTokens },\n { key: 'cacheReadTokens', label: '缓存读', value: (row) => row.buckets.cacheReadTokens },\n { key: 'cacheHitRate', label: '命中率(%)', value: (row) => row.cacheHitRate },\n { key: 'cost', label: '成本(元)', value: (row) => row.cost },\n { key: 'costSource', label: '成本来源', value: (row) => row.costSource === undefined ? null : COST_SOURCE_LABELS[row.costSource] },\n { key: 'costMode', label: '计费模式', value: (row) => row.costMode },\n { key: 'sessionCount', label: '会话数', value: (row) => row.sessionCount },\n { key: 'lastTime', label: '最近活跃', value: (row) => fmtDateTime(row.lastTime) },\n]\n\nexport function ModelsTab(props: { data: ModelsResponse | null; channels: Channel[] }): ReactNode {\n const [query, setQuery] = useState('')\n const [channelFilter, setChannelFilter] = useState('ALL')\n const [sortKey, setSortKey] = useState<SortKey>('tokensDesc')\n const [nowMs] = useState(() => Date.now())\n const rows = props.data?.rows ?? []\n\n const visible = useMemo(() => {\n const keyword = query.trim().toLowerCase()\n const filtered = dropEmptyRows(rows, (row) => row.tokens).rows.filter((row) => {\n const haystack = (row.model + ' ' + row.provider + ' ' + row.providerLabel).toLowerCase()\n const matchesQuery = keyword === '' || haystack.includes(keyword)\n const matchesChannel = channelFilter === 'ALL' || row.provider === channelFilter\n return matchesQuery && matchesChannel\n })\n const sorters: Record<SortKey, (first: ModelAggregateRow, second: ModelAggregateRow) => number> = {\n tokensDesc: (first, second) => second.tokens - first.tokens,\n callsDesc: (first, second) => second.calls - first.calls,\n costDesc: (first, second) => (second.cost ?? 0) - (first.cost ?? 0),\n recent: (first, second) => (second.lastTime ?? 0) - (first.lastTime ?? 0),\n }\n return [...filtered].sort(sorters[sortKey])\n }, [rows, query, channelFilter, sortKey])\n\n const totalTokens = rows.reduce((total, row) => total + row.tokens, 0)\n // 零 Token 的模型(多为调用失败)不展示,条数如实告知\n const hiddenEmpty = dropEmptyRows(rows, (row) => row.tokens).hidden\n\n /** 导出当前筛选与排序后的行(JSON 取整行,CSV 按固定列映射)。 */\n const exportRows = (format: 'csv' | 'json'): void => {\n if (format === 'csv') downloadFile(exportFileName('models', 'csv'), toCsv(visible, EXPORT_COLUMNS), CSV_MIME)\n else downloadFile(exportFileName('models', 'json'), toJson(visible), JSON_MIME)\n }\n\n if (props.data === null) {\n const reason = failureReasonOf(MODELS_PATH)\n return <div className={styles.empty}>{reason === null ? '按模型数据读取中…' : '按模型数据不可用:' + reason}</div>\n }\n\n return (\n <div>\n {props.data.coverage.status !== 'complete' && (\n <div className={styles.warning}>{coverageText(props.data.coverage.status, props.data.coverage.skippedSessions)}</div>\n )}\n <div className={listStyles.filterBar}>\n <input className={listStyles.searchInput} placeholder=\"搜索模型名、通道…\" value={query} onChange={(event) => setQuery(event.target.value)} />\n <select className={listStyles.filterSelect} value={channelFilter} onChange={(event) => setChannelFilter(event.target.value)}>\n <option value=\"ALL\">全部通道</option>\n {props.channels.map((channel) => <option key={channel.provider} value={channel.provider}>{channel.displayName}</option>)}\n </select>\n <select className={listStyles.filterSelect} value={sortKey} onChange={(event) => setSortKey(event.target.value as SortKey)}>\n <option value=\"tokensDesc\">Tokens 最多</option>\n <option value=\"callsDesc\">调用最多</option>\n <option value=\"costDesc\">成本最高</option>\n <option value=\"recent\">最近活跃</option>\n </select>\n <span className={exportStyles.exportGroup}>\n <button className={exportStyles.exportBtn} disabled={visible.length === 0} onClick={() => exportRows('csv')}>导出 CSV</button>\n <button className={exportStyles.exportBtn} disabled={visible.length === 0} onClick={() => exportRows('json')}>导出 JSON</button>\n </span>\n </div>\n\n <table className={styles.table + ' ' + listStyles.modelTable}>\n <thead>\n <tr><th>模型</th><th>调用</th><th>Tokens</th><th>占比</th><th>命中率</th><th>成本</th><th>最近活跃</th></tr>\n </thead>\n <tbody>\n {visible.map((row) => {\n const percent = totalTokens > 0 ? Math.round(row.tokens / totalTokens * 100) : 0\n const channel = channelOf(props.channels, row.provider)\n const costCell = costCellText(channel, row.cost ?? 0)\n return (\n <tr key={row.provider + '|' + row.model}>\n <td>\n <div className={listStyles.listTitle}>\n <div>\n <div className={listStyles.listMain}>{row.model}</div>\n <div className={listStyles.listSub}>\n <span\n className={styles.statusDot}\n style={{ background: channelColorOf(props.channels, row.provider), marginRight: 4 }}\n />\n {row.providerLabel} · {row.sessionCount} 个会话\n </div>\n </div>\n </div>\n </td>\n <td>{fmtCalls(row.calls)}</td>\n <td>{fmtTokens(row.tokens)}</td>\n <td>\n <span className={listStyles.listBar}>\n <i style={{ width: Math.max(2, percent) + '%', background: channelColorOf(props.channels, row.provider) }} />\n </span> {percent}%\n </td>\n <td>{row.cacheHitRate === null ? '—' : row.cacheHitRate.toFixed(1) + '%'}</td>\n <td>{row.cost === null || channel?.costMode !== 'perToken'\n ? <span className={styles.dim}>{costCell.text}</span>\n : <>{costCell.text}{showsAmount(costCell) && <CostSourceChip source={row.costSource} />}</>}</td>\n <td>{fmtRelative(row.lastTime, nowMs)}</td>\n </tr>\n )\n })}\n {visible.length === 0 && <tr><td colSpan={7} className={styles.empty}>没有符合条件的模型</td></tr>}\n </tbody>\n </table>\n {hiddenEmpty > 0 && <div className={styles.statExtra}>{hiddenEmptyRowsText(hiddenEmpty)}</div>}\n <div className={styles.statExtra}>\n 模型用量按宿主会话事件折叠(每个结算样本计一次调用);成本按台账模型均价估算\n {props.data.priced ? '' : '(台账无成本数据,暂不可估)'};命中率 = 缓存读 ÷(输入 + 输出 + 缓存读)\n </div>\n </div>\n )\n}\n\nfunction coverageText(status: string, skipped: number): string {\n if (status === 'unavailable') return '会话数据不可用(宿主未提供会话服务或全部读取失败)'\n return '会话数据不完整:' + String(skipped) + ' 个会话读取失败,未计入统计'\n}\n","/** 项目用量:按会话工作目录聚合(数据来自宿主会话事件折叠)。 */\nimport { useMemo, useState, type ReactNode } from 'react'\nimport { channelColorOf, channelOf, costCellText, displayNameOf, showsAmount } from '../channels.ts'\nimport { fmtCalls, fmtDateTime, fmtRelative, fmtTokens } from '../format.ts'\nimport { CSV_MIME, JSON_MIME, downloadFile, exportFileName, toCsv, toJson, type ExportColumn } from '../export.ts'\nimport { dropEmptyRows, hiddenEmptyRowsText } from '../rows.ts'\nimport { CostSourceChip } from '../components/CostSourceChip.tsx'\nimport { COST_SOURCE_LABELS } from '../pricing.ts'\nimport type { Channel, ProjectRow, ProjectsResponse } from '../types.ts'\nimport styles from '../styles/shared.module.css'\nimport listStyles from '../styles/lists.module.css'\nimport exportStyles from '../styles/export.module.css'\n\ntype SortKey = 'recent' | 'tokensDesc' | 'tokensAsc' | 'callsDesc'\n\n/** 导出列:成本与命中率都给原始数值,方便在表格里继续算。 */\nconst EXPORT_COLUMNS: Array<ExportColumn<ProjectRow>> = [\n { key: 'workspace', label: '项目路径', value: (row) => row.workspace },\n { key: 'dominantProvider', label: '主要通道', value: (row) => row.dominantProvider },\n { key: 'calls', label: '调用', value: (row) => row.calls },\n { key: 'tokens', label: 'Tokens', value: (row) => row.tokens },\n { key: 'cacheHitRate', label: '命中率(%)', value: (row) => row.cacheHitRate },\n { key: 'cost', label: '成本(元)', value: (row) => row.cost },\n { key: 'costSource', label: '成本来源', value: (row) => row.costSource === undefined ? null : COST_SOURCE_LABELS[row.costSource] },\n { key: 'sessionCount', label: '会话数', value: (row) => row.sessionCount },\n { key: 'archivedSessionCount', label: '已归档会话数', value: (row) => row.archivedSessionCount },\n { key: 'lastTime', label: '最近活跃', value: (row) => fmtDateTime(row.lastTime) },\n]\n\nexport function ProjectsTab(props: { data: ProjectsResponse | null; channels: Channel[] }): ReactNode {\n const [query, setQuery] = useState('')\n const [channelFilter, setChannelFilter] = useState('ALL')\n const [sortKey, setSortKey] = useState<SortKey>('recent')\n const [nowMs] = useState(() => Date.now())\n const rows = props.data?.rows ?? []\n\n const visible = useMemo(() => {\n const keyword = query.trim().toLowerCase()\n const filtered = dropEmptyRows(rows, (row) => row.tokens).rows.filter((row) => {\n const matchesQuery = keyword === '' || row.workspace.toLowerCase().includes(keyword)\n const matchesChannel = channelFilter === 'ALL' || row.providers[channelFilter] !== undefined\n return matchesQuery && matchesChannel\n })\n const sorters: Record<SortKey, (first: ProjectRow, second: ProjectRow) => number> = {\n recent: (first, second) => (second.lastTime ?? 0) - (first.lastTime ?? 0),\n tokensDesc: (first, second) => second.tokens - first.tokens,\n tokensAsc: (first, second) => first.tokens - second.tokens,\n callsDesc: (first, second) => second.calls - first.calls,\n }\n return [...filtered].sort(sorters[sortKey])\n }, [rows, query, channelFilter, sortKey])\n\n const totalTokens = rows.reduce((total, row) => total + row.tokens, 0)\n // 零 Token 的项目(多为调用失败)不展示,条数如实告知\n const hiddenEmpty = dropEmptyRows(rows, (row) => row.tokens).hidden\n\n /** 导出当前筛选与排序后的项目行(JSON 取整行,CSV 按固定列映射)。 */\n const exportRows = (format: 'csv' | 'json'): void => {\n if (format === 'csv') downloadFile(exportFileName('projects', 'csv'), toCsv(visible, EXPORT_COLUMNS), CSV_MIME)\n else downloadFile(exportFileName('projects', 'json'), toJson(visible), JSON_MIME)\n }\n\n if (props.data === null) return <div className={styles.empty}>会话数据读取中或不可用…</div>\n\n return (\n <div>\n {props.data.coverage.status !== 'complete' && (\n <div className={styles.warning}>{coverageText(props.data.coverage.status, props.data.coverage.skippedSessions)}</div>\n )}\n <div className={listStyles.filterBar}>\n <input className={listStyles.searchInput} placeholder=\"搜索项目路径…\" value={query} onChange={(event) => setQuery(event.target.value)} />\n <select className={listStyles.filterSelect} value={channelFilter} onChange={(event) => setChannelFilter(event.target.value)}>\n <option value=\"ALL\">全部通道</option>\n {props.channels.map((channel) => <option key={channel.provider} value={channel.provider}>{channel.displayName}</option>)}\n </select>\n <select className={listStyles.filterSelect} value={sortKey} onChange={(event) => setSortKey(event.target.value as SortKey)}>\n <option value=\"recent\">最近活跃</option>\n <option value=\"tokensDesc\">Tokens 最多</option>\n <option value=\"tokensAsc\">Tokens 最少</option>\n <option value=\"callsDesc\">调用最多</option>\n </select>\n <span className={exportStyles.exportGroup}>\n <button className={exportStyles.exportBtn} disabled={visible.length === 0} onClick={() => exportRows('csv')}>导出 CSV</button>\n <button className={exportStyles.exportBtn} disabled={visible.length === 0} onClick={() => exportRows('json')}>导出 JSON</button>\n </span>\n </div>\n\n <table className={styles.table + ' ' + listStyles.projectTable}>\n <thead>\n <tr><th>项目</th><th>调用</th><th>Tokens</th><th>占比</th><th>成本</th><th>最近活跃</th></tr>\n </thead>\n <tbody>\n {visible.map((row) => {\n const percent = totalTokens > 0 ? Math.round(row.tokens / totalTokens * 100) : 0\n const dominant = row.dominantProvider\n const channel = channelOf(props.channels, dominant)\n const costCell = costCellText(channel, row.cost ?? 0)\n return (\n <tr key={row.workspace}>\n <td>\n <div className={listStyles.listTitle}>\n <div>\n <div className={listStyles.listMain}>{baseNameOf(row.workspace)}</div>\n <div className={listStyles.listSub}>\n {row.workspace} · {row.sessionCount} 个会话\n {row.archivedSessionCount > 0 ? '(含 ' + row.archivedSessionCount + ' 个已归档,仍计入)' : ''}\n </div>\n </div>\n </div>\n </td>\n <td>{fmtCalls(row.calls)}</td>\n <td>{fmtTokens(row.tokens)}</td>\n <td>\n <span className={listStyles.listBar}>\n <i style={{ width: Math.max(2, percent) + '%', background: channelColorOf(props.channels, dominant ?? '') }} />\n </span> {percent}%\n </td>\n <td>{row.cost === null || channel?.costMode === 'sub' || channel?.costMode === 'free' || channel?.costMode === 'none'\n ? <span className={styles.dim}>{costCell.text}</span>\n : <>{costCell.text}{showsAmount(costCell) && <CostSourceChip source={row.costSource} />}</>}</td>\n <td>{fmtRelative(row.lastTime, nowMs)}</td>\n </tr>\n )\n })}\n {visible.length === 0 && <tr><td colSpan={6} className={styles.empty}>没有符合条件的项目</td></tr>}\n </tbody>\n </table>\n {hiddenEmpty > 0 && <div className={styles.statExtra}>{hiddenEmptyRowsText(hiddenEmpty)}</div>}\n <div className={styles.statExtra}>\n 成本按台账模型中位均价估算{props.data.priced ? '' : '(台账无成本数据,暂不可估)'};命中率 = 缓存读 /(输入 + 输出 + 缓存读)\n </div>\n </div>\n )\n}\n\nfunction coverageText(status: string, skipped: number): string {\n if (status === 'unavailable') return '会话数据不可用(宿主未提供会话服务或全部读取失败)'\n return '会话数据不完整:' + String(skipped) + ' 个会话读取失败,未计入统计'\n}\n\nexport function baseNameOf(path: string): string {\n const normalized = path.replace(/[\\\\/]+$/, '')\n const parts = normalized.split(/[\\\\/]/)\n return parts[parts.length - 1] === '' ? path : parts[parts.length - 1]\n}\n\n/** 通道显示名(列表里复用)。 */\nexport { displayNameOf }\n","/**\n * 计费规则面板:并入「余额与配额」页下半部分(不新增 Tab),插件页卡片复用同一份。\n *\n * 层级:默认只显示一行摘要(依据 / 已省 / 口径 + 「配置规则」),细节全部收进抽屉。\n * 目的是让「这一格钱凭什么」一眼可读,同时把矛盾提示合并成一条带优先级的提示。\n * 规则本体存在宿主设置服务里,成本计算全在服务端(src/server/pricing.ts),界面不重复算。\n */\nimport { useMemo, useRef, useState, type ReactNode } from 'react'\nimport {\n CURRENCY_OPTIONS, DAY_SCOPE_DAYS, DAY_SCOPE_LABELS, DAY_SCOPE_OPTIONS, EMPTY_CONFIG,\n UNIT_LABELS, UNIT_OPTIONS,\n blankRule, currencySymbolOf, dayScopeOf, offPeakWindowsText,\n parseImportedPricing, ruleKeyOf, ruleLabelOf, ruleProblemOf,\n type DayScope, type OffPeakWindow, type PricingConfig, type PricingRates, type PricingResponse, type PricingRule,\n} from '../pricing.ts'\nimport type { PricingSettingsState, PricingSettingsStore } from '../pricingSettings.ts'\nimport { JSON_MIME, downloadFile, exportFileName, toJson } from '../export.ts'\nimport { fmtTokens } from '../format.ts'\nimport type { Channel, ModelAggregateRow, ModelsResponse } from '../types.ts'\nimport styles from '../styles/shared.module.css'\nimport pricingStyles from '../styles/pricing.module.css'\nimport exportStyles from '../styles/export.module.css'\n\n/** 金额一律两位小数;服务端给的 4 位是计算精度,不是展示精度。 */\nconst AMOUNT_DIGITS = 2\n/** 「最值得补规则」最多列几条 —— 多于一屏就失去「最值得」的意义。 */\nconst WORTH_RULE_LIMIT = 3\n\nexport function PricingRulesPanel(props: {\n settings: PricingSettingsStore\n state: PricingSettingsState\n pricing: PricingResponse | null\n channels: Channel[]\n models?: ModelsResponse | null\n}): ReactNode {\n const { settings, state, pricing, channels } = props\n const [expanded, setExpanded] = useState(false)\n const [draft, setDraft] = useState<PricingRule | null>(null)\n const [editingKey, setEditingKey] = useState<string | null>(null)\n const [editorError, setEditorError] = useState<string | null>(null)\n const [templateId, setTemplateId] = useState('')\n const [notice, setNotice] = useState<string | null>(null)\n const [showAllSavings, setShowAllSavings] = useState(false)\n const [showExplanation, setShowExplanation] = useState(false)\n const fileInput = useRef<HTMLInputElement | null>(null)\n\n const config = state.config\n const rules = config.rules\n const offPeakNowOf = (rule: PricingRule): boolean => {\n if (pricing === null) return false\n const index = rules.indexOf(rule)\n return index >= 0 && pricing.offPeakNow[index] === true\n }\n\n const templates = pricing?.templates ?? []\n // 内置官方价目:随插件发布、自动生效;这里只展示条数与来源,用户不需要也不能编辑它\n const catalog = pricing?.catalog ?? null\n const providerOptions = useMemo(() => channels.map((channel) => channel.provider), [channels])\n const modelOptions = useMemo(() => {\n const ids = new Set<string>()\n for (const channel of channels) for (const model of channel.models) ids.add(model.id)\n for (const row of props.models?.rows ?? []) ids.add(row.model)\n return [...ids]\n }, [channels, props.models])\n\n const save = async (next: PricingConfig, done: string): Promise<void> => {\n const accepted = await settings.save(next)\n if (accepted) {\n setNotice(done)\n setDraft(null)\n setEditingKey(null)\n setEditorError(null)\n }\n }\n\n const startNew = (): void => {\n setDraft(blankRule(config))\n setEditingKey(null)\n setEditorError(null)\n }\n\n /** 「为它新增规则」:直接把 provider / model 预填进表单,省掉一次手抄。 */\n const startNewFor = (provider: string, model: string): void => {\n setDraft({ ...blankRule(config), provider, model })\n setEditingKey(null)\n setEditorError(null)\n }\n\n const startEdit = (rule: PricingRule): void => {\n setDraft(structuredClone(rule))\n setEditingKey(ruleKeyOf(rule))\n setEditorError(null)\n }\n\n const commitDraft = async (): Promise<void> => {\n if (draft === null) return\n const problem = ruleProblemOf(draft)\n if (problem !== null) {\n setEditorError(problem)\n return\n }\n const nextRules = [...rules]\n const editedIndex = editingKey === null ? -1 : nextRules.findIndex((rule) => ruleKeyOf(rule) === editingKey)\n const duplicateIndex = nextRules.findIndex((rule) => ruleKeyOf(rule) === ruleKeyOf(draft))\n if (editedIndex >= 0) {\n nextRules[editedIndex] = draft\n // 改了通道 / 模型等于改了主键:把同键的旧行删掉,避免留下两行同名规则\n if (duplicateIndex >= 0 && duplicateIndex !== editedIndex) nextRules.splice(duplicateIndex, 1)\n } else if (duplicateIndex >= 0) {\n nextRules[duplicateIndex] = draft\n } else {\n nextRules.push(draft)\n }\n await save({ ...config, rules: nextRules }, '规则已保存')\n }\n\n const removeRule = async (rule: PricingRule): Promise<void> => {\n await save(\n { ...config, rules: rules.filter((candidate) => candidate !== rule) },\n '规则已删除',\n )\n }\n\n const applyTemplate = async (): Promise<void> => {\n const template = templates.find((candidate) => candidate.id === templateId)\n if (template === undefined) return\n // 同键覆盖、新键追加:套用模板不会把已有的手工规则冲掉\n const nextRules = [...rules]\n for (const rule of template.rules) {\n const index = nextRules.findIndex((candidate) => ruleKeyOf(candidate) === ruleKeyOf(rule))\n if (index >= 0) nextRules[index] = rule\n else nextRules.push(rule)\n }\n await save({ ...config, rules: nextRules }, '已套用模板「' + template.label + '」,数值请自行核对')\n }\n\n const exportRules = (): void => {\n downloadFile(exportFileName('pricing-rules', 'json'), toJson(config), JSON_MIME)\n }\n\n const importRules = async (file: File): Promise<void> => {\n const parsed = parseImportedPricing(await file.text())\n if (parsed.config === null) {\n settings.noteError(parsed.error ?? '导入失败:文件内容无法识别')\n return\n }\n await save(parsed.config, '规则已导入(整份替换)')\n }\n\n const coverage = pricing?.coverage ?? null\n const savingsEntries = Object.entries(coverage?.savingsByCurrency ?? {}).filter(([, amount]) => amount > 0)\n const savingsDetail = coverage?.savingsDetail ?? []\n const visibleSavings = showAllSavings ? savingsDetail : savingsDetail.slice(0, 3)\n const ruleCostEntries = Object.entries(coverage?.ruleCostByCurrency ?? {}).filter(([, amount]) => amount > 0)\n const worthRules = worthRuleCandidates(props.models, rules)\n\n return (\n <div className={pricingStyles.panel}>\n <SummaryStrip\n coverage={coverage}\n rulesCount={rules.length}\n loading={state.status === 'loading'}\n savingsEntries={savingsEntries}\n expanded={expanded}\n onToggle={() => setExpanded((previous) => !previous)}\n showExplanation={showExplanation}\n onToggleExplanation={() => setShowExplanation((previous) => !previous)}\n />\n\n {showExplanation && <ExplanationBlock />}\n\n {expanded && (\n <div className={pricingStyles.drawer}>\n {/* 状态提示只渲染一条(优先级见 StatusNotice),不与「写入被拒绝」叠加 */}\n <StatusNotice state={state} />\n\n {notice !== null && <div className={pricingStyles.panelHint}>{notice}</div>}\n\n {ruleCostEntries.length > 0 && (\n <div className={pricingStyles.statStrip}>\n <div className={pricingStyles.statItem}>\n <div className={pricingStyles.statName}>按当前规则试算(近 30 天,仅参照)</div>\n <div className={pricingStyles.statNum}>\n {ruleCostEntries.map(([currency, amount]) => moneyText(currency, amount)).join(' / ')}\n </div>\n <div className={pricingStyles.statNote}>\n 不是账单:实际成本按「官方 &gt; 规则 &gt; 官方价 &gt; 均价」逐格取值\n </div>\n </div>\n </div>\n )}\n\n {catalog !== null && catalog.entries > 0 && (\n <div className={pricingStyles.catalogNote}>\n 已内置 <b>{String(catalog.entries)}</b> 条厂商官方价目,<b>无需套用模板即自动生效</b>\n (你的规则优先于它)。来源:\n {catalog.sources.map((entry, index) => (\n <span key={entry.source}>\n {index > 0 && ';'}\n <a className={pricingStyles.linkBtn} href={entry.source} target=\"_blank\" rel=\"noreferrer\">\n {entry.providers.join(' / ')}\n </a>\n ({entry.count} 条,{entry.fetchedAt} 抓取)\n </span>\n ))}\n </div>\n )}\n\n <div className={pricingStyles.toolbar}>\n <select\n className={pricingStyles.actionBtn}\n value={templateId}\n onChange={(event) => setTemplateId(event.target.value)}\n >\n <option value=\"\">选择厂商模板…</option>\n {templates.map((template) => <option key={template.id} value={template.id}>{template.label}</option>)}\n </select>\n <button className={pricingStyles.actionBtn} disabled={templateId === ''} onClick={() => void applyTemplate()}>\n 套用模板\n </button>\n <button className={pricingStyles.actionBtn + ' ' + pricingStyles.primary} onClick={startNew}>\n + 新增规则\n </button>\n <span className={pricingStyles.toolbarSpacer} />\n <button className={pricingStyles.linkBtn} disabled={rules.length === 0} onClick={exportRules}>导出 JSON</button>\n <button className={pricingStyles.linkBtn} onClick={() => fileInput.current?.click()}>导入 JSON</button>\n <button\n className={pricingStyles.linkBtn}\n disabled={rules.length === 0}\n onClick={() => void save({ ...EMPTY_CONFIG, currency: config.currency }, '已清空规则:成本回到台账反推均价')}\n >\n 清空规则\n </button>\n <input\n ref={fileInput}\n className={pricingStyles.hiddenFile}\n type=\"file\"\n accept=\"application/json,.json\"\n onChange={(event) => {\n const file = event.target.files?.[0]\n event.target.value = ''\n if (file !== undefined) void importRules(file)\n }}\n />\n </div>\n\n {rules.length === 0\n ? (\n <div className={pricingStyles.empty}>\n 还没有规则。点「+ 新增规则」手填,或从上方的厂商模板起步。\n </div>\n )\n : (\n <table className={pricingStyles.ruleTable}>\n <thead>\n <tr>\n <th>通道</th><th>模型</th><th>单位</th><th>输入</th><th>缓存读</th><th>缓存写</th><th>输出</th>\n <th>币种</th><th>错峰</th><th>备注</th><th>操作</th>\n </tr>\n </thead>\n <tbody>\n {rules.map((rule) => (\n <tr key={ruleKeyOf(rule)} className={editingKey === ruleKeyOf(rule) ? pricingStyles.editing : ''}>\n <td><span className={pricingStyles.ruleName}>{rule.provider}</span></td>\n <td><span className={pricingStyles.ruleName}>{rule.model}</span></td>\n <td>{UNIT_LABELS[rule.unit]}</td>\n <td>{rule.input}</td>\n <td>{rule.cacheRead}</td>\n <td>{rule.cacheWrite}</td>\n <td>{rule.output}</td>\n <td>{rule.currency}</td>\n <td>\n {rule.offPeak === null\n ? <span className={styles.dim}>—</span>\n : (\n <span title={offPeakTooltipOf(rule)}>\n <span className={pricingStyles.ruleName}>{offPeakWindowsText(rule)}</span>\n {offPeakNowOf(rule) && <span className={pricingStyles.offPeakChip}>错峰中</span>}\n </span>\n )}\n </td>\n <td className={pricingStyles.ruleNote}>\n {rule.note === ''\n ? <span className={styles.dim}>—</span>\n : <span title={rule.note}>{rule.note}</span>}\n </td>\n <td>\n <button className={pricingStyles.linkBtn} onClick={() => startEdit(rule)}>编辑</button>\n <button className={pricingStyles.linkBtn} onClick={() => void removeRule(rule)}>删除</button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n )}\n\n {draft !== null && (\n <RuleEditor\n draft={draft}\n onChange={setDraft}\n onCancel={() => { setDraft(null); setEditorError(null); setEditingKey(null) }}\n onSave={() => void commitDraft()}\n error={editorError}\n providerOptions={providerOptions}\n modelOptions={modelOptions}\n />\n )}\n\n {worthRules.length > 0 && (\n <div className={pricingStyles.sectionBlock}>\n <div className={pricingStyles.subLabel}>最值得补规则的模型</div>\n <div className={pricingStyles.panelHint}>\n 这些模型要么按台账均价估算、要么没有任何价格依据,但用量占比最高 —— 给它们补规则最能提升准确度。\n </div>\n <ul className={pricingStyles.worthList}>\n {worthRules.map((candidate) => (\n <li key={candidate.provider + '|' + candidate.model}>\n <span className={pricingStyles.ruleName}>{candidate.model}</span>\n <span className={styles.dim}> · {candidate.provider}</span>\n <span className={pricingStyles.worthMeta}>\n {fmtTokens(candidate.tokens)} tokens({percentText(candidate.share)})\n {candidate.estimated ? ' · 现为估算' : ' · 无价格依据'}\n </span>\n <button\n className={pricingStyles.linkBtn}\n onClick={() => startNewFor(candidate.provider, candidate.model)}\n >\n 为它新增规则\n </button>\n </li>\n ))}\n </ul>\n </div>\n )}\n\n {savingsDetail.length > 0 && (\n <div className={pricingStyles.sectionBlock}>\n <div className={pricingStyles.subLabel}>\n 缓存命中省钱明细{coverage === null ? '' : '(' + coverage.from + ' 起)'}\n </div>\n <ul className={pricingStyles.savingsList}>\n {visibleSavings.map((entry) => (\n <li key={entry.provider + '|' + entry.model}>\n <span className={pricingStyles.ruleName}>{entry.model}</span>\n <span className={styles.dim}> · {entry.provider}</span>\n <span className={pricingStyles.worthMeta}>\n 命中缓存 {fmtTokens(entry.cacheReadTokens)} tokens\n </span>\n <span className={pricingStyles.saving}>\n 省 {moneyText(entry.currency, entry.amount)}\n </span>\n </li>\n ))}\n </ul>\n {savingsDetail.length > 3 && (\n <button className={pricingStyles.linkBtn} onClick={() => setShowAllSavings((previous) => !previous)}>\n {showAllSavings ? '收起' : '展开全部(' + String(savingsDetail.length) + ' 条)'}\n </button>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n )\n}\n\n/**\n * 摘要行:默认收起的全部内容就这一行。\n * 「依据」用 /pricing 的 coverage 数模型个数,让用户一眼看出哪些模型可信、哪些只是估算。\n */\nfunction SummaryStrip(props: {\n coverage: PricingResponse['coverage'] | null\n rulesCount: number\n loading: boolean\n savingsEntries: Array<[string, number]>\n expanded: boolean\n onToggle: () => void\n showExplanation: boolean\n onToggleExplanation: () => void\n}): ReactNode {\n const { coverage } = props\n const days = coverage === null ? null : daysBetween(coverage.from, coverage.to)\n return (\n <div className={pricingStyles.summaryStrip}>\n <div className={pricingStyles.summaryBasis}>\n <div className={pricingStyles.summaryName}>这一格钱的依据</div>\n <div className={pricingStyles.summaryValue}>\n {coverage === null\n ? (props.loading ? '正在读取规则与覆盖度…' : '还没读到服务端覆盖度 —— 稍后自动重试')\n : <>\n 官方账单 {days === null ? '—' : String(days)} 天 ·\n 你的规则 {String(coverage.ruleModels)} 个模型 ·\n 内置官方价 {String(coverage.catalogModels ?? 0)} 个模型 ·\n 台账均价估算 {String(coverage.averagedModels)} 个模型\n {coverage.unpricedModels > 0 && ' · 无依据 ' + String(coverage.unpricedModels) + ' 个'}\n </>}\n </div>\n </div>\n\n <div className={pricingStyles.summarySaving}>\n <div className={pricingStyles.summaryName}>缓存命中已省</div>\n <div className={pricingStyles.summaryValue + (props.savingsEntries.length > 0 ? ' ' + pricingStyles.saving : '')}>\n {props.savingsEntries.length === 0\n ? '—'\n : props.savingsEntries.map(([currency, amount]) => moneyText(currency, amount)).join(' / ')}\n </div>\n </div>\n\n <div className={pricingStyles.summaryActions}>\n <button\n className={pricingStyles.infoBtn + (props.showExplanation ? ' ' + pricingStyles.infoBtnActive : '')}\n title=\"来源角标、单位、错峰与多币种口径\"\n onClick={props.onToggleExplanation}\n >\n ⓘ\n </button>\n <button className={pricingStyles.actionBtn + ' ' + pricingStyles.primary} onClick={props.onToggle}>\n {props.expanded ? '收起规则 ◂' : '配置规则 ▸'}\n </button>\n </div>\n </div>\n )\n}\n\n/** 完整口径说明:默认不占正文,点 ⓘ 才出现。 */\nfunction ExplanationBlock(): ReactNode {\n return (\n <div className={pricingStyles.explanation}>\n <div className={pricingStyles.explanationTitle}>口径说明</div>\n <ul className={pricingStyles.explanationList}>\n <li><b>官方</b>:台账记录的厂商账单金额,是既成事实,不会被规则覆盖。</li>\n <li><b>自定</b>:按你填的规则算出,匹配顺序 精确 → 通道通配 → 模型通配 → 全通配。</li>\n <li><b>官方价</b>:按插件<b>内置的厂商官方价目</b>算出(自动生效,无需套用模板);你的规则优先于它。匹配只做精确 / 忽略大小写 / 去 <code>vendor/</code> 前缀,不做模糊匹配。</li>\n <li><b>估算</b>:按台账反推的均价推算,仅供参照,不是账单。</li>\n <li><b>—</b>:没有价格依据(规则与内置价目都没命中,台账也没有成本数据)。</li>\n <li>单位与按次计费:规则里显式声明「每百万 / 每千 tokens / 每次调用」;按次计费只用「输入」档当每次调用价。</li>\n <li>错峰:窗口按<b>本地时间</b>判断,起止相同表示全天,<code>from</code> 大于 <code>to</code> 表示跨午夜;每个窗口可按<b>每天 / 仅工作日 / 仅周末</b>限定生效的星期(不选即每天)。跨天范围拿不到小时分布,按标准价算。</li>\n <li>多币种不换算、不合计:规则与内置价目各按文档原币种算(DeepSeek 取中文文档的 CNY,Kimi 为 CNY,OpenRouter / Z.ai 为 USD),金额按币种分行显示。</li>\n <li>规则存在宿主设置服务里(命名空间 <code>dsh-key-usage</code>),插件不写任何文件。</li>\n </ul>\n </div>\n )\n}\n\n/**\n * 状态提示:优先级从高到低只渲染一条,避免「写入被拒绝」和「无法保存」同时出现。\n * 1) 命名空间不可写 / 取不到配置表单服务 —— 规则根本存不下去,说清楚「重启 DSH 后可用」;\n * 2) 刚发生的写入失败(如乐观锁冲突)—— 可重试;\n * 3) 正常 —— 不显示任何提示。\n */\nfunction StatusNotice(props: { state: PricingSettingsState }): ReactNode {\n const { state } = props\n if (state.status === 'unavailable' || (state.status === 'ready' && !state.writable)) {\n return (\n <div className={pricingStyles.warning}>\n 规则暂不可编辑:宿主还没加载本插件的配置(<b>重启 DSH 后可用</b>);现在仍可导入 / 导出 JSON。\n </div>\n )\n }\n if (state.error !== null) {\n return <div className={pricingStyles.error}>保存失败:{state.error},可重试</div>\n }\n return null\n}\n\n/** 两位小数 + 币种符号;未知币种保留代码前缀,避免把 USD 当 CNY 渲染。 */\nfunction moneyText(currency: string, amount: number): string {\n return currencySymbolOf(currency) + amount.toFixed(AMOUNT_DIGITS)\n}\n\nfunction percentText(share: number): string {\n return (share * 100).toFixed(1) + '%'\n}\n\n/** 覆盖区间的自然天数(含首尾),用作「官方账单 X 天」的口径。 */\nfunction daysBetween(from: string, to: string): number | null {\n const start = new Date(from + 'T00:00:00').getTime()\n const end = new Date(to + 'T00:00:00').getTime()\n if (Number.isNaN(start) || Number.isNaN(end) || end < start) return null\n return Math.round((end - start) / 86400000) + 1\n}\n\n/** 错峰说明进 tooltip:规则表因此不被一整列文字撑开。 */\nfunction offPeakTooltipOf(rule: PricingRule): string {\n const windows = offPeakWindowsText(rule)\n if (rule.offPeak === null) return windows\n const peak = '标准价 ' + String(rule.input) + ' / ' + String(rule.cacheRead) + ' / ' + String(rule.cacheWrite) + ' / ' + String(rule.output)\n const offPeak = '错峰价 ' + String(rule.offPeak.input) + ' / ' + String(rule.offPeak.cacheRead) + ' / ' + String(rule.offPeak.cacheWrite) + ' / ' + String(rule.offPeak.output)\n return '错峰时段(本地时间,跨午夜用 from > to 表示;括号内是生效的星期):' + windows + '\\n' + peak + '\\n' + offPeak\n + '\\n四档顺序:输入 / 缓存读 / 缓存写 / 输出'\n}\n\ninterface WorthRuleCandidate {\n provider: string\n model: string\n tokens: number\n share: number\n /** true = 台账反推均价在兜底(估算);false = 完全无价格依据。 */\n estimated: boolean\n}\n\n/**\n * 「最值得补规则」的判定:先筛出**没有价格依据**的模型,再按近 30 天 tokens 占比倒序取前 3。\n * 「没有价格依据」用两处数据交叉确认:/pricing 的 coverage 计数只给总数,\n * 逐模型是否命中则用 /models 的 costSource —— 它正是成本单元格上那个角标,口径一致。\n * `catalog`(内置官方价目)已有官方价,不算缺口,因此不列入候选。\n */\nfunction worthRuleCandidates(\n models: ModelsResponse | null | undefined,\n rules: PricingRule[],\n): WorthRuleCandidate[] {\n const rows: ModelAggregateRow[] = (models?.rows ?? []).filter((row) => row.tokens > 0)\n if (rows.length === 0) return []\n const unpriced = rows.filter((row) => {\n if (row.costSource === 'rule' || row.costSource === 'official' || row.costSource === 'catalog') return false\n // costSource 缺失(旧响应 / 未标注)时退回本地匹配,避免整块不显示\n return row.costSource === 'estimate' || row.costSource === 'none' || !matchesAnyRule(rules, row.provider, row.model)\n })\n const total = unpriced.reduce((sum, row) => sum + row.tokens, 0)\n if (total <= 0) return []\n return unpriced\n .map((row) => ({\n provider: row.provider,\n model: row.model,\n tokens: row.tokens,\n share: row.tokens / total,\n // 只有明确标了「估算」才算均价兜底;角标缺失时按「无依据」说,不替服务端下结论\n estimated: row.costSource === 'estimate',\n }))\n .sort((first, second) => second.tokens - first.tokens)\n .slice(0, WORTH_RULE_LIMIT)\n}\n\n/** 与服务端 matchPricingRule 同序的粗判:精确 → 通道通配 → 模型通配 → 全通配。 */\nfunction matchesAnyRule(rules: PricingRule[], provider: string, model: string): boolean {\n const patterns = [\n (rule: PricingRule) => rule.provider === provider && rule.model === model,\n (rule: PricingRule) => rule.provider === provider && rule.model === '*',\n (rule: PricingRule) => rule.provider === '*' && rule.model === model,\n (rule: PricingRule) => rule.provider === '*' && rule.model === '*',\n ]\n return patterns.some((matches) => rules.some(matches))\n}\n\n/** 单条规则的编辑器:单位换算、错峰窗口都在这里显式呈现,避免「按千 / 按百万」填错 1000 倍。 */\nfunction RuleEditor(props: {\n draft: PricingRule\n onChange: (rule: PricingRule) => void\n onCancel: () => void\n onSave: () => void\n error: string | null\n providerOptions: string[]\n modelOptions: string[]\n}): ReactNode {\n const { draft, onChange } = props\n const numberField = (\n label: string,\n key: 'input' | 'cacheRead' | 'cacheWrite' | 'output',\n value: number,\n extra?: { onChange?: (value: number) => void },\n ): ReactNode => (\n <div className={pricingStyles.field} key={label}>\n <label>{label}</label>\n <input\n type=\"number\"\n min={0}\n step=\"any\"\n value={String(value)}\n onChange={(event) => {\n const next = Number(event.target.value)\n const safe = Number.isFinite(next) && next >= 0 ? next : 0\n if (extra?.onChange !== undefined) extra.onChange(safe)\n else onChange({ ...draft, [key]: safe })\n }}\n />\n </div>\n )\n\n const windows = draft.offPeak?.windows ?? []\n const setWindows = (next: OffPeakWindow[]): void => {\n if (next.length === 0) {\n onChange({ ...draft, offPeak: null })\n return\n }\n onChange({\n ...draft,\n offPeak: {\n windows: next,\n input: draft.offPeak?.input ?? draft.input,\n cacheRead: draft.offPeak?.cacheRead ?? draft.cacheRead,\n cacheWrite: draft.offPeak?.cacheWrite ?? draft.cacheWrite,\n output: draft.offPeak?.output ?? draft.output,\n },\n })\n }\n\n return (\n <div className={pricingStyles.editor}>\n <div className={pricingStyles.editorGrid}>\n <div className={pricingStyles.field}>\n <label>通道 id(* = 任意通道)</label>\n <input list=\"dsh-ku-providers\" value={draft.provider} onChange={(event) => onChange({ ...draft, provider: event.target.value })} />\n <datalist id=\"dsh-ku-providers\">\n {props.providerOptions.map((provider) => <option key={provider} value={provider} />)}\n </datalist>\n </div>\n <div className={pricingStyles.field}>\n <label>模型 id(* = 该通道全部)</label>\n <input list=\"dsh-ku-models\" value={draft.model} onChange={(event) => onChange({ ...draft, model: event.target.value })} />\n <datalist id=\"dsh-ku-models\">\n {props.modelOptions.map((model) => <option key={model} value={model} />)}\n </datalist>\n </div>\n <div className={pricingStyles.field}>\n <label>计价单位</label>\n <select value={draft.unit} onChange={(event) => onChange({ ...draft, unit: event.target.value as PricingRule['unit'] })}>\n {UNIT_OPTIONS.map((unit) => <option key={unit} value={unit}>{UNIT_LABELS[unit]}</option>)}\n </select>\n </div>\n <div className={pricingStyles.field}>\n <label>币种</label>\n <select value={draft.currency} onChange={(event) => onChange({ ...draft, currency: event.target.value })}>\n {CURRENCY_OPTIONS.map((currency) => <option key={currency} value={currency}>{currency}</option>)}\n </select>\n </div>\n {numberField('输入(未命中缓存)', 'input', draft.input)}\n {numberField('缓存读(命中)', 'cacheRead', draft.cacheRead)}\n {numberField('缓存写', 'cacheWrite', draft.cacheWrite)}\n {numberField('输出', 'output', draft.output)}\n <div className={pricingStyles.field + ' ' + pricingStyles.fieldWide}>\n <label>备注(建议写价目来源与日期)</label>\n <input value={draft.note} onChange={(event) => onChange({ ...draft, note: event.target.value })} />\n </div>\n </div>\n\n <div className={pricingStyles.subLabel}>错峰时段(本地时间;留空表示没有错峰价)</div>\n {windows.map((window, index) => (\n <div className={pricingStyles.windowRow} key={index}>\n <input\n value={window.from}\n placeholder=\"00:00\"\n onChange={(event) => setWindows(windows.map((candidate, position) => position === index ? { ...candidate, from: event.target.value } : candidate))}\n />\n <span className={styles.dim}>至</span>\n <input\n value={window.to}\n placeholder=\"09:00\"\n onChange={(event) => setWindows(windows.map((candidate, position) => position === index ? { ...candidate, to: event.target.value } : candidate))}\n />\n {/* 三选一只改 days:改时间不碰它,避免手填的星期组合被顺手抹掉 */}\n <select\n value={dayScopeOf(window.days)}\n onChange={(event) => setWindows(windows.map((candidate, position) => (\n position === index ? withDayScope(candidate, event.target.value as DayScope) : candidate\n )))}\n >\n {DAY_SCOPE_OPTIONS.map((scope) => (\n <option key={scope} value={scope}>{DAY_SCOPE_LABELS[scope]}</option>\n ))}\n </select>\n <button className={pricingStyles.linkBtn} onClick={() => setWindows(windows.filter((_, position) => position !== index))}>移除</button>\n </div>\n ))}\n <button className={pricingStyles.actionBtn} onClick={() => setWindows([...windows, { from: '00:00', to: '08:00' }])}>+ 加时间窗</button>\n\n {draft.offPeak !== null && (\n <>\n <div className={pricingStyles.subLabel}>错峰价(留空即与标准价相同)</div>\n <div className={pricingStyles.editorGrid}>\n {numberField('错峰输入', 'input', draft.offPeak.input, { onChange: (value) => patchOffPeak(draft, onChange, { input: value }) })}\n {numberField('错峰缓存读', 'cacheRead', draft.offPeak.cacheRead, { onChange: (value) => patchOffPeak(draft, onChange, { cacheRead: value }) })}\n {numberField('错峰缓存写', 'cacheWrite', draft.offPeak.cacheWrite, { onChange: (value) => patchOffPeak(draft, onChange, { cacheWrite: value }) })}\n {numberField('错峰输出', 'output', draft.offPeak.output, { onChange: (value) => patchOffPeak(draft, onChange, { output: value }) })}\n </div>\n </>\n )}\n\n {props.error !== null && <div className={pricingStyles.editorError}>{props.error}</div>}\n <div className={pricingStyles.editorHint}>\n 正在编辑:{ruleLabelOf(draft)} · 单位 {UNIT_LABELS[draft.unit]}\n </div>\n <div className={pricingStyles.editorActions}>\n <button className={pricingStyles.actionBtn + ' ' + pricingStyles.primary} onClick={props.onSave}>保存规则</button>\n <button className={pricingStyles.actionBtn} onClick={props.onCancel}>取消</button>\n </div>\n </div>\n )\n}\n\nfunction patchOffPeak(draft: PricingRule, onChange: (rule: PricingRule) => void, patch: Partial<PricingRates>): void {\n if (draft.offPeak === null) return\n onChange({ ...draft, offPeak: { ...draft.offPeak, ...patch } })\n}\n\n/**\n * 单个窗口的星期范围:三选一直接改写 `days`。\n * 「每天」删掉该字段(而不是写 [1..7]),这样升级前保存的规则往返后字节一致;\n * 手改 JSON 得到的自定义组合在下拉里显示为「每天」,但只要用户不碰这个下拉,原值原样保留。\n */\nfunction withDayScope(window: OffPeakWindow, scope: DayScope): OffPeakWindow {\n const days = DAY_SCOPE_DAYS[scope]\n if (days === undefined) {\n const { from, to } = window\n return { from, to }\n }\n return { ...window, days: [...days] }\n}\n","/**\n * 余额与配额:按通道展示官方余额快照与订阅窗口(原样数据,不换算不建议)。\n * 下半部分是计费规则面板(规则存在宿主设置服务里,成本重算在服务端)。\n */\nimport { type ReactNode } from 'react'\nimport { quotaBarColor, statusColorOf } from '../channels.ts'\nimport { fmtDateTime } from '../format.ts'\nimport type { Channel, ModelsResponse, PricingResponse, QuotaProvider } from '../types.ts'\nimport type { PricingSettingsState, PricingSettingsStore } from '../pricingSettings.ts'\nimport { PricingRulesPanel } from '../components/PricingRulesPanel.tsx'\nimport styles from '../styles/shared.module.css'\nimport quotaStyles from '../styles/quota.module.css'\n\n/** 余额字段展示顺序(原型顺序);未收录字段按原键名追加在后。 */\nconst BALANCE_ORDER = ['totalBalance', 'topUpBalance', 'giftBalance', 'balance', 'currency']\nconst BALANCE_LABELS: Record<string, string> = {\n totalBalance: '总余额', topUpBalance: '充值余额', giftBalance: '赠送余额', balance: '余额', currency: '币种',\n}\n/** 订阅窗口固定展示顺序。 */\nconst WINDOW_ORDER = ['5h', 'week', 'month', 'day']\nconst WINDOW_LABELS: Record<string, string> = { '5h': '5 小时窗口', week: '本周窗口', month: '本月窗口', day: '当日窗口' }\n\nfunction resetTextOf(value: unknown): string {\n if (typeof value !== 'string' || value === '') return '重置时间 —'\n const time = new Date(value)\n if (Number.isNaN(time.getTime())) return '重置于 ' + value\n return '重置于 ' + fmtDateTime(time.getTime())\n}\n\nexport function QuotaTab(props: {\n channels: Channel[]\n quotas: QuotaProvider[]\n pricing: PricingResponse | null\n pricingState: PricingSettingsState\n pricingSettings: PricingSettingsStore\n models: ModelsResponse | null\n}): ReactNode {\n const snapshotOf = (provider: string): QuotaProvider | null => props.quotas.find((item) => item.provider === provider) ?? null\n return (\n <div className={quotaStyles.quotaList}>\n {props.channels.map((channel) => {\n const snapshot = snapshotOf(channel.provider)\n const balance = snapshot?.balance ?? null\n const plan = snapshot?.plan ?? null\n const isLive = snapshot?.source === 'live'\n const windows = plan !== null && Array.isArray((plan as { windows?: unknown }).windows)\n ? (plan as { windows: Array<{ key?: unknown; percent?: unknown; resetsAt?: unknown }> }).windows\n : null\n return (\n <div className={quotaStyles.quotaCard} key={channel.provider}>\n <div className={quotaStyles.quotaHead}>\n <span className={styles.statusDot} style={{ background: statusColorOf(channel.status) }} />\n <span className={quotaStyles.quotaTitle}>{channel.displayName}</span>\n {isLive && <span className={quotaStyles.liveChip}>实时</span>}\n <span className={quotaStyles.quotaProvider}>{channel.provider} · {channel.costLabel}</span>\n </div>\n\n {balance !== null && (\n <div className={quotaStyles.balanceStrip}>\n {orderedBalanceEntries(balance).map(([key, value]) => (\n <div className={quotaStyles.balanceItem} key={key}>\n <div className={quotaStyles.bsLabel}>{BALANCE_LABELS[key] ?? key}</div>\n <div className={quotaStyles.bsValue}>{String(value)}</div>\n </div>\n ))}\n </div>\n )}\n\n {balance === null && windows !== null && windows.length > 0 && (\n <div className={quotaStyles.windowRow}>\n {orderedWindows(windows).map((window) => {\n const percent = typeof window.percent === 'number' ? window.percent : 0\n const key = typeof window.key === 'string' ? window.key : 'window'\n return (\n <div className={quotaStyles.windowItem} key={key}>\n <div className={quotaStyles.windowHead}>\n <span className={quotaStyles.windowName}>{WINDOW_LABELS[key] ?? key}</span>\n <span className={quotaStyles.windowValue}>{percent}%</span>\n </div>\n <div className={quotaStyles.windowBar}>\n <i style={{ width: Math.max(percent, 0) + '%', background: quotaBarColor(percent) }} />\n </div>\n <div className={quotaStyles.windowReset}>{resetTextOf(window.resetsAt)}</div>\n </div>\n )\n })}\n </div>\n )}\n\n {balance === null && (windows === null || windows.length === 0) && (\n <div className={styles.dim}>{emptyReasonOf(channel, snapshot)}</div>\n )}\n\n {isLive && (\n <div className={quotaStyles.snapshotHint}>\n 实时查询于 {freshTextOf(snapshot?.fetchedAt ?? null)}(来自官方接口,最多缓存 1 分钟)\n </div>\n )}\n {snapshot !== null && !isLive && snapshot.supported && (\n <div className={staleDaysOf(snapshot.updatedAt) >= 1 ? quotaStyles.snapshotStale : quotaStyles.snapshotHint}>\n 实时查询未成功({errorTextOf(snapshot.error)})\n {snapshot.updatedAt === null\n ? ',且暂无可用快照 —— 点右上角「刷新」重试'\n : ',显示快照 · 快照时间 ' + fmtDateTime(snapshot.updatedAt) + (staleDaysOf(snapshot.updatedAt) >= 1 ? ',已 ' + staleDaysOf(snapshot.updatedAt) + ' 天未更新' : '')}\n </div>\n )}\n </div>\n )\n })}\n {props.channels.length === 0 && <div className={styles.empty}>未读取到通道配置</div>}\n\n <PricingRulesPanel\n settings={props.pricingSettings}\n state={props.pricingState}\n pricing={props.pricing}\n channels={props.channels}\n // 按模型用量交给抽屉里的「最值得补规则的模型」排序用\n models={props.models}\n />\n </div>\n )\n}\n\n/** 实时结果的相对时间文案。 */\nfunction freshTextOf(fetchedAt: number | null): string {\n if (fetchedAt === null) return '刚刚'\n const seconds = Math.max(0, Math.floor((Date.now() - fetchedAt) / 1000))\n if (seconds < 60) return '刚刚'\n const minutes = Math.floor(seconds / 60)\n if (minutes < 60) return minutes + ' 分钟前'\n return Math.floor(minutes / 60) + ' 小时前'\n}\n\n/** 实时查询失败原因的展示文案。 */\nfunction errorTextOf(error: string | null): string {\n if (error === null) return '未启用实时查询'\n if (error === 'no-key') return '该通道未配置 API Key'\n if (error === 'no-snapshot') return '没有快照可用'\n if (error === 'network') return '网络不可达'\n if (error === 'timeout') return '请求超时'\n if (error === 'unauthorized') return '凭据被拒绝(401/403)'\n if (error === 'bad-json') return '接口响应无法解析'\n if (error === 'too-large') return '接口响应异常大'\n if (error.startsWith('http-')) return '接口返回 HTTP ' + error.slice(5)\n return error\n}\n\n/** 快照距今天数(向下取整);用于把「宿主很久没刷新」显式标出来。 */\nfunction staleDaysOf(updatedAt: number | null): number {\n if (updatedAt === null) return 0\n return Math.floor((Date.now() - updatedAt) / 86400000)\n}\n\nfunction orderedBalanceEntries(balance: Record<string, unknown>): Array<[string, unknown]> {\n const entries = Object.entries(balance).filter(([key]) => key !== 'updatedAt')\n const ordered: Array<[string, unknown]> = []\n for (const key of BALANCE_ORDER) {\n const found = entries.find(([entryKey]) => entryKey === key)\n if (found !== undefined) ordered.push(found)\n }\n for (const entry of entries) {\n if (!BALANCE_ORDER.includes(entry[0])) ordered.push(entry)\n }\n return ordered\n}\n\nfunction orderedWindows(windows: Array<{ key?: unknown }>): Array<{ key?: unknown; percent?: unknown; resetsAt?: unknown }> {\n const typed = windows as Array<{ key?: unknown; percent?: unknown; resetsAt?: unknown }>\n return [...typed].sort((first, second) => {\n const firstIndex = WINDOW_ORDER.indexOf(typeof first.key === 'string' ? first.key : '')\n const secondIndex = WINDOW_ORDER.indexOf(typeof second.key === 'string' ? second.key : '')\n return (firstIndex < 0 ? 99 : firstIndex) - (secondIndex < 0 ? 99 : secondIndex)\n })\n}\n\n/** 无数据时的分档说明:区分未配置凭据 / 免费额度 / 本地端点 / 无查询能力。 */\nfunction emptyReasonOf(channel: Channel, snapshot: QuotaProvider | null): string {\n if (snapshot?.source === 'snapshot' && snapshot.error === 'no-key') return '该通道未配置 API Key,无法查询余额'\n if (snapshot?.source === 'snapshot' && snapshot.error === 'unauthorized') return '凭据被通道拒绝,无法查询余额'\n if (channel.status === 'off') return '凭据引用存在,Key 未填写'\n if (channel.costMode === 'none') return '本地端点,无余额查询接口'\n if (channel.costMode === 'free') return '该通道无余额查询接口(免费额度)'\n return '该通道暂无可查询的余额 / 配额接口'\n}\n","/** 会话用量:按会话列出 tokens / 命中率 / 时长,按最近活跃时按日分组。 */\nimport { Fragment, useMemo, useState, type ReactNode } from 'react'\nimport { channelOf, costCellText, displayNameOf, showsAmount } from '../channels.ts'\nimport { fmtCalls, fmtDateTime, fmtDuration, fmtTime, fmtTokens, isoDate } from '../format.ts'\nimport { CSV_MIME, JSON_MIME, downloadFile, exportFileName, toCsv, toJson, type ExportColumn } from '../export.ts'\nimport { dropEmptyRows, hiddenEmptyRowsText } from '../rows.ts'\nimport { CostSourceChip } from '../components/CostSourceChip.tsx'\nimport { COST_SOURCE_LABELS } from '../pricing.ts'\nimport type { Channel, SessionRow, SessionsResponse } from '../types.ts'\nimport styles from '../styles/shared.module.css'\nimport listStyles from '../styles/lists.module.css'\nimport exportStyles from '../styles/export.module.css'\n\ntype SortKey = 'recent' | 'tokensDesc' | 'tokensAsc' | 'durationDesc'\n/** 会话归档筛选:与宿主原生「筛选会话」菜单同三档。 */\ntype ArchiveFilter = 'hide' | 'all' | 'only'\n\n/** 导出列:标题可能带逗号或换行,由 toCsv 统一转义。 */\nconst EXPORT_COLUMNS: Array<ExportColumn<SessionRow>> = [\n { key: 'id', label: '会话 id', value: (row) => row.id },\n { key: 'title', label: '标题', value: (row) => row.title },\n { key: 'workspace', label: '工作区', value: (row) => row.workspace },\n { key: 'provider', label: '通道', value: (row) => row.provider },\n { key: 'firstTime', label: '首次时间', value: (row) => fmtDateTime(row.firstTime) },\n { key: 'lastTime', label: '最近时间', value: (row) => fmtDateTime(row.lastTime) },\n { key: 'calls', label: '调用', value: (row) => row.calls },\n { key: 'tokens', label: 'Tokens', value: (row) => row.tokens },\n { key: 'cacheHitRate', label: '命中率(%)', value: (row) => row.cacheHitRate },\n { key: 'cost', label: '成本(元)', value: (row) => row.cost },\n { key: 'costSource', label: '成本来源', value: (row) => row.costSource === undefined ? null : COST_SOURCE_LABELS[row.costSource] },\n { key: 'archived', label: '已归档', value: (row) => row.archived ? '是' : '否' },\n]\n\nexport function SessionsTab(props: { data: SessionsResponse | null; channels: Channel[] }): ReactNode {\n const [query, setQuery] = useState('')\n const [channelFilter, setChannelFilter] = useState('ALL')\n const [daysFilter, setDaysFilter] = useState('30')\n const [sortKey, setSortKey] = useState<SortKey>('recent')\n const [archiveFilter, setArchiveFilter] = useState<ArchiveFilter>('hide')\n const [nowMs] = useState(() => Date.now())\n const rows = props.data?.rows ?? []\n const archivedCount = rows.filter((row) => row.archived).length\n // 零 Token 的会话(调用失败、没产生用量)不展示,条数如实告知\n const hiddenEmpty = dropEmptyRows(rows, (row) => row.tokens).hidden\n\n const visible = useMemo(() => {\n const keyword = query.trim().toLowerCase()\n const maxAgeDays = Number(daysFilter)\n const filtered = dropEmptyRows(rows, (row) => row.tokens).rows.filter((row) => {\n const title = (row.title ?? '') + ' ' + row.id + ' ' + (row.workspace ?? '')\n const matchesQuery = keyword === '' || title.toLowerCase().includes(keyword)\n const matchesChannel = channelFilter === 'ALL' || row.provider === channelFilter\n const matchesAge = maxAgeDays === 0 || row.lastTime === null\n || (nowMs - row.lastTime) <= maxAgeDays * 86400000\n const matchesArchive = archiveFilter === 'all' || (archiveFilter === 'only' ? row.archived : !row.archived)\n return matchesQuery && matchesChannel && matchesAge && matchesArchive\n })\n const sorters: Record<SortKey, (first: SessionRow, second: SessionRow) => number> = {\n recent: (first, second) => (second.lastTime ?? 0) - (first.lastTime ?? 0),\n tokensDesc: (first, second) => second.tokens - first.tokens,\n tokensAsc: (first, second) => first.tokens - second.tokens,\n durationDesc: (first, second) => durationOf(second) - durationOf(first),\n }\n return [...filtered].sort(sorters[sortKey])\n }, [rows, query, channelFilter, daysFilter, sortKey, nowMs, archiveFilter])\n\n /** 只导当前筛选后的会话行(归档筛选、时间窗口、搜索都算数)。 */\n const exportRows = (format: 'csv' | 'json'): void => {\n if (format === 'csv') downloadFile(exportFileName('sessions', 'csv'), toCsv(visible, EXPORT_COLUMNS), CSV_MIME)\n else downloadFile(exportFileName('sessions', 'json'), toJson(visible), JSON_MIME)\n }\n\n if (props.data === null) return <div className={styles.empty}>会话数据读取中或不可用…</div>\n\n const groups: Array<{ label: string; rows: SessionRow[] }> = []\n if (sortKey === 'recent') {\n for (const row of visible) {\n const label = dayLabelOf(row.lastTime, nowMs)\n const last = groups[groups.length - 1]\n if (last === undefined || last.label !== label) groups.push({ label, rows: [row] })\n else last.rows.push(row)\n }\n }\n\n return (\n <div>\n {props.data.coverage.status !== 'complete' && (\n <div className={styles.warning}>\n {props.data.coverage.status === 'unavailable'\n ? '会话数据不可用(宿主未提供会话服务或全部读取失败)'\n : '会话数据不完整:' + String(props.data.coverage.skippedSessions) + ' 个会话读取失败,未计入统计'}\n </div>\n )}\n <div className={listStyles.filterBar}>\n <input className={listStyles.searchInput} placeholder=\"搜索会话标题、session id、工作区…\" value={query} onChange={(event) => setQuery(event.target.value)} />\n <select className={listStyles.filterSelect} value={channelFilter} onChange={(event) => setChannelFilter(event.target.value)}>\n <option value=\"ALL\">全部通道</option>\n {props.channels.map((channel) => <option key={channel.provider} value={channel.provider}>{channel.displayName}</option>)}\n </select>\n <select className={listStyles.filterSelect} value={daysFilter} onChange={(event) => setDaysFilter(event.target.value)}>\n <option value=\"7\">近 7 天</option>\n <option value=\"30\">近 30 天</option>\n <option value=\"0\">全部</option>\n </select>\n <select className={listStyles.filterSelect} value={sortKey} onChange={(event) => setSortKey(event.target.value as SortKey)}>\n <option value=\"recent\">最新会话</option>\n <option value=\"tokensDesc\">Tokens 最多</option>\n <option value=\"tokensAsc\">Tokens 最少</option>\n <option value=\"durationDesc\">时长最长</option>\n </select>\n <select\n className={listStyles.filterSelect}\n value={archiveFilter}\n onChange={(event) => setArchiveFilter(event.target.value as ArchiveFilter)}\n title=\"已归档会话只做标记,仍然计入统计\"\n >\n <option value=\"hide\">隐藏已归档</option>\n <option value=\"all\">全部对话(显示已归档)</option>\n <option value=\"only\">仅显示已归档</option>\n </select>\n <span className={exportStyles.exportGroup}>\n <button className={exportStyles.exportBtn} disabled={visible.length === 0} onClick={() => exportRows('csv')}>导出 CSV</button>\n <button className={exportStyles.exportBtn} disabled={visible.length === 0} onClick={() => exportRows('json')}>导出 JSON</button>\n </span>\n </div>\n {archiveFilter === 'hide' && archivedCount > 0 && (\n <div className={styles.statExtra}>\n 另有 {archivedCount} 个已归档会话未显示(归档只是标记,用量仍计入上方统计)\n </div>\n )}\n\n <table className={styles.table + ' ' + listStyles.sessionTable}>\n <thead>\n <tr><th>会话</th><th>通道</th><th>时间 / 时长</th><th>Tokens</th><th>命中率</th><th>成本</th></tr>\n </thead>\n <tbody>\n {groups.map((group) => {\n const groupTokens = group.rows.reduce((total, row) => total + row.tokens, 0)\n return (\n <Fragment key={'group-' + group.label}>\n <tr className={listStyles.sessionDay}>\n <td colSpan={6}>\n {group.label}\n <span className={listStyles.dayCount}>{group.rows.length} 个会话 · {fmtTokens(groupTokens)}</span>\n </td>\n </tr>\n {group.rows.map((row) => sessionRowOf(row, props.channels))}\n </Fragment>\n )\n })}\n {sortKey !== 'recent' && visible.map((row) => sessionRowOf(row, props.channels))}\n {visible.length === 0 && <tr><td colSpan={6} className={styles.empty}>没有符合条件的会话</td></tr>}\n </tbody>\n </table>\n {hiddenEmpty > 0 && <div className={styles.statExtra}>{hiddenEmptyRowsText(hiddenEmpty)}</div>}\n <div className={styles.statExtra}>\n 会话用量按宿主会话事件折叠(每个结算样本计一次调用);成本按台账模型均价估算\n {props.data.priced ? '' : '(台账无成本数据,暂不可估)'}\n </div>\n </div>\n )\n}\n\nfunction sessionRowOf(row: SessionRow, channels: Channel[]): ReactNode {\n const channel = channelOf(channels, row.provider)\n const costCell = costCellText(channel, row.cost ?? 0)\n return (\n <tr key={row.id} className={row.archived ? listStyles.rowArchived : undefined}>\n <td>\n <div className={listStyles.listMain}>\n {row.title ?? '会话 ' + shortIdOf(row.id)}\n {row.archived && <span className={listStyles.archivedTag}>已归档</span>}\n </div>\n <div className={listStyles.listSub}>{row.workspace ?? '未归属工作区'}</div>\n </td>\n <td>{row.providerLabel ?? displayNameOf(channels, row.provider ?? '')}</td>\n <td>\n <div>{row.lastTime === null ? '—' : dayLabelOf(row.lastTime, Date.now()) + ' ' + fmtTime(row.lastTime)}</div>\n <div className={listStyles.listSub}>时长 {fmtDuration(durationOf(row))}</div>\n </td>\n <td>{fmtTokens(row.tokens)}</td>\n <td>{row.cacheHitRate === null ? '—' : row.cacheHitRate.toFixed(1) + '%'}</td>\n <td>{row.cost === null || channel === null || channel.costMode !== 'perToken'\n ? <span className={styles.dim}>{costCell.text}</span>\n : <>{costCell.text}{showsAmount(costCell) && <CostSourceChip source={row.costSource} />}</>}</td>\n </tr>\n )\n}\n\nfunction durationOf(row: SessionRow): number {\n if (row.firstTime === null || row.lastTime === null) return 0\n return Math.max(0, row.lastTime - row.firstTime)\n}\n\n/** 会话头通常不带标题,用 id 的短片段做可读标识。 */\nfunction shortIdOf(id: string): string {\n const stripped = id.replace(/^session-/, '')\n return stripped.slice(0, 8)\n}\n\nfunction dayLabelOf(timeMs: number | null, nowMs: number): string {\n if (timeMs === null) return '未知日期'\n const dateKey = isoDate(new Date(timeMs))\n if (dateKey === isoDate(new Date(nowMs))) return '今日'\n if (dateKey === isoDate(new Date(nowMs - 86400000))) return '昨日'\n return dateKey\n}\n\n/** 保留调用计数格式,避免各 Tab 各写一份。 */\nexport { fmtCalls }\n","/**\n * 「使用情况」设置页外壳:Tab 路由、范围 / 通道筛选状态与取数。\n * 台账类数据(通道 / 台账 / 热力图 / 汇总 / 快照)来自本地文件端点;\n * 项目与会话数据来自宿主会话事件折叠,切到对应 Tab 时才首次拉取。\n */\nimport { useCallback, useEffect, useMemo, useState, useSyncExternalStore } from 'react'\nimport { loadChannels, loadHeatmap, loadModels, loadPricing, loadProjects, loadQuota, loadSessions, loadSummary, loadUsage } from './api.ts'\nimport { isoDate, shiftedIsoDate } from './format.ts'\nimport { pricingSettings } from './pricingSettings.ts'\nimport { TooltipView, useTooltip } from './tooltip.tsx'\nimport { OverviewTab } from './tabs/OverviewTab.tsx'\nimport { DetailTab, type RangeKey } from './tabs/DetailTab.tsx'\nimport { ModelsTab } from './tabs/ModelsTab.tsx'\nimport { ProjectsTab } from './tabs/ProjectsTab.tsx'\nimport { QuotaTab } from './tabs/QuotaTab.tsx'\nimport { SessionsTab } from './tabs/SessionsTab.tsx'\nimport type { DetailSortState } from './components/DailyDetailTable.tsx'\nimport type {\n Channel,\n HeatmapDay,\n ModelsResponse,\n PricingResponse,\n ProjectsResponse,\n QuotaProvider,\n SessionsResponse,\n SummaryResponse,\n UsageResponse,\n} from './types.ts'\nimport styles from './styles/shared.module.css'\n\ntype TabId = 'overview' | 'detail' | 'projects' | 'models' | 'sessions' | 'quota'\n\nconst TABS: Array<[TabId, string]> = [\n ['overview', '总览'],\n ['detail', '使用明细'],\n ['projects', '项目用量'],\n ['models', '按模型'],\n ['sessions', '会话用量'],\n ['quota', '余额与配额'],\n]\n\nexport function KeyUsageSection() {\n const [activeTab, setActiveTab] = useState<TabId>('overview')\n const [range, setRange] = useState<RangeKey>('month')\n const [customFrom, setCustomFrom] = useState(() => shiftedIsoDate(-29))\n const [customTo, setCustomTo] = useState(() => isoDate(new Date()))\n const [channelFilter, setChannelFilter] = useState('ALL')\n const [expandedPeriods, setExpandedPeriods] = useState<Record<string, boolean>>({})\n const [detailSort, setDetailSort] = useState<DetailSortState>({ key: 'period', dir: 'desc' })\n\n const [channels, setChannels] = useState<Channel[]>([])\n const [quotas, setQuotas] = useState<QuotaProvider[]>([])\n const [summary, setSummary] = useState<SummaryResponse | null>(null)\n const [heatmap, setHeatmap] = useState<HeatmapDay[]>([])\n const [usage, setUsage] = useState<UsageResponse | null>(null)\n const [sessions, setSessions] = useState<SessionsResponse | null>(null)\n const [projects, setProjects] = useState<ProjectsResponse | null>(null)\n const [models, setModels] = useState<ModelsResponse | null>(null)\n const [pricing, setPricing] = useState<PricingResponse | null>(null)\n const [available, setAvailable] = useState<{ from: string; to: string } | null>(null)\n const [loading, setLoading] = useState(false)\n const tooltip = useTooltip()\n // 规则改动会经 configForms 推回来,这里跟着重取一次服务端对照(覆盖度 / 错峰状态)\n const pricingState = useSyncExternalStore(pricingSettings.store.subscribe, pricingSettings.store.getSnapshot)\n const pricingSignature = JSON.stringify(pricingState.config)\n\n const reload = useCallback(async (includeSessionData: boolean, forceQuota = false) => {\n setLoading(true)\n // 先查余额:服务端会借这次调用预热实时结果,随后 /channels 的状态判定就能用上\n const quotaResult = await loadQuota(forceQuota)\n const [channelResult, summaryResult, heatmapResult] = await Promise.all([\n loadChannels(), loadSummary(), loadHeatmap(),\n ])\n setChannels(channelResult ?? [])\n setQuotas(quotaResult ?? [])\n setSummary(summaryResult)\n setHeatmap(heatmapResult ?? [])\n if (includeSessionData) {\n const [sessionResult, projectResult, modelResult] = await Promise.all([loadSessions(), loadProjects(), loadModels()])\n setSessions(sessionResult)\n setProjects(projectResult)\n setModels(modelResult)\n }\n setLoading(false)\n // pricingSignature 不是被用到的值,而是「规则变了」的失效信号:\n // 成本在服务端按规则算,规则一改这里就必须整体重取,否则四个页签还是旧数字\n }, [pricingSignature])\n\n useEffect(() => { void reload(false) }, [reload])\n\n // 计费规则面板的服务端对照:规则一变就重取,让覆盖度与四个页签的成本角标同步\n useEffect(() => {\n let cancelled = false\n void loadPricing().then((result) => { if (!cancelled) setPricing(result) })\n return () => { cancelled = true }\n }, [pricingSignature])\n\n // 项目 / 会话 / 模型数据按需加载(首次切到对应 Tab 时;余额页也需要按模型用量给「最值得补规则」排序)\n useEffect(() => {\n if (activeTab === 'sessions' && sessions === null) void loadSessions().then(setSessions)\n if (activeTab === 'projects' && projects === null) void loadProjects().then(setProjects)\n if ((activeTab === 'models' || activeTab === 'quota') && models === null) void loadModels().then(setModels)\n }, [activeTab, sessions, projects, models])\n\n const bounds = useMemo(() => {\n const today = isoDate(new Date())\n if (range === 'today') return { from: today, to: today }\n if (range === 'week') return { from: shiftedIsoDate(-6), to: today }\n if (range === 'month') return { from: shiftedIsoDate(-29), to: today }\n if (range === 'custom') return { from: customFrom, to: customTo < customFrom ? customFrom : customTo }\n return { from: available?.from ?? today, to: available?.to ?? today }\n }, [range, customFrom, customTo, available])\n\n useEffect(() => {\n let cancelled = false\n void loadUsage(bounds.from, bounds.to, channelFilter).then((result) => {\n if (cancelled || result === null) return\n setUsage(result)\n if (result.availableFrom !== null && result.availableTo !== null) {\n setAvailable({ from: result.availableFrom, to: result.availableTo })\n }\n })\n return () => { cancelled = true }\n }, [bounds.from, bounds.to, channelFilter, pricingSignature])\n\n const refresh = useCallback(() => {\n void reload(\n activeTab === 'sessions' || activeTab === 'projects' || activeTab === 'models'\n || sessions !== null || projects !== null || models !== null,\n true,\n )\n void loadUsage(bounds.from, bounds.to, channelFilter).then((result) => { if (result !== null) setUsage(result) })\n }, [reload, activeTab, sessions, projects, models, bounds.from, bounds.to, channelFilter])\n\n return (\n <div className={styles.section}>\n <div className={styles.title}>\n <span>使用情况</span>\n <span className={styles.titleActions}>\n <button className={styles.refreshBtn} disabled={loading} onClick={refresh}>\n {loading ? '刷新中…' : '↻ 刷新'}\n </button>\n </span>\n </div>\n\n <div className={styles.tabBar}>\n {TABS.map(([tabId, label]) => (\n <button key={tabId} className={activeTab === tabId ? styles.active : ''} onClick={() => setActiveTab(tabId)}>{label}</button>\n ))}\n </div>\n\n {activeTab === 'overview' && (\n <OverviewTab\n channels={channels}\n summary={summary}\n quotas={quotas}\n heatmap={heatmap}\n tooltip={tooltip}\n onOpenDetail={(provider) => { setChannelFilter(provider); setActiveTab('detail') }}\n />\n )}\n {activeTab === 'detail' && (\n <DetailTab\n usage={usage}\n channels={channels}\n range={range}\n onRange={setRange}\n customFrom={customFrom}\n onCustomFrom={setCustomFrom}\n customTo={customTo}\n onCustomTo={setCustomTo}\n channelFilter={channelFilter}\n onChannelFilter={setChannelFilter}\n expandedPeriods={expandedPeriods}\n onTogglePeriod={(periodKey) => setExpandedPeriods((previous) => ({ ...previous, [periodKey]: previous[periodKey] !== true }))}\n sort={detailSort}\n onSort={setDetailSort}\n bounds={bounds}\n tooltip={tooltip}\n />\n )}\n {activeTab === 'projects' && <ProjectsTab data={projects} channels={channels} />}\n {activeTab === 'models' && <ModelsTab data={models} channels={channels} />}\n {activeTab === 'sessions' && <SessionsTab data={sessions} channels={channels} />}\n {activeTab === 'quota' && (\n <QuotaTab\n channels={channels}\n quotas={quotas}\n pricing={pricing}\n pricingState={pricingState}\n pricingSettings={pricingSettings}\n models={models}\n />\n )}\n\n <div className={styles.footnote}>\n <b>口径说明</b>\n <ul className={styles.footnoteList}>\n <li>\n 按天数据优先取宿主用量台账(含官方成本);台账无记录的日期回退本地会话事件折叠,那些天没有官方成本\n {summary !== null && summary.todaySource === 'session' ? '(当前有 ' + summary.sessionDates.length + ' 天由会话补位)' : ''}\n 。两套来源按天取舍、不相加。\n </li>\n <li>热力图按可见区间内活跃日的三分位分档(少 / 中 / 高)。</li>\n <li>项目用量、会话用量、按模型与单日「按小时」均来自会话事件,每个结算样本计一次调用(不计成本)。</li>\n <li>已归档会话只是标记:用量照常计入,会话列表默认隐藏、可切换显示(显示时淡化并标注)。</li>\n <li>命中率 = 缓存读 ÷(输入 + 输出 + 缓存读)。</li>\n <li>\n 成本优先级:<b>台账当天的官方成本</b> &gt; <b>你的计费规则</b> &gt; <b>台账反推均价</b> &gt; 无依据;\n 每个成本单元格旁的角标写明来源(<b>官方</b> / <b>自定</b> / <b>估算</b>,无依据显示 —)。\n 规则在「余额与配额」页下半部分维护,存在宿主设置服务里,改完立即重算。\n </li>\n <li>余额与订阅窗口实时查询官方接口(失败回落本机快照),原样展示,不做换算与建议。</li>\n </ul>\n </div>\n\n <TooltipView tooltip={tooltip.tooltip} />\n </div>\n )\n}\n","/**\n * 「使用情况」主区域页面(`main` slot,与 sidebar.panellist 的 id 同名配对)。\n * 点击侧边栏导航项后由宿主在主内容区内联渲染 —— 不是弹窗、不占设置页。\n * 滚动由本容器负责:宿主主内容区不会滚动,长表格必须靠自己滚。\n */\nimport type { ReactNode } from 'react'\nimport { KeyUsageSection } from './KeyUsageSection.tsx'\nimport styles from './styles/page.module.css'\n\n/** 宿主会传入根作用域的标准 kit 与绑定的 `t`;本页面当前不需要它们。 */\nexport function UsagePage(_props: Record<string, unknown>): ReactNode {\n return (\n <div className={styles.page}>\n <div className={styles.inner}>\n <KeyUsageSection />\n </div>\n </div>\n )\n}\n","/**\n * 插件页(`plugins.bundle.config` 槽,以包名为键)里的计费规则卡片。\n * 与「余额与配额」页下半部分共用同一个面板与同一份状态(存在宿主设置服务里),\n * 这里只是多一个入口,不做第二套逻辑。\n */\nimport { useEffect, useState, useSyncExternalStore, type ReactNode } from 'react'\nimport { loadChannels, loadModels, loadPricing } from '../api.ts'\nimport { pricingSettings } from '../pricingSettings.ts'\nimport type { Channel, ModelsResponse, PricingResponse } from '../types.ts'\nimport { PricingRulesPanel } from './PricingRulesPanel.tsx'\n\nexport function PricingCard(): ReactNode {\n const state = useSyncExternalStore(pricingSettings.store.subscribe, pricingSettings.store.getSnapshot)\n const [pricing, setPricing] = useState<PricingResponse | null>(null)\n const [channels, setChannels] = useState<Channel[]>([])\n // 按模型用量只用于抽屉里的「最值得补规则的模型」,拿不到就整块不显示\n const [models, setModels] = useState<ModelsResponse | null>(null)\n\n useEffect(() => {\n let cancelled = false\n void loadPricing().then((result) => { if (!cancelled) setPricing(result) })\n void loadChannels().then((result) => { if (!cancelled) setChannels(result ?? []) })\n void loadModels().then((result) => { if (!cancelled) setModels(result) })\n return () => { cancelled = true }\n }, [state.config])\n\n return (\n <PricingRulesPanel\n settings={pricingSettings}\n state={state}\n pricing={pricing}\n channels={channels}\n models={models}\n />\n )\n}\n","/**\n * dsh-key-usage 客户端入口:注册「使用情况」侧边栏导航项 + 主区域页面,\n * 并把计费规则面板接到宿主的配置表单服务上。\n * UI 逻辑在 UsagePage / KeyUsageSection 里;本文件只做 cordis apply 接线。\n *\n * slot 契约(对齐已装的 dsh-context「上下文洞察」写法):\n * - `sidebar.panellist`:宿主自持整行(标签 / hover / active),插件只提供图标,`id` 是面板标识;\n * - `main`:同一标识放在 `key` 上,宿主在主内容区按它渲染整页 —— 因此不是弹窗、也不占设置页;\n * - `plugins.bundle.config`:插件页(以包名为键)里的配置卡片,与页面里的规则面板共用同一份状态。\n *\n * 计费规则的存储:命名空间就是本包在 profile 里的条目 id,写入由宿主的 config-editor\n * 落到当前 profile 的 cordis patch 上;本插件不写任何文件(见 AGENTS.md 硬约束)。\n */\nimport { createElement as h } from 'react'\nimport type { SectionContext } from './types.ts'\nimport { pricingSettings } from './pricingSettings.ts'\nimport { UsageIcon } from './UsageIcon.tsx'\nimport { UsagePage } from './UsagePage.tsx'\nimport { PricingCard } from './components/PricingCard.tsx'\n\nconst NS = 'dsh-key-usage'\n/** 侧边栏条目与 main 页面共用的面板标识(宿主 MainPanelId 域,命名空间化避免撞车)。 */\nconst PANEL_ID = NS\n\nexport const name = NS\nexport const inject = ['slots']\n\nexport function apply(ctx: SectionContext): void {\n ctx.slots.inject('main', () => ctx.slots.register({\n name: 'main',\n key: PANEL_ID,\n }, UsagePage))\n\n ctx.slots.inject('sidebar.panellist', () => ctx.slots.register({\n name: 'sidebar.panellist',\n id: PANEL_ID,\n order: 30,\n label: () => '使用情况',\n }, (props: { size?: number }) => h(UsageIcon, { size: props.size })))\n\n // 配置表单服务由宿主 ui-settings 提供;没有它就只读(面板会提示只能导入 / 导出)\n ctx.inject?.(['configForms'], (scope) => {\n const forms = scope.configForms\n if (forms === undefined) return\n scope.effect?.(() => pricingSettings.attach(forms.get(NS)), 'dsh-key-usage: pricing rules binding')\n // 只在宿主真的服务这个命名空间时才登记插件页卡片,否则那个部署里不该留下痕迹\n scope.effect?.(() => forms.whileServed([NS], () => scope.slots.inject('plugins.bundle.config', () => scope.slots.register({\n name: 'plugins.bundle.config',\n key: NS,\n }, PricingCard))), 'dsh-key-usage: plugins page card')\n })\n}\n"],"mappings":";;;;;;;;;EAwFA,MAAa,qBAAiD;GAC5D,UAAU;GACV,MAAM;GACN,SAAS;GACT,UAAU;GACV,MAAM;EACR;;EAGA,MAAa,oBAAgD;GAC3D,UAAU;GACV,MAAM;GACN,SAAS;GACT,UAAU;GACV,MAAM;EACR;EAEA,MAAa,cAA2C;GACtD,kBAAkB;GAClB,mBAAmB;GACnB,SAAS;EACX;EAEA,MAAa,eAA8B;GAAC;GAAoB;GAAqB;EAAS;EAC9F,MAAa,mBAAmB,CAAC,OAAO,KAAK;EAE7C,MAAa,eAA8B;GAAE,SAAS;GAAG,UAAU;GAAO,OAAO,CAAC;EAAE;;EAGpF,SAAgB,iBAAiB,UAA0B;GACzD,IAAI,aAAa,OAAO,OAAO;GAC/B,IAAI,aAAa,OAAO,OAAO;GAC/B,OAAO,WAAW;EACpB;EAEA,SAAgB,UAAU,MAA2B;GACnD,OAAO,KAAK,WAAW,MAAM,KAAK;EACpC;EAEA,SAAgB,YAAY,MAA2B;GACrD,MAAM,QAAQ,KAAK,UAAU,MAAM,SAAS,KAAK;GACjD,QAAQ,KAAK,aAAa,MAAM,SAAS,KAAK,YAAY,QAAQ;EACpE;;EAGA,SAAgB,mBAAmB,MAA2B;GAC5D,IAAI,KAAK,YAAY,QAAQ,KAAK,QAAQ,QAAQ,WAAW,GAAG,OAAO;GACvE,OAAO,KAAK,QAAQ,QAAQ,KAAK,WAAW;IAC1C,MAAM,OAAO,OAAO,OAAO,MAAM,OAAO;IACxC,MAAM,SAAS,iBAAiB,OAAO,IAAI;IAC3C,OAAO,WAAW,KAAK,OAAO,OAAO,MAAM,SAAS;GACtD,CAAC,CAAC,CAAC,KAAK,GAAG;EACb;EAKA,MAAa,oBAAgC;GAAC;GAAS;GAAW;EAAS;EAE3E,MAAa,mBAA6C;GACxD,OAAO;GACP,SAAS;GACT,SAAS;EACX;;EAGA,MAAa,iBAAyD;GACpE,OAAO,KAAA;GACP,SAAS;IAAC;IAAG;IAAG;IAAG;IAAG;GAAC;GACvB,SAAS,CAAC,GAAG,CAAC;EAChB;;EAGA,SAAgB,WAAW,MAAsC;GAC/D,MAAM,aAAa,cAAc,IAAI;GACrC,IAAI,eAAe,KAAA,GAAW,OAAO;GACrC,MAAM,MAAM,WAAW,KAAK,GAAG;GAC/B,IAAI,QAAQ,aAAa,OAAO;GAChC,IAAI,QAAQ,OAAO,OAAO;GAE1B,OAAO;EACT;;EAGA,SAAgB,iBAAiB,MAAoC;GACnE,MAAM,QAAQ,WAAW,IAAI;GAC7B,OAAO,UAAU,UAAU,KAAK,iBAAiB;EACnD;;;;;EAMA,SAAgB,cAAc,KAAoC;GAChE,IAAI,CAAC,MAAM,QAAQ,GAAG,GAAG,OAAO,KAAA;GAChC,MAAM,uBAAO,IAAI,IAAY;GAC7B,KAAK,MAAM,SAAS,KAAK;IACvB,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,QAAQ,GAAG;IACrF,KAAK,IAAI,KAAK;GAChB;GACA,IAAI,KAAK,SAAS,GAAG,OAAO,KAAA;GAC5B,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,OAAO,WAAW,QAAQ,MAAM;EACzD;EAEA,SAAS,SAAS,OAAgB,UAA0B;GAC1D,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,SAAS,IAAI,QAAQ;EACrF;EAEA,SAAS,OAAO,OAAgB,UAA0B;GACxD,OAAO,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,IAAI;EAC3E;EAEA,SAAS,QAAQ,KAA8B,UAAsC;GACnF,OAAO;IACL,OAAO,SAAS,IAAI,OAAO,SAAS,KAAK;IACzC,WAAW,SAAS,IAAI,WAAW,SAAS,SAAS;IACrD,YAAY,SAAS,IAAI,YAAY,SAAS,UAAU;IACxD,QAAQ,SAAS,IAAI,QAAQ,SAAS,MAAM;GAC9C;EACF;EAEA,SAAS,UAAU,KAA+B;GAChD,IAAI,CAAC,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC;GACjC,MAAM,UAA2B,CAAC;GAClC,KAAK,MAAM,SAAS,KAAK;IACvB,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM;IACjD,MAAM,OAAQ,MAA6B;IAC3C,MAAM,KAAM,MAA2B;IACvC,IAAI,OAAO,SAAS,YAAY,OAAO,OAAO,UAAU;IACxD,IAAI,CAAC,kBAAkB,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,kBAAkB,KAAK,GAAG,KAAK,CAAC,GAAG;IAChF,MAAM,OAAO,cAAe,MAA6B,IAAI;IAC7D,QAAQ,KAAK;KAAE,MAAM,KAAK,KAAK;KAAG,IAAI,GAAG,KAAK;KAAG,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;IAAG,CAAC;GAC5F;GACA,OAAO;EACT;;;;;EAMA,SAAgB,uBAAuB,OAA+B;GACpE,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;GACxD,MAAM,SAAS;GACf,MAAM,WAAW,OAAO,OAAO,UAAU,aAAa,QAAQ;GAC9D,MAAM,QAAuB,CAAC;GAC9B,KAAK,MAAM,SAAS,MAAM,QAAQ,OAAO,KAAK,IAAI,OAAO,QAAQ,CAAC,GAAG;IACnE,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM;IACjD,MAAM,MAAM;IACZ,MAAM,OAAO,QAAQ,KAAK;KAAE,OAAO;KAAG,WAAW;KAAG,YAAY;KAAG,QAAQ;IAAE,CAAC;IAC9E,IAAI,UAAiC;IACrC,IAAI,OAAO,IAAI,YAAY,YAAY,IAAI,YAAY,MAAM;KAC3D,MAAM,aAAa,IAAI;KACvB,MAAM,UAAU,UAAU,WAAW,OAAO;KAC5C,IAAI,QAAQ,SAAS,GAAG,UAAU;MAAE,GAAG,QAAQ,YAAY,IAAI;MAAG;KAAQ;IAC5E;IACA,MAAM,KAAK;KACT,UAAU,OAAO,IAAI,UAAU,GAAG;KAClC,OAAO,OAAO,IAAI,OAAO,GAAG;KAC5B,MAAM,aAAa,SAAS,IAAI,IAAmB,IAAI,IAAI,OAAsB;KACjF,UAAU,OAAO,IAAI,UAAU,QAAQ;KACvC,GAAG;KACH;KACA,MAAM,OAAO,IAAI,SAAS,WAAW,IAAI,OAAO;IAClD,CAAC;GACH;GACA,OAAO;IACL,SAAS,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;IAC/D;IACA;GACF;EACF;;EAGA,SAAgB,kBAAkB,MAA4C;GAC5E,MAAM,SAAkC;IACtC,UAAU,KAAK,SAAS,KAAK,MAAM,KAAK,MAAM,KAAK,SAAS,KAAK;IACjE,OAAO,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK;IACxD,MAAM,KAAK;IACX,UAAU,KAAK;IACf,OAAO,KAAK;IACZ,WAAW,KAAK;IAChB,YAAY,KAAK;IACjB,QAAQ,KAAK;IACb,MAAM,KAAK;GACb;GACA,IAAI,KAAK,YAAY,QAAQ,KAAK,QAAQ,QAAQ,SAAS,GACzD,OAAO,UAAU;IAEf,SAAS,KAAK,QAAQ,QAAQ,KAAK,WAAW;KAC5C,MAAM,OAAO,cAAc,OAAO,IAAI;KACtC,OAAO,SAAS,KAAA,IACZ;MAAE,MAAM,OAAO;MAAM,IAAI,OAAO;KAAG,IACnC;MAAE,MAAM,OAAO;MAAM,IAAI,OAAO;MAAI;KAAK;IAC/C,CAAC;IACD,OAAO,KAAK,QAAQ;IACpB,WAAW,KAAK,QAAQ;IACxB,YAAY,KAAK,QAAQ;IACzB,QAAQ,KAAK,QAAQ;GACvB;GAEF,OAAO;EACT;EAEA,SAAgB,eAAe,QAAgD;GAC7E,OAAO;IACL,SAAS,OAAO;IAChB,UAAU,OAAO;IACjB,OAAO,OAAO,MAAM,IAAI,iBAAiB;GAC3C;EACF;;EAGA,SAAgB,UAAU,QAAoC;GAC5D,OAAO;IACL,UAAU;IAAK,OAAO;IAAK,MAAM;IAAoB,UAAU,OAAO;IACtE,OAAO;IAAG,WAAW;IAAG,YAAY;IAAG,QAAQ;IAAG,SAAS;IAAM,MAAM;GACzE;EACF;;EAQA,SAAgB,qBAAqB,MAA4B;GAC/D,IAAI;GACJ,IAAI;IACF,SAAS,KAAK,MAAM,IAAI;GAC1B,SAAS,OAAO;IACd,OAAO;KAAE,QAAQ;KAAM,OAAO,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;IAAG;GACxG;GACA,MAAM,YAAY,MAAM,QAAQ,MAAM,IAAI;IAAE,SAAS;IAAG,UAAU,aAAa;IAAU,OAAO;GAAO,IAAI;GAC3G,IAAI,OAAO,cAAc,YAAY,cAAc,MACjD,OAAO;IAAE,QAAQ;IAAM,OAAO;GAAe;GAE/C,MAAM,SAAS,uBAAuB,SAAS;GAC/C,IAAI,OAAO,MAAM,WAAW,GAAG,OAAO;IAAE,QAAQ;IAAM,OAAO;GAAwC;GACrG,OAAO;IAAE;IAAQ,OAAO;GAAK;EAC/B;;EAGA,SAAgB,cAAc,MAAkC;GAC9D,MAAM,SAAS;IAAC,KAAK;IAAO,KAAK;IAAW,KAAK;IAAY,KAAK;GAAM;GACxE,IAAI,OAAO,OAAO,UAAU,UAAU,CAAC,GAAG,OAAO;GACjD,IAAI,OAAO,MAAM,UAAU,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,CAAC,GAAG,OAAO;GACzE,IAAI,KAAK,YAAY,QAAQ,KAAK,QAAQ,QAAQ,WAAW,GAAG,OAAO;GACvE,OAAO;EACT;;;;;;;;;;ECpSA,SAAgB,wBAA8C;GAC5D,IAAI,QAA8B;IAChC,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,OAAO;GACT;GACA,IAAI,OAA2B;GAC/B,IAAI,cAAmC;GACvC,MAAM,4BAAY,IAAI,IAAgB;GAEtC,MAAM,WAAW,SAAqC;IACpD,IACE,KAAK,WAAW,MAAM,UAAU,KAAK,aAAa,MAAM,YACrD,KAAK,UAAU,MAAM,SAAS,KAAK,WAAW,MAAM,QACvD;IACF,QAAQ;IACR,KAAK,MAAM,YAAY,WAAW,SAAS;GAC7C;GAEA,MAAM,aAAmB;IACvB,IAAI,SAAS,MAAM;KACjB,QAAQ;MAAE,QAAQ;MAAe,UAAU;MAAO,QAAQ,MAAM;MAAQ,OAAO,MAAM;KAAM,CAAC;KAC5F;IACF;IACA,MAAM,WAAW,KAAK,YAAY;IAClC,MAAM,QAAQ,SAAS,WAAW,WAAW,SAAS,UAAU,KAAA;IAChE,QAAQ;KACN,QAAQ,QAAQ,UAAU,SAAS,WAAW,gBAAgB,gBAAgB;KAC9E,UAAU,SAAS,aAAa;KAChC,QAAQ,QAAQ,uBAAuB,SAAS,KAAK,IAAI,MAAM;KAC/D,OAAO,MAAM;IACf,CAAC;GACH;GAEA,OAAO;IACL,OAAO;KACL,UAAU,UAAU;MAClB,UAAU,IAAI,QAAQ;MACtB,aAAa;OAAE,UAAU,OAAO,QAAQ;MAAE;KAC5C;KACA,mBAAmB;IACrB;IACA,OAAO,MAAM;KACX,cAAc;KACd,cAAc;KACd,OAAO;KACP,IAAI,SAAS,MAAM;MACjB,cAAc,KAAK,UAAU,IAAI;MACjC,QAAQ;OAAE,GAAG;OAAO,OAAO;MAAK,CAAC;KACnC;KACA,KAAK;KACL,aAAa;MACX,cAAc;MACd,cAAc;MACd,OAAO;KACT;IACF;IACA,MAAM,KAAK,QAAQ;KACjB,IAAI,SAAS,MAAM;MACjB,QAAQ;OAAE,GAAG;OAAO,OAAO;MAAgC,CAAC;MAC5D,OAAO;KACT;KACA,QAAQ;MAAE,GAAG;MAAO,OAAO;KAAK,CAAC;KACjC,IAAI,WAAW;KACf,IAAI;MAEF,WAAW,MAAM,KAAK,OAAO,CAAC;OAAE,IAAI;OAAO,MAAM,CAAC,SAAS;OAAG,OAAO,eAAe,MAAM;MAAE,CAAC,CAAC;KAChG,SAAS,OAAO;MACd,QAAQ;OAAE,GAAG;OAAO,OAAO,WAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;MAAG,CAAC;MAC/F,OAAO;KACT;KACA,IAAI,CAAC,UAAU,QAAQ;MAAE,GAAG;MAAO,OAAO;KAA6B,CAAC;KACxE,OAAO;IACT;IACA,gBAAgB,MAAM,WAAW;IACjC,UAAU,SAAS;KACjB,QAAQ;MAAE,GAAG;MAAO,OAAO;KAAQ,CAAC;IACtC;GACF;EACF;;;;;EAMA,MAAa,kBAAkB,sBAAsB;;;EC3HrD,SAAgB,UAAU,EAAE,OAAO,MAAoC;GACrE,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IACE,OAAO;IACP,QAAQ;IACR,SAAQ;IACR,MAAK;IACL,eAAY;IACZ,WAAU;IACV,OAAO,EAAE,SAAS,QAAQ;IAP5B,UAAA;KASE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,GAAE;MAAM,GAAE;MAAM,OAAM;MAAM,QAAO;MAAM,IAAG;MAAM,MAAK;KAAgB,CAAA;KAC7E,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,GAAE;MAAM,GAAE;MAAM,OAAM;MAAM,QAAO;MAAM,IAAG;MAAM,MAAK;KAAgB,CAAA;KAC7E,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,GAAE;MAAO,GAAE;MAAM,OAAM;MAAM,QAAO;MAAO,IAAG;MAAM,MAAK;KAAgB,CAAA;IAC5E;;EAET;;;;;;;ECLA,MAAM,iCAAiB,IAAI,IAAoB;EAE/C,SAAgB,gBAAgB,MAA6B;GAC3D,OAAO,eAAe,IAAI,IAAI,KAAK;EACrC;EAEA,eAAe,UAAa,MAAiC;GAC3D,IAAI;IACF,MAAM,WAAW,MAAM,MAAM,MAAM,EAAE,SAAS,EAAE,QAAQ,mBAAmB,EAAE,CAAC;IAC9E,IAAI,CAAC,SAAS,IAAI;KAChB,eAAe,IAAI,MAAM,SAAS,WAAW,MACzC,iDACA,UAAU,OAAO,SAAS,MAAM,CAAC;KACrC,OAAO;IACT;IACA,eAAe,OAAO,IAAI;IAC1B,OAAO,MAAM,SAAS,KAAK;GAC7B,SAAS,OAAO;IACd,eAAe,IAAI,MAAM,WAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;IAC3F,OAAO;GACT;EACF;EAEA,eAAsB,eAA0C;GAC9D,MAAM,SAAS,MAAM,UAAmC,yBAAyB;GACjF,OAAO,WAAW,OAAO,OAAO,OAAO;EACzC;EAEA,eAAsB,UAAU,MAAc,IAAY,UAAiD;GACzG,MAAM,SAAS,IAAI,gBAAgB;IAAE;IAAM;GAAG,CAAC;GAC/C,IAAI,aAAa,OAAO,OAAO,IAAI,YAAY,QAAQ;GACvD,OAAO,UAAyB,0BAA0B,OAAO,SAAS,CAAC;EAC7E;EAEA,eAAsB,cAA4C;GAChE,MAAM,SAAS,MAAM,UAAkC,wBAAwB;GAC/E,OAAO,WAAW,OAAO,OAAO,OAAO;EACzC;;;;;EAMA,eAAsB,UAAU,QAAQ,OAAwC;GAE9E,MAAM,SAAS,MAAM,UAA0C,0BADjD,QAAQ,aAAa,GAC0D;GAC7F,OAAO,WAAW,OAAO,OAAO,OAAO;EACzC;EAEA,SAAgB,cAA+C;GAC7D,OAAO,UAA2B,wBAAwB;EAC5D;EAEA,SAAgB,aAAa,QAAQ,KAAuC;GAC1E,OAAO,UAA4B,mCAAmC,OAAO,KAAK,CAAC;EACrF;EAEA,SAAgB,aAAa,QAAQ,KAAuC;GAC1E,OAAO,UAA4B,mCAAmC,OAAO,KAAK,CAAC;EACrF;EAEA,SAAgB,WAAW,QAAQ,KAAqC;GACtE,OAAO,UAA0B,iCAAiC,OAAO,KAAK,CAAC;EACjF;;EAGA,SAAgB,cAA+C;GAC7D,OAAO,UAA2B,wBAAwB;EAC5D;;;;;ECnFA,SAAgB,QAAQ,MAAoB;GAC1C,MAAM,QAAQ,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;GACzD,MAAM,MAAM,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;GAClD,OAAO,GAAG,KAAK,YAAY,EAAE,GAAG,MAAM,GAAG;EAC3C;EAEA,SAAgB,eAAe,YAA4B;GACzD,OAAO,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,aAAa,KAAQ,CAAC;EAC7D;EAEA,SAAgB,UAAU,OAAuB;GAC/C,IAAI,SAAS,KAAK,QAAQ,QAAQ,IAAA,CAAK,QAAQ,CAAC,IAAI;GACpD,IAAI,SAAS,KAAK,QAAQ,QAAQ,IAAA,CAAK,QAAQ,CAAC,IAAI;GACpD,IAAI,SAAS,KAAK,QAAQ,QAAQ,IAAA,CAAK,QAAQ,CAAC,IAAI;GACpD,OAAO,OAAO,KAAK;EACrB;EAEA,SAAgB,QAAQ,QAAwB;GAC9C,OAAO,MAAM,OAAO,QAAQ,CAAC;EAC/B;EAEA,SAAgB,SAAS,OAAuB;GAC9C,OAAO,MAAM,eAAe,OAAO,CAAC,CAAC,QAAQ,MAAM,GAAG;EACxD;;EAGA,SAAgB,aAAa,SAAyB;GACpD,OAAO,QAAQ,MAAM,CAAC;EACxB;;EAGA,SAAgB,YAAY,QAA+B;GACzD,IAAI,WAAW,MAAM,OAAO;GAC5B,MAAM,OAAO,IAAI,KAAK,MAAM;GAC5B,MAAM,QAAQ,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;GACrD,MAAM,UAAU,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;GACzD,OAAO,GAAG,QAAQ,IAAI,EAAE,GAAG,MAAM,GAAG;EACtC;;EAGA,SAAgB,QAAQ,QAA+B;GACrD,IAAI,WAAW,MAAM,OAAO;GAC5B,MAAM,OAAO,IAAI,KAAK,MAAM;GAC5B,OAAO,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,GAAG,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;EACjG;;EAGA,SAAgB,YAAY,cAAqC;GAC/D,IAAI,iBAAiB,QAAQ,gBAAgB,GAAG,OAAO;GACvD,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,MAAM,eAAe,GAAK,CAAC;GAC5D,IAAI,UAAU,IAAI,OAAO,GAAG,QAAQ;GACpC,OAAO,GAAG,KAAK,MAAM,UAAU,EAAE,EAAE,IAAI,UAAU,GAAG;EACtD;;EAGA,SAAgB,YAAY,QAAuB,OAAuB;GACxE,IAAI,WAAW,MAAM,OAAO;GAC5B,MAAM,UAAU,KAAK,OAAO,QAAQ,UAAU,GAAK;GACnD,IAAI,UAAU,GAAG,OAAO;GACxB,IAAI,UAAU,IAAI,OAAO,GAAG,QAAQ;GACpC,IAAI,UAAU,MAAS,OAAO,GAAG,KAAK,MAAM,UAAU,EAAE,EAAE;GAC1D,OAAO,GAAG,KAAK,MAAM,UAAW,IAAQ,EAAE;EAC5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECjDA,SAAgB,aAAyB;GACvC,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAgC,IAAI;GAKlE,OAAO;IAAE;IAAS,OAAA,GAJLC,MAAAA,YAAAA,EAAa,OAAyB,SAAoB;KACrE,WAAW;MAAE,GAAG,MAAM;MAAS,GAAG,MAAM;MAAS;KAAK,CAAC;IACzD,GAAG,CAAC,CAEiB;IAAG,OAAA,GADXA,MAAAA,YAAAA,OAAkB,WAAW,IAAI,GAAG,CAAC,CACvB;GAAE;EAC/B;EAEA,SAAgB,YAAY,EAAE,WAA0D;GACtF,MAAM,cAAA,GAAaC,MAAAA,OAAAA,CAA8B,IAAI;GACrD,CAAA,GAAA,MAAA,gBAAA,OAAsB;IACpB,MAAM,UAAU,WAAW;IAC3B,IAAI,YAAY,QAAQ,YAAY,MAAM;IAC1C,MAAM,OAAO,OAAO,aAAa,QAAQ,cAAc;IACvD,MAAM,OAAO,OAAO,cAAc,QAAQ,eAAe;IACzD,QAAQ,MAAM,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,IAAI,IAAI,IAAI,CAAC,IAAI;IACnE,QAAQ,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,IAAI,IAAI,IAAI,CAAC,IAAI;GACpE,GAAG,CAAC,OAAO,CAAC;GACZ,IAAI,YAAY,MAAM,OAAO;GAC7B,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,KAAK;IAAY,WAAWC,0BAAO;IAAU,UAAA,QAAQ;GAAU,CAAA;EAC7E;EAEA,SAAgB,SAAS,EAAE,YAAgD;GACzE,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWA,0BAAO;IAAW;GAAc,CAAA;EACzD;EAEA,SAAgB,OAAO,EAAE,YAAgD;GACvE,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWA,0BAAO;IAAS;GAAc,CAAA;EACvD;EAEA,SAAgB,OAAO,OAA8F;GACnH,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWA,0BAAO;IAAvB,UAAA;KACG,MAAM,UAAU,KAAA,KAAa,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAG,OAAO,EAAE,YAAY,MAAM,MAAM,EAAI,CAAA;KACtE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,0BAAO;MAAU,UAAA,MAAM;KAAY,CAAA;KACnD,MAAM,WAAW,KAAA,KAAa,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,0BAAO;MAAY,UAAA,MAAM;KAAa,CAAA;KACrF,MAAM,SAAS,KAAA,KAAa,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,0BAAO;MAAU,UAAA,MAAM;KAAW,CAAA;IAC7E;;EAET;EAEA,SAAgB,OAAO,EAAE,SAAS,SAAwD;GACxF,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWA,0BAAO;IAAQ,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAG,OAAO;KAAE,OAAO,KAAK,IAAI,GAAG,OAAO,IAAI;KAAK,YAAY;IAAM,EAAI,CAAA;GAAM,CAAA;EACnH;EAEA,SAAgB,WAAW,EAAE,YAAgD;GAC3E,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWA,0BAAO;IAAa;GAAc,CAAA;EAC3D;;;EC7DA,MAAM,iBAAiB;GAAC;GAAW;GAAW;GAAW;GAAW;GAAW;EAAS;EASxF,SAAgB,eAAe,UAAqB,UAA0B;GAC5E,OAAO,SAAS,WAAW,YAAY,QAAQ,aAAa,QAAQ;EACtE;EAEA,SAAgB,eAAe,UAAqB,UAA0B;GAC5E,MAAM,QAAQ,eAAe,UAAU,QAAQ;GAC/C,OAAO,gBAAgB,SAAS,IAAI,QAAQ,KAAK,eAAe;EAClE;EAEA,SAAgB,cAAc,UAAqB,UAA0B;GAC3E,OAAO,SAAS,MAAM,YAAY,QAAQ,aAAa,QAAQ,CAAC,EAAE,eAAe;EACnF;EAEA,SAAgB,UAAU,UAAqB,UAAyC;GACtF,IAAI,aAAa,MAAM,OAAO;GAC9B,OAAO,SAAS,MAAM,YAAY,QAAQ,aAAa,QAAQ,KAAK;EACtE;;EAGA,SAAgB,aAAa,SAAyB,MAA8C;GAClG,IAAI,YAAY,MAAM,OAAO,OAAO,IAAI;IAAE,MAAM,MAAM,KAAK,QAAQ,CAAC;IAAG,KAAK;GAAM,IAAI;IAAE,MAAM;IAAK,KAAK;GAAK;GAC7G,IAAI,QAAQ,aAAa,OAAO,OAAO;IAAE,MAAM;IAAO,KAAK;GAAK;GAChE,IAAI,QAAQ,aAAa,QAAQ,OAAO;IAAE,MAAM;IAAS,KAAK;GAAK;GACnE,IAAI,QAAQ,aAAa,QAAQ,OAAO;IAAE,MAAM;IAAO,KAAK;GAAK;GACjE,OAAO,OAAO,IAAI;IAAE,MAAM,MAAM,KAAK,QAAQ,CAAC;IAAG,KAAK;GAAM,IAAI;IAAE,MAAM;IAAK,KAAK;GAAK;EACzF;;;;;EAMA,SAAgB,YAAY,MAAiC;GAC3D,OAAO,KAAK,KAAK,WAAW,GAAG;EACjC;;EAGA,SAAgB,cAAc,QAA+B;GAC3D,IAAI,WAAW,MAAM,OAAO;GAC5B,IAAI,WAAW,QAAQ,OAAO;GAC9B,IAAI,WAAW,UAAU,OAAO;GAChC,OAAO;EACT;;EAGA,SAAgB,cAAc,SAAyB;GACrD,IAAI,WAAW,IAAI,OAAO;GAC1B,IAAI,WAAW,IAAI,OAAO;GAC1B,OAAO;EACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EC5CA,MAAMC,WAAS;EAQf,SAAS,gBAAgB,MAAsC;GAC7D,MAAM,SAAS,KAAK,KAAK,QAAQ,IAAI,WAAW,CAAC,CAAC,QAAQ,WAAW,SAAS,CAAC,CAAC,CAAC,MAAM,OAAO,WAAW,QAAQ,MAAM;GACvH,IAAI,OAAO,SAAS,GAAG,OAAO,CAAC,KAAK,GAAG;GACvC,MAAM,QAAQ,aAA6B,OAAO,KAAK,IAAI,OAAO,SAAS,GAAG,KAAK,MAAM,OAAO,SAAS,QAAQ,CAAC;GAClH,OAAO,CAAC,KAAK,GAAI,GAAG,KAAK,GAAI,CAAC;EAChC;EAEA,SAAS,QAAQ,QAAgB,YAAsC;GACrE,IAAI,UAAU,GAAG,OAAO;GACxB,IAAI,SAAS,WAAW,IAAI,OAAO;GACnC,IAAI,SAAS,WAAW,IAAI,OAAO;GACnC,OAAO;EACT;EAEA,MAAM,eAAe;GAAC;GAAyB;GAAwB;GAAwB;EAAS;EAExG,SAAgB,QAAQ,OAAoF;GAC1G,MAAM,EAAE,MAAM,UAAU,YAAY;GACpC,MAAM,iBAAA,GAAgBC,MAAAA,QAAAA,OAAc,IAAI,IAAI,KAAK,KAAK,QAAQ,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;GACvF,MAAM,cAAA,GAAaA,MAAAA,QAAAA,OAAc,gBAAgB,IAAI,GAAG,CAAC,IAAI,CAAC;GAE9D,MAAM,EAAE,SAAS,iBAAA,GAAgBA,MAAAA,QAAAA,OAAc;IAC7C,MAAM,wBAAQ,IAAI,KAAK;IACvB,MAAM,SAAS,GAAG,GAAG,GAAG,CAAC;IACzB,MAAM,cAAc,IAAI,KAAK,MAAM,QAAQ,KAAK,IAAI,MAAM,OAAO,KAAKD,QAAM;IAC5E,MAAM,wBAAQ,IAAI,KAAK,YAAY,QAAQ,IAAK,MAAsBA,QAAM;IAC5E,MAAM,YAAY,KAAK,SAAS,IAAI,KAAK,EAAE,CAAC,OAAO;IACnD,MAAM,QAAoB,CAAC;IAC3B,KAAK,IAAI,SAAS,GAAG,SAAS,KAAgB,UAAU,GAAG;KACzD,MAAM,OAAO,IAAI,KAAK,MAAM,QAAQ,IAAI,SAASA,QAAM;KACvD,MAAM,UAAU,QAAQ,IAAI;KAC5B,IAAI,KAAK,QAAQ,IAAI,MAAM,QAAQ,GAAG;MACpC,MAAM,KAAK;OAAE,MAAM;OAAS,OAAO;OAAU,OAAO;MAAE,CAAC;MACvD;KACF;KAEA,IAAI,cAAc,QAAQ,UAAU,WAAW;MAC7C,MAAM,KAAK;OAAE,MAAM;OAAS,OAAO;OAAS,OAAO;MAAE,CAAC;MACtD;KACF;KACA,MAAM,MAAM,cAAc,IAAI,OAAO;KACrC,IAAI,QAAQ,KAAA,KAAa,IAAI,eAAe,GAAG;MAC7C,MAAM,KAAK;OAAE,MAAM;OAAS,OAAO;OAAQ,OAAO;MAAE,CAAC;MACrD;KACF;KACA,MAAM,KAAK;MAAE,MAAM;MAAS,OAAO;MAAU,OAAO,QAAQ,IAAI,aAAa,UAAU;KAAE,CAAC;IAC5F;IACA,MAAM,QAAsB,CAAC;IAC7B,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG,MAAM,KAAK,MAAM,MAAM,OAAO,QAAQ,CAAC,CAAC;IAC9F,MAAM,SAAmB,CAAC;IAC1B,IAAI,gBAAgB;IACpB,KAAK,MAAM,QAAQ,OAAO;KACxB,MAAM,QAAQ,OAAO,KAAK,EAAE,CAAC,KAAK,MAAM,GAAG,CAAC,CAAC;KAC7C,OAAO,KAAK,UAAU,gBAAgB,QAAQ,MAAM,EAAE;KACtD,gBAAgB;IAClB;IACA,OAAO;KAAE,SAAS;KAAO,aAAa;IAAO;GAC/C,GAAG,CAAC,MAAM,aAAa,CAAC;GAGxB,MAAM,aAAA,GAAYE,MAAAA,OAAAA,CAA8B,IAAI;GACpD,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,MAAM,OAAO,UAAU;IACvB,IAAI,SAAS,MAAM;IACnB,KAAK,aAAa,KAAK,cAAc,KAAK;GAC5C,GAAG,CAAC,CAAC;GAEL,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWC,4BAAO;IAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,4BAAO;KAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,4BAAO;MAAc,UAAA;KAAkD,CAAA,GACxF,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;MAAM,WAAWC,0BAAO;MAAxB,UAAA;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAG,WAAU,QAAS,CAAA,GAAC,KAAS,EAAA,CAAA;OACtC,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAG,OAAO,EAAE,YAAY,aAAa,GAAG,EAAI,CAAA,GAAC,KAAS,EAAA,CAAA;OAC5D,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAG,OAAO,EAAE,YAAY,aAAa,GAAG,EAAI,CAAA,GAAC,GAAO,EAAA,CAAA;OAC1D,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAG,OAAO,EAAE,YAAY,aAAa,GAAG,EAAI,CAAA,GAAC,GAAO,EAAA,CAAA;OAC1D,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAG,OAAO,EAAE,YAAY,aAAa,GAAG,EAAI,CAAA,GAAC,GAAO,EAAA,CAAA;MACtD;KACH,CAAA,CAAA;IACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWD,4BAAO;KAAe,KAAK;KACzC,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,4BAAO;MAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,4BAAO;OAAvB,UAAA;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,IAAO,CAAA;QAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,IAAO,CAAA;QAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,IAAO,CAAA;QAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,IAAO,CAAA;QAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,IAAO,CAAA;QAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,IAAO,CAAA;QAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,IAAO,CAAA;OAC9F;MACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,4BAAO;OAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAWA,4BAAO;QACpB,UAAA,QAAQ,KAAK,MAAM,cAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,4BAAO;SACpB,UAAA,KAAK,KAAK,SAAS;UAClB,MAAM,MAAM,KAAK,UAAU,WAAW,cAAc,IAAI,KAAK,IAAI,IAAI,KAAA;UACrE,MAAM,YAAY,KAAK,UAAU,WAC7BA,4BAAO,WACP,KAAK,UAAU,SAASA,4BAAO,WAAW,MAAMA,4BAAO,OAAOA,4BAAO,WAAW,MAAMA,4BAAO;UACjG,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;WAEa;WACX,OAAO,KAAK,UAAU,WAAW,EAAE,YAAY,aAAa,KAAK,OAAO,IAAI,KAAA;WAC5E,cAAc,UAAU,QAAQ,KAAK,OAAO,MAAM,MAAM,KAAK,QAAQ,CAAC;WACtE,cAAc,QAAQ;UACvB,GALM,KAAK,IAKX;SAEL,CAAC;QACE,GAhBiC,SAgBjC,CACN;OACE,CAAA,GACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAWA,4BAAO;QACpB,UAAA,YAAY,KAAK,OAAO,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAmB,MAAY,GAApB,KAAoB,CAAC;OAChE,CAAA,CACF;MACF,CAAA,CAAA;;IACF,CAAA,CACF;;EAET;EAEA,SAAS,MAAM,MAAgB,KAA6B,UAAgC;GAC1F,IAAI,KAAK,UAAU,YAAY,QAAQ,KAAA,GACrC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD,EAAA,UAAW,KAAK,KAAe,CAAA,GAC/B,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAS,KAAK,UAAU,SAAS,YAAY,SAAiB,CAAA,CAC9D,EAAA,CAAA;GAGN,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;IACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD,EAAA,UAAW,KAAK,KAAe,CAAA;IAC/B,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA;KAAQ;KAAG,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAI,UAAU,IAAI,WAAW,EAAK,CAAA;KAAC;IAAe,EAAA,CAAA;IAC5D,IAAI,OAAO,KAAK,UAAU;KACzB,MAAM,UAAU,IAAI,cAAc,IAAI,KAAK,MAAM,MAAM,cAAc,IAAI,cAAc,GAAG,IAAI;KAC9F,MAAM,QAAQ,eAAe,UAAU,MAAM,QAAQ;KACrD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MACS;MACP,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CAAG,MAAM,OAAM,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;OAAM,WAAWC,0BAAO;OAAxB,UAAA,CAA6B,OAAI,cAAc,UAAU,MAAM,QAAQ,CAAQ;MAAG,CAAA,CAAA,EAAA,CAAA;MACxG,QAAQ,UAAU,MAAM,WAAW;MACnC,MAAM,UAAU;KACjB,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAiB;MAAgB;KAAQ,CAAA,CACtC,EAAA,GARK,MAAM,WAAW,MAAM,MAAM,KAQlC;IAET,CAAC;GACD,EAAA,CAAA;EAEN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECjKA,SAAgB,eAAe,OAAgF;GAC7G,MAAM,SAAS,MAAM,UAAU;GAC/B,IAAI,WAAW,QAAQ,OAAO;GAC9B,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAWC,2BAAO,aAAa,MAAM,YAAY,MAAM;IAAG,OAAO,kBAAkB;IACtF,UAAA,mBAAmB;GAChB,CAAA;EAEV;EAEA,SAAS,YAAY,QAA4B;GAC/C,IAAI,WAAW,YAAY,OAAOA,2BAAO;GACzC,IAAI,WAAW,QAAQ,OAAOA,2BAAO;GACrC,IAAI,WAAW,WAAW,OAAOA,2BAAO;GACxC,OAAOA,2BAAO;EAChB;;;ECbA,SAAgB,YAAY,OAOd;GACZ,MAAM,EAAE,UAAU,YAAY;GAC9B,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD,EAAA,UAAA;IACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWC,0BAAO;KAAY,UAAA;IAAW,CAAA;IAC9C,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;KAAO,WAAWC,4BAAe;KAAjC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;MACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,SAAU,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,UAAW,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,SAAU,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,CAAQ,CAAA;KACrF,EAAA,CAAA,EACC,CAAA,GACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD,EAAA,UAAA,CACG,SAAS,KAAK,YAAY;MACzB,MAAM,MAAM,SAAS,SAAS,MAAM,SAAS,KAAK,aAAa,QAAQ,QAAQ,KAAK;MACpF,MAAM,cAAc,QAAQ,OAAO,IAAI,IAAI,MAAM;MACjD,MAAM,cAAc,QAAQ,OAAO,IAAI,IAAI,MAAM;MAEjD,MAAM,WAAW,aAAa,SADZ,QAAQ,OAAO,IAAI,IAAI,MAAM,IACC;MAChD,MAAM,WAAW,QAAQ,WAAW;MACpC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;OAEE,WAAW,WAAWA,4BAAe,cAAcA,4BAAe;OAClE,SAAS,WAAW,KAAA,UAAkB,MAAM,aAAa,QAAQ,QAAQ;OAH3E,UAAA;QAKE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,4BAAe;SAA/B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWD,0BAAO;UAAW,OAAO,EAAE,YAAY,cAAc,QAAQ,MAAM,EAAE;SAAI,CAAA,GAC1F,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,WAAWC,4BAAe;UAAa,UAAA,QAAQ;SAAiB,CAAA,CAClE;QACH,CAAA,EAAA,CAAA;QACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAW,WAAW,OAAO;SAAI,UAAA,QAAQ,WAAW,QAAQ,QAAQ,QAAQ;QAAgB,CAAA,EAAK,CAAA;QAC3G,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,cAAc,IAAI,UAAU,WAAW,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWD,0BAAO;SAAK,UAAA;QAAO,CAAA,EAAM,CAAA;QAC1F,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,cAAc,IAAI,UAAU,WAAW,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,0BAAO;SAAK,UAAA;QAAO,CAAA,EAAM,CAAA;QAC1F,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,YAAY,OAAO,EAAM,CAAA;QAC9B,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,SAAS,MAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,0BAAO;SAAM,UAAA,SAAS;QAAW,CAAA,IAAI,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CAAG,SAAS,MAAM,YAAY,QAAQ,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAD,EAAgB,QAAQ,KAAK,MAAM,WAAa,CAAA,CAAI,EAAA,CAAA,EAAM,CAAA;QAC/K,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,WAAW,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWC,4BAAe;SAAS,UAAA;QAAU,CAAA,EAAM,CAAA;OAC9E;MAhBG,GAAA,QAAQ,QAgBX;KAER,CAAC,GACA,SAAS,WAAW,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,SAAS;MAAG,WAAWD,0BAAO;MAAO,UAAA;KAAY,CAAA,EAAK,CAAA,CACnF,EAAA,CAAA,CACF;;IAEP,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;KAAS,MAAM,MAAM;KAAmB;KAAU,SAAS,MAAM;IAAU,CAAA;IAE1E,YAAY,QACX,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAO,UAAA;IAA6B,CAAA;IAE5D,MAAM,OAAO,WAAW,KAAK,SAAS,SAAS,KAC9C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAO,UAAA;IAA2B,CAAA;GAExD,EAAA,CAAA;EAET;EAEA,SAAS,WAAW,SAA0B;GAC5C,MAAM,OAAOC,4BAAe;GAC5B,IAAI,QAAQ,WAAW,OAAO,OAAO,OAAO,MAAMA,4BAAe;GACjE,IAAI,QAAQ,aAAa,QAAQ,OAAO,OAAO,MAAMA,4BAAe;GACpE,IAAI,QAAQ,aAAa,OAAO,OAAO,OAAO,MAAMA,4BAAe;GACnE,OAAO;EACT;EAEA,SAAS,YAAY,SAA6B;GAChD,IAAI,QAAQ,aAAa,SAAS,QAAQ,iBAAiB,MAAM;IAC/D,MAAM,UAAU,QAAQ;IACxB,MAAM,aAAa,WAAW,KAAKA,4BAAe,SAAS,WAAW,KAAKA,4BAAe,OAAO;IACjG,MAAM,cAAc,QAAQ,oBAAoB,QAAQ,kBAAkB;IAC1E,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;KAAM,WAAWA,4BAAe;KAAhC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,4BAAe;MAC9B,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAG,OAAO;OAAE,OAAO,KAAK,IAAI,GAAG,OAAO,IAAI;OAAK,YAAY,WAAW,KAAK,oDAAoD;MAAkD,EAAI,CAAA;KACjL,CAAA,GACN,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;MAAM,WAAW,CAACA,4BAAe,WAAW,UAAU,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK;MAAvE,UAAA;OAA2E;OAAY;OAAE;OAAQ;MAAO;KACpG,CAAA,CAAA;;GAEV;GACA,IAAI,QAAQ,gBAAgB,MAAM;IAChC,MAAM,aAAa,QAAQ,WAAW,WAAWA,4BAAe,SAAS,QAAQ,WAAW,SAASA,4BAAe,OAAO;IAC3H,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,4BAAe;KAC9B,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAW,CAACA,4BAAe,WAAW,UAAU,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK;MAAI,UAAA,QAAQ;KAAkB,CAAA;IACjG,CAAA;GAEV;GACA,MAAM,WAAW,QAAQ,aAAa,SAAS,QAAQ,QAAQ,aAAa,SAAS,MAAM;GAC3F,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAW,CAACA,4BAAe,WAAWA,4BAAe,GAAG,CAAC,CAAC,KAAK,GAAG;IAAI,UAAA;GAAe,CAAA;EACpG;;;;;;;;;;;ECzFA,MAAM,WAAW;EAEjB,MAAa,WAAW;EACxB,MAAa,YAAY;;EAGzB,SAAgB,MAAW,MAAa,SAA2C;GACjF,MAAM,QAAQ,CAAC,QAAQ,KAAK,WAAW,QAAQ,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;GACvE,KAAK,MAAM,OAAO,MAChB,MAAM,KAAK,QAAQ,KAAK,WAAW,QAAQ,OAAO,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;GAE1E,OAAO,WAAW,MAAM,KAAK,MAAM,IAAI;EACzC;EAEA,SAAgB,OAAO,OAAwB;GAC7C,OAAO,KAAK,UAAU,OAAO,MAAM,CAAC,IAAI;EAC1C;;EAGA,SAAgB,eAAe,OAAe,WAAmC;GAC/E,OAAO,eAAe,QAAQ,MAAM,wBAAQ,IAAI,KAAK,CAAC,IAAI,MAAM;EAClE;EAEA,SAAgB,aAAa,MAAc,MAAc,MAAoB;GAC3E,MAAM,YAAY,IAAI,gBAAgB,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,KAAK,CAAC,CAAC;GACtE,MAAM,SAAS,SAAS,cAAc,GAAG;GACzC,OAAO,OAAO;GACd,OAAO,WAAW;GAClB,SAAS,KAAK,YAAY,MAAM;GAChC,OAAO,MAAM;GACb,OAAO,OAAO;GAEd,OAAO,iBAAiB,IAAI,gBAAgB,SAAS,GAAG,CAAC;EAC3D;;EAGA,SAAS,QAAQ,OAAuC;GACtD,IAAI,UAAU,MAAM,OAAO;GAC3B,MAAM,OAAO,OAAO,KAAK;GACzB,OAAO,WAAW,KAAK,IAAI,IAAI,OAAM,KAAK,QAAQ,MAAM,MAAI,IAAI,OAAM;EACxE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECtCA,SAAgB,SAAS,OAMX;GACZ,MAAM,EAAE,OAAO,aAAa,aAAa;GACzC,IAAI,UAAU,QAAQ,eAAe,GACnC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWC,0BAAO;IAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAW,UAAA;IAAkB,CAAA,GACpD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAO,OAAO,EAAE,SAAS,QAAQ;KAAG,UAAA;IAAe,CAAA,CACvE;;GAGT,IAAI,OAAmB,CAAC;GACxB,IAAI,QAAQ;GACZ,IAAI,MAAM,kBAAkB,OAAO;IACjC,MAAM,6BAAa,IAAI,IAAoB;IAC3C,KAAK,MAAM,OAAO,MAAM,MACtB,KAAK,MAAM,SAAS,IAAI,QACtB,WAAW,IAAI,MAAM,WAAW,WAAW,IAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,cAAc,MAAM,eAAe,MAAM,eAAe;IAGzI,OAAO,CAAC,GAAG,WAAW,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,aAAa;KAC5D,KAAK;KAAU,OAAO,cAAc,UAAU,QAAQ;KAAG;KAAQ,OAAO,eAAe,UAAU,QAAQ;IAC3G,EAAE;GACJ,OAAO;IACL,QAAQ;IACR,MAAM,0BAAU,IAAI,IAAkD;IACtE,KAAK,MAAM,OAAO,MAAM,MACtB,KAAK,MAAM,SAAS,IAAI,QAAQ;KAC9B,MAAM,SAAS,QAAQ,IAAI,MAAM,KAAK;KACtC,MAAM,SAAS,MAAM,cAAc,MAAM,eAAe,MAAM;KAC9D,IAAI,WAAW,KAAA,GAAW,QAAQ,IAAI,MAAM,OAAO;MAAE;MAAQ,UAAU,MAAM;KAAS,CAAC;UAClF,OAAO,UAAU;IACxB;IAEF,OAAO,CAAC,GAAG,QAAQ,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY;KACrD,KAAK;KAAO,OAAO;KAAO,QAAQ,MAAM;KAAQ,OAAO,eAAe,UAAU,MAAM,QAAQ;IAChG,EAAE;GACJ;GACA,KAAK,MAAM,OAAO,WAAW,OAAO,SAAS,MAAM,MAAM;GACzD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWA,0BAAO;IAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAY,UAAA;IAAW,CAAA,GAC9C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWC,0BAAa;KAC1B,UAAA,KAAK,KAAK,QAAQ;MACjB,MAAM,UAAU,cAAc,IAAI,KAAK,MAAM,IAAI,SAAS,cAAc,GAAG,IAAI;MAC/E,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAEE,OAAO;QAAE,OAAQ,IAAI,SAAS,cAAc,MAAO;QAAK,YAAY,IAAI;OAAM;OAC9E,cAAc,UAAU,MAAM,QAAQ,KAAK,OACzC,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD,EAAA,UAAW,IAAI,MAAgB,CAAA;QAC/B,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAQ,OAAG,iBAAA,GAAA,kBAAA,KAAA,CAAC,KAAD,EAAA,UAAA,CAAI,SAAQ,GAAI,EAAA,CAAA,CAAS,EAAA,CAAA;QACpC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAQ,OAAO,IAAI;SAAO,OAAM;SAAS,QAAQ,UAAU,IAAI,MAAM;SAAG,MAAM,UAAU;QAAM,CAAA;OAC9F,EAAA,CAAA,CACH;OACD,cAAc,MAAM,QAAQ;MAC7B,GAVM,IAAI,GAUV;KAEL,CAAC;IACE,CAAA,CACF;;EAET;;;ECnFA,SAAgB,SAAS,OAA0E;GACjG,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWC,0BAAO;IAAvB,UAAA;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,0BAAO;MAAY,UAAA,MAAM;KAAW,CAAA;KACpD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,0BAAO;MAAY,UAAA,MAAM;KAAW,CAAA;KACnD,MAAM,UAAU,KAAA,KAAa,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,0BAAO;MAAY,UAAA,MAAM;KAAW,CAAA;IAC/E;;EAET;;;ECEA,SAAgB,UAAU,OAIZ;GACZ,MAAM,EAAE,MAAM,YAAY;GAC1B,IAAI,MAAM,WAAW,QAAQ,KAAK,WAAW,GAAG,OAAO;GACvD,MAAM,OAAO,KAAK,IAAI,GAAG,GAAG,KAAK,KAAK,QAAQ,IAAI,kBAAkB,IAAI,cAAc,IAAI,YAAY,CAAC;GACvG,MAAM,YAAY,WAA2B,OAAO,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,OAAO,GAAG,CAAC,IAAI,KAAK;GAE3G,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,SAAS,EAAE,CAAC;GAC1D,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAW,KAAK,SAAS,KAAKC,0BAAO,OAAO,MAAMA,0BAAO,YAAYA,0BAAO;IAC9E,UAAA,KAAK,KAAK,QAAQ;KACjB,MAAM,WAAW,IAAI,kBAAkB,IAAI,cAAc,IAAI;KAC7D,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAEE,WAAWA,0BAAO;MAClB,cAAc,UAAU,QAAQ,KAAK,OAAO,IAAI,GAAG;MACnD,cAAc,QAAQ;MAErB,UAAA,WAAW,KACV,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,0BAAO;QAAU,OAAO,EAAE,QAAQ,SAAS,IAAI,eAAe,EAAE;OAAI,CAAA;OACrF,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,0BAAO;QAAO,OAAO,EAAE,QAAQ,SAAS,IAAI,WAAW,EAAE;OAAI,CAAA;OAC9E,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,0BAAO;QAAQ,OAAO,EAAE,QAAQ,SAAS,IAAI,YAAY,EAAE;OAAI,CAAA;MAChF,EAAA,CAAA;KAED,GAZE,IAAI,GAYN;IAET,CAAC;GACE,CAAA,GACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWA,0BAAO;IACpB,UAAA,KAAK,KAAK,KAAK,UACd,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAqB,QAAQ,eAAe,KAAK,UAAU,KAAK,SAAS,IAAI,IAAI,YAAY,GAAS,GAA3F,IAAI,GAAuF,CACvG;GACE,CAAA,CACL,EAAA,CAAA;EAEN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECpCA,MAAM,SAAS;EAiBf,MAAM,OAAmB;GAAE,MAAM;GAAM,MAAM;GAAQ,MAAM;EAAM;EACjE,MAAM,cAA0B;GAAE,MAAM;GAAK,MAAM;GAAQ,MAAM;EAAM;;EAGvE,SAAS,WAAW,MAAc,IAAoB;GACpD,MAAM,4BAAW,IAAI,KAAK,OAAO,WAAW,EAAA,CAAE,QAAQ;GACtD,MAAM,0BAAS,IAAI,KAAK,KAAK,WAAW,EAAA,CAAE,QAAQ;GAClD,OAAO,KAAK,IAAI,GAAG,KAAK,OAAO,SAAS,YAAY,MAAM,IAAI,CAAC;EACjE;;EAGA,SAAS,iBAAiB,MAAc,IAA0C;GAChF,MAAM,6BAAY,IAAI,KAAK,OAAO,WAAW,EAAA,CAAE,QAAQ;GACvD,MAAM,OAAO,WAAW,MAAM,EAAE;GAChC,OAAO;IAAE,MAAM,wBAAQ,IAAI,KAAK,YAAY,OAAO,MAAM,CAAC;IAAG,IAAI,wBAAQ,IAAI,KAAK,YAAY,MAAM,CAAC;GAAE;EACzG;;EAGA,SAAS,gBAAgB,QAA4B;GACnD,OAAO,OAAO,cAAc,OAAO,eAAe,OAAO;EAC3D;;EAGA,SAASC,YAAU,QAAmC;GACpD,MAAM,QAAQ,gBAAgB,MAAM;GACpC,OAAO,QAAQ,IAAI,OAAO,kBAAkB,QAAQ,MAAM;EAC5D;;EAGA,SAAS,WAAW,QAAoC;GACtD,OAAO,WAAW,SAAS,OAAO,QAAQ,KAAK,gBAAgB,MAAM,IAAI,KAAK,OAAO,OAAO;EAC9F;;EAGA,SAAS,gBAAgB,SAAiB,UAAkB,UAA+B;GACzF,IAAI,YAAY,GAAG,OAAO,WAAW,IAAI,OAAO;IAAE,MAAM;IAAS,MAAM;IAAQ,MAAM;GAAM;GAC3F,MAAM,WAAW,UAAU,YAAY,WAAW;GAClD,IAAI,KAAK,IAAI,OAAO,IAAI,KAAM,OAAO;GACrC,OAAO;IACL,OAAO,UAAU,IAAI,MAAM,MAAM,QAAQ,QAAQ,CAAC,IAAI;IACtD,MAAM,UAAU,IAAI,OAAO;IAC3B,MAAM,YAAY,UAAU;GAC9B;EACF;;EAGA,SAAS,cAAc,SAAiB,UAA8B;GACpE,MAAM,aAAa,UAAU;GAC7B,IAAI,KAAK,IAAI,UAAU,IAAI,KAAM,OAAO;GACxC,OAAO;IACL,OAAO,aAAa,IAAI,MAAM,MAAM,WAAW,QAAQ,CAAC,IAAI;IAC5D,MAAM,aAAa,IAAI,OAAO;IAC9B,MAAM;GACR;EACF;;;;;EAMA,SAAS,WAAW,SAAyB,MAA+D;GAC1G,IAAI,YAAY,QAAQ,QAAQ,aAAa,cAAc,QAAQ,aAAa,WAAW;IACzF,MAAM,OAAO,aAAa,SAAS,IAAI;IACvC,OAAO;KAAE,MAAM,KAAK;KAAM,KAAK,KAAK;KAAK,QAAQ;IAAM;GACzD;GACA,OAAO;IAAE,MAAM,QAAQ,IAAI;IAAG,KAAK;IAAO,QAAQ;GAAK;EACzD;EAEA,SAAS,aAAa,QAA+B;GACnD,IAAI,OAAO,SAAS,QAAQ,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAWC,yBAAY;IAAQ,UAAA,OAAO;GAAW,CAAA;GAC1F,MAAM,QAAQ,OAAO,SAAS,OAAO,MAAM,OAAO,SAAS,SAAS,MAAM;GAC1E,MAAM,OAAO,OAAO,OAAOA,yBAAY,OAAO,OAAO,SAAS,SAASA,yBAAY,OAAO;GAC1F,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;IAAM,WAAW,SAAS,KAAKA,yBAAY,SAASA,yBAAY,SAAS,MAAM;IAA/E,UAAA;KAAsF;KAAM;KAAE,OAAO;IAAW;;EACzH;EAEA,SAAgB,WAAW,OAMb;GACZ,MAAM,EAAE,OAAO,QAAQ,kBAAkB;GACzC,MAAM,aAAa,MAAM,UAAU;GACnC,MAAM,kBAAA,GAAiBC,MAAAA,QAAAA,OAAc,iBAAiB,OAAO,MAAM,OAAO,EAAE,GAAG,CAAC,OAAO,MAAM,OAAO,EAAE,CAAC;GACvG,MAAM,CAAC,eAAe,qBAAA,GAAoBC,MAAAA,SAAAA,CAA+B,IAAI;GAC7E,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAA8B,SAAS;GAEnE,MAAM,gBAAA,GAAeC,MAAAA,qBAAAA,CAAqB,gBAAgB,MAAM,WAAW,gBAAgB,MAAM,WAAW;GAC5G,MAAM,mBAAmB,KAAK,UAAU,aAAa,MAAM;GAE3D,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,CAAC,YAAY;IACjB,IAAI,YAAY;IAChB,UAAU,SAAS;IACnB,UAAe,eAAe,MAAM,eAAe,IAAI,aAAa,CAAC,CAAC,MAAM,WAAW;KACrF,IAAI,WAAW;KACf,iBAAiB,MAAM;KACvB,UAAU,OAAO;IACnB,CAAC;IACD,aAAa;KAAE,YAAY;IAAK;GAClC,GAAG;IAAC;IAAY,eAAe;IAAM,eAAe;IAAI;IAAe;GAAgB,CAAC;GAExF,MAAM,SACJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWH,yBAAY;IAA5B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWI,0BAAO;KAAW,UAAA;IAAqB,CAAA,GACxD,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;KAAM,WAAWJ,yBAAY;KAA7B,UAAA;MAAmC;MAC7B,OAAO;MAAK;MAAI,OAAO;MAC1B,aAAa,WAAW,eAAe,OAAO,QAAQ,eAAe,KAAK;KACvE;IACH,CAAA,CAAA;;GAGP,IAAI,CAAC,YACH,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWI,0BAAO,OAAO,MAAMJ,yBAAY;IAAhD,UAAA,CACG,QACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,yBAAY;KAAa,UAAA;IAAkB,CAAA,CACxD;;GAIT,MAAM,gBAAgB,MAAM;GAC5B,MAAM,iBAAiB,eAAe,UAAU;GAChD,MAAM,kBAAkB,WAAW,WAAW,WAAW,cAAc;GACvE,MAAM,iBAAiB,WAAW,aAAa;GAC/C,MAAM,sBAAsB,WAAW,YAAY,SAAS,kBAAkB,OAAO,SAAS;GAE9F,MAAM,gBAAgB,SAA4B,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAWA,yBAAY;IAAU,UAAA;GAAW,CAAA;GACpG,MAAM,iBAAiB,SAA4B,kBAC/C,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAWA,yBAAY;IAAW,UAAA;GAAW,CAAA,IACnD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAWA,yBAAY;IAAQ,UAAA;GAA0B,CAAA;GACnE,MAAM,eAAe,WAAkC,kBACnD,aAAa,MAAM,IACnB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAWA,yBAAY;IAAO,UAAA;GAAO,CAAA;GAE/C,MAAM,eAAe,eAAe,SAAS;GAC7C,MAAM,gBAAgB,gBAAgB,SAAS;GAC/C,MAAM,gBAAgB,kBAAkB,OAAO,IAAI,gBAAgB,aAAa;GAChF,MAAM,iBAAiB,mBAAmB,OAAO,IAAI,gBAAgB,cAAc;GACnF,MAAM,iBAAiB,kBAAkB,OAAO,OAAOD,YAAU,aAAa;GAC9E,MAAM,kBAAkB,mBAAmB,OAAO,OAAOA,YAAU,cAAc;GACjF,MAAM,cAAc,eAAe,QAAQ;GAC3C,MAAM,eAAe,gBAAgB,QAAQ;GAC7C,MAAM,gBAAgB,kBAAkB,QAAQ,OAAO,UAAU,MAAM,UAAU,aAAa;GAC9F,MAAM,kBAAkB,WAAW,eAAe,WAAW;GAC7D,MAAM,mBAAmB,WAAW,eAAe,YAAY;GAC/D,MAAM,iBAAiB,gBAAgB,UAAU,iBAAiB;GAElE,MAAM,OAAmB;IACvB;KACE,KAAK;KACL,OAAO;KACP,SAAS,aAAa,SAAS,YAAY,CAAC;KAC5C,UAAU,cAAc,SAAS,aAAa,CAAC;KAC/C,QAAQ,YAAY,gBAAgB,cAAc,eAAe,KAAK,CAAC;IACzE;IACA;KACE,KAAK;KACL,OAAO;KACP,SAAS,aAAa,UAAU,aAAa,CAAC;KAC9C,UAAU,cAAc,UAAU,cAAc,CAAC;KACjD,QAAQ,YAAY,gBAAgB,eAAe,gBAAgB,KAAK,CAAC;IAC3E;IACA;KACE,KAAK;KACL,OAAO;KACP,SAAS,gBAAgB,SACrB,aAAa,gBAAgB,IAAI,IACjC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWC,yBAAY;MAAQ,UAAA,gBAAgB;KAAW,CAAA;KACpE,UAAU,cAAc,iBAAiB,IAAI;KAC7C,QAAQ,iBACJ,YAAY,gBAAgB,aAAa,cAAc,IAAI,CAAC,IAC5D,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,yBAAY;MAAO,UAAA;KAAS,CAAA;IACnD;IACA;KACE,KAAK;KACL,OAAO;KACP,SAAS,aAAa,mBAAmB,OAAO,MAAM,eAAe,QAAQ,CAAC,IAAI,GAAG;KACrF,UAAU,cAAc,oBAAoB,OAAO,MAAM,gBAAgB,QAAQ,CAAC,IAAI,GAAG;KACzF,QAAQ,YAAY,mBAAmB,QAAQ,oBAAoB,OAC/D,cAAc,gBAAgB,eAAe,IAC7C,WAAW;IACjB;GACF;GAEA,MAAM,QAAkB,CAAC;GACzB,KAAK,MAAM,gBAAgB,CAAC,EAAA,CAAG,SAAS,MAAM,eAAe,gBAAgB,CAAC,EAAA,CAAG,SAAS,GACxF,MAAM,KAAK,oBAAoB;GAEjC,IAAI,mBAAmB,gBAAgB;IACrC,MAAM,gBAAgB,eAAe,cAAc;IACnD,MAAM,iBAAiB,gBAAgB,cAAc;IACrD,IAAI,kBAAkB,gBACpB,MAAM,KAAK,iBAAiB,mBAAmB,iBAAiB,WAAW,mBAAmB,kBAAkB,WAAW;GAE/H;GACA,IAAI,WAAW,WAAW,kBAAkB,MAAM,MAAM,KAAK,gBAAgB;GAC7E,IAAI,CAAC,gBAAgB,MAAM,KAAK,YAAY;GAC5C,MAAM,KAAK,4BAA4B;GAEvC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWI,0BAAO,OAAO,MAAMJ,yBAAY;IAAhD,UAAA;KACG;KACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;MAAO,WAAWI,0BAAO;MAAzB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;OACV,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;OACV,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;OACV,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;MACR,EAAA,CAAA,EACC,CAAA,GACP,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UACG,KAAK,KAAK,QACT,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,IAAI,MAAU,CAAA;OACnB,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,IAAI,QAAY,CAAA;OACrB,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,IAAI,SAAa,CAAA;OACtB,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,IAAI,OAAW,CAAA;MAClB,EAAA,GALK,IAAI,GAKT,CACL,EACI,CAAA,CACF;;KACP,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWJ,yBAAY;MACzB,UAAA,MAAM,KAAK,SAAS,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAgB,WAAWA,yBAAY;OAAO,UAAA;MAAU,GAA9C,IAA8C,CAAC;KAC3E,CAAA;IACF;;EAET;;;EC3PA,SAAgB,cAAmB,MAAa,UAAqD;GACnG,MAAM,OAAO,KAAK,QAAQ,QAAQ,SAAS,GAAG,IAAI,CAAC;GACnD,OAAO;IAAE,MAAM;IAAM,QAAQ,KAAK,SAAS,KAAK;GAAO;EACzD;;EAGA,SAAgB,oBAAoB,QAAwB;GAC1D,OAAO,SAAS,OAAO,MAAM,IAAI;EACnC;;;;;;;;ECJA,SAAS,YAAY,OAA0B;GAC7C,OAAO,UAAU,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAWK,0BAAO;IAAK,UAAA;GAAO,CAAA,IAAI,UAAU,KAAK;EAC9E;EAwBA,SAASC,YAAU,iBAAyB,aAAqB,cAA8B;GAC7F,MAAM,QAAQ,cAAc,eAAe;GAC3C,IAAI,SAAS,GAAG,OAAO;GACvB,QAAQ,kBAAkB,QAAQ,IAAA,CAAK,QAAQ,CAAC,IAAI;EACtD;EAEA,MAAM,YAA6E;GACjF,SAAS,OAAO,WAAY,MAAM,SAAS,OAAO,SAAS,KAAK,MAAM,SAAS,OAAO,SAAS,IAAI;GACnG,QAAQ,OAAO,WAAW,MAAM,cAAc,OAAO;GACrD,QAAQ,OAAO,WAAW,MAAM,QAAQ,OAAO;GAC/C,QAAQ,OAAO,WAAW,MAAM,cAAc,OAAO;GACrD,SAAS,OAAO,WAAW,MAAM,eAAe,OAAO;GACvD,YAAY,OAAO,WAAW,MAAM,kBAAkB,OAAO;GAC7D,MAAM,OAAO,WAAW;IACtB,MAAM,aAAa,MAAM,cAAc,MAAM,eAAe,MAAM;IAClE,MAAM,cAAc,OAAO,cAAc,OAAO,eAAe,OAAO;IACtE,QAAQ,aAAa,IAAI,MAAM,kBAAkB,aAAa,OAAO,cAAc,IAAI,OAAO,kBAAkB,cAAc;GAChI;GACA,OAAO,OAAO,WAAW,MAAM,OAAO,OAAO;EAC/C;EAEA,SAAgB,iBAAiB,OAQnB;GACZ,MAAM,EAAE,OAAO,UAAU,eAAe,iBAAiB,gBAAgB,MAAM,WAAW;GAC1F,MAAM,YAAwB,CAAC;GAC/B,KAAK,MAAM,OAAO,MAAM,MACtB,KAAK,MAAM,SAAS,IAAI,QAAQ;IAC9B,MAAM,cAAc,MAAM,cAAc,MAAM,eAAe,MAAM;IACnE,UAAU,KAAK;KACb,QAAQ,IAAI;KAAM,OAAO,MAAM;KAAO,UAAU,MAAM;KAAU,OAAO,MAAM;KAC7E,aAAa,MAAM;KAAa,cAAc,MAAM;KAAc,iBAAiB,MAAM;KACzF,MAAM,MAAM;KAAM;IACpB,CAAC;GACH;GAEF,MAAM,6BAAa,IAAI,IAAuB;GAC9C,KAAK,MAAM,OAAO,WAAW;IAC3B,MAAM,SAAS,WAAW,IAAI,IAAI,MAAM;IACxC,IAAI,WAAW,KAAA,GACb,WAAW,IAAI,IAAI,QAAQ;KACzB,QAAQ,IAAI;KAAQ,OAAO,IAAI;KAAO,aAAa,IAAI;KAAa,cAAc,IAAI;KACtF,iBAAiB,IAAI;KAAiB,MAAM,IAAI;KAAM,aAAa,IAAI;IACzE,CAAC;SACI;KACL,OAAO,SAAS,IAAI;KACpB,OAAO,eAAe,IAAI;KAC1B,OAAO,gBAAgB,IAAI;KAC3B,OAAO,mBAAmB,IAAI;KAC9B,OAAO,QAAQ,IAAI;KACnB,OAAO,eAAe,IAAI;IAC5B;GACF;GACA,MAAM,WAAW,UAAU,KAAK,QAAQ,UAAU;GAElD,MAAM,WAAW,CAAC,GAAG,WAAW,OAAO,CAAC,CAAC,CAAC,QAAQ,UAAU,MAAM,cAAc,CAAC;GACjF,MAAM,cAAc,WAAW,OAAO,SAAS;GAC/C,MAAM,UAAU,SAAS,MAAM,OAAO,WAAW;IAC/C,MAAM,WAAW,SAAS,OAAO,MAAM;IACvC,OAAO,KAAK,QAAQ,QAAQ,WAAW,CAAC;GAC1C,CAAC;GAED,MAAM,UAAU,KAAa,UAA6B;IACxD,MAAM,WAAW,KAAK,QAAQ;IAC9B,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;KACE,WAAW,WAAWD,0BAAO,aAAaA,0BAAO;KACjD,eAAe,OAAO,WAAW;MAAE;MAAK,KAAK,KAAK,QAAQ,QAAQ,SAAS;KAAM,IAAI;MAAE;MAAK,KAAK;KAAO,CAAC;KAF3G,UAAA,CAIG,OAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,0BAAO;MAAY,UAAA,WAAY,KAAK,QAAQ,QAAQ,MAAM,MAAO;KAAU,CAAA,CACjG;;GAER;GAEA,MAAM,SAAS,MAAM;GACrB,MAAM,cAAc,WAAW,OAAO,IAAI,OAAO,cAAc,OAAO,eAAe,OAAO;GAG5F,IAFoB,QAAQ,WAER,GAClB,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWA,0BAAO;IAAY,UAAA;GAAS,CAAA,GAC5C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWA,0BAAO;IAAO,UAAA;GAAe,CAAA,CAC1C,EAAA,CAAA;GAIT,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD,EAAA,UAAA;IACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAY,UAAA;IAAS,CAAA;IAC5C,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;KAAO,WAAWA,0BAAO;KAAzB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;MACG,OAAO,UAAU,IAAI;MACrB,OAAO,SAAS,IAAI;MACpB,OAAO,SAAS,IAAI;MACpB,OAAO,SAAS,IAAI;MACpB,OAAO,UAAU,IAAI;MACrB,OAAO,aAAa,KAAK;MACzB,OAAO,OAAO,KAAK;KAClB,EAAA,CAAA,EACC,CAAA,GACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD,EAAA,UAAA,CACG,QAAQ,KAAK,WAAW;MACvB,MAAM,iBAAiB,UACpB,QAAQ,QAAQ,IAAI,WAAW,OAAO,MAAM,CAAC,CAC7C,QAAQ,QAAQ,IAAI,cAAc,CAAC,CAAC,CACpC,MAAM,OAAO,WAAW,OAAO,cAAc,MAAM,WAAW;MACjE,MAAM,aAAa,eAAe,SAAS;MAC3C,MAAM,SAAS,cAAc,gBAAgB,OAAO,YAAY;MAChE,OACE,iBAAA,GAAA,kBAAA,KAAA,CAACE,MAAAA,UAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;OACE,WAAW,aAAaF,0BAAO,YAAY;OAC3C,SAAS,mBAAmB,eAAe,OAAO,MAAM,IAAI,KAAA;OAF9D,UAAA;QAIE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA,CACG,cAAc,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWG,0BAAa;SAAc,UAAA,SAAS,MAAM;QAAU,CAAA,GACnF,OAAO,MACN,EAAA,CAAA;QACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,UAAU,OAAO,WAAW,EAAM,CAAA;QACvC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,SAAS,OAAO,KAAK,EAAM,CAAA;QAChC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,YAAY,OAAO,WAAW,EAAM,CAAA;QACzC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,YAAY,OAAO,YAAY,EAAM,CAAA;QAC1C,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,UAAU,OAAO,eAAe,EAAM,CAAA;QAC3C,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAKF,YAAU,OAAO,iBAAiB,OAAO,aAAa,OAAO,YAAY,EAAM,CAAA;OAClF;MACH,CAAA,GAAA,UACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;OAAI,WAAWE,0BAAa;OAAY,SAAS;OAAjD,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,0BAAa;QAA7B,UAAA;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,CAAO,CAAA;SACP,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,0BAAa;UAAW,UAAA;SAAQ,CAAA;SACjD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,0BAAa;UAAW,UAAA;SAAQ,CAAA;SACjD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,0BAAa;UAAW,UAAA;SAAQ,CAAA;SACjD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,0BAAa;UAAW,UAAA;SAAS,CAAA;SAClD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,0BAAa;UAAW,UAAA;SAAS,CAAA;QAC/C;OACJ,CAAA,GAAA,eAAe,KAAK,QACnB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,0BAAa;QAA7B,UAAA;SACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;UAAM,WAAWA,0BAAa;UAA9B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,WAAWA,0BAAa;WAAW,UAAA,IAAI;UAAY,CAAA,GACxD,kBAAkB,SAAS,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,WAAWA,0BAAa;WAAa,UAAA,cAAc,UAAU,IAAI,QAAQ;UAAQ,CAAA,CAC/G;;SACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,0BAAa;UAAY,UAAA,SAAS,IAAI,KAAK;SAAQ,CAAA;SACpE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,0BAAa;UAAY,UAAA,YAAY,IAAI,WAAW;SAAQ,CAAA;SAC7E,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,0BAAa;UAAY,UAAA,YAAY,IAAI,YAAY;SAAQ,CAAA;SAC9E,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,0BAAa;UAAY,UAAA,UAAU,IAAI,eAAe;SAAQ,CAAA;SAC/E,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,0BAAa;UAAYF,UAAAA,YAAU,IAAI,iBAAiB,IAAI,aAAa,IAAI,YAAY;SAAQ,CAAA;QAC/G;OAVqC,GAAA,IAAI,SAAS,MAAM,IAAI,QAAQ,MAAM,IAAI,QAU9E,CACN,CACC;MACF,CAAA,EAAA,CAAA,CAEE,EAAA,GA3CK,OAAO,MA2CZ;KAEd,CAAC,GACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;MAAI,WAAWD,0BAAO;MAAtB,UAAA;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;OACV,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,UAAU,WAAW,EAAM,CAAA;OAChC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,SAAS,QAAQ,SAAS,CAAC,EAAM,CAAA;OACtC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,UAAU,QAAQ,eAAe,CAAC,EAAM,CAAA;OAC7C,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,UAAU,QAAQ,gBAAgB,CAAC,EAAM,CAAA;OAC9C,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,UAAU,QAAQ,mBAAmB,CAAC,EAAM,CAAA;OACjD,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAKC,YAAU,QAAQ,mBAAmB,GAAG,QAAQ,eAAe,GAAG,QAAQ,gBAAgB,CAAC,EAAM,CAAA;MACpG;KACC,CAAA,CAAA,EAAA,CAAA,CACF;;IACN,cAAc,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWD,0BAAO;KAAY,UAAA,oBAAoB,WAAW;IAAO,CAAA;GAC1F,EAAA,CAAA;EAET;;;;;;;;;;;;;;;;;;;;;;;EC1MA,MAAM,aAAwC;GAC5C,CAAC,SAAS,IAAI;GAAG,CAAC,QAAQ,GAAG;GAAG,CAAC,SAAS,GAAG;GAAG,CAAC,SAAS,IAAI;GAAG,CAAC,UAAU,KAAK;EACnF;;EAGA,MAAM,gBAAgB;;EAGtB,MAAMI,mBAA2D;GAC/D;IAAE,KAAK;IAAQ,OAAO;IAAM,QAAQ,QAAQ,IAAI;GAAK;GACrD;IAAE,KAAK;IAAS,OAAO;IAAM,QAAQ,QAAQ,IAAI;GAAM;GACvD;IAAE,KAAK;IAAe,OAAO;IAAM,QAAQ,QAAQ,IAAI;GAAY;GACnE;IAAE,KAAK;IAAgB,OAAO;IAAM,QAAQ,QAAQ,IAAI;GAAa;GACrE;IAAE,KAAK;IAAmB,OAAO;IAAO,QAAQ,QAAQ,IAAI;GAAgB;GAC5E;IAAE,KAAK;IAAgB,OAAO;IAAU,QAAQ,QAAQ,eAAe,GAAG;GAAE;GAC5E;IAAE,KAAK;IAAQ,OAAO;IAAS,QAAQ,QAAQ,IAAI;GAAK;EAC1D;;EAGA,SAAS,eAAe,KAAyC;GAC/D,MAAM,QAAQ,IAAI,cAAc,IAAI,eAAe,IAAI;GACvD,OAAO,QAAQ,IAAI,KAAK,MAAM,IAAI,kBAAkB,QAAQ,GAAI,IAAI,KAAK;EAC3E;EAEA,SAAS,UAAU,iBAAyB,aAAqB,cAA8B;GAC7F,MAAM,QAAQ,cAAc,eAAe;GAC3C,OAAO,QAAQ,KAAK,kBAAkB,QAAQ,IAAA,CAAK,QAAQ,CAAC,IAAI,MAAM;EACxE;EAEA,SAASC,cAAY,MAAc,IAAoB;GACrD,MAAM,4BAAW,IAAI,KAAK,OAAO,WAAW,EAAA,CAAE,QAAQ;GACtD,MAAM,0BAAS,IAAI,KAAK,KAAK,WAAW,EAAA,CAAE,QAAQ;GAClD,OAAO,KAAK,IAAI,GAAG,KAAK,OAAO,SAAS,YAAY,KAAQ,IAAI,CAAC;EACnE;;EAGA,SAAS,gBAAgB,MAAc,IAAsB;GAC3D,MAAM,yBAAQ,IAAI,KAAK,OAAO,WAAW,EAAA,CAAE,QAAQ;GACnD,MAAM,QAAQ,KAAK,IAAIA,cAAY,MAAM,EAAE,GAAG,aAAa;GAC3D,MAAM,OAAiB,CAAC;GACxB,KAAK,IAAI,SAAS,GAAG,SAAS,OAAO,UAAU,GAAG,KAAK,KAAK,QAAQ,IAAI,KAAK,QAAQ,SAAS,KAAQ,CAAC,CAAC;GACxG,OAAO;EACT;EAEA,SAAgB,UAAU,OAiBZ;GACZ,MAAM,EAAE,OAAO,UAAU,QAAQ,SAAS,kBAAkB;GAC5D,IAAI,UAAU,MAAM,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWC,0BAAO;IAAO,UAAA;GAAe,CAAA;GAGxE,MAAM,aADS,MAAM,UACoB;IACvC,MAAM;IAAI,OAAO;IAAG,aAAa;IAAG,cAAc;IAAG,iBAAiB;IAAG,kBAAkB;IAAG,iBAAiB;IAAG,MAAM;GAC1H;GACA,MAAM,cAAc,WAAW,cAAc,WAAW,eAAe,WAAW;GAClF,MAAM,UAAU,UAAU,WAAW,iBAAiB,WAAW,aAAa,WAAW,YAAY;;GAErG,MAAM,iBAAiB,cAAc,KAAK,WAAW,kBAAkB,cAAc,IAAA,CAAK,QAAQ,CAAC,IAAI,MAAM;;GAE7G,MAAM,aAAa,MAAM,KAAK,QAAQ,QAAQ,IAAI,cAAc,IAAI,eAAe,IAAI,kBAAkB,CAAC,CAAC,CAAC;GAC5G,MAAM,gBAAgB,kBAAkB,QAAQ,OAAO,UAAU,UAAU,aAAa;GACxF,MAAM,WAAW,aAAa,eAAe,WAAW,IAAI;GAC5D,MAAM,YAAY,OAAO,SAAS,OAAO;GACzC,MAAM,YAAY,KAAK,IAAID,cAAY,OAAO,MAAM,OAAO,EAAE,GAAG,aAAa;;GAG7E,MAAM,eAAe,WAAiC;IACpD,IAAI,WAAW,OAAO,aAAa,eAAe,SAAS,KAAK,GAAG,MAAM,MAAM,MAAMD,gBAAc,GAAG,QAAQ;SACzG,aAAa,eAAe,SAAS,MAAM,GAAG,OAAO,MAAM,IAAI,GAAG,SAAS;GAClF;GAEA,MAAM,kCAAkB,IAAI,IAAY;GACxC,KAAK,MAAM,OAAO,MAAM,MACtB,KAAK,MAAM,SAAS,IAAI,QACtB,IAAI,MAAM,cAAc,MAAM,eAAe,MAAM,kBAAkB,GAAG,gBAAgB,IAAI,MAAM,QAAQ;GAI9G,MAAM,aAA4B,CAAC;GACnC,IAAI,aAAa,MAAM,UAAU,MAC/B,MAAM,MAAM,SAAS,MAAM,SAAS;IAClC,MAAM,aAAa,KAAK,QAAQ,cAAc,KAAK,QAAQ,eAAe,KAAK,QAAQ;IACvF,WAAW,KAAK;KACd,KAAK,OAAO,IAAI;KAChB,WAAW,OAAO,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG,IAAI;KAC3C,iBAAiB,KAAK,QAAQ;KAC9B,aAAa,KAAK,QAAQ;KAC1B,cAAc,KAAK,QAAQ;KAC3B,KACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD,EAAA,UAAW,OAAO,OAAO,MAAM,OAAO,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG,IAAI,MAAgB,CAAA,GAC9E,KAAK,UAAU,KAAK,eAAe,IAChC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAQ,WAAgB,CAAA,IAExB,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA;OAAQ;OAAG,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAI,SAAS,KAAK,KAAK,EAAK,CAAA;OAAC;OAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAI,UAAU,UAAU,EAAK,CAAA;MAAS,EAAA,CAAA;MACxF,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAQ,OAAM;OAAiD,OAAM;OAAK,QAAQ,UAAU,KAAK,QAAQ,WAAW;MAAI,CAAA;MACxH,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAQ,OAAM;OAAmD,OAAM;OAAK,QAAQ,UAAU,KAAK,QAAQ,YAAY;MAAI,CAAA;MAC3H,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OACE,OAAM;OACN,OAAM;OACN,QAAQ,UAAU,KAAK,QAAQ,eAAe;OAC9C,MAAM,UAAU,KAAK,QAAQ,iBAAiB,KAAK,QAAQ,aAAa,KAAK,QAAQ,YAAY;MAClG,CAAA;KACD,EAAA,CAAA,CAEN,EAAA,CAAA;IAEN,CAAC;GACH,CAAC;GAIH,MAAM,eAAe,IAAI,IAAI,MAAM,gBAAgB,CAAC,CAAC;GACrD,MAAM,YAAY,IAAI,IAAiC,MAAM,KAAK,KAAK,QAAQ,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC;GAC/F,MAAM,YAA2B,gBAAgB,OAAO,MAAM,OAAO,EAAE,CAAC,CAAC,KAAK,YAAY;IACxF,MAAM,MAAM,UAAU,IAAI,OAAO;IACjC,IAAI,QAAQ,KAAA,GACV,OAAO;KACL,KAAK;KACL,WAAW,aAAa,OAAO;KAC/B,iBAAiB;KACjB,aAAa;KACb,cAAc;KACd,KACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD,EAAA,UAAW,QAAkB,CAAA,GAC7B,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAQ,UAAe,CAAA,CACvB,EAAA,CAAA;IAEN;IAEF,MAAM,WAAW,IAAI,cAAc,IAAI,eAAe,IAAI;IAC1D,MAAM,cAAc,aAAa,IAAI,IAAI,IAAI;IAC7C,MAAM,YAAY,CAAC,GAAG,IAAI,MAAM,CAAC,CAC9B,MAAM,OAAO,WAAY,OAAO,cAAc,OAAO,eAAe,OAAO,mBAAoB,MAAM,cAAc,MAAM,eAAe,MAAM,gBAAgB,CAAC,CAC/J,MAAM,GAAG,CAAC;IACb,OAAO;KACL,KAAK,IAAI;KACT,WAAW,aAAa,IAAI,IAAI;KAChC,iBAAiB,IAAI;KACrB,aAAa,IAAI;KACjB,cAAc,IAAI;KAClB,KACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;MACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD,EAAA,UAAW,IAAI,KAAe,CAAA;MAC9B,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA;OAAQ;OAAG,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAI,SAAS,IAAI,KAAK,EAAK,CAAA;OAAC;OAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAI,UAAU,QAAQ,EAAK,CAAA;MAAS,EAAA,CAAA;MACrF,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAQ,OAAM;OAAiD,OAAM;OAAK,QAAQ,UAAU,IAAI,WAAW;MAAI,CAAA;MAC/G,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAQ,OAAM;OAAmD,OAAM;OAAK,QAAQ,UAAU,IAAI,YAAY;MAAI,CAAA;MAClH,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OACE,OAAM;OACN,OAAM;OACN,QAAQ,UAAU,IAAI,eAAe;OACrC,MAAM,UAAU,IAAI,iBAAiB,IAAI,aAAa,IAAI,YAAY;MACvE,CAAA;MACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,YAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,KAAQ,CAAA,GACd,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAI,IAAI,OAAO,IAAI,QAAQ,IAAI,IAAI,IAAI,IAAO,CAAA,CACpC,EAAA,CAAA;MACX,eAAe,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAQ,0BAA+B,CAAA;MACtD,UAAU,KAAK,UACd,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAEE,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CAAG,MAAM,OAAM,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWE,0BAAO;QAAxB,UAAA,CAA6B,OAAI,cAAc,UAAU,MAAM,QAAQ,CAAQ;OAAG,CAAA,CAAA,EAAA,CAAA;OACxG,QAAQ,UAAU,MAAM,cAAc,MAAM,eAAe,MAAM,eAAe;MACjF,GAHM,MAAM,WAAW,MAAM,MAAM,KAGnC,CACF;KACD,EAAA,CAAA;IAEN;GACF,CAAC;GAED,MAAM,cAAc,aAAa,MAAM,UAAU;GACjD,MAAM,YAAY,cAAc,aAAa;GAC7C,MAAM,aAAa,cAAc,gBAAgB,OAAO,OAAO,MAAM,eAAe,YAAY;GAEhG,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD,EAAA,UAAA;IACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWC,0BAAa;KAA7B,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,0BAAa;MAA7B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,0BAAa;OAC1B,UAAA,WAAW,KAAK,CAAC,KAAK,WACrB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAkB,WAAW,MAAM,UAAU,MAAMA,0BAAa,SAAS;QAAI,eAAe,MAAM,QAAQ,GAAG;QAAI,UAAA;OAAc,GAAlH,GAAkH,CAChI;MACE,CAAA,GACJ,MAAM,UAAU,YACf,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QAAO,MAAK;QAAO,WAAWA,0BAAa;QAAY,OAAO,MAAM;QAAY,WAAW,UAAU,MAAM,aAAa,MAAM,OAAO,KAAK;OAAI,CAAA;OAC9I,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWD,0BAAO;QAAK,UAAA;OAAO,CAAA;OACpC,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QAAO,MAAK;QAAO,WAAWC,0BAAa;QAAY,OAAO,MAAM;QAAU,WAAW,UAAU,MAAM,WAAW,MAAM,OAAO,KAAK;OAAI,CAAA;MAC1I,EAAA,CAAA,CAED;KACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;MAAM,WAAWC,0BAAa;MAA9B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,WAAWA,0BAAa;OAAW,UAAU,MAAM,KAAK,WAAW;OAAG,eAAe,YAAY,KAAK;OAAG,UAAA;MAAc,CAAA,GAC/H,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,WAAWA,0BAAa;OAAW,UAAU,MAAM,KAAK,WAAW;OAAG,eAAe,YAAY,MAAM;OAAG,UAAA;MAAe,CAAA,CAC7H;KACH,CAAA,CAAA;;IAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWF,0BAAO;KAAvB,UAAA;MACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAU,OAAM;OAAO,OAAO,SAAS,WAAW,KAAK;OAAG,OAAO,gBAAgB,OAAO;MAAY,CAAA;MACpG,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OACE,OAAM;OACN,OAAO,UAAU,WAAW;OAC5B,OAAO,QAAQ,UAAU,WAAW,WAAW,IAAI,WAAW,UAAU,WAAW,YAAY;MAChG,CAAA;MACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OACE,OAAM;OACN,OAAO,UAAU,WAAW,eAAe;OAC3C,OAAO,mBAAmB,OAAO,mBAAmB,gBAAgB;MACrE,CAAA;MACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAU,OAAM;OAAQ,OAAO;OAAS,OAAM;MAAwB,CAAA;MACtE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OACE,OAAM;OACN,OAAO,eAAe,IAAI,MAAM,UAAU,KAAK,MAAM,cAAc,UAAU,CAAC;OAC9E,OAAO,SAAS,OAAO,UAAU,IAAI;MACtC,CAAA;MACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OACE,OAAM;OACN,OAAO,SAAS,MACZ,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,0BAAO;QAAM,UAAA,SAAS;OAAW,CAAA,IAClD,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CAAG,SAAS,MAAM,YAAY,QAAQ,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAD,EAAgB,QAAQ,WAAW,WAAa,CAAA,CAAI,EAAA,CAAA;OACnG,OAAM;MACP,CAAA;KACE;;IAEL,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;KAAmB;KAAiB;KAAU,OAAO,MAAM;KAAe;KAAuB;IAAgB,CAAA;IAEjH,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KAAiB;KAAoB;KAA4B;KAAyB;KAAmB;IAAU,CAAA;IAEvH,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAS,OAAO,EAAE,WAAW,GAAG;KAAvD,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;MAAQ,WAAW,kBAAkB,QAAQA,0BAAO,OAAO,MAAMA,0BAAO,SAASA,0BAAO;MAAM,eAAe,MAAM,gBAAgB,KAAK;MAAxI,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,0BAAO;OAAW,OAAO,EAAE,YAAY,iDAAiD;MAAI,CAAA,GAAC,MACxG;KACP,CAAA,GAAA,SAAS,KAAK,YACb,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;MAEE,WAAW,kBAAkB,QAAQ,WAAWA,0BAAO,OAAO,MAAMA,0BAAO,SAASA,0BAAO;MAC3F,eAAe,MAAM,gBAAgB,QAAQ,QAAQ;MAHvD,UAAA,CAKE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,0BAAO;OAAW,OAAO,EAAE,YAAY,cAAc,QAAQ,MAAM,EAAE;MAAI,CAAA,GAAE,QAAQ,WAC9F;KALD,GAAA,QAAQ,QAKP,CACT,CACE;;IAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAvB,UAAA;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWC,0BAAa;OAA7B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,OAAO;SAAE,SAAS;SAAe,YAAY;SAAU,KAAK;QAAE;QACjE,UAAA,kBAAkB,OACf,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,OAAO,CAAA,IAEV,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWD,0BAAO;SAAW,OAAO,EAAE,YAAY,cAAc,cAAc,MAAM,EAAE;QAAI,CAAA,GAChG,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAI,cAAc,YAAe,CAAA,CACjC,EAAA,CAAA;OAEF,CAAA,GACN,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,0BAAO;QAAK,OAAO,EAAE,UAAU,KAAK;QAArD,UAAA;SAAyD,OAAO;SAAK;SAAI,OAAO;QAAS;OACtF,CAAA,CAAA;;MACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWC,0BAAa;OAAY,OAAO,EAAE,WAAW,GAAG;OAAhE,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWD,0BAAO;QAAY,UAAA;OAAiB,CAAA,GACrD,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,0BAAO;QAAxB,UAAA;SACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAG,OAAO,EAAE,YAAY,uBAAuB,EAAI,CAAA,GAAC,KAAS,EAAA,CAAA;SACnE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAG,OAAO,EAAE,YAAY,iDAAiD,EAAI,CAAA,GAAC,IAAQ,EAAA,CAAA;SAC5F,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA,CAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAG,OAAO,EAAE,YAAY,mDAAmD,EAAI,CAAA,GAAC,IAAQ,EAAA,CAAA;QAC1F;OACH,CAAA,CAAA;;MACJ,UAAU,WAAW,IAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,0BAAO;OAAO,UAAA;MAAe,CAAA,IAC7C,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD;OAAW,MAAM;OAAoB;MAAU,CAAA;MAClD,eAAe,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,0BAAO;OAAW,UAAA;MAAuB,CAAA;KACtE;;IAEL,iBAAA,GAAA,kBAAA,IAAA,CAAC,kBAAD;KACS;KACG;KACK;KACf,iBAAiB,MAAM;KACvB,gBAAgB,MAAM;KACtB,MAAM,MAAM;KACZ,QAAQ,MAAM;IACf,CAAA;GACE,EAAA,CAAA;EAET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EChTA,MAAM,cAAc;;EAKpB,MAAMG,mBAAyD;GAC7D;IAAE,KAAK;IAAY,OAAO;IAAS,QAAQ,QAAQ,IAAI;GAAS;GAChE;IAAE,KAAK;IAAiB,OAAO;IAAM,QAAQ,QAAQ,IAAI;GAAc;GACvE;IAAE,KAAK;IAAS,OAAO;IAAM,QAAQ,QAAQ,IAAI;GAAM;GACvD;IAAE,KAAK;IAAS,OAAO;IAAM,QAAQ,QAAQ,IAAI;GAAM;GACvD;IAAE,KAAK;IAAU,OAAO;IAAU,QAAQ,QAAQ,IAAI;GAAO;GAC7D;IAAE,KAAK;IAAe,OAAO;IAAM,QAAQ,QAAQ,IAAI,QAAQ;GAAY;GAC3E;IAAE,KAAK;IAAgB,OAAO;IAAM,QAAQ,QAAQ,IAAI,QAAQ;GAAa;GAC7E;IAAE,KAAK;IAAmB,OAAO;IAAO,QAAQ,QAAQ,IAAI,QAAQ;GAAgB;GACpF;IAAE,KAAK;IAAgB,OAAO;IAAU,QAAQ,QAAQ,IAAI;GAAa;GACzE;IAAE,KAAK;IAAQ,OAAO;IAAS,QAAQ,QAAQ,IAAI;GAAK;GACxD;IAAE,KAAK;IAAc,OAAO;IAAQ,QAAQ,QAAQ,IAAI,eAAe,KAAA,IAAY,OAAO,mBAAmB,IAAI;GAAY;GAC7H;IAAE,KAAK;IAAY,OAAO;IAAQ,QAAQ,QAAQ,IAAI;GAAS;GAC/D;IAAE,KAAK;IAAgB,OAAO;IAAO,QAAQ,QAAQ,IAAI;GAAa;GACtE;IAAE,KAAK;IAAY,OAAO;IAAQ,QAAQ,QAAQ,YAAY,IAAI,QAAQ;GAAE;EAC9E;EAEA,SAAgB,UAAU,OAAwE;GAChG,MAAM,CAAC,OAAO,aAAA,GAAYC,MAAAA,SAAAA,CAAS,EAAE;GACrC,MAAM,CAAC,eAAe,qBAAA,GAAoBA,MAAAA,SAAAA,CAAS,KAAK;GACxD,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAkB,YAAY;GAC5D,MAAM,CAAC,UAAA,GAASA,MAAAA,SAAAA,OAAe,KAAK,IAAI,CAAC;GACzC,MAAM,OAAO,MAAM,MAAM,QAAQ,CAAC;GAElC,MAAM,WAAA,GAAUC,MAAAA,QAAAA,OAAc;IAC5B,MAAM,UAAU,MAAM,KAAK,CAAC,CAAC,YAAY;IACzC,MAAM,WAAW,cAAc,OAAO,QAAQ,IAAI,MAAM,CAAC,CAAC,KAAK,QAAQ,QAAQ;KAC7E,MAAM,YAAY,IAAI,QAAQ,MAAM,IAAI,WAAW,MAAM,IAAI,cAAA,CAAe,YAAY;KACxF,MAAM,eAAe,YAAY,MAAM,SAAS,SAAS,OAAO;KAChE,MAAM,iBAAiB,kBAAkB,SAAS,IAAI,aAAa;KACnE,OAAO,gBAAgB;IACzB,CAAC;IACD,MAAM,UAA4F;KAChG,aAAa,OAAO,WAAW,OAAO,SAAS,MAAM;KACrD,YAAY,OAAO,WAAW,OAAO,QAAQ,MAAM;KACnD,WAAW,OAAO,YAAY,OAAO,QAAQ,MAAM,MAAM,QAAQ;KACjE,SAAS,OAAO,YAAY,OAAO,YAAY,MAAM,MAAM,YAAY;IACzE;IACA,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,KAAK,QAAQ,QAAQ;GAC5C,GAAG;IAAC;IAAM;IAAO;IAAe;GAAO,CAAC;GAExC,MAAM,cAAc,KAAK,QAAQ,OAAO,QAAQ,QAAQ,IAAI,QAAQ,CAAC;GAErE,MAAM,cAAc,cAAc,OAAO,QAAQ,IAAI,MAAM,CAAC,CAAC;;GAG7D,MAAM,cAAc,WAAiC;IACnD,IAAI,WAAW,OAAO,aAAa,eAAe,UAAU,KAAK,GAAG,MAAM,SAASF,gBAAc,GAAG,QAAQ;SACvG,aAAa,eAAe,UAAU,MAAM,GAAG,OAAO,OAAO,GAAG,SAAS;GAChF;GAEA,IAAI,MAAM,SAAS,MAAM;IACvB,MAAM,SAAS,gBAAgB,WAAW;IAC1C,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWG,0BAAO;KAAQ,UAAA,WAAW,OAAO,cAAc,cAAc;IAAY,CAAA;GAClG;GAEA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD,EAAA,UAAA;IACG,MAAM,KAAK,SAAS,WAAW,cAC9B,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAUC,UAAAA,eAAa,MAAM,KAAK,SAAS,QAAQ,MAAM,KAAK,SAAS,eAAe;IAAO,CAAA;IAEtH,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWC,yBAAW;KAA3B,UAAA;MACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OAAO,WAAWA,yBAAW;OAAa,aAAY;OAAY,OAAO;OAAO,WAAW,UAAU,SAAS,MAAM,OAAO,KAAK;MAAI,CAAA;MACpI,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OAAQ,WAAWA,yBAAW;OAAc,OAAO;OAAe,WAAW,UAAU,iBAAiB,MAAM,OAAO,KAAK;OAA1H,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,OAAM;QAAM,UAAA;OAAY,CAAA,GAC/B,MAAM,SAAS,KAAK,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAA+B,OAAO,QAAQ;QAAW,UAAA,QAAQ;OAAoB,GAAxE,QAAQ,QAAgE,CAAC,CACjH;;MACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OAAQ,WAAWA,yBAAW;OAAc,OAAO;OAAS,WAAW,UAAU,WAAW,MAAM,OAAO,KAAgB;OAAzH,UAAA;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAa,UAAA;QAAiB,CAAA;QAC5C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAY,UAAA;QAAY,CAAA;QACtC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAW,UAAA;QAAY,CAAA;QACrC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAS,UAAA;QAAY,CAAA;OAC7B;;MACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;OAAM,WAAWC,0BAAa;OAA9B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,WAAWA,0BAAa;QAAW,UAAU,QAAQ,WAAW;QAAG,eAAe,WAAW,KAAK;QAAG,UAAA;OAAc,CAAA,GAC3H,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,WAAWA,0BAAa;QAAW,UAAU,QAAQ,WAAW;QAAG,eAAe,WAAW,MAAM;QAAG,UAAA;OAAe,CAAA,CACzH;;KACH;;IAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;KAAO,WAAWH,0BAAO,QAAQ,MAAME,yBAAW;KAAlD,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;MAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,SAAU,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,MAAO,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,OAAQ,CAAA;KAAK,EAAA,CAAA,EACvF,CAAA,GACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD,EAAA,UAAA,CACG,QAAQ,KAAK,QAAQ;MACpB,MAAM,UAAU,cAAc,IAAI,KAAK,MAAM,IAAI,SAAS,cAAc,GAAG,IAAI;MAC/E,MAAM,UAAU,UAAU,MAAM,UAAU,IAAI,QAAQ;MACtD,MAAM,WAAW,aAAa,SAAS,IAAI,QAAQ,CAAC;MACpD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAWA,yBAAW;QACzB,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAW;SAAW,UAAA,IAAI;QAAW,CAAA,GACrD,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,yBAAW;SAA3B,UAAA;UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WACE,WAAWF,0BAAO;WAClB,OAAO;YAAE,YAAY,eAAe,MAAM,UAAU,IAAI,QAAQ;YAAG,aAAa;WAAE;UACnF,CAAA;UACA,IAAI;UAAc;UAAI,IAAI;UAAa;SACrC;QACF,CAAA,CAAA,EAAA,CAAA;OACF,CAAA,EACH,CAAA;OACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,SAAS,IAAI,KAAK,EAAM,CAAA;OAC7B,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,UAAU,IAAI,MAAM,EAAM,CAAA;OAC/B,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWE,yBAAW;SAC1B,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAG,OAAO;UAAE,OAAO,KAAK,IAAI,GAAG,OAAO,IAAI;UAAK,YAAY,eAAe,MAAM,UAAU,IAAI,QAAQ;SAAE,EAAI,CAAA;QACxG,CAAA;QAAC;QAAE;QAAQ;OACf,EAAA,CAAA;OACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,IAAI,iBAAiB,OAAO,MAAM,IAAI,aAAa,QAAQ,CAAC,IAAI,IAAQ,CAAA;OAC7E,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,IAAI,SAAS,QAAQ,SAAS,aAAa,aAC5C,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWF,0BAAO;QAAM,UAAA,SAAS;OAAW,CAAA,IAClD,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CAAG,SAAS,MAAM,YAAY,QAAQ,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAD,EAAgB,QAAQ,IAAI,WAAa,CAAA,CAAI,EAAA,CAAA,EAAM,CAAA;OAClG,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,YAAY,IAAI,UAAU,KAAK,EAAM,CAAA;MACxC,EAAA,GA3BK,IAAI,WAAW,MAAM,IAAI,KA2B9B;KAER,CAAC,GACA,QAAQ,WAAW,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,SAAS;MAAG,WAAWA,0BAAO;MAAO,UAAA;KAAa,CAAA,EAAK,CAAA,CACnF,EAAA,CAAA,CACF;;IACN,cAAc,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAY,UAAA,oBAAoB,WAAW;IAAO,CAAA;IAC7F,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAvB,UAAA;MAAkC;MAE/B,MAAM,KAAK,SAAS,KAAK;MAAiB;KACxC;;GACF,EAAA,CAAA;EAET;EAEA,SAASC,eAAa,QAAgB,SAAyB;GAC7D,IAAI,WAAW,eAAe,OAAO;GACrC,OAAO,aAAa,OAAO,OAAO,IAAI;EACxC;;;;;ECzIA,MAAMG,mBAAkD;GACtD;IAAE,KAAK;IAAa,OAAO;IAAQ,QAAQ,QAAQ,IAAI;GAAU;GACjE;IAAE,KAAK;IAAoB,OAAO;IAAQ,QAAQ,QAAQ,IAAI;GAAiB;GAC/E;IAAE,KAAK;IAAS,OAAO;IAAM,QAAQ,QAAQ,IAAI;GAAM;GACvD;IAAE,KAAK;IAAU,OAAO;IAAU,QAAQ,QAAQ,IAAI;GAAO;GAC7D;IAAE,KAAK;IAAgB,OAAO;IAAU,QAAQ,QAAQ,IAAI;GAAa;GACzE;IAAE,KAAK;IAAQ,OAAO;IAAS,QAAQ,QAAQ,IAAI;GAAK;GACxD;IAAE,KAAK;IAAc,OAAO;IAAQ,QAAQ,QAAQ,IAAI,eAAe,KAAA,IAAY,OAAO,mBAAmB,IAAI;GAAY;GAC7H;IAAE,KAAK;IAAgB,OAAO;IAAO,QAAQ,QAAQ,IAAI;GAAa;GACtE;IAAE,KAAK;IAAwB,OAAO;IAAU,QAAQ,QAAQ,IAAI;GAAqB;GACzF;IAAE,KAAK;IAAY,OAAO;IAAQ,QAAQ,QAAQ,YAAY,IAAI,QAAQ;GAAE;EAC9E;EAEA,SAAgB,YAAY,OAA0E;GACpG,MAAM,CAAC,OAAO,aAAA,GAAYC,MAAAA,SAAAA,CAAS,EAAE;GACrC,MAAM,CAAC,eAAe,qBAAA,GAAoBA,MAAAA,SAAAA,CAAS,KAAK;GACxD,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAkB,QAAQ;GACxD,MAAM,CAAC,UAAA,GAASA,MAAAA,SAAAA,OAAe,KAAK,IAAI,CAAC;GACzC,MAAM,OAAO,MAAM,MAAM,QAAQ,CAAC;GAElC,MAAM,WAAA,GAAUC,MAAAA,QAAAA,OAAc;IAC5B,MAAM,UAAU,MAAM,KAAK,CAAC,CAAC,YAAY;IACzC,MAAM,WAAW,cAAc,OAAO,QAAQ,IAAI,MAAM,CAAC,CAAC,KAAK,QAAQ,QAAQ;KAC7E,MAAM,eAAe,YAAY,MAAM,IAAI,UAAU,YAAY,CAAC,CAAC,SAAS,OAAO;KACnF,MAAM,iBAAiB,kBAAkB,SAAS,IAAI,UAAU,mBAAmB,KAAA;KACnF,OAAO,gBAAgB;IACzB,CAAC;IACD,MAAM,UAA8E;KAClF,SAAS,OAAO,YAAY,OAAO,YAAY,MAAM,MAAM,YAAY;KACvE,aAAa,OAAO,WAAW,OAAO,SAAS,MAAM;KACrD,YAAY,OAAO,WAAW,MAAM,SAAS,OAAO;KACpD,YAAY,OAAO,WAAW,OAAO,QAAQ,MAAM;IACrD;IACA,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,KAAK,QAAQ,QAAQ;GAC5C,GAAG;IAAC;IAAM;IAAO;IAAe;GAAO,CAAC;GAExC,MAAM,cAAc,KAAK,QAAQ,OAAO,QAAQ,QAAQ,IAAI,QAAQ,CAAC;GAErE,MAAM,cAAc,cAAc,OAAO,QAAQ,IAAI,MAAM,CAAC,CAAC;;GAG7D,MAAM,cAAc,WAAiC;IACnD,IAAI,WAAW,OAAO,aAAa,eAAe,YAAY,KAAK,GAAG,MAAM,SAASF,gBAAc,GAAG,QAAQ;SACzG,aAAa,eAAe,YAAY,MAAM,GAAG,OAAO,OAAO,GAAG,SAAS;GAClF;GAEA,IAAI,MAAM,SAAS,MAAM,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWG,0BAAO;IAAO,UAAA;GAAiB,CAAA;GAE/E,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD,EAAA,UAAA;IACG,MAAM,KAAK,SAAS,WAAW,cAC9B,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAU,UAAA,aAAa,MAAM,KAAK,SAAS,QAAQ,MAAM,KAAK,SAAS,eAAe;IAAO,CAAA;IAEtH,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWC,yBAAW;KAA3B,UAAA;MACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OAAO,WAAWA,yBAAW;OAAa,aAAY;OAAU,OAAO;OAAO,WAAW,UAAU,SAAS,MAAM,OAAO,KAAK;MAAI,CAAA;MAClI,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OAAQ,WAAWA,yBAAW;OAAc,OAAO;OAAe,WAAW,UAAU,iBAAiB,MAAM,OAAO,KAAK;OAA1H,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,OAAM;QAAM,UAAA;OAAY,CAAA,GAC/B,MAAM,SAAS,KAAK,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAA+B,OAAO,QAAQ;QAAW,UAAA,QAAQ;OAAoB,GAAxE,QAAQ,QAAgE,CAAC,CACjH;;MACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OAAQ,WAAWA,yBAAW;OAAc,OAAO;OAAS,WAAW,UAAU,WAAW,MAAM,OAAO,KAAgB;OAAzH,UAAA;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAS,UAAA;QAAY,CAAA;QACnC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAa,UAAA;QAAiB,CAAA;QAC5C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAY,UAAA;QAAiB,CAAA;QAC3C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAY,UAAA;QAAY,CAAA;OAChC;;MACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;OAAM,WAAWC,0BAAa;OAA9B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,WAAWA,0BAAa;QAAW,UAAU,QAAQ,WAAW;QAAG,eAAe,WAAW,KAAK;QAAG,UAAA;OAAc,CAAA,GAC3H,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,WAAWA,0BAAa;QAAW,UAAU,QAAQ,WAAW;QAAG,eAAe,WAAW,MAAM;QAAG,UAAA;OAAe,CAAA,CACzH;;KACH;;IAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;KAAO,WAAWF,0BAAO,QAAQ,MAAMC,yBAAW;KAAlD,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;MAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,SAAU,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,OAAQ,CAAA;KAAK,EAAA,CAAA,EAC3E,CAAA,GACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD,EAAA,UAAA,CACG,QAAQ,KAAK,QAAQ;MACpB,MAAM,UAAU,cAAc,IAAI,KAAK,MAAM,IAAI,SAAS,cAAc,GAAG,IAAI;MAC/E,MAAM,WAAW,IAAI;MACrB,MAAM,UAAU,UAAU,MAAM,UAAU,QAAQ;MAClD,MAAM,WAAW,aAAa,SAAS,IAAI,QAAQ,CAAC;MACpD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAWA,yBAAW;QACzB,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAW;SAAW,UAAA,WAAW,IAAI,SAAS;QAAO,CAAA,GACrE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,yBAAW;SAA3B,UAAA;UACG,IAAI;UAAU;UAAI,IAAI;UAAa;UACnC,IAAI,uBAAuB,IAAI,QAAQ,IAAI,uBAAuB,eAAe;SAC/E;QACF,CAAA,CAAA,EAAA,CAAA;OACF,CAAA,EACH,CAAA;OACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,SAAS,IAAI,KAAK,EAAM,CAAA;OAC7B,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,UAAU,IAAI,MAAM,EAAM,CAAA;OAC/B,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,yBAAW;SAC1B,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAG,OAAO;UAAE,OAAO,KAAK,IAAI,GAAG,OAAO,IAAI;UAAK,YAAY,eAAe,MAAM,UAAU,YAAY,EAAE;SAAE,EAAI,CAAA;QAC1G,CAAA;QAAC;QAAE;QAAQ;OACf,EAAA,CAAA;OACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,IAAI,SAAS,QAAQ,SAAS,aAAa,SAAS,SAAS,aAAa,UAAU,SAAS,aAAa,SAC3G,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWD,0BAAO;QAAM,UAAA,SAAS;OAAW,CAAA,IAClD,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CAAG,SAAS,MAAM,YAAY,QAAQ,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAD,EAAgB,QAAQ,IAAI,WAAa,CAAA,CAAI,EAAA,CAAA,EAAM,CAAA;OAClG,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,YAAY,IAAI,UAAU,KAAK,EAAM,CAAA;MACxC,EAAA,GAvBK,IAAI,SAuBT;KAER,CAAC,GACA,QAAQ,WAAW,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,SAAS;MAAG,WAAWA,0BAAO;MAAO,UAAA;KAAa,CAAA,EAAK,CAAA,CACnF,EAAA,CAAA,CACF;;IACN,cAAc,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAY,UAAA,oBAAoB,WAAW;IAAO,CAAA;IAC7F,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAvB,UAAA;MAAkC;MAClB,MAAM,KAAK,SAAS,KAAK;MAAiB;KACrD;;GACF,EAAA,CAAA;EAET;EAEA,SAAS,aAAa,QAAgB,SAAyB;GAC7D,IAAI,WAAW,eAAe,OAAO;GACrC,OAAO,aAAa,OAAO,OAAO,IAAI;EACxC;EAEA,SAAgB,WAAW,MAAsB;GAE/C,MAAM,QADa,KAAK,QAAQ,WAAW,EACpB,CAAC,CAAC,MAAM,OAAO;GACtC,OAAO,MAAM,MAAM,SAAS,OAAO,KAAK,OAAO,MAAM,MAAM,SAAS;EACtE;;;;;;;;;;;ECxHA,MAAM,gBAAgB;;EAEtB,MAAM,mBAAmB;EAEzB,SAAgB,kBAAkB,OAMpB;GACZ,MAAM,EAAE,UAAU,OAAO,SAAS,aAAa;GAC/C,MAAM,CAAC,UAAU,gBAAA,GAAeG,MAAAA,SAAAA,CAAS,KAAK;GAC9C,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAA6B,IAAI;GAC3D,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAwB,IAAI;GAChE,MAAM,CAAC,aAAa,mBAAA,GAAkBA,MAAAA,SAAAA,CAAwB,IAAI;GAClE,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAS,EAAE;GAC/C,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAwB,IAAI;GACxD,MAAM,CAAC,gBAAgB,sBAAA,GAAqBA,MAAAA,SAAAA,CAAS,KAAK;GAC1D,MAAM,CAAC,iBAAiB,uBAAA,GAAsBA,MAAAA,SAAAA,CAAS,KAAK;GAC5D,MAAM,aAAA,GAAYC,MAAAA,OAAAA,CAAgC,IAAI;GAEtD,MAAM,SAAS,MAAM;GACrB,MAAM,QAAQ,OAAO;GACrB,MAAM,gBAAgB,SAA+B;IACnD,IAAI,YAAY,MAAM,OAAO;IAC7B,MAAM,QAAQ,MAAM,QAAQ,IAAI;IAChC,OAAO,SAAS,KAAK,QAAQ,WAAW,WAAW;GACrD;GAEA,MAAM,YAAY,SAAS,aAAa,CAAC;GAEzC,MAAM,UAAU,SAAS,WAAW;GACpC,MAAM,mBAAA,GAAkBC,MAAAA,QAAAA,OAAc,SAAS,KAAK,YAAY,QAAQ,QAAQ,GAAG,CAAC,QAAQ,CAAC;GAC7F,MAAM,gBAAA,GAAeA,MAAAA,QAAAA,OAAc;IACjC,MAAM,sBAAM,IAAI,IAAY;IAC5B,KAAK,MAAM,WAAW,UAAU,KAAK,MAAM,SAAS,QAAQ,QAAQ,IAAI,IAAI,MAAM,EAAE;IACpF,KAAK,MAAM,OAAO,MAAM,QAAQ,QAAQ,CAAC,GAAG,IAAI,IAAI,IAAI,KAAK;IAC7D,OAAO,CAAC,GAAG,GAAG;GAChB,GAAG,CAAC,UAAU,MAAM,MAAM,CAAC;GAE3B,MAAM,OAAO,OAAO,MAAqB,SAAgC;IAEvE,IAAI,MADmB,SAAS,KAAK,IAAI,GAC3B;KACZ,UAAU,IAAI;KACd,SAAS,IAAI;KACb,cAAc,IAAI;KAClB,eAAe,IAAI;IACrB;GACF;GAEA,MAAM,iBAAuB;IAC3B,SAAS,UAAU,MAAM,CAAC;IAC1B,cAAc,IAAI;IAClB,eAAe,IAAI;GACrB;;GAGA,MAAM,eAAe,UAAkB,UAAwB;IAC7D,SAAS;KAAE,GAAG,UAAU,MAAM;KAAG;KAAU;IAAM,CAAC;IAClD,cAAc,IAAI;IAClB,eAAe,IAAI;GACrB;GAEA,MAAM,aAAa,SAA4B;IAC7C,SAAS,gBAAgB,IAAI,CAAC;IAC9B,cAAc,UAAU,IAAI,CAAC;IAC7B,eAAe,IAAI;GACrB;GAEA,MAAM,cAAc,YAA2B;IAC7C,IAAI,UAAU,MAAM;IACpB,MAAM,UAAU,cAAc,KAAK;IACnC,IAAI,YAAY,MAAM;KACpB,eAAe,OAAO;KACtB;IACF;IACA,MAAM,YAAY,CAAC,GAAG,KAAK;IAC3B,MAAM,cAAc,eAAe,OAAO,KAAK,UAAU,WAAW,SAAS,UAAU,IAAI,MAAM,UAAU;IAC3G,MAAM,iBAAiB,UAAU,WAAW,SAAS,UAAU,IAAI,MAAM,UAAU,KAAK,CAAC;IACzF,IAAI,eAAe,GAAG;KACpB,UAAU,eAAe;KAEzB,IAAI,kBAAkB,KAAK,mBAAmB,aAAa,UAAU,OAAO,gBAAgB,CAAC;IAC/F,OAAO,IAAI,kBAAkB,GAC3B,UAAU,kBAAkB;SAE5B,UAAU,KAAK,KAAK;IAEtB,MAAM,KAAK;KAAE,GAAG;KAAQ,OAAO;IAAU,GAAG,OAAO;GACrD;GAEA,MAAM,aAAa,OAAO,SAAqC;IAC7D,MAAM,KACJ;KAAE,GAAG;KAAQ,OAAO,MAAM,QAAQ,cAAc,cAAc,IAAI;IAAE,GACpE,OACF;GACF;GAEA,MAAM,gBAAgB,YAA2B;IAC/C,MAAM,WAAW,UAAU,MAAM,cAAc,UAAU,OAAO,UAAU;IAC1E,IAAI,aAAa,KAAA,GAAW;IAE5B,MAAM,YAAY,CAAC,GAAG,KAAK;IAC3B,KAAK,MAAM,QAAQ,SAAS,OAAO;KACjC,MAAM,QAAQ,UAAU,WAAW,cAAc,UAAU,SAAS,MAAM,UAAU,IAAI,CAAC;KACzF,IAAI,SAAS,GAAG,UAAU,SAAS;UAC9B,UAAU,KAAK,IAAI;IAC1B;IACA,MAAM,KAAK;KAAE,GAAG;KAAQ,OAAO;IAAU,GAAG,WAAW,SAAS,QAAQ,WAAW;GACrF;GAEA,MAAM,oBAA0B;IAC9B,aAAa,eAAe,iBAAiB,MAAM,GAAG,OAAO,MAAM,GAAG,SAAS;GACjF;GAEA,MAAM,cAAc,OAAO,SAA8B;IACvD,MAAM,SAAS,qBAAqB,MAAM,KAAK,KAAK,CAAC;IACrD,IAAI,OAAO,WAAW,MAAM;KAC1B,SAAS,UAAU,OAAO,SAAS,eAAe;KAClD;IACF;IACA,MAAM,KAAK,OAAO,QAAQ,aAAa;GACzC;GAEA,MAAM,WAAW,SAAS,YAAY;GACtC,MAAM,iBAAiB,OAAO,QAAQ,UAAU,qBAAqB,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,YAAY,SAAS,CAAC;GAC1G,MAAM,gBAAgB,UAAU,iBAAiB,CAAC;GAClD,MAAM,iBAAiB,iBAAiB,gBAAgB,cAAc,MAAM,GAAG,CAAC;GAChF,MAAM,kBAAkB,OAAO,QAAQ,UAAU,sBAAsB,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,YAAY,SAAS,CAAC;GAC5G,MAAM,aAAa,oBAAoB,MAAM,QAAQ,KAAK;GAE1D,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWC,2BAAc;IAA9B,UAAA;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD;MACY;MACV,YAAY,MAAM;MAClB,SAAS,MAAM,WAAW;MACV;MACN;MACV,gBAAgB,aAAa,aAAa,CAAC,QAAQ;MAClC;MACjB,2BAA2B,oBAAoB,aAAa,CAAC,QAAQ;KACtE,CAAA;KAEA,mBAAmB,iBAAA,GAAA,kBAAA,IAAA,CAAC,kBAAD,CAAmB,CAAA;KAEtC,YACC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,2BAAc;MAA9B,UAAA;OAEE,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD,EAAqB,MAAQ,CAAA;OAE5B,WAAW,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAWA,2BAAc;QAAY,UAAA;OAAY,CAAA;OAEzE,gBAAgB,SAAS,KACxB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAWA,2BAAc;QAC5B,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,2BAAc;SAA9B,UAAA;UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;WAAK,WAAWA,2BAAc;WAAU,UAAA;UAAwB,CAAA;UAChE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;WAAK,WAAWA,2BAAc;WAC3B,UAAA,gBAAgB,KAAK,CAAC,UAAU,YAAY,UAAU,UAAU,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK;UACjF,CAAA;UACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;WAAK,WAAWA,2BAAc;WAAU,UAAA;UAEnC,CAAA;SACF;;OACF,CAAA;OAGN,YAAY,QAAQ,QAAQ,UAAU,KACrC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,2BAAc;QAA9B,UAAA;SAA2C;SACrC,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAI,OAAO,QAAQ,OAAO,EAAK,CAAA;SAAC;SAAS,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,cAAc,CAAA;SAAC;SAE9D,QAAQ,QAAQ,KAAK,OAAO,UAC3B,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA;UACG,QAAQ,KAAK;UACd,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;WAAG,WAAWA,2BAAc;WAAS,MAAM,MAAM;WAAQ,QAAO;WAAS,KAAI;WAC1E,UAAA,MAAM,UAAU,KAAK,KAAK;UAC1B,CAAA;UAAC;UACF,MAAM;UAAM;UAAI,MAAM;UAAU;SAC9B,EAAA,GANK,MAAM,MAMX,CACP;QACE;;OAGP,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,2BAAc;QAA9B,UAAA;SACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;UACE,WAAWA,2BAAc;UACzB,OAAO;UACP,WAAW,UAAU,cAAc,MAAM,OAAO,KAAK;UAHvD,UAAA,CAKE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAM;WAAG,UAAA;UAAe,CAAA,GAC/B,UAAU,KAAK,aAAa,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAA0B,OAAO,SAAS;WAAK,UAAA,SAAS;UAAc,GAAzD,SAAS,EAAgD,CAAC,CAC9F;;SACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,WAAWA,2BAAc;UAAW,UAAU,eAAe;UAAI,eAAe,KAAK,cAAc;UAAG,UAAA;SAEtG,CAAA;SACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,WAAWA,2BAAc,YAAY,MAAMA,2BAAc;UAAS,SAAS;UAAU,UAAA;SAErF,CAAA;SACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,2BAAc,cAAgB,CAAA;SAC/C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,WAAWA,2BAAc;UAAS,UAAU,MAAM,WAAW;UAAG,SAAS;UAAa,UAAA;SAAe,CAAA;SAC7G,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,WAAWA,2BAAc;UAAS,eAAe,UAAU,SAAS,MAAM;UAAG,UAAA;SAAe,CAAA;SACpG,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UACE,WAAWA,2BAAc;UACzB,UAAU,MAAM,WAAW;UAC3B,eAAe,KAAK,KAAK;WAAE,GAAG;WAAc,UAAU,OAAO;UAAS,GAAG,kBAAkB;UAC5F,UAAA;SAEO,CAAA;SACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;UACE,KAAK;UACL,WAAWA,2BAAc;UACzB,MAAK;UACL,QAAO;UACP,WAAW,UAAU;WACnB,MAAM,OAAO,MAAM,OAAO,QAAQ;WAClC,MAAM,OAAO,QAAQ;WACrB,IAAI,SAAS,KAAA,GAAW,YAAiB,IAAI;UAC/C;SACD,CAAA;QACE;;OAEJ,MAAM,WAAW,IAEd,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAWA,2BAAc;QAAO,UAAA;OAEhC,CAAA,IAGL,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;QAAO,WAAWA,2BAAc;QAAhC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;SAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;SAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;SAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;SAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,MAAO,CAAA;SAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,MAAO,CAAA;SAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;SAC9E,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;SAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;SAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;SAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;QACzC,EAAA,CAAA,EACC,CAAA,GACP,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UACG,MAAM,KAAK,SACV,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;SAA0B,WAAW,eAAe,UAAU,IAAI,IAAIA,2BAAc,UAAU;SAA9F,UAAA;UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,WAAWA,2BAAc;WAAW,UAAA,KAAK;UAAe,CAAA,EAAK,CAAA;UACvE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,WAAWA,2BAAc;WAAW,UAAA,KAAK;UAAY,CAAA,EAAK,CAAA;UACpE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,YAAY,KAAK,MAAU,CAAA;UAChC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,KAAK,MAAU,CAAA;UACpB,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,KAAK,UAAc,CAAA;UACxB,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,KAAK,WAAe,CAAA;UACzB,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,KAAK,OAAW,CAAA;UACrB,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,KAAK,SAAa,CAAA;UACvB,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UACG,KAAK,YAAY,OACd,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,WAAWC,0BAAO;WAAK,UAAA;UAAO,CAAA,IAEpC,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;WAAM,OAAO,iBAAiB,IAAI;WAAlC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;YAAM,WAAWD,2BAAc;YAAW,UAAA,mBAAmB,IAAI;WAAQ,CAAA,GACxE,aAAa,IAAI,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;YAAM,WAAWA,2BAAc;YAAa,UAAA;WAAS,CAAA,CACxE;UAER,CAAA,EAAA,CAAA;UACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;WAAI,WAAWA,2BAAc;WAC1B,UAAA,KAAK,SAAS,KACX,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;YAAM,WAAWC,0BAAO;YAAK,UAAA;WAAO,CAAA,IACpC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;YAAM,OAAO,KAAK;YAAO,UAAA,KAAK;WAAW,CAAA;UAC3C,CAAA;UACJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,WAAWD,2BAAc;WAAS,eAAe,UAAU,IAAI;WAAG,UAAA;UAAU,CAAA,GACpF,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,WAAWA,2BAAc;WAAS,eAAe,KAAK,WAAW,IAAI;WAAG,UAAA;UAAU,CAAA,CACxF,EAAA,CAAA;SACF;QA5BK,GAAA,UAAU,IAAI,CA4BnB,CACL,EACI,CAAA,CACF;;OAGV,UAAU,QACT,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;QACS;QACP,UAAU;QACV,gBAAgB;SAAE,SAAS,IAAI;SAAG,eAAe,IAAI;SAAG,cAAc,IAAI;QAAE;QAC5E,cAAc,KAAK,YAAY;QAC/B,OAAO;QACU;QACH;OACf,CAAA;OAGF,WAAW,SAAS,KACnB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,2BAAc;QAA9B,UAAA;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,WAAWA,2BAAc;UAAU,UAAA;SAAc,CAAA;SACtD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,WAAWA,2BAAc;UAAW,UAAA;SAEpC,CAAA;SACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;UAAI,WAAWA,2BAAc;UAC1B,UAAA,WAAW,KAAK,cACf,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;WACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;YAAM,WAAWA,2BAAc;YAAW,UAAA,UAAU;WAAY,CAAA;WAChE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;YAAM,WAAWC,0BAAO;YAAxB,UAAA,CAA6B,OAAI,UAAU,QAAe;;WAC1D,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;YAAM,WAAWD,2BAAc;YAA/B,UAAA;aACG,UAAU,UAAU,MAAM;aAAE;aAAS,YAAY,UAAU,KAAK;aAAE;aAClE,UAAU,YAAY,YAAY;YAC/B;;WACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;YACE,WAAWA,2BAAc;YACzB,eAAe,YAAY,UAAU,UAAU,UAAU,KAAK;YAC/D,UAAA;WAEO,CAAA;UACN,EAAA,GAbK,UAAU,WAAW,MAAM,UAAU,KAa1C,CACL;SACC,CAAA;QACD;;OAGN,cAAc,SAAS,KACtB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,2BAAc;QAA9B,UAAA;SACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,WAAWA,2BAAc;UAA9B,UAAA,CAAwC,YAC7B,aAAa,OAAO,KAAK,MAAM,SAAS,OAAO,KACrD;;SACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;UAAI,WAAWA,2BAAc;UAC1B,UAAA,eAAe,KAAK,UACnB,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;WACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;YAAM,WAAWA,2BAAc;YAAW,UAAA,MAAM;WAAY,CAAA;WAC5D,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;YAAM,WAAWC,0BAAO;YAAxB,UAAA,CAA6B,OAAI,MAAM,QAAe;;WACtD,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;YAAM,WAAWD,2BAAc;YAA/B,UAAA;aAA0C;aAClC,UAAU,MAAM,eAAe;aAAE;YACnC;;WACN,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;YAAM,WAAWA,2BAAc;YAA/B,UAAA,CAAuC,MAClC,UAAU,MAAM,UAAU,MAAM,MAAM,CACrC;;UACJ,EAAA,GATK,MAAM,WAAW,MAAM,MAAM,KASlC,CACL;SACC,CAAA;SACH,cAAc,SAAS,KACtB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,WAAWA,2BAAc;UAAS,eAAe,mBAAmB,aAAa,CAAC,QAAQ;UAC/F,UAAA,iBAAiB,OAAO,UAAU,OAAO,cAAc,MAAM,IAAI;SAC5D,CAAA;QAEP;;MAEJ;;IAEJ;;EAET;;;;;EAMA,SAAS,aAAa,OASR;GACZ,MAAM,EAAE,aAAa;GACrB,MAAM,OAAO,aAAa,OAAO,OAAO,YAAY,SAAS,MAAM,SAAS,EAAE;GAC9E,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWA,2BAAc;IAA9B,UAAA;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,2BAAc;MAA9B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,2BAAc;OAAa,UAAA;MAAY,CAAA,GACvD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,2BAAc;OAC3B,UAAA,aAAa,OACT,MAAM,UAAU,gBAAgB,yBACjC,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;QAAE;QACI,SAAS,OAAO,MAAM,OAAO,IAAI;QAAE;QACnC,OAAO,SAAS,UAAU;QAAE;QAC3B,OAAO,SAAS,iBAAiB,CAAC;QAAE;QACnC,OAAO,SAAS,cAAc;QAAE;QACvC,SAAS,iBAAiB,KAAK,YAAY,OAAO,SAAS,cAAc,IAAI;OAC9E,EAAA,CAAA;MACD,CAAA,CACF;;KAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,2BAAc;MAA9B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,2BAAc;OAAa,UAAA;MAAW,CAAA,GACtD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,2BAAc,gBAAgB,MAAM,eAAe,SAAS,IAAI,MAAMA,2BAAc,SAAS;OAC1G,UAAA,MAAM,eAAe,WAAW,IAC7B,MACA,MAAM,eAAe,KAAK,CAAC,UAAU,YAAY,UAAU,UAAU,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK;MACzF,CAAA,CACF;;KAEL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,2BAAc;MAA9B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OACE,WAAWA,2BAAc,WAAW,MAAM,kBAAkB,MAAMA,2BAAc,gBAAgB;OAChG,OAAM;OACN,SAAS,MAAM;OAChB,UAAA;MAEO,CAAA,GACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,WAAWA,2BAAc,YAAY,MAAMA,2BAAc;OAAS,SAAS,MAAM;OACtF,UAAA,MAAM,WAAW,WAAW;MACvB,CAAA,CACL;;IACF;;EAET;;EAGA,SAAS,mBAA8B;GACrC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWA,2BAAc;IAA9B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,2BAAc;KAAkB,UAAA;IAAS,CAAA,GACzD,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;KAAI,WAAWA,2BAAc;KAA7B,UAAA;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA,CAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,KAAK,CAAA,GAAC,6BAA+B,EAAA,CAAA;MAC5C,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA,CAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,KAAK,CAAA,GAAC,wCAA0C,EAAA,CAAA;MACvD,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;OAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,MAAM,CAAA;OAAC;OAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,YAAY,CAAA;OAAC;OAA4C,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,UAAa,CAAA;OAAC;MAAe,EAAA,CAAA;MACjH,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA,CAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,KAAK,CAAA,GAAC,wBAA0B,EAAA,CAAA;MACvC,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA,CAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,IAAI,CAAA,GAAC,iCAAmC,EAAA,CAAA;MAC/C,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,6DAA8D,CAAA;MAClE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;OAAI;OAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,OAAO,CAAA;OAAC;OAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,OAAU,CAAA;OAAC;OAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,KAAQ,CAAA;OAAC;OAAa,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,kBAAkB,CAAA;OAAC;MAAqC,EAAA,CAAA;MAC7I,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,gGAAiG,CAAA;MACrG,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;OAAI;OAAiB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,gBAAmB,CAAA;OAAC;MAAe,EAAA,CAAA;KAC5D;IACD,CAAA,CAAA;;EAET;;;;;;;EAQA,SAAS,aAAa,OAAmD;GACvE,MAAM,EAAE,UAAU;GAClB,IAAI,MAAM,WAAW,iBAAkB,MAAM,WAAW,WAAW,CAAC,MAAM,UACxE,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWA,2BAAc;IAA9B,UAAA;KAAuC;KAChB,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,aAAa,CAAA;KAAC;IACnC;;GAGT,IAAI,MAAM,UAAU,MAClB,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWA,2BAAc;IAA9B,UAAA;KAAqC;KAAM,MAAM;KAAM;IAAS;;GAEzE,OAAO;EACT;;EAGA,SAAS,UAAU,UAAkB,QAAwB;GAC3D,OAAO,iBAAiB,QAAQ,IAAI,OAAO,QAAQ,aAAa;EAClE;EAEA,SAAS,YAAY,OAAuB;GAC1C,QAAQ,QAAQ,IAAA,CAAK,QAAQ,CAAC,IAAI;EACpC;;EAGA,SAAS,YAAY,MAAc,IAA2B;GAC5D,MAAM,yBAAQ,IAAI,KAAK,OAAO,WAAW,EAAA,CAAE,QAAQ;GACnD,MAAM,uBAAM,IAAI,KAAK,KAAK,WAAW,EAAA,CAAE,QAAQ;GAC/C,IAAI,OAAO,MAAM,KAAK,KAAK,OAAO,MAAM,GAAG,KAAK,MAAM,OAAO,OAAO;GACpE,OAAO,KAAK,OAAO,MAAM,SAAS,KAAQ,IAAI;EAChD;;EAGA,SAAS,iBAAiB,MAA2B;GACnD,MAAM,UAAU,mBAAmB,IAAI;GACvC,IAAI,KAAK,YAAY,MAAM,OAAO;GAClC,MAAM,OAAO,SAAS,OAAO,KAAK,KAAK,IAAI,QAAQ,OAAO,KAAK,SAAS,IAAI,QAAQ,OAAO,KAAK,UAAU,IAAI,QAAQ,OAAO,KAAK,MAAM;GACxI,MAAM,UAAU,SAAS,OAAO,KAAK,QAAQ,KAAK,IAAI,QAAQ,OAAO,KAAK,QAAQ,SAAS,IAAI,QAAQ,OAAO,KAAK,QAAQ,UAAU,IAAI,QAAQ,OAAO,KAAK,QAAQ,MAAM;GAC3K,OAAO,4CAA4C,UAAU,OAAO,OAAO,OAAO,UAC9E;EACN;;;;;;;EAiBA,SAAS,oBACP,QACA,OACsB;GACtB,MAAM,QAA6B,QAAQ,QAAQ,CAAC,EAAA,CAAG,QAAQ,QAAQ,IAAI,SAAS,CAAC;GACrF,IAAI,KAAK,WAAW,GAAG,OAAO,CAAC;GAC/B,MAAM,WAAW,KAAK,QAAQ,QAAQ;IACpC,IAAI,IAAI,eAAe,UAAU,IAAI,eAAe,cAAc,IAAI,eAAe,WAAW,OAAO;IAEvG,OAAO,IAAI,eAAe,cAAc,IAAI,eAAe,UAAU,CAAC,eAAe,OAAO,IAAI,UAAU,IAAI,KAAK;GACrH,CAAC;GACD,MAAM,QAAQ,SAAS,QAAQ,KAAK,QAAQ,MAAM,IAAI,QAAQ,CAAC;GAC/D,IAAI,SAAS,GAAG,OAAO,CAAC;GACxB,OAAO,SACJ,KAAK,SAAS;IACb,UAAU,IAAI;IACd,OAAO,IAAI;IACX,QAAQ,IAAI;IACZ,OAAO,IAAI,SAAS;IAEpB,WAAW,IAAI,eAAe;GAChC,EAAE,CAAC,CACF,MAAM,OAAO,WAAW,OAAO,SAAS,MAAM,MAAM,CAAC,CACrD,MAAM,GAAG,gBAAgB;EAC9B;;EAGA,SAAS,eAAe,OAAsB,UAAkB,OAAwB;GAOtF,OAAO;KALJ,SAAsB,KAAK,aAAa,YAAY,KAAK,UAAU;KACnE,SAAsB,KAAK,aAAa,YAAY,KAAK,UAAU;KACnE,SAAsB,KAAK,aAAa,OAAO,KAAK,UAAU;KAC9D,SAAsB,KAAK,aAAa,OAAO,KAAK,UAAU;GAEnD,CAAC,CAAC,MAAM,YAAY,MAAM,KAAK,OAAO,CAAC;EACvD;;EAGA,SAAS,WAAW,OAQN;GACZ,MAAM,EAAE,OAAO,aAAa;GAC5B,MAAM,eACJ,OACA,KACA,OACA,UAEA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWA,2BAAc;IAA9B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UAAQ,MAAa,CAAA,GACrB,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;KACE,MAAK;KACL,KAAK;KACL,MAAK;KACL,OAAO,OAAO,KAAK;KACnB,WAAW,UAAU;MACnB,MAAM,OAAO,OAAO,MAAM,OAAO,KAAK;MACtC,MAAM,OAAO,OAAO,SAAS,IAAI,KAAK,QAAQ,IAAI,OAAO;MACzD,IAAI,OAAO,aAAa,KAAA,GAAW,MAAM,SAAS,IAAI;WACjD,SAAS;OAAE,GAAG;QAAQ,MAAM;MAAK,CAAC;KACzC;IACD,CAAA,CACE;GAdqC,GAAA,KAcrC;GAGP,MAAM,UAAU,MAAM,SAAS,WAAW,CAAC;GAC3C,MAAM,cAAc,SAAgC;IAClD,IAAI,KAAK,WAAW,GAAG;KACrB,SAAS;MAAE,GAAG;MAAO,SAAS;KAAK,CAAC;KACpC;IACF;IACA,SAAS;KACP,GAAG;KACH,SAAS;MACP,SAAS;MACT,OAAO,MAAM,SAAS,SAAS,MAAM;MACrC,WAAW,MAAM,SAAS,aAAa,MAAM;MAC7C,YAAY,MAAM,SAAS,cAAc,MAAM;MAC/C,QAAQ,MAAM,SAAS,UAAU,MAAM;KACzC;IACF,CAAC;GACH;GAEA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWA,2BAAc;IAA9B,UAAA;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,2BAAc;MAA9B,UAAA;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,2BAAc;QAA9B,UAAA;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UAAO,kBAAsB,CAAA;SAC7B,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;UAAO,MAAK;UAAmB,OAAO,MAAM;UAAU,WAAW,UAAU,SAAS;WAAE,GAAG;WAAO,UAAU,MAAM,OAAO;UAAM,CAAC;SAAI,CAAA;SAClI,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;UAAU,IAAG;UACV,UAAA,MAAM,gBAAgB,KAAK,aAAa,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD,EAAuB,OAAO,SAAW,GAA5B,QAA4B,CAAC;SAC3E,CAAA;QACP;;OACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,2BAAc;QAA9B,UAAA;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UAAO,mBAAuB,CAAA;SAC9B,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;UAAO,MAAK;UAAgB,OAAO,MAAM;UAAO,WAAW,UAAU,SAAS;WAAE,GAAG;WAAO,OAAO,MAAM,OAAO;UAAM,CAAC;SAAI,CAAA;SACzH,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;UAAU,IAAG;UACV,UAAA,MAAM,aAAa,KAAK,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD,EAAoB,OAAO,MAAQ,GAAtB,KAAsB,CAAC;SAC/D,CAAA;QACP;;OACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,2BAAc;QAA9B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UAAO,OAAW,CAAA,GAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAO,MAAM;SAAM,WAAW,UAAU,SAAS;UAAE,GAAG;UAAO,MAAM,MAAM,OAAO;SAA6B,CAAC;SACnH,UAAA,aAAa,KAAK,SAAS,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAmB,OAAO;UAAO,UAAA,YAAY;SAAc,GAA9C,IAA8C,CAAC;QAClF,CAAA,CACL;;OACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,2BAAc;QAA9B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UAAO,KAAS,CAAA,GAChB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAO,MAAM;SAAU,WAAW,UAAU,SAAS;UAAE,GAAG;UAAO,UAAU,MAAM,OAAO;SAAM,CAAC;SACpG,UAAA,iBAAiB,KAAK,aAAa,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAuB,OAAO;UAAW,UAAA;SAAiB,GAA7C,QAA6C,CAAC;QACzF,CAAA,CACL;;OACJ,YAAY,aAAa,SAAS,MAAM,KAAK;OAC7C,YAAY,WAAW,aAAa,MAAM,SAAS;OACnD,YAAY,OAAO,cAAc,MAAM,UAAU;OACjD,YAAY,MAAM,UAAU,MAAM,MAAM;OACzC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,2BAAc,QAAQ,MAAMA,2BAAc;QAA1D,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UAAO,iBAAqB,CAAA,GAC5B,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,OAAO,MAAM;SAAM,WAAW,UAAU,SAAS;UAAE,GAAG;UAAO,MAAM,MAAM,OAAO;SAAM,CAAC;QAAI,CAAA,CAC/F;;MACF;;KAEL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,2BAAc;MAAU,UAAA;KAAyB,CAAA;KAChE,QAAQ,KAAK,QAAQ,UACpB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,2BAAc;MAA9B,UAAA;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,OAAO,OAAO;QACd,aAAY;QACZ,WAAW,UAAU,WAAW,QAAQ,KAAK,WAAW,aAAa,aAAa,QAAQ;SAAE,GAAG;SAAW,MAAM,MAAM,OAAO;QAAM,IAAI,SAAS,CAAC;OAClJ,CAAA;OACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWC,0BAAO;QAAK,UAAA;OAAO,CAAA;OACpC,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,OAAO,OAAO;QACd,aAAY;QACZ,WAAW,UAAU,WAAW,QAAQ,KAAK,WAAW,aAAa,aAAa,QAAQ;SAAE,GAAG;SAAW,IAAI,MAAM,OAAO;QAAM,IAAI,SAAS,CAAC;OAChJ,CAAA;OAED,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QACE,OAAO,WAAW,OAAO,IAAI;QAC7B,WAAW,UAAU,WAAW,QAAQ,KAAK,WAAW,aACtD,aAAa,QAAQ,aAAa,WAAW,MAAM,OAAO,KAAiB,IAAI,SAChF,CAAC;QAED,UAAA,kBAAkB,KAAK,UACtB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAoB,OAAO;SAAQ,UAAA,iBAAiB;QAAe,GAAtD,KAAsD,CACpE;OACK,CAAA;OACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,WAAWD,2BAAc;QAAS,eAAe,WAAW,QAAQ,QAAQ,GAAG,aAAa,aAAa,KAAK,CAAC;QAAG,UAAA;OAAU,CAAA;MACjI;KAxByC,GAAA,KAwBzC,CACN;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;MAAQ,WAAWA,2BAAc;MAAW,eAAe,WAAW,CAAC,GAAG,SAAS;OAAE,MAAM;OAAS,IAAI;MAAQ,CAAC,CAAC;MAAG,UAAA;KAAc,CAAA;KAElI,MAAM,YAAY,QACjB,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,2BAAc;MAAU,UAAA;KAAmB,CAAA,GAC3D,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,2BAAc;MAA9B,UAAA;OACG,YAAY,QAAQ,SAAS,MAAM,QAAQ,OAAO,EAAE,WAAW,UAAU,aAAa,OAAO,UAAU,EAAE,OAAO,MAAM,CAAC,EAAE,CAAC;OAC1H,YAAY,SAAS,aAAa,MAAM,QAAQ,WAAW,EAAE,WAAW,UAAU,aAAa,OAAO,UAAU,EAAE,WAAW,MAAM,CAAC,EAAE,CAAC;OACvI,YAAY,SAAS,cAAc,MAAM,QAAQ,YAAY,EAAE,WAAW,UAAU,aAAa,OAAO,UAAU,EAAE,YAAY,MAAM,CAAC,EAAE,CAAC;OAC1I,YAAY,QAAQ,UAAU,MAAM,QAAQ,QAAQ,EAAE,WAAW,UAAU,aAAa,OAAO,UAAU,EAAE,QAAQ,MAAM,CAAC,EAAE,CAAC;MAC3H;KACL,CAAA,CAAA,EAAA,CAAA;KAGH,MAAM,UAAU,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,2BAAc;MAAc,UAAA,MAAM;KAAW,CAAA;KACtF,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,2BAAc;MAA9B,UAAA;OAA0C;OAClC,YAAY,KAAK;OAAE;OAAO,YAAY,MAAM;MAC/C;;KACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,2BAAc;MAA9B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,WAAWA,2BAAc,YAAY,MAAMA,2BAAc;OAAS,SAAS,MAAM;OAAQ,UAAA;MAAY,CAAA,GAC7G,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,WAAWA,2BAAc;OAAW,SAAS,MAAM;OAAU,UAAA;MAAU,CAAA,CAC5E;;IACF;;EAET;EAEA,SAAS,aAAa,OAAoB,UAAuC,OAAoC;GACnH,IAAI,MAAM,YAAY,MAAM;GAC5B,SAAS;IAAE,GAAG;IAAO,SAAS;KAAE,GAAG,MAAM;KAAS,GAAG;IAAM;GAAE,CAAC;EAChE;;;;;;EAOA,SAAS,aAAa,QAAuB,OAAgC;GAC3E,MAAM,OAAO,eAAe;GAC5B,IAAI,SAAS,KAAA,GAAW;IACtB,MAAM,EAAE,MAAM,OAAO;IACrB,OAAO;KAAE;KAAM;IAAG;GACpB;GACA,OAAO;IAAE,GAAG;IAAQ,MAAM,CAAC,GAAG,IAAI;GAAE;EACtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECrrBA,MAAM,gBAAgB;GAAC;GAAgB;GAAgB;GAAe;GAAW;EAAU;EAC3F,MAAM,iBAAyC;GAC7C,cAAc;GAAO,cAAc;GAAQ,aAAa;GAAQ,SAAS;GAAM,UAAU;EAC3F;;EAEA,MAAM,eAAe;GAAC;GAAM;GAAQ;GAAS;EAAK;EAClD,MAAM,gBAAwC;GAAE,MAAM;GAAU,MAAM;GAAQ,OAAO;GAAQ,KAAK;EAAO;EAEzG,SAAS,YAAY,OAAwB;GAC3C,IAAI,OAAO,UAAU,YAAY,UAAU,IAAI,OAAO;GACtD,MAAM,OAAO,IAAI,KAAK,KAAK;GAC3B,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG,OAAO,SAAS;GAClD,OAAO,SAAS,YAAY,KAAK,QAAQ,CAAC;EAC5C;EAEA,SAAgB,SAAS,OAOX;GACZ,MAAM,cAAc,aAA2C,MAAM,OAAO,MAAM,SAAS,KAAK,aAAa,QAAQ,KAAK;GAC1H,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWE,yBAAY;IAA5B,UAAA;KACG,MAAM,SAAS,KAAK,YAAY;MAC/B,MAAM,WAAW,WAAW,QAAQ,QAAQ;MAC5C,MAAM,UAAU,UAAU,WAAW;MACrC,MAAM,OAAO,UAAU,QAAQ;MAC/B,MAAM,SAAS,UAAU,WAAW;MACpC,MAAM,UAAU,SAAS,QAAQ,MAAM,QAAS,KAA+B,OAAO,IACjF,KAAsF,UACvF;MACJ,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAY;OAA5B,UAAA;QACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,yBAAY;SAA5B,UAAA;UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,WAAWC,0BAAO;WAAW,OAAO,EAAE,YAAY,cAAc,QAAQ,MAAM,EAAE;UAAI,CAAA;UAC1F,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,WAAWD,yBAAY;WAAa,UAAA,QAAQ;UAAkB,CAAA;UACnE,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;WAAM,WAAWA,yBAAY;WAAU,UAAA;UAAQ,CAAA;UAC1D,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;WAAM,WAAWA,yBAAY;WAA7B,UAAA;YAA6C,QAAQ;YAAS;YAAI,QAAQ;WAAgB;;SACvF;;QAEJ,YAAY,QACX,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAY;SACzB,UAAA,sBAAsB,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,WACzC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,WAAWA,yBAAY;UAA5B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;WAAK,WAAWA,yBAAY;WAAU,UAAA,eAAe,QAAQ;UAAS,CAAA,GACtE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;WAAK,WAAWA,yBAAY;WAAU,UAAA,OAAO,KAAK;UAAO,CAAA,CACtD;SAHyC,GAAA,GAGzC,CACN;QACE,CAAA;QAGN,YAAY,QAAQ,YAAY,QAAQ,QAAQ,SAAS,KACxD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAY;SACzB,UAAA,eAAe,OAAO,CAAC,CAAC,KAAK,WAAW;UACvC,MAAM,UAAU,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;UACtE,MAAM,MAAM,OAAO,OAAO,QAAQ,WAAW,OAAO,MAAM;UAC1D,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;WAAK,WAAWA,yBAAY;WAA5B,UAAA;YACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;aAAK,WAAWA,yBAAY;aAA5B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;cAAM,WAAWA,yBAAY;cAAa,UAAA,cAAc,QAAQ;aAAU,CAAA,GAC1E,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;cAAM,WAAWA,yBAAY;cAA7B,UAAA,CAA2C,SAAQ,GAAO;aACvD,CAAA,CAAA;;YACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;aAAK,WAAWA,yBAAY;aAC1B,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAG,OAAO;cAAE,OAAO,KAAK,IAAI,SAAS,CAAC,IAAI;cAAK,YAAY,cAAc,OAAO;aAAE,EAAI,CAAA;YACnF,CAAA;YACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;aAAK,WAAWA,yBAAY;aAAc,UAAA,YAAY,OAAO,QAAQ;YAAO,CAAA;WACzE;UATwC,GAAA,GASxC;SAET,CAAC;QACE,CAAA;QAGN,YAAY,SAAS,YAAY,QAAQ,QAAQ,WAAW,MAC3D,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWC,0BAAO;SAAM,UAAA,cAAc,SAAS,QAAQ;QAAO,CAAA;QAGpE,UACC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWD,yBAAY;SAA5B,UAAA;UAA0C;UACjC,YAAY,UAAU,aAAa,IAAI;UAAE;SAC7C;;QAEN,aAAa,QAAQ,CAAC,UAAU,SAAS,aACxC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAW,YAAY,SAAS,SAAS,KAAK,IAAIA,yBAAY,gBAAgBA,yBAAY;SAA/F,UAAA;UAA6G;UAClG,YAAY,SAAS,KAAK;UAAE;UACpC,SAAS,cAAc,OACpB,2BACA,kBAAkB,YAAY,SAAS,SAAS,KAAK,YAAY,SAAS,SAAS,KAAK,IAAI,QAAQ,YAAY,SAAS,SAAS,IAAI,UAAU;SACjJ;;OAEJ;MAzDuC,GAAA,QAAQ,QAyD/C;KAET,CAAC;KACA,MAAM,SAAS,WAAW,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWC,0BAAO;MAAO,UAAA;KAAa,CAAA;KAE3E,iBAAA,GAAA,kBAAA,IAAA,CAAC,mBAAD;MACE,UAAU,MAAM;MAChB,OAAO,MAAM;MACb,SAAS,MAAM;MACf,UAAU,MAAM;MAEhB,QAAQ,MAAM;KACf,CAAA;IACE;;EAET;;EAGA,SAAS,YAAY,WAAkC;GACrD,IAAI,cAAc,MAAM,OAAO;GAC/B,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,OAAO,KAAK,IAAI,IAAI,aAAa,GAAI,CAAC;GACvE,IAAI,UAAU,IAAI,OAAO;GACzB,MAAM,UAAU,KAAK,MAAM,UAAU,EAAE;GACvC,IAAI,UAAU,IAAI,OAAO,UAAU;GACnC,OAAO,KAAK,MAAM,UAAU,EAAE,IAAI;EACpC;;EAGA,SAAS,YAAY,OAA8B;GACjD,IAAI,UAAU,MAAM,OAAO;GAC3B,IAAI,UAAU,UAAU,OAAO;GAC/B,IAAI,UAAU,eAAe,OAAO;GACpC,IAAI,UAAU,WAAW,OAAO;GAChC,IAAI,UAAU,WAAW,OAAO;GAChC,IAAI,UAAU,gBAAgB,OAAO;GACrC,IAAI,UAAU,YAAY,OAAO;GACjC,IAAI,UAAU,aAAa,OAAO;GAClC,IAAI,MAAM,WAAW,OAAO,GAAG,OAAO,eAAe,MAAM,MAAM,CAAC;GAClE,OAAO;EACT;;EAGA,SAAS,YAAY,WAAkC;GACrD,IAAI,cAAc,MAAM,OAAO;GAC/B,OAAO,KAAK,OAAO,KAAK,IAAI,IAAI,aAAa,KAAQ;EACvD;EAEA,SAAS,sBAAsB,SAA4D;GACzF,MAAM,UAAU,OAAO,QAAQ,OAAO,CAAC,CAAC,QAAQ,CAAC,SAAS,QAAQ,WAAW;GAC7E,MAAM,UAAoC,CAAC;GAC3C,KAAK,MAAM,OAAO,eAAe;IAC/B,MAAM,QAAQ,QAAQ,MAAM,CAAC,cAAc,aAAa,GAAG;IAC3D,IAAI,UAAU,KAAA,GAAW,QAAQ,KAAK,KAAK;GAC7C;GACA,KAAK,MAAM,SAAS,SAClB,IAAI,CAAC,cAAc,SAAS,MAAM,EAAE,GAAG,QAAQ,KAAK,KAAK;GAE3D,OAAO;EACT;EAEA,SAAS,eAAe,SAAoG;GAE1H,OAAO,CAAC,GAAGC,OAAK,CAAC,CAAC,MAAM,OAAO,WAAW;IACxC,MAAM,aAAa,aAAa,QAAQ,OAAO,MAAM,QAAQ,WAAW,MAAM,MAAM,EAAE;IACtF,MAAM,cAAc,aAAa,QAAQ,OAAO,OAAO,QAAQ,WAAW,OAAO,MAAM,EAAE;IACzF,QAAQ,aAAa,IAAI,KAAK,eAAe,cAAc,IAAI,KAAK;GACtE,CAAC;EACH;;EAGA,SAAS,cAAc,SAAkB,UAAwC;GAC/E,IAAI,UAAU,WAAW,cAAc,SAAS,UAAU,UAAU,OAAO;GAC3E,IAAI,UAAU,WAAW,cAAc,SAAS,UAAU,gBAAgB,OAAO;GACjF,IAAI,QAAQ,WAAW,OAAO,OAAO;GACrC,IAAI,QAAQ,aAAa,QAAQ,OAAO;GACxC,IAAI,QAAQ,aAAa,QAAQ,OAAO;GACxC,OAAO;EACT;;;;;ECrKA,MAAM,iBAAkD;GACtD;IAAE,KAAK;IAAM,OAAO;IAAS,QAAQ,QAAQ,IAAI;GAAG;GACpD;IAAE,KAAK;IAAS,OAAO;IAAM,QAAQ,QAAQ,IAAI;GAAM;GACvD;IAAE,KAAK;IAAa,OAAO;IAAO,QAAQ,QAAQ,IAAI;GAAU;GAChE;IAAE,KAAK;IAAY,OAAO;IAAM,QAAQ,QAAQ,IAAI;GAAS;GAC7D;IAAE,KAAK;IAAa,OAAO;IAAQ,QAAQ,QAAQ,YAAY,IAAI,SAAS;GAAE;GAC9E;IAAE,KAAK;IAAY,OAAO;IAAQ,QAAQ,QAAQ,YAAY,IAAI,QAAQ;GAAE;GAC5E;IAAE,KAAK;IAAS,OAAO;IAAM,QAAQ,QAAQ,IAAI;GAAM;GACvD;IAAE,KAAK;IAAU,OAAO;IAAU,QAAQ,QAAQ,IAAI;GAAO;GAC7D;IAAE,KAAK;IAAgB,OAAO;IAAU,QAAQ,QAAQ,IAAI;GAAa;GACzE;IAAE,KAAK;IAAQ,OAAO;IAAS,QAAQ,QAAQ,IAAI;GAAK;GACxD;IAAE,KAAK;IAAc,OAAO;IAAQ,QAAQ,QAAQ,IAAI,eAAe,KAAA,IAAY,OAAO,mBAAmB,IAAI;GAAY;GAC7H;IAAE,KAAK;IAAY,OAAO;IAAO,QAAQ,QAAQ,IAAI,WAAW,MAAM;GAAI;EAC5E;EAEA,SAAgB,YAAY,OAA0E;GACpG,MAAM,CAAC,OAAO,aAAA,GAAYC,MAAAA,SAAAA,CAAS,EAAE;GACrC,MAAM,CAAC,eAAe,qBAAA,GAAoBA,MAAAA,SAAAA,CAAS,KAAK;GACxD,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAS,IAAI;GACjD,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAkB,QAAQ;GACxD,MAAM,CAAC,eAAe,qBAAA,GAAoBA,MAAAA,SAAAA,CAAwB,MAAM;GACxE,MAAM,CAAC,UAAA,GAASA,MAAAA,SAAAA,OAAe,KAAK,IAAI,CAAC;GACzC,MAAM,OAAO,MAAM,MAAM,QAAQ,CAAC;GAClC,MAAM,gBAAgB,KAAK,QAAQ,QAAQ,IAAI,QAAQ,CAAC,CAAC;GAEzD,MAAM,cAAc,cAAc,OAAO,QAAQ,IAAI,MAAM,CAAC,CAAC;GAE7D,MAAM,WAAA,GAAUC,MAAAA,QAAAA,OAAc;IAC5B,MAAM,UAAU,MAAM,KAAK,CAAC,CAAC,YAAY;IACzC,MAAM,aAAa,OAAO,UAAU;IACpC,MAAM,WAAW,cAAc,OAAO,QAAQ,IAAI,MAAM,CAAC,CAAC,KAAK,QAAQ,QAAQ;KAC7E,MAAM,SAAS,IAAI,SAAS,MAAM,MAAM,IAAI,KAAK,OAAO,IAAI,aAAa;KACzE,MAAM,eAAe,YAAY,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,OAAO;KAC3E,MAAM,iBAAiB,kBAAkB,SAAS,IAAI,aAAa;KACnE,MAAM,aAAa,eAAe,KAAK,IAAI,aAAa,QAClD,QAAQ,IAAI,YAAa,aAAa;KAC5C,MAAM,iBAAiB,kBAAkB,UAAU,kBAAkB,SAAS,IAAI,WAAW,CAAC,IAAI;KAClG,OAAO,gBAAgB,kBAAkB,cAAc;IACzD,CAAC;IACD,MAAM,UAA8E;KAClF,SAAS,OAAO,YAAY,OAAO,YAAY,MAAM,MAAM,YAAY;KACvE,aAAa,OAAO,WAAW,OAAO,SAAS,MAAM;KACrD,YAAY,OAAO,WAAW,MAAM,SAAS,OAAO;KACpD,eAAe,OAAO,WAAW,WAAW,MAAM,IAAI,WAAW,KAAK;IACxE;IACA,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,KAAK,QAAQ,QAAQ;GAC5C,GAAG;IAAC;IAAM;IAAO;IAAe;IAAY;IAAS;IAAO;GAAa,CAAC;;GAG1E,MAAM,cAAc,WAAiC;IACnD,IAAI,WAAW,OAAO,aAAa,eAAe,YAAY,KAAK,GAAG,MAAM,SAAS,cAAc,GAAG,QAAQ;SACzG,aAAa,eAAe,YAAY,MAAM,GAAG,OAAO,OAAO,GAAG,SAAS;GAClF;GAEA,IAAI,MAAM,SAAS,MAAM,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWC,0BAAO;IAAO,UAAA;GAAiB,CAAA;GAE/E,MAAM,SAAuD,CAAC;GAC9D,IAAI,YAAY,UACd,KAAK,MAAM,OAAO,SAAS;IACzB,MAAM,QAAQ,WAAW,IAAI,UAAU,KAAK;IAC5C,MAAM,OAAO,OAAO,OAAO,SAAS;IACpC,IAAI,SAAS,KAAA,KAAa,KAAK,UAAU,OAAO,OAAO,KAAK;KAAE;KAAO,MAAM,CAAC,GAAG;IAAE,CAAC;SAC7E,KAAK,KAAK,KAAK,GAAG;GACzB;GAGF,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD,EAAA,UAAA;IACG,MAAM,KAAK,SAAS,WAAW,cAC9B,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KACpB,UAAA,MAAM,KAAK,SAAS,WAAW,gBAC5B,8BACA,aAAa,OAAO,MAAM,KAAK,SAAS,eAAe,IAAI;IAC5D,CAAA;IAEP,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWC,yBAAW;KAA3B,UAAA;MACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OAAO,WAAWA,yBAAW;OAAa,aAAY;OAAyB,OAAO;OAAO,WAAW,UAAU,SAAS,MAAM,OAAO,KAAK;MAAI,CAAA;MACjJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OAAQ,WAAWA,yBAAW;OAAc,OAAO;OAAe,WAAW,UAAU,iBAAiB,MAAM,OAAO,KAAK;OAA1H,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,OAAM;QAAM,UAAA;OAAY,CAAA,GAC/B,MAAM,SAAS,KAAK,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAA+B,OAAO,QAAQ;QAAW,UAAA,QAAQ;OAAoB,GAAxE,QAAQ,QAAgE,CAAC,CACjH;;MACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OAAQ,WAAWA,yBAAW;OAAc,OAAO;OAAY,WAAW,UAAU,cAAc,MAAM,OAAO,KAAK;OAApH,UAAA;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAI,UAAA;QAAa,CAAA;QAC/B,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAK,UAAA;QAAc,CAAA;QACjC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAI,UAAA;QAAU,CAAA;OACtB;;MACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OAAQ,WAAWA,yBAAW;OAAc,OAAO;OAAS,WAAW,UAAU,WAAW,MAAM,OAAO,KAAgB;OAAzH,UAAA;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAS,UAAA;QAAY,CAAA;QACnC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAa,UAAA;QAAiB,CAAA;QAC5C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAY,UAAA;QAAiB,CAAA;QAC3C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAe,UAAA;QAAY,CAAA;OACnC;;MACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;OACE,WAAWA,yBAAW;OACtB,OAAO;OACP,WAAW,UAAU,iBAAiB,MAAM,OAAO,KAAsB;OACzE,OAAM;OAJR,UAAA;QAME,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAO,UAAA;QAAa,CAAA;QAClC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAM,UAAA;QAAmB,CAAA;QACvC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,OAAM;SAAO,UAAA;QAAc,CAAA;OAC7B;;MACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;OAAM,WAAWC,0BAAa;OAA9B,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,WAAWA,0BAAa;QAAW,UAAU,QAAQ,WAAW;QAAG,eAAe,WAAW,KAAK;QAAG,UAAA;OAAc,CAAA,GAC3H,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,WAAWA,0BAAa;QAAW,UAAU,QAAQ,WAAW;QAAG,eAAe,WAAW,MAAM;QAAG,UAAA;OAAe,CAAA,CACzH;;KACH;;IACJ,kBAAkB,UAAU,gBAAgB,KAC3C,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWF,0BAAO;KAAvB,UAAA;MAAkC;MAC5B;MAAc;KACf;;IAGP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;KAAO,WAAWA,0BAAO,QAAQ,MAAMC,yBAAW;KAAlD,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;MAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,UAAW,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,SAAU,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,MAAO,CAAA;MAAC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,KAAM,CAAA;KAAK,EAAA,CAAA,EAC/E,CAAA,GACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD,EAAA,UAAA;MACG,OAAO,KAAK,UAAU;OACrB,MAAM,cAAc,MAAM,KAAK,QAAQ,OAAO,QAAQ,QAAQ,IAAI,QAAQ,CAAC;OAC3E,OACE,iBAAA,GAAA,kBAAA,KAAA,CAACE,MAAAA,UAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;QAAI,WAAWF,yBAAW;QACxB,UAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;SAAI,SAAS;SAAb,UAAA,CACG,MAAM,OACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;UAAM,WAAWA,yBAAW;UAA5B,UAAA;WAAuC,MAAM,KAAK;WAAO;WAAQ,UAAU,WAAW;UAAQ;SAC5F,CAAA,CAAA;;OACF,CAAA,GACH,MAAM,KAAK,KAAK,QAAQ,aAAa,KAAK,MAAM,QAAQ,CAAC,CAClD,EAAA,GARK,WAAW,MAAM,KAQtB;MAEd,CAAC;MACA,YAAY,YAAY,QAAQ,KAAK,QAAQ,aAAa,KAAK,MAAM,QAAQ,CAAC;MAC9E,QAAQ,WAAW,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;OAAI,SAAS;OAAG,WAAWD,0BAAO;OAAO,UAAA;MAAa,CAAA,EAAK,CAAA;KACnF,EAAA,CAAA,CACF;;IACN,cAAc,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAY,UAAA,oBAAoB,WAAW;IAAO,CAAA;IAC7F,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,0BAAO;KAAvB,UAAA,CAAkC,0CAE/B,MAAM,KAAK,SAAS,KAAK,gBACvB;;GACF,EAAA,CAAA;EAET;EAEA,SAAS,aAAa,KAAiB,UAAgC;GACrE,MAAM,UAAU,UAAU,UAAU,IAAI,QAAQ;GAChD,MAAM,WAAW,aAAa,SAAS,IAAI,QAAQ,CAAC;GACpD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;IAAiB,WAAW,IAAI,WAAWC,yBAAW,cAAc,KAAA;IAApE,UAAA;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAW;MAA3B,UAAA,CACG,IAAI,SAAS,QAAQ,UAAU,IAAI,EAAE,GACrC,IAAI,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,yBAAW;OAAa,UAAA;MAAS,CAAA,CAChE;KACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAW;MAAU,UAAA,IAAI,aAAa;KAAc,CAAA,CAClE,EAAA,CAAA;KACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,IAAI,iBAAiB,cAAc,UAAU,IAAI,YAAY,EAAE,EAAM,CAAA;KAC1E,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD,EAAA,UAAM,IAAI,aAAa,OAAO,MAAM,WAAW,IAAI,UAAU,KAAK,IAAI,CAAC,IAAI,MAAM,QAAQ,IAAI,QAAQ,EAAO,CAAA,GAC5G,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAW;MAA3B,UAAA,CAAoC,OAAI,YAAY,WAAW,GAAG,CAAC,CAAO;KACxE,CAAA,CAAA,EAAA,CAAA;KACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,UAAU,IAAI,MAAM,EAAM,CAAA;KAC/B,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,IAAI,iBAAiB,OAAO,MAAM,IAAI,aAAa,QAAQ,CAAC,IAAI,IAAQ,CAAA;KAC7E,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,IAAI,SAAS,QAAQ,YAAY,QAAQ,QAAQ,aAAa,aAC/D,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWD,0BAAO;MAAM,UAAA,SAAS;KAAW,CAAA,IAClD,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CAAG,SAAS,MAAM,YAAY,QAAQ,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAD,EAAgB,QAAQ,IAAI,WAAa,CAAA,CAAI,EAAA,CAAA,EAAM,CAAA;IAChG;GAlBK,GAAA,IAAI,EAkBT;EAER;EAEA,SAAS,WAAW,KAAyB;GAC3C,IAAI,IAAI,cAAc,QAAQ,IAAI,aAAa,MAAM,OAAO;GAC5D,OAAO,KAAK,IAAI,GAAG,IAAI,WAAW,IAAI,SAAS;EACjD;;EAGA,SAAS,UAAU,IAAoB;GAErC,OADiB,GAAG,QAAQ,aAAa,EAC3B,CAAC,CAAC,MAAM,GAAG,CAAC;EAC5B;EAEA,SAAS,WAAW,QAAuB,OAAuB;GAChE,IAAI,WAAW,MAAM,OAAO;GAC5B,MAAM,UAAU,QAAQ,IAAI,KAAK,MAAM,CAAC;GACxC,IAAI,YAAY,QAAQ,IAAI,KAAK,KAAK,CAAC,GAAG,OAAO;GACjD,IAAI,YAAY,wBAAQ,IAAI,KAAK,QAAQ,KAAQ,CAAC,GAAG,OAAO;GAC5D,OAAO;EACT;;;;;;;;EC9KA,MAAM,OAA+B;GACnC,CAAC,YAAY,IAAI;GACjB,CAAC,UAAU,MAAM;GACjB,CAAC,YAAY,MAAM;GACnB,CAAC,UAAU,KAAK;GAChB,CAAC,YAAY,MAAM;GACnB,CAAC,SAAS,OAAO;EACnB;EAEA,SAAgB,kBAAkB;GAChC,MAAM,CAAC,WAAW,iBAAA,GAAgBI,MAAAA,SAAAA,CAAgB,UAAU;GAC5D,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAmB,OAAO;GACpD,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,OAAe,eAAe,GAAG,CAAC;GACtE,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,OAAe,wBAAQ,IAAI,KAAK,CAAC,CAAC;GAClE,MAAM,CAAC,eAAe,qBAAA,GAAoBA,MAAAA,SAAAA,CAAS,KAAK;GACxD,MAAM,CAAC,iBAAiB,uBAAA,GAAsBA,MAAAA,SAAAA,CAAkC,CAAC,CAAC;GAClF,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAA0B;IAAE,KAAK;IAAU,KAAK;GAAO,CAAC;GAE5F,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAoB,CAAC,CAAC;GACtD,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAA0B,CAAC,CAAC;GACxD,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAiC,IAAI;GACnE,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAuB,CAAC,CAAC;GACvD,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAA+B,IAAI;GAC7D,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAkC,IAAI;GACtE,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAkC,IAAI;GACtE,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAgC,IAAI;GAChE,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAiC,IAAI;GACnE,MAAM,CAAC,WAAW,iBAAA,GAAgBA,MAAAA,SAAAA,CAA8C,IAAI;GACpF,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAS,KAAK;GAC5C,MAAM,UAAU,WAAW;GAE3B,MAAM,gBAAA,GAAeC,MAAAA,qBAAAA,CAAqB,gBAAgB,MAAM,WAAW,gBAAgB,MAAM,WAAW;GAC5G,MAAM,mBAAmB,KAAK,UAAU,aAAa,MAAM;GAE3D,MAAM,UAAA,GAASC,MAAAA,YAAAA,CAAY,OAAO,oBAA6B,aAAa,UAAU;IACpF,WAAW,IAAI;IAEf,MAAM,cAAc,MAAM,UAAU,UAAU;IAC9C,MAAM,CAAC,eAAe,eAAe,iBAAiB,MAAM,QAAQ,IAAI;KACtE,aAAa;KAAG,YAAY;KAAG,YAAY;IAC7C,CAAC;IACD,YAAY,iBAAiB,CAAC,CAAC;IAC/B,UAAU,eAAe,CAAC,CAAC;IAC3B,WAAW,aAAa;IACxB,WAAW,iBAAiB,CAAC,CAAC;IAC9B,IAAI,oBAAoB;KACtB,MAAM,CAAC,eAAe,eAAe,eAAe,MAAM,QAAQ,IAAI;MAAC,aAAa;MAAG,aAAa;MAAG,WAAW;KAAC,CAAC;KACpH,YAAY,aAAa;KACzB,YAAY,aAAa;KACzB,UAAU,WAAW;IACvB;IACA,WAAW,KAAK;GAGlB,GAAG,CAAC,gBAAgB,CAAC;GAErB,CAAA,GAAA,MAAA,UAAA,OAAgB;IAAE,OAAY,KAAK;GAAE,GAAG,CAAC,MAAM,CAAC;GAGhD,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,YAAY;IAChB,YAAiB,CAAC,CAAC,MAAM,WAAW;KAAE,IAAI,CAAC,WAAW,WAAW,MAAM;IAAE,CAAC;IAC1E,aAAa;KAAE,YAAY;IAAK;GAClC,GAAG,CAAC,gBAAgB,CAAC;GAGrB,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,cAAc,cAAc,aAAa,MAAM,aAAkB,CAAC,CAAC,KAAK,WAAW;IACvF,IAAI,cAAc,cAAc,aAAa,MAAM,aAAkB,CAAC,CAAC,KAAK,WAAW;IACvF,KAAK,cAAc,YAAY,cAAc,YAAY,WAAW,MAAM,WAAgB,CAAC,CAAC,KAAK,SAAS;GAC5G,GAAG;IAAC;IAAW;IAAU;IAAU;GAAM,CAAC;GAE1C,MAAM,UAAA,GAASC,MAAAA,QAAAA,OAAc;IAC3B,MAAM,QAAQ,wBAAQ,IAAI,KAAK,CAAC;IAChC,IAAI,UAAU,SAAS,OAAO;KAAE,MAAM;KAAO,IAAI;IAAM;IACvD,IAAI,UAAU,QAAQ,OAAO;KAAE,MAAM,eAAe,EAAE;KAAG,IAAI;IAAM;IACnE,IAAI,UAAU,SAAS,OAAO;KAAE,MAAM,eAAe,GAAG;KAAG,IAAI;IAAM;IACrE,IAAI,UAAU,UAAU,OAAO;KAAE,MAAM;KAAY,IAAI,WAAW,aAAa,aAAa;IAAS;IACrG,OAAO;KAAE,MAAM,WAAW,QAAQ;KAAO,IAAI,WAAW,MAAM;IAAM;GACtE,GAAG;IAAC;IAAO;IAAY;IAAU;GAAS,CAAC;GAE3C,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,YAAY;IAChB,UAAe,OAAO,MAAM,OAAO,IAAI,aAAa,CAAC,CAAC,MAAM,WAAW;KACrE,IAAI,aAAa,WAAW,MAAM;KAClC,SAAS,MAAM;KACf,IAAI,OAAO,kBAAkB,QAAQ,OAAO,gBAAgB,MAC1D,aAAa;MAAE,MAAM,OAAO;MAAe,IAAI,OAAO;KAAY,CAAC;IAEvE,CAAC;IACD,aAAa;KAAE,YAAY;IAAK;GAClC,GAAG;IAAC,OAAO;IAAM,OAAO;IAAI;IAAe;GAAgB,CAAC;GAE5D,MAAM,WAAA,GAAUD,MAAAA,YAAAA,OAAkB;IAChC,OACE,cAAc,cAAc,cAAc,cAAc,cAAc,YACnE,aAAa,QAAQ,aAAa,QAAQ,WAAW,MACxD,IACF;IACA,UAAe,OAAO,MAAM,OAAO,IAAI,aAAa,CAAC,CAAC,MAAM,WAAW;KAAE,IAAI,WAAW,MAAM,SAAS,MAAM;IAAE,CAAC;GAClH,GAAG;IAAC;IAAQ;IAAW;IAAU;IAAU;IAAQ,OAAO;IAAM,OAAO;IAAI;GAAa,CAAC;GAEzF,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWE,0BAAO;IAAvB,UAAA;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,0BAAO;MAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAM,OAAU,CAAA,GAChB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,0BAAO;OACtB,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,WAAWA,0BAAO;QAAY,UAAU;QAAS,SAAS;QAC/D,UAAA,UAAU,SAAS;OACd,CAAA;MACJ,CAAA,CACH;;KAEL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,0BAAO;MACpB,UAAA,KAAK,KAAK,CAAC,OAAO,WACjB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAoB,WAAW,cAAc,QAAQA,0BAAO,SAAS;OAAI,eAAe,aAAa,KAAK;OAAI,UAAA;MAAc,GAA/G,KAA+G,CAC7H;KACE,CAAA;KAEJ,cAAc,cACb,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MACY;MACD;MACD;MACC;MACA;MACT,eAAe,aAAa;OAAE,iBAAiB,QAAQ;OAAG,aAAa,QAAQ;MAAE;KAClF,CAAA;KAEF,cAAc,YACb,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD;MACS;MACG;MACH;MACP,SAAS;MACG;MACZ,cAAc;MACJ;MACV,YAAY;MACG;MACf,iBAAiB;MACA;MACjB,iBAAiB,cAAc,oBAAoB,cAAc;OAAE,GAAG;QAAW,YAAY,SAAS,eAAe;MAAK,EAAE;MAC5H,MAAM;MACN,QAAQ;MACA;MACC;KACV,CAAA;KAEF,cAAc,cAAc,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MAAa,MAAM;MAAoB;KAAW,CAAA;KAC9E,cAAc,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD;MAAW,MAAM;MAAkB;KAAW,CAAA;KACxE,cAAc,cAAc,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MAAa,MAAM;MAAoB;KAAW,CAAA;KAC9E,cAAc,WACb,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;MACY;MACF;MACC;MACK;MACG;MACT;KACT,CAAA;KAGH,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,0BAAO;MAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,OAAO,CAAA,GACV,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;OAAI,WAAWA,0BAAO;OAAtB,UAAA;QACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;SAAI;SAED,YAAY,QAAQ,QAAQ,gBAAgB,YAAY,UAAU,QAAQ,aAAa,SAAS,aAAa;SAAG;QAE/G,EAAA,CAAA;QACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,iCAAkC,CAAA;QACtC,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,kDAAmD,CAAA;QACvD,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,6CAA8C,CAAA;QAClD,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,8BAA+B,CAAA;QACnC,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA;SAAI;SACI,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,YAAY,CAAA;SAAC;SAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,SAAS,CAAA;SAAC;SAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,SAAS,CAAA;SAAC;SAC5C,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,KAAK,CAAA;SAAC;SAAG,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,KAAK,CAAA;SAAC;SAAG,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD,EAAA,UAAG,KAAK,CAAA;SAAC;QAE/C,EAAA,CAAA;QACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAI,0CAA2C,CAAA;OAC7C;MACD,CAAA,CAAA;;KAEL,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD,EAAa,SAAS,QAAQ,QAAU,CAAA;IACrC;;EAET;;;;;;;;;;;;;;;;;;;;;;;;ECjNA,SAAgB,UAAU,QAA4C;GACpE,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWC,wBAAO;IACrB,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,wBAAO;KACrB,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,iBAAD,CAAkB,CAAA;IACf,CAAA;GACF,CAAA;EAET;;;;;;;;ECPA,SAAgB,cAAyB;GACvC,MAAM,SAAA,GAAQC,MAAAA,qBAAAA,CAAqB,gBAAgB,MAAM,WAAW,gBAAgB,MAAM,WAAW;GACrG,MAAM,CAAC,SAAS,eAAA,GAAcC,MAAAA,SAAAA,CAAiC,IAAI;GACnE,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAoB,CAAC,CAAC;GAEtD,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAgC,IAAI;GAEhE,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,YAAY;IAChB,YAAiB,CAAC,CAAC,MAAM,WAAW;KAAE,IAAI,CAAC,WAAW,WAAW,MAAM;IAAE,CAAC;IAC1E,aAAkB,CAAC,CAAC,MAAM,WAAW;KAAE,IAAI,CAAC,WAAW,YAAY,UAAU,CAAC,CAAC;IAAE,CAAC;IAClF,WAAgB,CAAC,CAAC,MAAM,WAAW;KAAE,IAAI,CAAC,WAAW,UAAU,MAAM;IAAE,CAAC;IACxE,aAAa;KAAE,YAAY;IAAK;GAClC,GAAG,CAAC,MAAM,MAAM,CAAC;GAEjB,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,mBAAD;IACE,UAAU;IACH;IACE;IACC;IACF;GACT,CAAA;EAEL;;;;;;;;;;;;;;;;ECfA,MAAM,KAAK;;EAEX,MAAM,WAAW;EAEjB,MAAa,OAAO;EACpB,MAAa,SAAS,CAAC,OAAO;EAE9B,SAAgB,MAAM,KAA2B;GAC/C,IAAI,MAAM,OAAO,cAAc,IAAI,MAAM,SAAS;IAChD,MAAM;IACN,KAAK;GACP,GAAG,SAAS,CAAC;GAEb,IAAI,MAAM,OAAO,2BAA2B,IAAI,MAAM,SAAS;IAC7D,MAAM;IACN,IAAI;IACJ,OAAO;IACP,aAAa;GACf,IAAI,WAAA,GAA6BC,MAAAA,cAAAA,CAAE,WAAW,EAAE,MAAM,MAAM,KAAK,CAAC,CAAC,CAAC;GAGpE,IAAI,SAAS,CAAC,aAAa,IAAI,UAAU;IACvC,MAAM,QAAQ,MAAM;IACpB,IAAI,UAAU,KAAA,GAAW;IACzB,MAAM,eAAe,gBAAgB,OAAO,MAAM,IAAI,EAAE,CAAC,GAAG,sCAAsC;IAElG,MAAM,eAAe,MAAM,YAAY,CAAC,EAAE,SAAS,MAAM,MAAM,OAAO,+BAA+B,MAAM,MAAM,SAAS;KACxH,MAAM;KACN,KAAK;IACP,GAAG,WAAW,CAAC,CAAC,GAAG,kCAAkC;GACvD,CAAC;EACH"}