@agentaily/design-system 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"file":"IntegrationSettings.js","sources":["../../../src/components/settings/IntegrationSettings.jsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from \"react\";\nimport { Alert } from \"../feedback/Alert.jsx\";\nimport { Badge } from \"../display/Badge.jsx\";\nimport { BrandMark } from \"../utilities/BrandMark.jsx\";\nimport { Button } from \"../buttons/Button.jsx\";\nimport { HelpSteps } from \"./HelpSteps.jsx\";\nimport { Icon } from \"../utilities/Icon.jsx\";\nimport { IconButton } from \"../buttons/IconButton.jsx\";\nimport { SecretField } from \"../inputs/SecretField.jsx\";\nimport { Select } from \"../inputs/Select.jsx\";\nimport { Spinner } from \"../feedback/Spinner.jsx\";\nimport { StatusPill } from \"../display/StatusPill.jsx\";\nimport { Switch } from \"../inputs/Switch.jsx\";\nimport { TestRow } from \"./TestRow.jsx\";\n\n// IntegrationSettings — fullscreen modal for connecting the two services an\n// Agentaily designer needs to run: a DeepSeek key (drives the conversation) and\n// a Feishu Bitable (receives the data). Self-persisting to localStorage; reports\n// readiness; gated save. The one cross-app difference (a monthly usage cap) is\n// behind `showUsageCap`. Composes SecretField / StatusPill / TestRow / HelpSteps.\nconst AX_INTEGRATION_CSS = `\n.s-overlay { position: fixed; inset: 0; z-index: 100; display: flex; animation: s-fade var(--dur-2) var(--ease-out) both; }\n.s-modal { position: relative; flex: 1; display: flex; flex-direction: column; min-height: 0;\n background: var(--surface-page); animation: s-rise var(--dur-3) var(--ease-out) both; }\n@keyframes s-fade { from { opacity: 0; } to { opacity: 1; } }\n@keyframes s-rise { from { opacity: 0; transform: translateY(10px) scale(0.994); } to { opacity: 1; transform: none; } }\n@media (prefers-reduced-motion: reduce) { .s-overlay, .s-modal { animation: none; } }\n\n.s-modal__bar { flex: none; display: flex; align-items: center; gap: 16px; height: 52px;\n padding: 0 12px 0 18px; border-bottom: 1px solid var(--border-default); background: var(--surface-panel); }\n.s-modal__brand { display: flex; align-items: center; gap: 8px; }\n.s-modal__word { font-family: var(--font-mono); font-size: 15px; font-weight: 500; letter-spacing: -0.02em; color: var(--text-body); }\n.s-modal__div { color: var(--text-faint); }\n.s-modal__crumb { font-family: var(--font-mono); font-size: 13px; color: var(--text-body); }\n.s-modal__baractions { margin-left: auto; display: flex; align-items: center; gap: 12px; flex: none; }\n\n.s-modal__body { flex: 1; overflow-y: auto; min-height: 0; }\n.s-wrap { max-width: 768px; margin: 0 auto; padding: 40px 24px 48px; }\n\n.s-hero { margin-bottom: 28px; }\n.s-hero__kicker { color: var(--text-faint); margin-bottom: 12px; }\n.s-hero__h { font-family: var(--font-display); font-size: var(--text-2xl); font-weight: 500;\n letter-spacing: var(--tracking-tight); line-height: var(--leading-tight); color: var(--text-body); margin: 0 0 10px; }\n.s-hero__p { font-size: var(--text-md); color: var(--text-muted); line-height: var(--leading-body); margin: 0; max-width: 62ch; }\n\n.s-ready { display: flex; align-items: center; gap: 14px; padding: 13px 16px; margin-bottom: 26px;\n border: 1px solid var(--border-default); border-radius: var(--radius-3); background: var(--surface-panel); }\n.s-ready__steps { display: flex; align-items: center; gap: 7px; flex: none; }\n.s-ready__dot { width: 9px; height: 9px; border-radius: var(--radius-1); border: 1px solid var(--border-strong);\n background: transparent; transition: background var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out); }\n.s-ready__dot.is-on { background: var(--ok); border-color: var(--ok); }\n.s-ready__txt { flex: 1; min-width: 0; font-size: var(--text-sm); color: var(--text-muted); }\n.s-ready__txt strong { color: var(--text-body); font-weight: 500; }\n.s-ready__count { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-faint); letter-spacing: 0.04em; flex: none; }\n\n.s-cards { display: flex; flex-direction: column; gap: 18px; }\n.s-card { position: relative; background: var(--surface-card); border: 1px solid var(--border-default);\n border-radius: var(--radius-3); overflow: hidden; transition: border-color var(--dur-2) var(--ease-out); }\n.s-card.is-ok { border-color: rgba(62, 207, 142, 0.4); }\n.s-card.is-error { border-color: rgba(229, 72, 77, 0.4); }\n.s-card__head { padding: 20px 24px 18px; }\n.s-card__toprow { display: flex; align-items: center; gap: 11px; margin-bottom: 15px; }\n.s-card__icon { flex: none; width: 30px; height: 30px; border-radius: var(--radius-2);\n border: 1px solid var(--border-strong); background: var(--surface-raised); color: var(--text-body);\n display: flex; align-items: center; justify-content: center; }\n.s-card__eyebrow { color: var(--text-faint); }\n.s-card__status { margin-left: auto; flex: none; }\n.s-card__title { font-family: var(--font-display); font-size: var(--text-xl); font-weight: 500;\n letter-spacing: var(--tracking-tight); line-height: var(--leading-tight); color: var(--text-body); margin: 0; }\n.s-card__desc { font-size: var(--text-sm); color: var(--text-muted); line-height: var(--leading-snug); margin: 9px 0 0; max-width: 58ch; }\n.s-card__body { padding: 4px 24px 22px; display: flex; flex-direction: column; gap: 18px; }\n\n.s-row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }\n@media (max-width: 560px) { .s-row2 { grid-template-columns: 1fr; } }\n\n.s-lock { display: flex; align-items: flex-start; gap: 8px; font-size: var(--text-xs); color: var(--text-faint); line-height: var(--leading-snug); }\n.s-lock svg { flex: none; margin-top: 1px; color: var(--text-muted); }\n.s-lock strong { color: var(--text-muted); font-weight: 500; }\n\n.s-detect { display: flex; flex-direction: column; gap: 9px; padding: 13px 14px; border: 1px solid var(--border-default);\n border-radius: var(--radius-2); background: var(--surface-page); }\n.s-detect__row { display: flex; align-items: center; gap: 10px; }\n.s-detect__k { font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--tracking-label); text-transform: uppercase;\n color: var(--text-faint); width: 84px; flex: none; }\n.s-detect__v { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-body); word-break: break-all; flex: 1; }\n.s-detect__ok { color: var(--ok); display: flex; align-items: center; gap: 5px; font-family: var(--font-mono); font-size: 10px;\n letter-spacing: var(--tracking-label); text-transform: uppercase; flex: none; }\n\n.s-cap { display: flex; align-items: center; gap: 12px; padding-top: 4px; }\n.s-cap__field { display: flex; align-items: center; gap: 8px; }\n.s-cap__field .ax-input { width: 132px; }\n.s-cap.is-off { opacity: 0.5; }\n\n.s-map { width: 100%; border-collapse: collapse; font-size: var(--text-xs); }\n.s-map th { text-align: left; font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--tracking-label);\n text-transform: uppercase; color: var(--text-faint); font-weight: 500; padding: 0 0 8px; }\n.s-map td { padding: 7px 0; border-top: 1px solid var(--border-default); color: var(--text-body); vertical-align: middle; }\n.s-map__from { color: var(--text-muted); }\n.s-map__arrow { width: 36px; color: var(--text-faint); }\n.s-map__col { font-family: var(--font-mono); }\n.s-map__tag { font-family: var(--font-mono); font-size: 9px; letter-spacing: var(--tracking-label); text-transform: uppercase;\n color: var(--text-faint); border: 1px solid var(--border-default); border-radius: var(--radius-1); padding: 2px 5px; margin-left: 7px; }\n\n.s-sub { display: flex; align-items: center; gap: 8px; }\n.s-sub__line { flex: 1; height: 1px; background: var(--border-default); }\n\n.s-save { flex: none; border-top: 1px solid var(--border-default); background: var(--surface-panel); }\n.s-save__inner { max-width: 768px; margin: 0 auto; padding: 12px 24px; display: flex; align-items: center; gap: 16px; }\n.s-save__status { flex: 1; min-width: 0; display: flex; align-items: center; gap: 9px; font-size: var(--text-sm); color: var(--text-muted); }\n.s-save__status svg { flex: none; }\n.s-save__actions { display: flex; align-items: center; gap: 8px; flex: none; }\n@media (max-width: 520px) { .s-wrap { padding: 24px 16px 36px; } .s-modal__baractions { gap: 6px; } }\n`;\n\nif (typeof document !== \"undefined\" && !document.getElementById(\"ax-integration-css\")) {\n const s = document.createElement(\"style\");\n s.id = \"ax-integration-css\";\n s.textContent = AX_INTEGRATION_CSS;\n document.head.appendChild(s);\n}\n\nconst S_LS_KEY = \"agentaily.integrations.v1\";\nconst s_sleep = (ms) => new Promise((r) => setTimeout(r, ms));\n\nfunction s_parseFeishu(url) {\n if (!url) return null;\n const tokenM = url.match(/\\/base\\/([A-Za-z0-9]+)/) || url.match(/[?&]app_token=([A-Za-z0-9]+)/);\n const tableM = url.match(/[?&]table=([A-Za-z0-9]+)/);\n if (!tokenM) return null;\n return { token: tokenM[1], table: tableM ? tableM[1] : \"\" };\n}\n\nconst S_FIELD_MAP = [\n { from: \"姓名\", to: \"姓名\", tag: null },\n { from: \"手机号\", to: \"手机号\", tag: null },\n { from: \"邮箱\", to: \"邮箱\", tag: null },\n { from: \"报名场次\", to: \"场次\", tag: \"单选\" },\n { from: \"备注\", to: \"备注\", tag: null },\n { from: null, to: \"提交时间\", tag: \"自动\" },\n { from: null, to: \"来源链接\", tag: \"自动\" },\n];\n\nconst S_DEFAULTS = {\n dsKey: \"\",\n dsModel: \"deepseek-chat\",\n capOn: false,\n cap: \"200\",\n dsStatus: \"idle\",\n dsResult: \"\",\n appId: \"\",\n secret: \"\",\n link: \"\",\n fsStatus: \"idle\",\n fsResult: \"\",\n saved: false,\n};\n\n// Normalize a raw stored/external blob into a full config. Non-ok statuses\n// collapse to idle on (re)load — a stored \"error\"/\"testing\" is never trusted.\nfunction s_normalize(raw) {\n const r = raw || {};\n return {\n dsKey: r.dsKey || \"\",\n dsModel: r.dsModel || \"deepseek-chat\",\n capOn: !!r.capOn,\n cap: r.cap || \"200\",\n dsStatus: r.dsStatus === \"ok\" ? \"ok\" : \"idle\",\n dsResult: r.dsResult || \"\",\n appId: r.appId || \"\",\n secret: r.secret || \"\",\n link: r.link || \"\",\n fsStatus: r.fsStatus === \"ok\" ? \"ok\" : \"idle\",\n fsResult: r.fsResult || \"\",\n saved: !!r.saved,\n };\n}\n\nexport function IntegrationSettings({\n onClose,\n showUsageCap = true,\n storageKey = S_LS_KEY,\n value,\n onChange,\n onSave,\n onTest,\n readiness,\n masked,\n}) {\n // ── State source ──────────────────────────────────────────────────────────\n // Uncontrolled (default): own the config + self-persist to localStorage — the\n // exact legacy behavior. Controlled: `value` is the source of truth and every\n // mutation flows out through `onChange`; we never touch localStorage. The rest\n // of the component reads `cfg` and writes via `update()`, so both modes share\n // one code path.\n const controlled = value !== undefined;\n const load = () => {\n try {\n return JSON.parse(localStorage.getItem(storageKey)) || {};\n } catch (e) {\n return {};\n }\n };\n const [localCfg, setLocalCfg] = useState(() => (controlled ? S_DEFAULTS : s_normalize(load())));\n const cfg = controlled ? { ...S_DEFAULTS, ...value } : localCfg;\n const {\n dsKey,\n dsModel,\n capOn,\n cap,\n dsStatus,\n dsResult,\n appId,\n secret,\n link,\n fsStatus,\n fsResult,\n saved,\n } = cfg;\n // Always-fresh handle so async flows (test/save) read the latest config even\n // after the controlling parent has re-rendered mid-await.\n const cfgRef = useRef(cfg);\n cfgRef.current = cfg;\n\n const update = (partial) => {\n if (controlled) {\n if (onChange) onChange({ ...cfgRef.current, ...partial });\n } else setLocalCfg((c) => ({ ...c, ...partial }));\n };\n\n const [dirty, setDirty] = useState(false);\n const [saving, setSaving] = useState(false);\n const [dsKeyEdited, setDsKeyEdited] = useState(false);\n const [secretEdited, setSecretEdited] = useState(false);\n\n useEffect(() => {\n const onKey = (e) => {\n if (e.key === \"Escape\") onClose && onClose();\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [onClose]);\n\n // Self-persist ONLY when uncontrolled. Controlled callers own storage.\n useEffect(() => {\n if (controlled) return;\n try {\n localStorage.setItem(storageKey, JSON.stringify(localCfg));\n } catch (e) {}\n }, [controlled, localCfg, storageKey]);\n\n const parsed = s_parseFeishu(link);\n // Readiness: external override (`readiness.deepseek` / `.feishu`) wins over the\n // internal test status — lets a backend report \"already connected\" without a\n // fresh in-app test. The pill still shows live testing/error transitions.\n const dsConnected = readiness ? !!readiness.deepseek : dsStatus === \"ok\";\n const fsConnected = readiness ? !!readiness.feishu : fsStatus === \"ok\";\n const dsPill =\n dsStatus === \"testing\" || dsStatus === \"error\" ? dsStatus : dsConnected ? \"ok\" : \"idle\";\n const fsPill =\n fsStatus === \"testing\" || fsStatus === \"error\" ? fsStatus : fsConnected ? \"ok\" : \"idle\";\n const readyCount = (dsConnected ? 1 : 0) + (fsConnected ? 1 : 0);\n const allReady = dsConnected && fsConnected;\n\n // Masked echo: a stored secret exists server-side but is never sent back. While\n // the field is untouched we show a masked placeholder, keep the value empty, and\n // count it as \"present\" for test/validation — so the mask is never re-submitted.\n const maskedDs = !!(masked && masked.deepseek) && !dsKeyEdited;\n const maskedFs = !!(masked && masked.feishu) && !secretEdited;\n\n const setCfg = (partial) => {\n update({ ...partial, saved: false });\n setDirty(true);\n };\n const editDs = (key) => (v) => {\n const patch = { [key]: v, saved: false };\n if (cfgRef.current.dsStatus !== \"idle\") {\n patch.dsStatus = \"idle\";\n patch.dsResult = \"\";\n }\n update(patch);\n setDirty(true);\n };\n const editFs = (key) => (v) => {\n const patch = { [key]: v, saved: false };\n if (cfgRef.current.fsStatus !== \"idle\") {\n patch.fsStatus = \"idle\";\n patch.fsResult = \"\";\n }\n update(patch);\n setDirty(true);\n };\n const editDsKey = (v) => {\n if (!dsKeyEdited) setDsKeyEdited(true);\n editDs(\"dsKey\")(v);\n };\n const editSecret = (v) => {\n if (!secretEdited) setSecretEdited(true);\n editFs(\"secret\")(v);\n };\n\n const setTest = (which, status, result, finalize) => {\n const patch =\n which === \"deepseek\"\n ? { dsStatus: status, dsResult: result }\n : { fsStatus: status, fsResult: result };\n if (finalize) patch.saved = false;\n update(patch);\n if (finalize) setDirty(true);\n };\n\n // Built-in mock probe — used only when no `onTest` is wired.\n const builtinTest = async (which) => {\n if (which === \"deepseek\") {\n setTest(\"deepseek\", \"testing\", \"\", false);\n await s_sleep(1300);\n const k = cfgRef.current.dsKey.trim();\n if (k.startsWith(\"sk-\") && k.length >= 20)\n setTest(\"deepseek\", \"ok\", `连接正常 · 延迟 0.4s · ${cfgRef.current.dsModel}`, true);\n else\n setTest(\n \"deepseek\",\n \"error\",\n k ? \"密钥无效或额度不足,请核对后重试\" : \"请先填写 API Key\",\n true,\n );\n } else {\n setTest(\"feishu\", \"testing\", \"\", false);\n await s_sleep(1500);\n const c = cfgRef.current;\n const p = s_parseFeishu(c.link);\n if (!c.appId.trim() || !c.secret.trim())\n return setTest(\"feishu\", \"error\", \"缺少 App ID 或 App Secret\", true);\n if (!p) return setTest(\"feishu\", \"error\", \"无法识别多维表格链接,请粘贴完整 URL\", true);\n if (!p.table) return setTest(\"feishu\", \"error\", \"链接缺少数据表 (table) 参数\", true);\n setTest(\"feishu\", \"ok\", \"已连接 ·「报名登记表」· 检测到 6 个字段\", true);\n }\n };\n\n // `onTest(which)` → Promise<{ ok, message }> drives StatusPill + TestRow.\n const runTest = async (which) => {\n if (onTest) {\n setTest(which, \"testing\", \"\", false);\n try {\n const res = await onTest(which);\n const ok = !!(res && res.ok);\n setTest(\n which,\n ok ? \"ok\" : \"error\",\n (res && res.message) || (ok ? \"连接正常\" : \"连接失败\"),\n true,\n );\n } catch (e) {\n setTest(which, \"error\", (e && e.message) || \"测试失败\", true);\n }\n return;\n }\n builtinTest(which);\n };\n\n const afterSaved = () => {\n setDirty(false);\n setDsKeyEdited(false);\n setSecretEdited(false);\n };\n // `onSave(value)` → Promise. Save disables + spins while pending; resolve marks\n // saved (and re-masks secrets), reject leaves the form dirty for a retry.\n const doSave = async () => {\n if (onSave) {\n setSaving(true);\n try {\n await onSave(cfgRef.current);\n update({ saved: true });\n afterSaved();\n } catch (e) {\n /* keep dirty so the user can retry */\n } finally {\n setSaving(false);\n }\n } else {\n update({ saved: true });\n afterSaved();\n }\n };\n const onDiscard = () => {\n setDsKeyEdited(false);\n setSecretEdited(false);\n setDirty(false);\n if (controlled) return; // controlled callers own revert\n setLocalCfg(s_normalize(load()));\n };\n\n return (\n <div className=\"s-overlay\" role=\"dialog\" aria-modal=\"true\" aria-label=\"集成设置\">\n <div className=\"s-modal\">\n <header className=\"s-modal__bar\">\n <div className=\"s-modal__brand\">\n <BrandMark size={16} />\n <span className=\"s-modal__word\">agentaily</span>\n <span className=\"s-modal__div\">/</span>\n <span className=\"s-modal__crumb\">集成设置</span>\n </div>\n <div className=\"s-modal__baractions\">\n <Badge variant={allReady ? \"ok\" : \"neutral\"} dot={allReady}>\n {allReady ? \"就绪\" : \"未就绪\"}\n </Badge>\n <IconButton label=\"关闭\" onClick={() => onClose && onClose()}>\n <Icon name=\"x\" size={16} />\n </IconButton>\n </div>\n </header>\n\n <main className=\"s-modal__body\">\n <div className=\"s-wrap\">\n <div className=\"s-hero\">\n <div className=\"ax-label s-hero__kicker\">集成 · INTEGRATIONS</div>\n <h1 className=\"s-hero__h\">连接你的服务</h1>\n <p className=\"s-hero__p\">\n 运行需要两条连接:一把驱动对话的 DeepSeek\n 密钥,和一张接收数据的飞书多维表格。两项都连通后即可发布。\n </p>\n </div>\n\n <div className=\"s-ready\">\n <div className=\"s-ready__steps\">\n <span className={\"s-ready__dot\" + (dsConnected ? \" is-on\" : \"\")}></span>\n <span className={\"s-ready__dot\" + (fsConnected ? \" is-on\" : \"\")}></span>\n </div>\n <div className=\"s-ready__txt\">\n {allReady ? (\n <span>\n <strong>两项连接均已就绪。</strong>保存后即可开始运行。\n </span>\n ) : (\n <span>\n 完成下方 <strong>2 项</strong> 连接后才能发布运行。\n </span>\n )}\n </div>\n <span className=\"s-ready__count\">{readyCount} / 2</span>\n </div>\n\n <div className=\"s-cards\">\n {/* ── Card 1 · DeepSeek ── */}\n <section\n className={\n \"s-card\" + (dsPill === \"ok\" ? \" is-ok\" : dsPill === \"error\" ? \" is-error\" : \"\")\n }\n >\n <div className=\"s-card__head\">\n <div className=\"s-card__toprow\">\n <div className=\"s-card__icon\">\n <Icon name=\"key\" size={16} />\n </div>\n <span className=\"ax-label s-card__eyebrow\">对话引擎 · LLM</span>\n <span className=\"s-card__status\">\n <StatusPill status={dsPill} />\n </span>\n </div>\n <h2 className=\"s-card__title\">DeepSeek</h2>\n <p className=\"s-card__desc\">\n 驱动对话式交互。用户发送的每一条消息,都通过这把密钥调用 DeepSeek 补全。\n </p>\n </div>\n\n <div className=\"s-card__body\">\n <SecretField\n label=\"API KEY\"\n value={dsKey}\n onChange={editDsKey}\n placeholder={\n maskedDs\n ? \"已保存 ········ · 留空则保持不变\"\n : \"sk-xxxxxxxxxxxxxxxxxxxxxxxx\"\n }\n hint={maskedDs ? \"已存密钥 · 留空表示不修改,输入新值即覆盖\" : undefined}\n error={\n !maskedDs && dsStatus === \"error\" && !dsKey.trim() ? \"此项必填\" : undefined\n }\n />\n\n <div className=\"s-lock\">\n <Icon name=\"lock\" size={14} />\n <span>\n <strong>密钥加密存储</strong>,仅在服务端发起调用。用户\n <strong>永远看不到、也拿不到这把密钥。</strong>\n </span>\n </div>\n\n <div className=\"s-row2\">\n <div>\n <label className=\"s-field__label ax-label\">对话模型</label>\n <Select\n value={dsModel}\n onChange={(e) => editDs(\"dsModel\")(e.target.value)}\n options={[\n { value: \"deepseek-chat\", label: \"deepseek-chat · 通用 · 快\" },\n { value: \"deepseek-reasoner\", label: \"deepseek-reasoner · 深度推理\" },\n ]}\n />\n </div>\n </div>\n\n {showUsageCap ? (\n <React.Fragment>\n <Alert\n variant=\"warn\"\n icon={<Icon name=\"zap\" size={15} />}\n title=\"用量由你承担\"\n >\n 每一轮对话消耗的都是你自己 DeepSeek\n 账户的额度。用得越多,调用越多——建议设置每月上限以防意外超支。\n </Alert>\n <div className={\"s-cap\" + (capOn ? \"\" : \" is-off\")}>\n <Switch\n label=\"启用每月用量上限\"\n checked={capOn}\n onChange={(e) => setCfg({ capOn: e.target.checked })}\n />\n <div className=\"s-cap__field\" style={{ display: capOn ? \"flex\" : \"none\" }}>\n <input\n className=\"ax-input ax-input--mono\"\n type=\"text\"\n inputMode=\"numeric\"\n value={cap}\n onChange={(e) => setCfg({ cap: e.target.value.replace(/[^0-9]/g, \"\") })}\n aria-label=\"每月上限(元)\"\n />\n <span className=\"s-field__hint\" style={{ margin: 0 }}>\n 元 / 月,达到后暂停对话\n </span>\n </div>\n </div>\n </React.Fragment>\n ) : null}\n\n <HelpSteps\n title=\"如何获取 DeepSeek API Key?\"\n steps={[\n <>\n 登录 <code>platform.deepseek.com</code>,进入「API Keys」页面。\n </>,\n <>点击「创建 API Key」,命名后立即复制——密钥只在创建时完整显示一次。</>,\n <>在「充值」中确认账户余额充足,对话才能持续调用。</>,\n <>\n 把以 <code>sk-</code> 开头的密钥粘贴到上方输入框。\n </>,\n ]}\n link={{\n href: \"https://platform.deepseek.com\",\n label: \"打开 DeepSeek 开放平台\",\n }}\n />\n </div>\n\n <TestRow\n status={dsStatus}\n result={dsResult}\n onTest={() => runTest(\"deepseek\")}\n disabled={!dsKey.trim() && !maskedDs}\n idleHint=\"填写密钥后测试连通性\"\n />\n </section>\n\n {/* ── Card 2 · Feishu Bitable ── */}\n <section\n className={\n \"s-card\" + (fsPill === \"ok\" ? \" is-ok\" : fsPill === \"error\" ? \" is-error\" : \"\")\n }\n >\n <div className=\"s-card__head\">\n <div className=\"s-card__toprow\">\n <div className=\"s-card__icon\">\n <Icon name=\"table\" size={16} />\n </div>\n <span className=\"ax-label s-card__eyebrow\">数据写入 · FEISHU BITABLE</span>\n <span className=\"s-card__status\">\n <StatusPill status={fsPill} />\n </span>\n </div>\n <h2 className=\"s-card__title\">飞书多维表格</h2>\n <p className=\"s-card__desc\">\n 每次提交后,数据自动写入指定多维表格的一行。需要一个飞书自建应用的凭证,以及目标表格的链接。\n </p>\n </div>\n\n <div className=\"s-card__body\">\n <div className=\"s-row2\">\n <div>\n <label className=\"s-field__label ax-label\">App ID</label>\n <input\n className=\"ax-input ax-input--mono\"\n type=\"text\"\n value={appId}\n spellCheck=\"false\"\n placeholder=\"cli_xxxxxxxxxxxx\"\n onChange={(e) => editFs(\"appId\")(e.target.value)}\n />\n <p className=\"s-field__hint\">应用标识,可公开。</p>\n </div>\n <SecretField\n label=\"App Secret\"\n value={secret}\n onChange={editSecret}\n placeholder={\n maskedFs ? \"已保存 ········ · 留空则保持不变\" : \"••••••••••••••••\"\n }\n hint={maskedFs ? \"已存密钥 · 留空表示不修改\" : \"应用密钥,加密存储。\"}\n />\n </div>\n\n <div>\n <label className=\"s-field__label ax-label\">多维表格链接</label>\n <input\n className=\"ax-input\"\n type=\"text\"\n value={link}\n spellCheck=\"false\"\n placeholder=\"https://your-team.feishu.cn/base/bascn…?table=tbl…\"\n onChange={(e) => editFs(\"link\")(e.target.value)}\n />\n <p className=\"s-field__hint\">\n 在多维表格右上角「分享」中复制链接粘贴即可,App Token 与数据表会自动识别。\n </p>\n </div>\n\n {parsed ? (\n <div className=\"s-detect\">\n <div className=\"s-detect__row\">\n <span className=\"s-detect__k\">App Token</span>\n <span className=\"s-detect__v\">{parsed.token}</span>\n <span className=\"s-detect__ok\">\n <Icon name=\"check\" size={12} />\n 已识别\n </span>\n </div>\n <div className=\"s-detect__row\">\n <span className=\"s-detect__k\">数据表</span>\n <span className=\"s-detect__v\">{parsed.table || \"—\"}</span>\n {parsed.table ? (\n <span className=\"s-detect__ok\">\n <Icon name=\"check\" size={12} />\n 已识别\n </span>\n ) : (\n <span className=\"s-detect__ok\" style={{ color: \"var(--warn)\" }}>\n <Icon name=\"warn\" size={12} />\n 缺失\n </span>\n )}\n </div>\n </div>\n ) : null}\n\n <div className=\"s-lock\">\n <Icon name=\"shield\" size={14} />\n <span>\n <strong>凭证加密存储</strong>,仅服务端用于写入数据。用户\n <strong>无法接触你的飞书凭证或表格权限。</strong>\n </span>\n </div>\n\n {fsConnected ? (\n <div>\n <div className=\"s-sub\" style={{ marginBottom: 12 }}>\n <span className=\"ax-label\">字段映射 · 自动</span>\n <span className=\"s-sub__line\"></span>\n </div>\n <table className=\"s-map\">\n <thead>\n <tr>\n <th>字段</th>\n <th className=\"s-map__arrow\"></th>\n <th>表格列</th>\n </tr>\n </thead>\n <tbody>\n {S_FIELD_MAP.map((m, i) => (\n <tr key={i}>\n <td className=\"s-map__from\">\n {m.from || <span style={{ color: \"var(--text-faint)\" }}>—</span>}\n </td>\n <td className=\"s-map__arrow\">\n <Icon name=\"arrow\" size={14} />\n </td>\n <td>\n <span className=\"s-map__col\">{m.to}</span>\n {m.tag ? <span className=\"s-map__tag\">{m.tag}</span> : null}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ) : null}\n\n <HelpSteps\n title=\"如何获取飞书应用凭证?\"\n steps={[\n <>\n 打开飞书开放平台 <code>open.feishu.cn</code>,创建一个「企业自建应用」。\n </>,\n <>\n 在「凭证与基础信息」中复制 <code>App ID</code> 与 <code>App Secret</code>。\n </>,\n <>\n 到「权限管理」开通多维表格读写权限 <code>bitable:app</code>,并发布版本。\n </>,\n <>\n 在目标多维表格里,把这个应用添加为<strong>可编辑协作者</strong>。\n </>,\n <>复制该多维表格的分享链接,粘贴到上方「多维表格链接」。</>,\n ]}\n link={{ href: \"https://open.feishu.cn\", label: \"打开飞书开放平台\" }}\n />\n </div>\n\n <TestRow\n status={fsStatus}\n result={fsResult}\n onTest={() => runTest(\"feishu\")}\n disabled={!appId.trim() || (!secret.trim() && !maskedFs) || !parsed}\n idleHint=\"填写凭证与链接后测试写入权限\"\n />\n </section>\n </div>\n </div>\n </main>\n\n <footer className=\"s-save\">\n <div className=\"s-save__inner\">\n <div className=\"s-save__status\">\n {!allReady ? (\n <>\n <Icon name=\"info\" size={15} style={{ color: \"var(--text-faint)\" }} />\n <span>完成两项连接后即可保存并启用。</span>\n </>\n ) : saved ? (\n <>\n <Icon name=\"check\" size={15} style={{ color: \"var(--ok)\" }} />\n <span>已保存 · 已启用对话与数据写入。</span>\n </>\n ) : (\n <>\n <Icon name=\"zap\" size={15} style={{ color: \"var(--text-muted)\" }} />\n <span>配置已就绪,保存后立即生效。</span>\n </>\n )}\n </div>\n <div className=\"s-save__actions\">\n <Button variant=\"ghost\" size=\"md\" disabled={!dirty} onClick={onDiscard}>\n 放弃更改\n </Button>\n <Button\n variant=\"primary\"\n size=\"md\"\n icon={saving ? <Spinner size=\"sm\" /> : <Icon name=\"save\" size={14} />}\n disabled={!allReady || !dirty || saving}\n aria-busy={saving || undefined}\n onClick={doSave}\n >\n 保存配置\n </Button>\n </div>\n </div>\n </footer>\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AAoBA,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8F3B,IAAI,OAAO,aAAa,eAAe,CAAC,SAAS,eAAe,oBAAoB,GAAG;AACrF,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cAAc;AAChB,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEA,MAAM,WAAW;AACjB,MAAM,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAE5D,SAAS,cAAc,KAAK;AAC1B,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,SAAS,IAAI,MAAM,wBAAwB,KAAK,IAAI,MAAM,8BAA8B;AAC9F,QAAM,SAAS,IAAI,MAAM,0BAA0B;AACnD,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,EAAE,OAAO,OAAO,CAAC,GAAG,OAAO,SAAS,OAAO,CAAC,IAAI,GAAA;AACzD;AAEA,MAAM,cAAc;AAAA,EAClB,EAAE,MAAM,MAAM,IAAI,MAAM,KAAK,KAAA;AAAA,EAC7B,EAAE,MAAM,OAAO,IAAI,OAAO,KAAK,KAAA;AAAA,EAC/B,EAAE,MAAM,MAAM,IAAI,MAAM,KAAK,KAAA;AAAA,EAC7B,EAAE,MAAM,QAAQ,IAAI,MAAM,KAAK,KAAA;AAAA,EAC/B,EAAE,MAAM,MAAM,IAAI,MAAM,KAAK,KAAA;AAAA,EAC7B,EAAE,MAAM,MAAM,IAAI,QAAQ,KAAK,KAAA;AAAA,EAC/B,EAAE,MAAM,MAAM,IAAI,QAAQ,KAAK,KAAA;AACjC;AAEA,MAAM,aAAa;AAAA,EACjB,OAAO;AAAA,EACP,SAAS;AAAA,EACT,OAAO;AAAA,EACP,KAAK;AAAA,EACL,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AACT;AAIA,SAAS,YAAY,KAAK;AACxB,QAAM,IAAI,OAAO,CAAA;AACjB,SAAO;AAAA,IACL,OAAO,EAAE,SAAS;AAAA,IAClB,SAAS,EAAE,WAAW;AAAA,IACtB,OAAO,CAAC,CAAC,EAAE;AAAA,IACX,KAAK,EAAE,OAAO;AAAA,IACd,UAAU,EAAE,aAAa,OAAO,OAAO;AAAA,IACvC,UAAU,EAAE,YAAY;AAAA,IACxB,OAAO,EAAE,SAAS;AAAA,IAClB,QAAQ,EAAE,UAAU;AAAA,IACpB,MAAM,EAAE,QAAQ;AAAA,IAChB,UAAU,EAAE,aAAa,OAAO,OAAO;AAAA,IACvC,UAAU,EAAE,YAAY;AAAA,IACxB,OAAO,CAAC,CAAC,EAAE;AAAA,EAAA;AAEf;AAEO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA,eAAe;AAAA,EACf,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAG;AAOD,QAAM,aAAa,UAAU;AAC7B,QAAM,OAAO,MAAM;AACjB,QAAI;AACF,aAAO,KAAK,MAAM,aAAa,QAAQ,UAAU,CAAC,KAAK,CAAA;AAAA,IACzD,SAAS,GAAG;AACV,aAAO,CAAA;AAAA,IACT;AAAA,EACF;AACA,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,MAAO,aAAa,aAAa,YAAY,KAAA,CAAM,CAAE;AAC9F,QAAM,MAAM,aAAa,EAAE,GAAG,YAAY,GAAG,UAAU;AACvD,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AAGJ,QAAM,SAAS,OAAO,GAAG;AACzB,SAAO,UAAU;AAEjB,QAAM,SAAS,CAAC,YAAY;AAC1B,QAAI,YAAY;AACd,UAAI,mBAAmB,EAAE,GAAG,OAAO,SAAS,GAAG,SAAS;AAAA,IAC1D,mBAAmB,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,QAAA,EAAU;AAAA,EAClD;AAEA,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,KAAK;AACxC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,KAAK;AACpD,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AAEtD,YAAU,MAAM;AACd,UAAM,QAAQ,CAAC,MAAM;AACnB,UAAI,EAAE,QAAQ,SAAU,YAAW,QAAA;AAAA,IACrC;AACA,WAAO,iBAAiB,WAAW,KAAK;AACxC,WAAO,MAAM,OAAO,oBAAoB,WAAW,KAAK;AAAA,EAC1D,GAAG,CAAC,OAAO,CAAC;AAGZ,YAAU,MAAM;AACd,QAAI,WAAY;AAChB,QAAI;AACF,mBAAa,QAAQ,YAAY,KAAK,UAAU,QAAQ,CAAC;AAAA,IAC3D,SAAS,GAAG;AAAA,IAAC;AAAA,EACf,GAAG,CAAC,YAAY,UAAU,UAAU,CAAC;AAErC,QAAM,SAAS,cAAc,IAAI;AAIjC,QAAM,cAAc,YAAY,CAAC,CAAC,UAAU,WAAW,aAAa;AACpE,QAAM,cAAc,YAAY,CAAC,CAAC,UAAU,SAAS,aAAa;AAClE,QAAM,SACJ,aAAa,aAAa,aAAa,UAAU,WAAW,cAAc,OAAO;AACnF,QAAM,SACJ,aAAa,aAAa,aAAa,UAAU,WAAW,cAAc,OAAO;AACnF,QAAM,cAAc,cAAc,IAAI,MAAM,cAAc,IAAI;AAC9D,QAAM,WAAW,eAAe;AAKhC,QAAM,WAAW,CAAC,EAAE,UAAU,OAAO,aAAa,CAAC;AACnD,QAAM,WAAW,CAAC,EAAE,UAAU,OAAO,WAAW,CAAC;AAEjD,QAAM,SAAS,CAAC,YAAY;AAC1B,WAAO,EAAE,GAAG,SAAS,OAAO,OAAO;AACnC,aAAS,IAAI;AAAA,EACf;AACA,QAAM,SAAS,CAAC,QAAQ,CAAC,MAAM;AAC7B,UAAM,QAAQ,EAAE,CAAC,GAAG,GAAG,GAAG,OAAO,MAAA;AACjC,QAAI,OAAO,QAAQ,aAAa,QAAQ;AACtC,YAAM,WAAW;AACjB,YAAM,WAAW;AAAA,IACnB;AACA,WAAO,KAAK;AACZ,aAAS,IAAI;AAAA,EACf;AACA,QAAM,SAAS,CAAC,QAAQ,CAAC,MAAM;AAC7B,UAAM,QAAQ,EAAE,CAAC,GAAG,GAAG,GAAG,OAAO,MAAA;AACjC,QAAI,OAAO,QAAQ,aAAa,QAAQ;AACtC,YAAM,WAAW;AACjB,YAAM,WAAW;AAAA,IACnB;AACA,WAAO,KAAK;AACZ,aAAS,IAAI;AAAA,EACf;AACA,QAAM,YAAY,CAAC,MAAM;AACvB,QAAI,CAAC,YAAa,gBAAe,IAAI;AACrC,WAAO,OAAO,EAAE,CAAC;AAAA,EACnB;AACA,QAAM,aAAa,CAAC,MAAM;AACxB,QAAI,CAAC,aAAc,iBAAgB,IAAI;AACvC,WAAO,QAAQ,EAAE,CAAC;AAAA,EACpB;AAEA,QAAM,UAAU,CAAC,OAAO,QAAQ,QAAQ,aAAa;AACnD,UAAM,QACJ,UAAU,aACN,EAAE,UAAU,QAAQ,UAAU,OAAA,IAC9B,EAAE,UAAU,QAAQ,UAAU,OAAA;AACpC,QAAI,gBAAgB,QAAQ;AAC5B,WAAO,KAAK;AACZ,QAAI,mBAAmB,IAAI;AAAA,EAC7B;AAGA,QAAM,cAAc,OAAO,UAAU;AACnC,QAAI,UAAU,YAAY;AACxB,cAAQ,YAAY,WAAW,IAAI,KAAK;AACxC,YAAM,QAAQ,IAAI;AAClB,YAAM,IAAI,OAAO,QAAQ,MAAM,KAAA;AAC/B,UAAI,EAAE,WAAW,KAAK,KAAK,EAAE,UAAU;AACrC,gBAAQ,YAAY,MAAM,oBAAoB,OAAO,QAAQ,OAAO,IAAI,IAAI;AAAA;AAE5E;AAAA,UACE;AAAA,UACA;AAAA,UACA,IAAI,qBAAqB;AAAA,UACzB;AAAA,QAAA;AAAA,IAEN,OAAO;AACL,cAAQ,UAAU,WAAW,IAAI,KAAK;AACtC,YAAM,QAAQ,IAAI;AAClB,YAAM,IAAI,OAAO;AACjB,YAAM,IAAI,cAAc,EAAE,IAAI;AAC9B,UAAI,CAAC,EAAE,MAAM,KAAA,KAAU,CAAC,EAAE,OAAO,KAAA;AAC/B,eAAO,QAAQ,UAAU,SAAS,0BAA0B,IAAI;AAClE,UAAI,CAAC,EAAG,QAAO,QAAQ,UAAU,SAAS,wBAAwB,IAAI;AACtE,UAAI,CAAC,EAAE,MAAO,QAAO,QAAQ,UAAU,SAAS,sBAAsB,IAAI;AAC1E,cAAQ,UAAU,MAAM,2BAA2B,IAAI;AAAA,IACzD;AAAA,EACF;AAGA,QAAM,UAAU,OAAO,UAAU;AAC/B,QAAI,QAAQ;AACV,cAAQ,OAAO,WAAW,IAAI,KAAK;AACnC,UAAI;AACF,cAAM,MAAM,MAAM,OAAO,KAAK;AAC9B,cAAM,KAAK,CAAC,EAAE,OAAO,IAAI;AACzB;AAAA,UACE;AAAA,UACA,KAAK,OAAO;AAAA,UACX,OAAO,IAAI,YAAa,KAAK,SAAS;AAAA,UACvC;AAAA,QAAA;AAAA,MAEJ,SAAS,GAAG;AACV,gBAAQ,OAAO,SAAU,KAAK,EAAE,WAAY,QAAQ,IAAI;AAAA,MAC1D;AACA;AAAA,IACF;AACA,gBAAY,KAAK;AAAA,EACnB;AAEA,QAAM,aAAa,MAAM;AACvB,aAAS,KAAK;AACd,mBAAe,KAAK;AACpB,oBAAgB,KAAK;AAAA,EACvB;AAGA,QAAM,SAAS,YAAY;AACzB,QAAI,QAAQ;AACV,gBAAU,IAAI;AACd,UAAI;AACF,cAAM,OAAO,OAAO,OAAO;AAC3B,eAAO,EAAE,OAAO,MAAM;AACtB,mBAAA;AAAA,MACF,SAAS,GAAG;AAAA,MAEZ,UAAA;AACE,kBAAU,KAAK;AAAA,MACjB;AAAA,IACF,OAAO;AACL,aAAO,EAAE,OAAO,MAAM;AACtB,iBAAA;AAAA,IACF;AAAA,EACF;AACA,QAAM,YAAY,MAAM;AACtB,mBAAe,KAAK;AACpB,oBAAgB,KAAK;AACrB,aAAS,KAAK;AACd,QAAI,WAAY;AAChB,gBAAY,YAAY,KAAA,CAAM,CAAC;AAAA,EACjC;AAEA,SACE,oBAAC,OAAA,EAAI,WAAU,aAAY,MAAK,UAAS,cAAW,QAAO,cAAW,QACpE,UAAA,qBAAC,OAAA,EAAI,WAAU,WACb,UAAA;AAAA,IAAA,qBAAC,UAAA,EAAO,WAAU,gBAChB,UAAA;AAAA,MAAA,qBAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,QAAA,oBAAC,WAAA,EAAU,MAAM,GAAA,CAAI;AAAA,QACrB,oBAAC,QAAA,EAAK,WAAU,iBAAgB,UAAA,aAAS;AAAA,QACzC,oBAAC,QAAA,EAAK,WAAU,gBAAe,UAAA,KAAC;AAAA,QAChC,oBAAC,QAAA,EAAK,WAAU,kBAAiB,UAAA,OAAA,CAAI;AAAA,MAAA,GACvC;AAAA,MACA,qBAAC,OAAA,EAAI,WAAU,uBACb,UAAA;AAAA,QAAA,oBAAC,OAAA,EAAM,SAAS,WAAW,OAAO,WAAW,KAAK,UAC/C,UAAA,WAAW,OAAO,MAAA,CACrB;AAAA,QACA,oBAAC,YAAA,EAAW,OAAM,MAAK,SAAS,MAAM,WAAW,QAAA,GAC/C,8BAAC,MAAA,EAAK,MAAK,KAAI,MAAM,IAAI,EAAA,CAC3B;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,GACF;AAAA,wBAEC,QAAA,EAAK,WAAU,iBACd,UAAA,qBAAC,OAAA,EAAI,WAAU,UACb,UAAA;AAAA,MAAA,qBAAC,OAAA,EAAI,WAAU,UACb,UAAA;AAAA,QAAA,oBAAC,OAAA,EAAI,WAAU,2BAA0B,UAAA,qBAAiB;AAAA,QAC1D,oBAAC,MAAA,EAAG,WAAU,aAAY,UAAA,UAAM;AAAA,QAChC,oBAAC,KAAA,EAAE,WAAU,aAAY,UAAA,0DAAA,CAGzB;AAAA,MAAA,GACF;AAAA,MAEA,qBAAC,OAAA,EAAI,WAAU,WACb,UAAA;AAAA,QAAA,qBAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,UAAA,oBAAC,QAAA,EAAK,WAAW,kBAAkB,cAAc,WAAW,KAAK;AAAA,8BAChE,QAAA,EAAK,WAAW,kBAAkB,cAAc,WAAW,IAAA,CAAK;AAAA,QAAA,GACnE;AAAA,4BACC,OAAA,EAAI,WAAU,gBACZ,UAAA,gCACE,QAAA,EACC,UAAA;AAAA,UAAA,oBAAC,YAAO,UAAA,YAAA,CAAS;AAAA,UAAS;AAAA,QAAA,EAAA,CAC5B,yBAEC,QAAA,EAAK,UAAA;AAAA,UAAA;AAAA,UACC,oBAAC,YAAO,UAAA,MAAA,CAAG;AAAA,UAAS;AAAA,QAAA,EAAA,CAC3B,EAAA,CAEJ;AAAA,QACA,qBAAC,QAAA,EAAK,WAAU,kBAAkB,UAAA;AAAA,UAAA;AAAA,UAAW;AAAA,QAAA,EAAA,CAAI;AAAA,MAAA,GACnD;AAAA,MAEA,qBAAC,OAAA,EAAI,WAAU,WAEb,UAAA;AAAA,QAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WACE,YAAY,WAAW,OAAO,WAAW,WAAW,UAAU,cAAc;AAAA,YAG9E,UAAA;AAAA,cAAA,qBAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,gBAAA,qBAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,kBAAA,oBAAC,OAAA,EAAI,WAAU,gBACb,UAAA,oBAAC,QAAK,MAAK,OAAM,MAAM,GAAA,CAAI,EAAA,CAC7B;AAAA,kBACA,oBAAC,QAAA,EAAK,WAAU,4BAA2B,UAAA,cAAU;AAAA,kBACrD,oBAAC,UAAK,WAAU,kBACd,8BAAC,YAAA,EAAW,QAAQ,QAAQ,EAAA,CAC9B;AAAA,gBAAA,GACF;AAAA,gBACA,oBAAC,MAAA,EAAG,WAAU,iBAAgB,UAAA,YAAQ;AAAA,gBACtC,oBAAC,KAAA,EAAE,WAAU,gBAAe,UAAA,4CAAA,CAE5B;AAAA,cAAA,GACF;AAAA,cAEA,qBAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,gBAAA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,OAAM;AAAA,oBACN,OAAO;AAAA,oBACP,UAAU;AAAA,oBACV,aACE,WACI,6BACA;AAAA,oBAEN,MAAM,WAAW,2BAA2B;AAAA,oBAC5C,OACE,CAAC,YAAY,aAAa,WAAW,CAAC,MAAM,KAAA,IAAS,SAAS;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAIlE,qBAAC,OAAA,EAAI,WAAU,UACb,UAAA;AAAA,kBAAA,oBAAC,MAAA,EAAK,MAAK,QAAO,MAAM,IAAI;AAAA,uCAC3B,QAAA,EACC,UAAA;AAAA,oBAAA,oBAAC,YAAO,UAAA,SAAA,CAAM;AAAA,oBAAS;AAAA,oBACvB,oBAAC,YAAO,UAAA,kBAAA,CAAe;AAAA,kBAAA,EAAA,CACzB;AAAA,gBAAA,GACF;AAAA,gBAEA,oBAAC,OAAA,EAAI,WAAU,UACb,+BAAC,OAAA,EACC,UAAA;AAAA,kBAAA,oBAAC,SAAA,EAAM,WAAU,2BAA0B,UAAA,QAAI;AAAA,kBAC/C;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,OAAO;AAAA,sBACP,UAAU,CAAC,MAAM,OAAO,SAAS,EAAE,EAAE,OAAO,KAAK;AAAA,sBACjD,SAAS;AAAA,wBACP,EAAE,OAAO,iBAAiB,OAAO,yBAAA;AAAA,wBACjC,EAAE,OAAO,qBAAqB,OAAO,2BAAA;AAAA,sBAA2B;AAAA,oBAClE;AAAA,kBAAA;AAAA,gBACF,EAAA,CACF,EAAA,CACF;AAAA,gBAEC,eACC,qBAAC,MAAM,UAAN,EACC,UAAA;AAAA,kBAAA;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,SAAQ;AAAA,sBACR,MAAM,oBAAC,MAAA,EAAK,MAAK,OAAM,MAAM,IAAI;AAAA,sBACjC,OAAM;AAAA,sBACP,UAAA;AAAA,oBAAA;AAAA,kBAAA;AAAA,uCAIA,OAAA,EAAI,WAAW,WAAW,QAAQ,KAAK,YACtC,UAAA;AAAA,oBAAA;AAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,OAAM;AAAA,wBACN,SAAS;AAAA,wBACT,UAAU,CAAC,MAAM,OAAO,EAAE,OAAO,EAAE,OAAO,QAAA,CAAS;AAAA,sBAAA;AAAA,oBAAA;AAAA,oBAErD,qBAAC,OAAA,EAAI,WAAU,gBAAe,OAAO,EAAE,SAAS,QAAQ,SAAS,OAAA,GAC/D,UAAA;AAAA,sBAAA;AAAA,wBAAC;AAAA,wBAAA;AAAA,0BACC,WAAU;AAAA,0BACV,MAAK;AAAA,0BACL,WAAU;AAAA,0BACV,OAAO;AAAA,0BACP,UAAU,CAAC,MAAM,OAAO,EAAE,KAAK,EAAE,OAAO,MAAM,QAAQ,WAAW,EAAE,GAAG;AAAA,0BACtE,cAAW;AAAA,wBAAA;AAAA,sBAAA;AAAA,sBAEb,oBAAC,UAAK,WAAU,iBAAgB,OAAO,EAAE,QAAQ,EAAA,GAAK,UAAA,gBAAA,CAEtD;AAAA,oBAAA,EAAA,CACF;AAAA,kBAAA,EAAA,CACF;AAAA,gBAAA,EAAA,CACF,IACE;AAAA,gBAEJ;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,OAAM;AAAA,oBACN,OAAO;AAAA,sBACL,qBAAA,UAAA,EAAE,UAAA;AAAA,wBAAA;AAAA,wBACG,oBAAC,UAAK,UAAA,wBAAA,CAAqB;AAAA,wBAAO;AAAA,sBAAA,GACvC;AAAA,sDACE,UAAA,yCAAA,CAAsC;AAAA,sDACtC,UAAA,2BAAA,CAAwB;AAAA,sBAC1B,qBAAA,UAAA,EAAE,UAAA;AAAA,wBAAA;AAAA,wBACG,oBAAC,UAAK,UAAA,MAAA,CAAG;AAAA,wBAAO;AAAA,sBAAA,EAAA,CACrB;AAAA,oBAAA;AAAA,oBAEF,MAAM;AAAA,sBACJ,MAAM;AAAA,sBACN,OAAO;AAAA,oBAAA;AAAA,kBACT;AAAA,gBAAA;AAAA,cACF,GACF;AAAA,cAEA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,QAAQ;AAAA,kBACR,QAAQ;AAAA,kBACR,QAAQ,MAAM,QAAQ,UAAU;AAAA,kBAChC,UAAU,CAAC,MAAM,KAAA,KAAU,CAAC;AAAA,kBAC5B,UAAS;AAAA,gBAAA;AAAA,cAAA;AAAA,YACX;AAAA,UAAA;AAAA,QAAA;AAAA,QAIF;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WACE,YAAY,WAAW,OAAO,WAAW,WAAW,UAAU,cAAc;AAAA,YAG9E,UAAA;AAAA,cAAA,qBAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,gBAAA,qBAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,kBAAA,oBAAC,OAAA,EAAI,WAAU,gBACb,UAAA,oBAAC,QAAK,MAAK,SAAQ,MAAM,GAAA,CAAI,EAAA,CAC/B;AAAA,kBACA,oBAAC,QAAA,EAAK,WAAU,4BAA2B,UAAA,yBAAqB;AAAA,kBAChE,oBAAC,UAAK,WAAU,kBACd,8BAAC,YAAA,EAAW,QAAQ,QAAQ,EAAA,CAC9B;AAAA,gBAAA,GACF;AAAA,gBACA,oBAAC,MAAA,EAAG,WAAU,iBAAgB,UAAA,UAAM;AAAA,gBACpC,oBAAC,KAAA,EAAE,WAAU,gBAAe,UAAA,iDAAA,CAE5B;AAAA,cAAA,GACF;AAAA,cAEA,qBAAC,OAAA,EAAI,WAAU,gBACb,UAAA;AAAA,gBAAA,qBAAC,OAAA,EAAI,WAAU,UACb,UAAA;AAAA,kBAAA,qBAAC,OAAA,EACC,UAAA;AAAA,oBAAA,oBAAC,SAAA,EAAM,WAAU,2BAA0B,UAAA,UAAM;AAAA,oBACjD;AAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,WAAU;AAAA,wBACV,MAAK;AAAA,wBACL,OAAO;AAAA,wBACP,YAAW;AAAA,wBACX,aAAY;AAAA,wBACZ,UAAU,CAAC,MAAM,OAAO,OAAO,EAAE,EAAE,OAAO,KAAK;AAAA,sBAAA;AAAA,oBAAA;AAAA,oBAEjD,oBAAC,KAAA,EAAE,WAAU,iBAAgB,UAAA,YAAA,CAAS;AAAA,kBAAA,GACxC;AAAA,kBACA;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,OAAM;AAAA,sBACN,OAAO;AAAA,sBACP,UAAU;AAAA,sBACV,aACE,WAAW,6BAA6B;AAAA,sBAE1C,MAAM,WAAW,mBAAmB;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBACtC,GACF;AAAA,qCAEC,OAAA,EACC,UAAA;AAAA,kBAAA,oBAAC,SAAA,EAAM,WAAU,2BAA0B,UAAA,UAAM;AAAA,kBACjD;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,WAAU;AAAA,sBACV,MAAK;AAAA,sBACL,OAAO;AAAA,sBACP,YAAW;AAAA,sBACX,aAAY;AAAA,sBACZ,UAAU,CAAC,MAAM,OAAO,MAAM,EAAE,EAAE,OAAO,KAAK;AAAA,oBAAA;AAAA,kBAAA;AAAA,kBAEhD,oBAAC,KAAA,EAAE,WAAU,iBAAgB,UAAA,6CAAA,CAE7B;AAAA,gBAAA,GACF;AAAA,gBAEC,SACC,qBAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,kBAAA,qBAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,oBAAA,oBAAC,QAAA,EAAK,WAAU,eAAc,UAAA,aAAS;AAAA,oBACvC,oBAAC,QAAA,EAAK,WAAU,eAAe,iBAAO,OAAM;AAAA,oBAC5C,qBAAC,QAAA,EAAK,WAAU,gBACd,UAAA;AAAA,sBAAA,oBAAC,MAAA,EAAK,MAAK,SAAQ,MAAM,IAAI;AAAA,sBAAE;AAAA,oBAAA,EAAA,CAEjC;AAAA,kBAAA,GACF;AAAA,kBACA,qBAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,oBAAA,oBAAC,QAAA,EAAK,WAAU,eAAc,UAAA,OAAG;AAAA,wCAChC,QAAA,EAAK,WAAU,eAAe,UAAA,OAAO,SAAS,KAAI;AAAA,oBAClD,OAAO,QACN,qBAAC,QAAA,EAAK,WAAU,gBACd,UAAA;AAAA,sBAAA,oBAAC,MAAA,EAAK,MAAK,SAAQ,MAAM,IAAI;AAAA,sBAAE;AAAA,oBAAA,EAAA,CAEjC,yBAEC,QAAA,EAAK,WAAU,gBAAe,OAAO,EAAE,OAAO,cAAA,GAC7C,UAAA;AAAA,sBAAA,oBAAC,MAAA,EAAK,MAAK,QAAO,MAAM,IAAI;AAAA,sBAAE;AAAA,oBAAA,EAAA,CAEhC;AAAA,kBAAA,EAAA,CAEJ;AAAA,gBAAA,EAAA,CACF,IACE;AAAA,gBAEJ,qBAAC,OAAA,EAAI,WAAU,UACb,UAAA;AAAA,kBAAA,oBAAC,MAAA,EAAK,MAAK,UAAS,MAAM,IAAI;AAAA,uCAC7B,QAAA,EACC,UAAA;AAAA,oBAAA,oBAAC,YAAO,UAAA,SAAA,CAAM;AAAA,oBAAS;AAAA,oBACvB,oBAAC,YAAO,UAAA,mBAAA,CAAgB;AAAA,kBAAA,EAAA,CAC1B;AAAA,gBAAA,GACF;AAAA,gBAEC,mCACE,OAAA,EACC,UAAA;AAAA,kBAAA,qBAAC,SAAI,WAAU,SAAQ,OAAO,EAAE,cAAc,MAC5C,UAAA;AAAA,oBAAA,oBAAC,QAAA,EAAK,WAAU,YAAW,UAAA,aAAS;AAAA,oBACpC,oBAAC,QAAA,EAAK,WAAU,cAAA,CAAc;AAAA,kBAAA,GAChC;AAAA,kBACA,qBAAC,SAAA,EAAM,WAAU,SACf,UAAA;AAAA,oBAAA,oBAAC,SAAA,EACC,+BAAC,MAAA,EACC,UAAA;AAAA,sBAAA,oBAAC,QAAG,UAAA,KAAA,CAAE;AAAA,sBACN,oBAAC,MAAA,EAAG,WAAU,eAAA,CAAe;AAAA,sBAC7B,oBAAC,QAAG,UAAA,MAAA,CAAG;AAAA,oBAAA,EAAA,CACT,EAAA,CACF;AAAA,oBACA,oBAAC,WACE,UAAA,YAAY,IAAI,CAAC,GAAG,2BAClB,MAAA,EACC,UAAA;AAAA,sBAAA,oBAAC,MAAA,EAAG,WAAU,eACX,UAAA,EAAE,QAAQ,oBAAC,QAAA,EAAK,OAAO,EAAE,OAAO,oBAAA,GAAuB,eAAC,GAC3D;AAAA,sBACA,oBAAC,MAAA,EAAG,WAAU,gBACZ,UAAA,oBAAC,QAAK,MAAK,SAAQ,MAAM,GAAA,CAAI,EAAA,CAC/B;AAAA,2CACC,MAAA,EACC,UAAA;AAAA,wBAAA,oBAAC,QAAA,EAAK,WAAU,cAAc,UAAA,EAAE,IAAG;AAAA,wBAClC,EAAE,MAAM,oBAAC,QAAA,EAAK,WAAU,cAAc,UAAA,EAAE,KAAI,IAAU;AAAA,sBAAA,EAAA,CACzD;AAAA,oBAAA,EAAA,GAVO,CAWT,CACD,EAAA,CACH;AAAA,kBAAA,EAAA,CACF;AAAA,gBAAA,EAAA,CACF,IACE;AAAA,gBAEJ;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,OAAM;AAAA,oBACN,OAAO;AAAA,sBACL,qBAAA,UAAA,EAAE,UAAA;AAAA,wBAAA;AAAA,wBACS,oBAAC,UAAK,UAAA,iBAAA,CAAc;AAAA,wBAAO;AAAA,sBAAA,GACtC;AAAA,sBACA,qBAAA,UAAA,EAAE,UAAA;AAAA,wBAAA;AAAA,wBACc,oBAAC,UAAK,UAAA,SAAA,CAAM;AAAA,wBAAO;AAAA,wBAAG,oBAAC,UAAK,UAAA,aAAA,CAAU;AAAA,wBAAO;AAAA,sBAAA,GAC7D;AAAA,sBACA,qBAAA,UAAA,EAAE,UAAA;AAAA,wBAAA;AAAA,wBACkB,oBAAC,UAAK,UAAA,cAAA,CAAW;AAAA,wBAAO;AAAA,sBAAA,GAC5C;AAAA,sBACA,qBAAA,UAAA,EAAE,UAAA;AAAA,wBAAA;AAAA,wBACiB,oBAAC,YAAO,UAAA,SAAA,CAAM;AAAA,wBAAS;AAAA,sBAAA,GAC1C;AAAA,sDACE,UAAA,8BAAA,CAA2B;AAAA,oBAAA;AAAA,oBAE/B,MAAM,EAAE,MAAM,0BAA0B,OAAO,WAAA;AAAA,kBAAW;AAAA,gBAAA;AAAA,cAC5D,GACF;AAAA,cAEA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,QAAQ;AAAA,kBACR,QAAQ;AAAA,kBACR,QAAQ,MAAM,QAAQ,QAAQ;AAAA,kBAC9B,UAAU,CAAC,MAAM,UAAW,CAAC,OAAO,KAAA,KAAU,CAAC,YAAa,CAAC;AAAA,kBAC7D,UAAS;AAAA,gBAAA;AAAA,cAAA;AAAA,YACX;AAAA,UAAA;AAAA,QAAA;AAAA,MACF,EAAA,CACF;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,wBAEC,UAAA,EAAO,WAAU,UAChB,UAAA,qBAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,MAAA,oBAAC,OAAA,EAAI,WAAU,kBACZ,UAAA,CAAC,WACA,qBAAA,UAAA,EACE,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAK,MAAK,QAAO,MAAM,IAAI,OAAO,EAAE,OAAO,oBAAA,EAAoB,CAAG;AAAA,QACnE,oBAAC,UAAK,UAAA,kBAAA,CAAe;AAAA,MAAA,EAAA,CACvB,IACE,QACF,qBAAA,UAAA,EACE,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAK,MAAK,SAAQ,MAAM,IAAI,OAAO,EAAE,OAAO,YAAA,EAAY,CAAG;AAAA,QAC5D,oBAAC,UAAK,UAAA,oBAAA,CAAiB;AAAA,MAAA,EAAA,CACzB,IAEA,qBAAA,UAAA,EACE,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAK,MAAK,OAAM,MAAM,IAAI,OAAO,EAAE,OAAO,oBAAA,EAAoB,CAAG;AAAA,QAClE,oBAAC,UAAK,UAAA,iBAAA,CAAc;AAAA,MAAA,EAAA,CACtB,EAAA,CAEJ;AAAA,MACA,qBAAC,OAAA,EAAI,WAAU,mBACb,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAO,SAAQ,SAAQ,MAAK,MAAK,UAAU,CAAC,OAAO,SAAS,WAAW,UAAA,OAAA,CAExE;AAAA,QACA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,MAAM,SAAS,oBAAC,SAAA,EAAQ,MAAK,KAAA,CAAK,IAAK,oBAAC,MAAA,EAAK,MAAK,QAAO,MAAM,GAAA,CAAI;AAAA,YACnE,UAAU,CAAC,YAAY,CAAC,SAAS;AAAA,YACjC,aAAW,UAAU;AAAA,YACrB,SAAS;AAAA,YACV,UAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MAED,EAAA,CACF;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;"}