gz-research-assistant 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -0
- package/dist/AssistantAvatar.d.ts +1 -0
- package/dist/FloatingPanel.d.ts +9 -0
- package/dist/PerformancePanel.d.ts +8 -0
- package/dist/ResearchAssistant-DAsgcwcG.js +1757 -0
- package/dist/ResearchAssistant-DAsgcwcG.js.map +1 -0
- package/dist/ResearchAssistant.d.ts +6 -0
- package/dist/TimelinePanel.d.ts +5 -0
- package/dist/automation/AssertionEditor.d.ts +9 -0
- package/dist/automation/AutomationPanel.d.ts +4 -0
- package/dist/automation/StepSupplement.d.ts +6 -0
- package/dist/automation/recorder.d.ts +18 -0
- package/dist/automation/schema.d.ts +1 -0
- package/dist/automation/timeline-case.d.ts +5 -0
- package/dist/core.d.ts +5 -0
- package/dist/core.js +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/dist/knowledge.d.ts +15 -0
- package/dist/performance.d.ts +25 -0
- package/dist/privacy.d.ts +5 -0
- package/dist/recorder-Da1VSLid.js +709 -0
- package/dist/recorder-Da1VSLid.js.map +1 -0
- package/dist/runtime.d.ts +110 -0
- package/dist/sdk.d.ts +4 -0
- package/dist/sdk.js +15 -0
- package/dist/sdk.js.map +1 -0
- package/dist/snapshot.d.ts +4 -0
- package/dist/style.css +11 -0
- package/dist/useOverlayScrollbars.d.ts +4 -0
- package/package.json +55 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResearchAssistant-DAsgcwcG.js","names":[],"sources":["../src/automation/schema.ts","../src/automation/AssertionEditor.tsx","../src/automation/StepSupplement.tsx","../src/automation/AutomationPanel.tsx","../src/automation/timeline-case.ts","../src/TimelinePanel.tsx","../src/AssistantAvatar.tsx","../src/useOverlayScrollbars.ts","../src/FloatingPanel.tsx","../src/PerformancePanel.tsx","../src/ResearchAssistant.tsx"],"sourcesContent":["export * from 'gz-laya-pilot/schema';\n","import { useId, useState } from 'react';\nimport { Alert, Button, Input, InputNumber, Select } from '@chenhui996/gg-ui';\nimport { CheckCircleOutlined, SaveOutlined } from '@ant-design/icons';\nimport {\n assertionOperators,\n assertionSources,\n operatorsFor,\n parseAssertion,\n type Assertion,\n type Step,\n} from './schema';\n\nexport default function AssertionEditor({\n initial,\n steps,\n position,\n disabled,\n onSave,\n onCancel,\n}: {\n initial?: Assertion;\n steps: Step[];\n position: number;\n disabled: boolean;\n onSave: (assertion: Assertion, position: number) => void;\n onCancel: () => void;\n}) {\n const id = useId();\n const [draft, setDraft] = useState<Assertion>(\n initial ?? {\n name: '',\n source: 'page-text',\n operator: 'contains',\n expected: '',\n timeout: 10000,\n },\n );\n const [after, setAfter] = useState(position);\n const [error, setError] = useState('');\n const patch = (value: Partial<Assertion>) => setDraft((current) => ({ ...current, ...value }));\n return (\n <div\n className=\"research-assistant__assertion-editor research-assistant__form-stack\"\n aria-label={initial ? '编辑断言配置' : '新增断言配置'}\n >\n <h3 className=\"research-assistant__subheading\">\n <CheckCircleOutlined />\n {initial ? '编辑断言' : '添加断言'}\n </h3>\n <p className=\"research-assistant__hint\">\n 选择断言对象、比较条件和期望值。回放时在指定步骤后自动等待并校验。\n </p>\n <div className=\"research-assistant__field\">\n <label htmlFor={`${id}-name`}>断言名称</label>\n <Input\n id={`${id}-name`}\n placeholder=\"例如:保存后显示成功提示\"\n value={draft.name}\n maxLength={100}\n disabled={disabled}\n onChange={(e) => patch({ name: e.target.value })}\n />\n </div>\n {!initial && (\n <div className=\"research-assistant__field\">\n <label htmlFor={`${id}-position`}>执行位置</label>\n <Select\n id={`${id}-position`}\n value={after}\n disabled={disabled}\n onChange={setAfter}\n options={[\n { value: 0, label: '所有步骤之前' },\n ...steps.map((step, index) => ({\n value: index + 1,\n label: `第 ${index + 1} 步之后 · ${step.assertion?.name ?? step.target?.label ?? step.value ?? step.kind}`,\n })),\n ]}\n />\n </div>\n )}\n <div className=\"research-assistant__assertion-fields\">\n <div className=\"research-assistant__field\">\n <label htmlFor={`${id}-source`}>断言对象</label>\n <Select\n id={`${id}-source`}\n value={draft.source}\n disabled={disabled}\n options={Object.entries(assertionSources).map(([value, label]) => ({ value, label }))}\n onChange={(source) =>\n patch({\n source,\n operator: operatorsFor(source)[0],\n expected: source === 'element-count' ? '1' : '',\n selector: draft.selector ?? '',\n })\n }\n />\n </div>\n <div className=\"research-assistant__field\">\n <label htmlFor={`${id}-operator`}>比较条件</label>\n <Select\n id={`${id}-operator`}\n value={draft.operator}\n disabled={disabled}\n onChange={(operator) => patch({ operator })}\n options={operatorsFor(draft.source).map((value) => ({\n value,\n label: assertionOperators[value],\n }))}\n />\n </div>\n </div>\n {draft.source !== 'page-text' && (\n <div className=\"research-assistant__field\">\n <label htmlFor={`${id}-selector`}>元素定位(CSS)</label>\n <Input\n id={`${id}-selector`}\n value={draft.selector}\n maxLength={2000}\n placeholder='例如:[data-testid=\"save-result\"]'\n disabled={disabled}\n onChange={(e) => patch({ selector: e.target.value })}\n />\n <p className=\"research-assistant__hint\">\n 可从步骤的“定位信息”复制。文字、值和可见性要求唯一元素;数量支持匹配多个元素。\n </p>\n </div>\n )}\n {draft.source !== 'element-state' && (\n <div className=\"research-assistant__field\">\n <label htmlFor={`${id}-expected`}>期望值</label>\n <Input\n id={`${id}-expected`}\n value={draft.expected}\n maxLength={2000}\n placeholder={draft.source === 'element-count' ? '例如:1' : '输入期望内容'}\n disabled={disabled}\n onChange={(e) => patch({ expected: e.target.value })}\n />\n </div>\n )}\n <div className=\"research-assistant__field\">\n <label htmlFor={`${id}-timeout`}>最长等待时间(毫秒)</label>\n <InputNumber\n id={`${id}-timeout`}\n min={500}\n max={30000}\n step={500}\n value={draft.timeout}\n disabled={disabled}\n onChange={(timeout) => patch({ timeout: timeout ?? 10000 })}\n />\n </div>\n {error && <Alert showIcon type=\"error\" message={error} />}\n <div className=\"research-assistant__button-row\">\n <Button\n icon={<SaveOutlined />}\n type=\"primary\"\n disabled={disabled}\n onClick={() => {\n try {\n const assertion = parseAssertion(draft);\n if (assertion.selector) {\n try {\n document.querySelector(assertion.selector);\n } catch {\n throw Error('CSS 定位语法无效,请检查后再保存');\n }\n }\n onSave(assertion, Math.min(after, steps.length));\n } catch (e) {\n setError(e instanceof Error ? e.message : '断言配置无效');\n }\n }}\n >\n 保存断言\n </Button>\n <Button onClick={onCancel}>取消</Button>\n </div>\n </div>\n );\n}\n","import { useId, useState } from 'react';\nimport { Button, Input, Select } from '@chenhui996/gg-ui';\nimport { CheckOutlined, CodeOutlined, EditOutlined } from '@ant-design/icons';\nimport type { Step } from './schema';\n\nexport default function StepSupplement({\n step,\n disabled,\n onApply,\n}: {\n step: Step;\n disabled: boolean;\n onApply: (step: Step) => void;\n}) {\n const kindId = useId();\n const [kind, setKind] = useState<Step['kind']>('click');\n const [selector, setSelector] = useState(''),\n [label, setLabel] = useState(''),\n [value, setValue] = useState('');\n const [checked, setChecked] = useState(true),\n [error, setError] = useState('');\n return (\n <details className=\"research-assistant__supplement\">\n <summary>补充为可执行步骤</summary>\n <p className=\"research-assistant__hint\">\n 人工补充不会修改原始事件。填写业务控件的 CSS\n 定位与文字;不清楚定位时,可退出选段后重新主动录制。\n </p>\n <div className=\"research-assistant__form-stack\">\n <div className=\"research-assistant__field\">\n <label htmlFor={kindId}>操作类型</label>\n <Select\n id={kindId}\n aria-label=\"补充操作类型\"\n value={kind}\n disabled={disabled}\n onChange={setKind}\n style={{ width: '100%' }}\n options={[\n { value: 'click', label: '点击' },\n { value: 'fill', label: '输入' },\n { value: 'select', label: '原生下拉选择' },\n { value: 'check', label: '勾选' },\n { value: 'press', label: '按键' },\n { value: 'assert-text', label: '文字检查点' },\n ]}\n />\n </div>\n {kind !== 'assert-text' && (\n <>\n <Input\n prefix={<CodeOutlined />}\n aria-label=\"补充 CSS 定位\"\n placeholder='例如 button[aria-label=\"展开\"]'\n maxLength={2000}\n value={selector}\n disabled={disabled}\n onChange={(e) => setSelector(e.target.value)}\n />\n <Input\n prefix={<EditOutlined />}\n aria-label=\"补充控件文字\"\n placeholder=\"控件文字、aria-label 或输入框 placeholder\"\n maxLength={200}\n value={label}\n disabled={disabled}\n onChange={(e) => setLabel(e.target.value)}\n />\n </>\n )}\n {['fill', 'select', 'press', 'assert-text'].includes(kind) && (\n <Input\n aria-label=\"补充步骤内容\"\n placeholder={kind === 'press' ? 'Enter / Escape / Tab' : '输入值或预期文字'}\n maxLength={2000}\n value={value}\n disabled={disabled}\n onChange={(e) => setValue(e.target.value)}\n />\n )}\n {kind === 'check' && (\n <label>\n <input\n type=\"checkbox\"\n checked={checked}\n disabled={disabled}\n onChange={(e) => setChecked(e.target.checked)}\n />\n 选中\n </label>\n )}\n <Button\n icon={<CheckOutlined />}\n disabled={disabled}\n onClick={() => {\n try {\n if (kind !== 'assert-text') {\n if (!selector.trim() || !label.trim()) throw Error('请补充定位及控件文字');\n document.querySelector(selector); // Syntax only; historical controls may not currently exist.\n }\n if (kind === 'assert-text' && !value.trim()) throw Error('检查点文字不能为空');\n if (kind === 'press' && !['Enter', 'Escape', 'Tab'].includes(value))\n throw Error('请选择支持的按键');\n onApply({\n kind,\n supplemented: true,\n ...(step.sourceEventId ? { sourceEventId: step.sourceEventId } : {}),\n ...(kind !== 'assert-text'\n ? { target: { selector: selector.trim(), label: label.trim() } }\n : {}),\n ...(['fill', 'select', 'press', 'assert-text'].includes(kind) ? { value } : {}),\n ...(kind === 'check' ? { checked } : {}),\n });\n setError('');\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : '内容无效');\n }\n }}\n >\n 应用补充\n </Button>\n {error && <span role=\"alert\">{error}</span>}\n </div>\n </details>\n );\n}\n","import { useEffect, useRef, useState, useSyncExternalStore } from 'react';\nimport { Alert, Button, Input, Tag } from '@chenhui996/gg-ui';\nimport {\n VideoCameraOutlined,\n StopOutlined,\n EditOutlined,\n SaveOutlined,\n DownloadOutlined,\n UploadOutlined,\n PlusOutlined,\n DeleteOutlined,\n CheckCircleOutlined,\n PlayCircleOutlined,\n ClockCircleOutlined,\n FileTextOutlined,\n InfoCircleOutlined,\n} from '@ant-design/icons';\nimport { recorder } from './recorder';\nimport {\n parseCase,\n assertionSources,\n assertionOperators,\n type RunStatus,\n type Step,\n} from './schema';\nimport AssertionEditor from './AssertionEditor';\nimport StepSupplement from './StepSupplement';\n\nconst names: Record<Step['kind'], string> = {\n click: '点击',\n fill: '输入',\n select: '选择',\n check: '勾选',\n press: '按键',\n 'assert-text': '检查文字',\n assert: '断言',\n unsupported: '需要处理',\n};\nconst initial: RunStatus = { state: 'idle', step: 0, total: 0, message: '尚未运行' };\nasync function bridge(base: string, action: string, body?: unknown) {\n const response = await fetch(\n `${base.replace(/\\/$/, '')}/${action}`,\n body === undefined\n ? {}\n : {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-Laya-Pilot': 'recorded-case-v1' },\n body: JSON.stringify(body),\n },\n );\n if (!response.headers.get('content-type')?.includes('application/json'))\n throw Error('回放服务未连接,请检查宿主配置的服务地址');\n const result = await response.json();\n if (!response.ok) throw Error(result.message || '本地回放服务不可用');\n return result as RunStatus & { available?: boolean };\n}\n\nexport default function AutomationPanel({\n close,\n bridgeUrl,\n}: {\n close: () => void;\n bridgeUrl: string;\n}) {\n const state = useSyncExternalStore(recorder.subscribe, recorder.getState);\n const [notice, setNotice] = useState('');\n const [assertionForm, setAssertionForm] = useState<{ position: number; edit?: number } | null>(\n null,\n );\n const assertionArea = useRef<HTMLDivElement>(null);\n const showAssertion = (position: number, edit?: number) => {\n setAssertionForm({ position, edit });\n requestAnimationFrame(() =>\n assertionArea.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' }),\n );\n };\n const [run, setRun] = useState<RunStatus>(initial);\n const [available, setAvailable] = useState(false);\n const [pending, setPending] = useState(false);\n const [delay, setDelay] = useState(2000);\n const file = useRef<HTMLInputElement>(null);\n useEffect(() => {\n let disposed = false;\n let timer: ReturnType<typeof setTimeout>;\n const poll = async () => {\n try {\n const result = await bridge(bridgeUrl, 'status');\n if (!disposed) {\n setRun(result);\n setAvailable(result.available !== false);\n }\n } catch {\n if (!disposed) setAvailable(false);\n } finally {\n if (!disposed) timer = setTimeout(poll, 1500);\n }\n };\n void poll();\n return () => {\n disposed = true;\n clearTimeout(timer);\n };\n }, [bridgeUrl]);\n const busy = pending || run.state === 'running';\n const act = async (fn: () => void | Promise<void>) => {\n try {\n setNotice('');\n await fn();\n } catch (error) {\n setNotice(error instanceof Error ? error.message : '操作失败');\n }\n };\n const updateStep = (index: number, patch: Partial<Step>) =>\n recorder.edit({\n ...state.draft,\n steps: state.draft.steps.map((step, i) =>\n i === index ? { ...step, ...patch, supplemented: true } : step,\n ),\n });\n return (\n <div className=\"research-assistant__section research-assistant__automation\">\n <div className=\"research-assistant__section-heading\">\n <span className=\"research-assistant__heading-icon\">\n <VideoCameraOutlined />\n </span>\n <div>\n <h3>把操作变成可复现的用例</h3>\n <p>录制操作,配置断言,再验证结果。</p>\n </div>\n </div>\n {!available && (\n <Alert type=\"warning\" message=\"回放服务未连接。仍可录制、编辑断言和导出用例。\" />\n )}\n {notice && <Alert closable onClose={() => setNotice('')} type=\"info\" message={notice} />}\n <div className=\"research-assistant__automation-layout\">\n <section\n className=\"research-assistant__card research-assistant__record-card\"\n aria-label=\"录制操作\"\n >\n <div className=\"research-assistant__card-heading\">\n <h3>\n <VideoCameraOutlined />\n 录制操作\n </h3>\n <Tag color={state.recording ? 'red' : 'default'}>\n {state.recording ? '录制中' : '待录制'} · {state.draft.steps.length}/100 步\n </Tag>\n </div>\n <div className=\"research-assistant__button-row\">\n <Button\n icon={<VideoCameraOutlined />}\n type=\"primary\"\n disabled={busy || state.recording}\n onClick={() =>\n void act(() => {\n setAssertionForm(null);\n recorder.start();\n close();\n })\n }\n >\n 开始新录制\n </Button>\n <Button\n icon={<StopOutlined />}\n disabled={!state.recording}\n onClick={() => recorder.stop()}\n >\n 结束录制\n </Button>\n </div>\n <details className=\"research-assistant__help\">\n <summary>\n <InfoCircleOutlined />\n 录制范围与使用说明\n </summary>\n <p className=\"research-assistant__hint\">\n 先将业务页面恢复到初始状态,再开始录制;回放目标由宿主配置。需保留用例时请导出 JSON。\n </p>\n <p className=\"research-assistant__hint\">\n 录制会保存普通字段输入值。密码等敏感输入不记录;上传、跨域\n iframe、拖拽和刷新暂不支持。保存前请检查步骤。回放会真实操作模拟数据,不会自动恢复录制前的数据。\n </p>\n </details>\n </section>\n <section\n className=\"research-assistant__card research-assistant__editor-card\"\n aria-label=\"编辑用例\"\n >\n <div className=\"research-assistant__card-heading\">\n <h3>\n <EditOutlined />\n 编辑用例\n </h3>\n <span>{state.draft.steps.length} 个步骤</span>\n </div>\n <div className=\"research-assistant__field\">\n <label htmlFor=\"assistant-case-name\">用例名称</label>\n <Input\n id=\"assistant-case-name\"\n prefix={<FileTextOutlined />}\n aria-label=\"测试用例名称\"\n value={state.draft.name}\n maxLength={100}\n disabled={state.recording || busy}\n onChange={(e) => recorder.edit({ ...state.draft, name: e.target.value })}\n />\n </div>\n {!state.draft.steps.length && (\n <div className=\"research-assistant__empty-steps\">\n <FileTextOutlined />\n <span>还没有操作步骤</span>\n <p>开始录制,或导入已有用例。</p>\n </div>\n )}\n <ol className=\"research-assistant__case-steps\">\n {state.draft.steps.map((step, index) => (\n <li key={index}>\n <div className=\"research-assistant__step-heading\">\n <span className=\"research-assistant__step-number\">\n {String(index + 1).padStart(2, '0')}\n </span>\n <Tag color={step.kind === 'unsupported' ? 'red' : 'blue'}>{names[step.kind]}</Tag>\n <strong>{step.assertion?.name ?? step.target?.label ?? step.value}</strong>\n {step.sourceEventId && <Tag>源事件 #{step.sourceEventId}</Tag>}\n {step.supplemented && <Tag color=\"orange\">人工补充</Tag>}\n </div>\n {step.assertion && (\n <div className=\"research-assistant__assertion-summary\">\n <Tag color=\"green\">{assertionSources[step.assertion.source]}</Tag>\n <span>\n {assertionOperators[step.assertion.operator]}{' '}\n {step.assertion.expected === '' ? '空字符串' : step.assertion.expected}\n </span>\n <span className=\"research-assistant__hint\">\n 最多等待 {step.assertion.timeout / 1000} 秒\n </span>\n {step.assertion.selector && <code>{step.assertion.selector}</code>}\n </div>\n )}\n {step.kind === 'unsupported' && (\n <StepSupplement\n key={JSON.stringify(step)}\n step={step}\n disabled={state.recording || busy}\n onApply={(replacement) =>\n recorder.edit({\n ...state.draft,\n steps: state.draft.steps.map((current, i) =>\n i === index ? replacement : current,\n ),\n })\n }\n />\n )}\n {step.value !== undefined && step.kind !== 'unsupported' && (\n <Input\n aria-label={`第 ${index + 1} 步内容`}\n value={step.value}\n maxLength={2000}\n disabled={state.recording || busy}\n onChange={(e) => updateStep(index, { value: e.target.value })}\n />\n )}\n {step.kind === 'check' && <span>{step.checked ? '选中' : '取消选中'}</span>}\n {step.target && (\n <details>\n <summary>定位信息</summary>\n <code>{step.target.selector}</code>\n </details>\n )}\n <div className=\"research-assistant__button-row research-assistant__step-actions\">\n <Button\n size=\"small\"\n icon={<CheckCircleOutlined />}\n disabled={\n state.recording ||\n busy ||\n (!step.assertion && state.draft.steps.length >= 100)\n }\n onClick={() => showAssertion(index + 1, step.assertion ? index : undefined)}\n >\n {step.assertion ? '编辑断言' : '在此步后添加断言'}\n </Button>\n <Button\n icon={<PlusOutlined />}\n size=\"small\"\n disabled={state.recording || busy || state.draft.steps.length >= 100}\n onClick={() => {\n setAssertionForm(null);\n recorder.edit({\n ...state.draft,\n steps: [\n ...state.draft.steps.slice(0, index),\n { kind: 'unsupported', value: '人工前置步骤待补充' },\n ...state.draft.steps.slice(index),\n ],\n });\n }}\n >\n 在第 {index + 1} 步前插入\n </Button>\n <Button\n icon={<DeleteOutlined />}\n danger\n size=\"small\"\n disabled={state.recording || busy}\n onClick={() => {\n setAssertionForm(null);\n recorder.edit({\n ...state.draft,\n steps: state.draft.steps.filter((_, i) => i !== index),\n });\n }}\n >\n 移除第 {index + 1} 步\n </Button>\n </div>\n </li>\n ))}\n </ol>\n {state.draft.timeline && (\n <details>\n <summary>选段原始证据({state.draft.timeline.events.length} 条,只读)</summary>\n <p>接口、异常和性能事件不执行;人工补充与移除步骤不会改写这里的来源记录。</p>\n <pre className=\"research-assistant__json\">\n {JSON.stringify(state.draft.timeline, null, 2)}\n </pre>\n </details>\n )}\n <div ref={assertionArea} className=\"research-assistant__assertion-area\">\n <div className=\"research-assistant__card-heading\">\n <h3>\n <CheckCircleOutlined /> 结果断言\n </h3>\n <Tag>\n {\n state.draft.steps.filter(\n (step) => step.kind === 'assert' || step.kind === 'assert-text',\n ).length\n }{' '}\n 条\n </Tag>\n </div>\n <p className=\"research-assistant__hint\">\n 断言按步骤顺序执行,可检查页面文字、元素文字、输入值、可见性和数量。\n </p>\n {assertionForm ? (\n <AssertionEditor\n key={`${assertionForm.position}-${assertionForm.edit ?? 'new'}`}\n initial={\n assertionForm.edit === undefined\n ? undefined\n : state.draft.steps[assertionForm.edit]?.assertion\n }\n steps={state.draft.steps}\n position={assertionForm.position}\n disabled={busy || state.recording}\n onCancel={() => setAssertionForm(null)}\n onSave={(assertion, position) => {\n const steps = [...state.draft.steps];\n if (assertionForm.edit === undefined)\n steps.splice(position, 0, { kind: 'assert', assertion, supplemented: true });\n else\n steps[assertionForm.edit] = {\n ...steps[assertionForm.edit],\n kind: 'assert',\n assertion,\n supplemented: true,\n };\n recorder.edit(parseCase({ ...state.draft, steps }));\n setAssertionForm(null);\n }}\n />\n ) : (\n <Button\n icon={<PlusOutlined />}\n disabled={busy || state.recording || state.draft.steps.length >= 100}\n onClick={() => showAssertion(state.draft.steps.length)}\n >\n 添加断言\n </Button>\n )}\n </div>\n <div className=\"research-assistant__button-row research-assistant__card-actions\">\n <Button\n icon={<SaveOutlined />}\n disabled={state.recording || busy || !state.draft.steps.length}\n onClick={() =>\n void act(() => {\n const testCase = parseCase(state.draft);\n if (testCase.steps.some((s) => s.kind === 'unsupported'))\n throw Error('请处理“需要处理”的步骤,再保存用例');\n recorder.save(testCase);\n setNotice('已保存到当前页面内存,可以开始回放或导出');\n })\n }\n >\n 保存用例\n </Button>\n <Button\n icon={<DownloadOutlined />}\n disabled={!state.saved}\n onClick={() => {\n const url = URL.createObjectURL(\n new Blob([JSON.stringify(state.saved, null, 2)], { type: 'application/json' }),\n );\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = '页面录制用例.json';\n document.body.append(anchor);\n anchor.click();\n anchor.remove();\n setTimeout(() => URL.revokeObjectURL(url), 30000);\n }}\n >\n 导出用例 JSON\n </Button>\n <Button\n icon={<UploadOutlined />}\n disabled={state.recording || busy}\n onClick={() => file.current?.click()}\n >\n 导入用例\n </Button>\n <input\n ref={file}\n hidden\n type=\"file\"\n accept=\".json,application/json\"\n onChange={(e) => {\n const selected = e.target.files?.[0];\n e.target.value = '';\n if (selected)\n void act(async () => {\n if (selected.size > 512 * 1024) throw Error('用例不能超过 512 KB');\n recorder.save(parseCase(JSON.parse(await selected.text())));\n setAssertionForm(null);\n setNotice('已导入,请检查步骤后开始回放');\n });\n }}\n />\n </div>\n {state.saved && (\n <p className=\"research-assistant__saved-case\">\n <CheckCircleOutlined />\n 已保存:{state.saved.name}({state.saved.steps.length} 步)\n {JSON.stringify(state.saved) !== JSON.stringify(state.draft) && (\n <Tag color=\"orange\">草稿有未保存修改</Tag>\n )}\n </p>\n )}\n </section>\n <section\n className=\"research-assistant__card research-assistant__replay-card\"\n aria-label=\"执行回放\"\n >\n <div className=\"research-assistant__card-heading\">\n <h3>\n <PlayCircleOutlined />\n 执行回放\n </h3>\n </div>\n <p className=\"research-assistant__hint\">保存后在独立浏览器中执行,按断言验证结果。</p>\n <div className=\"research-assistant__field\">\n <label htmlFor=\"assistant-step-delay\">\n <ClockCircleOutlined />\n 每步间隔\n </label>\n <div className=\"research-assistant__delay-row\">\n <input\n id=\"assistant-step-delay\"\n aria-label=\"回放步骤间隔\"\n type=\"number\"\n min={0}\n max={10000}\n step={500}\n value={delay}\n disabled={busy}\n onChange={(e) => setDelay(Number(e.target.value))}\n />\n <span>毫秒</span>\n </div>\n </div>\n <div className=\"research-assistant__button-row\">\n <Button\n icon={<PlayCircleOutlined />}\n type=\"primary\"\n disabled={\n !available ||\n !state.saved ||\n state.saved.steps.some((step) => step.kind === 'unsupported') ||\n state.recording ||\n busy ||\n JSON.stringify(state.saved) !== JSON.stringify(state.draft)\n }\n onClick={() =>\n void act(async () => {\n setPending(true);\n try {\n setRun(\n await bridge(bridgeUrl, 'run', {\n testCase: state.saved,\n delay,\n headed: true,\n }),\n );\n } finally {\n setPending(false);\n }\n })\n }\n >\n 开始回放(本地 Chrome)\n </Button>\n <Button\n icon={<StopOutlined />}\n disabled={run.state !== 'running'}\n onClick={() =>\n void act(async () => {\n await bridge(bridgeUrl, 'stop', {});\n })\n }\n >\n 停止回放\n </Button>\n </div>\n <Alert\n showIcon\n type={run.state === 'failed' ? 'error' : run.state === 'passed' ? 'success' : 'info'}\n message={`${run.step}/${run.total} · ${run.message}`}\n />\n {!!run.assertions?.length && (\n <div className=\"research-assistant__assertion-results\" aria-label=\"断言结果\">\n <h3 className=\"research-assistant__subheading\">\n <CheckCircleOutlined /> 断言结果\n </h3>\n {run.assertions.map((result) => (\n <div key={result.step} className=\"research-assistant__assertion-result\">\n <div className=\"research-assistant__card-heading\">\n <strong>\n 第 {result.step} 步 · {result.name}\n </strong>\n <Tag color={result.passed ? 'green' : 'red'}>\n {result.passed ? '通过' : '失败'}\n </Tag>\n </div>\n <dl>\n <dt>期望</dt>\n <dd>{result.expected}</dd>\n <dt>实际</dt>\n <dd>{result.actual || '空字符串'}</dd>\n </dl>\n <span className=\"research-assistant__hint\">耗时 {result.duration} ms</span>\n </div>\n ))}\n </div>\n )}\n </section>\n </div>\n </div>\n );\n}\n","import type { TraceEvent } from '../runtime';\nimport { safeText, safeUrl } from '../privacy';\nimport { parseCase, type TestCase, type TimelineEvidence } from './schema';\n\nexport function freezeTimeline(events: TraceEvent[]): TimelineEvidence[] {\n const ids = new Set<number>();\n return events\n .map((event) => {\n if (!Number.isSafeInteger(event.id) || event.id <= 0 || ids.has(event.id))\n throw Error('事件编号重复或无效,无法选段');\n ids.add(event.id);\n // Keep a bounded, value-free copy. Request bodies are never executable steps.\n return {\n id: event.id,\n time: event.time,\n kind: event.kind,\n title: safeText(event.title, 180),\n page: safeUrl(event.page),\n ...(event.actionId ? { actionId: event.actionId } : {}),\n };\n })\n .sort((a, b) => a.time - b.time || a.id - b.id);\n}\n\nexport function timelineRange(events: TimelineEvidence[], startId?: number, endId?: number) {\n const start = events.findIndex((e) => e.id === startId),\n end = events.findIndex((e) => e.id === endId);\n if (start < 0 || end < start) return [];\n return events.slice(start, end + 1);\n}\n\nexport function buildTimelineCase(\n events: TimelineEvidence[],\n startId: number,\n endId: number,\n): TestCase {\n const selected = timelineRange(events, startId, endId);\n if (!selected.length) throw Error('请选择按时间先后排列的起点和终点');\n const actions = selected.filter((e) => ['route', 'click', 'change'].includes(e.kind));\n if (!actions.length) throw Error('该片段只有排查证据,没有页面操作,不能生成用例');\n if (actions.length >= 100) throw Error('操作过多,请缩小选段范围(需为前置步骤预留一个位置)');\n const first = new URL(actions[0].page);\n if (\n !['http:', 'https:'].includes(first.protocol) ||\n actions.some((e) => new URL(e.page).origin !== first.origin)\n )\n throw Error('请选择同一站点内的片段');\n return parseCase({\n schema: 'zhidao-recorded-case',\n version: 1,\n name: `时间线片段 #${startId}–#${endId}`,\n path: first.pathname,\n timeline: { capturedAt: new Date().toISOString(), events: structuredClone(selected) },\n steps: [\n {\n kind: 'unsupported',\n value:\n '前置条件待确认:回放从片段的入口页面开始。请补充登录、筛选、弹窗等必要步骤;无需前置操作时可移除此项。',\n },\n ...actions.map((e) => ({\n kind: 'unsupported',\n sourceEventId: e.id,\n value:\n e.kind === 'change'\n ? `待补充字段定位、操作类型和输入值:${e.title}(历史输入值未采集)`\n : e.kind === 'route'\n ? `待确认页面前置状态:${e.title}(不会自动恢复原现场)`\n : `待补充点击目标:${e.title}(历史记录没有可回放定位,不能按文字猜测)`,\n })),\n ],\n });\n}\n","import { useState, useSyncExternalStore } from 'react';\nimport { Alert, Button, Empty, Input, Tag } from '@chenhui996/gg-ui';\nimport {\n HistoryOutlined,\n ScissorOutlined,\n CloseOutlined,\n FileAddOutlined,\n SearchOutlined,\n FlagOutlined,\n CheckCircleOutlined,\n} from '@ant-design/icons';\nimport type { TraceEvent } from './runtime';\nimport { buildTimelineCase, freezeTimeline, timelineRange } from './automation/timeline-case';\nimport type { TimelineEvidence } from './automation/schema';\nimport { recorder } from './automation/recorder';\n\nconst labels: Record<string, string> = {\n route: '页面',\n click: '点击',\n change: '字段',\n request: '接口',\n error: '异常',\n performance: '性能',\n};\nexport default function TimelinePanel({\n events,\n onDraft,\n}: {\n events: TraceEvent[];\n onDraft: () => void;\n}) {\n const recording = useSyncExternalStore(recorder.subscribe, recorder.getState);\n const [frozen, setFrozen] = useState<TimelineEvidence[] | null>(null);\n const [start, setStart] = useState<number>(),\n [end, setEnd] = useState<number>();\n const [kind, setKind] = useState('all'),\n [filter, setFilter] = useState('');\n const [notice, setNotice] = useState('');\n const selected = frozen ? timelineRange(frozen, start, end) : [];\n const selectedIds = new Set(selected.map((e) => e.id));\n const shown = frozen ?? events;\n return (\n <div className=\"research-assistant__section\">\n <div className=\"research-assistant__section-heading\">\n <span className=\"research-assistant__heading-icon\">\n <HistoryOutlined />\n </span>\n <div>\n <h3>操作时间线</h3>\n <p>沿着操作轨迹,找到问题发生的时刻。</p>\n </div>\n </div>\n <div className=\"research-assistant__button-row\">\n <Button\n icon={<ScissorOutlined />}\n disabled={recording.recording || !events.length || !!frozen}\n onClick={() => {\n try {\n setFrozen(freezeTimeline(events));\n setStart(undefined);\n setEnd(undefined);\n setNotice('');\n } catch (error) {\n setNotice((error as Error).message);\n }\n }}\n >\n 开始选段\n </Button>\n {frozen && (\n <>\n <Button\n icon={<CloseOutlined />}\n onClick={() => {\n setFrozen(null);\n setStart(undefined);\n setEnd(undefined);\n setNotice('');\n }}\n >\n 退出选段\n </Button>\n <Button\n icon={<FileAddOutlined />}\n type=\"primary\"\n disabled={!selected.length || recording.recording}\n onClick={() => {\n try {\n recorder.loadDraft(buildTimelineCase(frozen, start!, end!));\n onDraft();\n } catch (error) {\n setNotice((error as Error).message);\n }\n }}\n >\n 生成用例草稿\n </Button>\n </>\n )}\n </div>\n {frozen && (\n <Alert\n type=\"info\"\n message={`已固定 ${frozen.length} 条事件;起点 ${start ? '#' + start : '未选'} → 终点 ${end ? '#' + end : '未选'},选中 ${selected.length} 条。`}\n description=\"列表仍按最新在上显示,生成步骤按实际时间正序。选段包含中间全部事件;接口、异常、性能只保留为证据。生成草稿会替换当前未保存草稿,保留已保存用例。\"\n />\n )}\n {notice && <Alert type=\"warning\" message={notice} />}\n {!frozen && (\n <div className=\"research-assistant__filters\">\n <select aria-label=\"事件类型\" value={kind} onChange={(e) => setKind(e.target.value)}>\n <option value=\"all\">全部事件</option>\n {Object.entries(labels).map(([key, label]) => (\n <option key={key} value={key}>\n {label}\n </option>\n ))}\n </select>\n <Input\n prefix={<SearchOutlined />}\n aria-label=\"搜索时间线\"\n placeholder=\"搜索操作或页面\"\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n allowClear\n />\n </div>\n )}\n <p className=\"research-assistant__hint\">\n 最新记录在最上方;接口详情中的 actionId\n 对应触发操作编号。历史记录缺少输入值及定位信息,生成后需要补充。\n </p>\n {!shown.length && <Empty description=\"等待页面操作\" />}\n <ol className=\"research-assistant__timeline\">\n {shown\n .filter(\n (e) =>\n !!frozen ||\n ((kind === 'all' || e.kind === kind) && (e.title + e.page).includes(filter)),\n )\n .slice()\n .sort((a, b) => b.time - a.time || b.id - a.id)\n .map((e) => (\n <li key={e.id} className={e.kind === 'error' ? 'is-error' : ''}>\n <div className=\"research-assistant__event-meta\">\n <Tag color={e.kind === 'error' ? 'red' : 'blue'}>{labels[e.kind]}</Tag>\n <time>{new Date(e.time).toLocaleTimeString('zh-CN', { hour12: false })}</time>\n <small>#{e.id}</small>\n {selectedIds.has(e.id) && <Tag color=\"gold\">已选</Tag>}\n </div>\n <strong>{e.title}</strong>\n {frozen && (\n <div className=\"research-assistant__button-row\">\n <Button\n icon={<FlagOutlined />}\n size=\"small\"\n aria-label={`从事件 ${e.id} 开始`}\n onClick={() => {\n setStart(e.id);\n setEnd(undefined);\n }}\n >\n 设为起点\n </Button>\n <Button\n icon={<CheckCircleOutlined />}\n size=\"small\"\n aria-label={`到事件 ${e.id} 结束`}\n disabled={\n start === undefined ||\n frozen.findIndex((x) => x.id === e.id) <\n frozen.findIndex((x) => x.id === start)\n }\n onClick={() => setEnd(e.id)}\n >\n 设为终点\n </Button>\n </div>\n )}\n <details>\n <summary>详情{e.actionId ? ` · 关联操作 #${e.actionId}` : ''}</summary>\n <pre className=\"research-assistant__json\">\n {JSON.stringify(\n { page: e.page, detail: 'detail' in e ? e.detail : undefined },\n null,\n 2,\n )}\n </pre>\n </details>\n </li>\n ))}\n </ol>\n </div>\n );\n}\n","import { RobotOutlined } from '@ant-design/icons';\nexport default function AssistantAvatar() {\n return (\n <span className=\"research-assistant__avatar\" aria-hidden=\"true\">\n <RobotOutlined />\n </span>\n );\n}\n","import { useEffect, type RefObject } from 'react';\nimport { OverlayScrollbars, type OverlayScrollbars as Instance } from 'overlayscrollbars';\nimport 'overlayscrollbars/overlayscrollbars.css';\n\n/** React owns content; OverlayScrollbars owns only its overlay handles and listeners. */\nexport function useOverlayScrollbars(rootRef: RefObject<HTMLElement | null>, open: boolean) {\n useEffect(() => {\n const root = rootRef.current;\n if (!root || !open) return;\n const instances = new Map<HTMLElement, Instance>();\n let frame = 0;\n const refresh = () => {\n for (const [element, instance] of instances) {\n if (!root.contains(element)) {\n instance.destroy();\n instances.delete(element);\n }\n }\n for (const element of root.querySelectorAll<HTMLElement>(\n '.research-assistant__body,.research-assistant__json,.research-assistant__steps,.ant-tabs-content-holder,.ant-tabs-body-holder',\n )) {\n if (instances.has(element)) continue;\n instances.set(\n element,\n OverlayScrollbars(\n { target: element, elements: { viewport: element } },\n {\n overflow: { x: 'scroll', y: 'scroll' },\n scrollbars: {\n theme: 'os-theme-dark',\n autoHide: 'scroll',\n autoHideDelay: 1200,\n dragScroll: true,\n },\n },\n ),\n );\n }\n };\n const observer = new MutationObserver(() => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(refresh);\n });\n observer.observe(root, { childList: true, subtree: true });\n refresh();\n return () => {\n observer.disconnect();\n cancelAnimationFrame(frame);\n instances.forEach((instance) => instance.destroy());\n };\n }, [rootRef, open]);\n}\n","import { Button } from '@chenhui996/gg-ui';\nimport { useEffect, useRef, useState, type FC, type PointerEvent, type ReactNode } from 'react';\nimport { FullscreenExitOutlined, FullscreenOutlined, MinusOutlined } from '@ant-design/icons';\nimport AssistantAvatar from './AssistantAvatar';\nimport { useOverlayScrollbars } from './useOverlayScrollbars';\n\ninterface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\ninterface Props {\n open: boolean;\n onMinimize: () => void;\n children: ReactNode;\n developer: boolean;\n}\nconst margin = 12;\nconst fit = (rect: Rect): Rect => {\n const width = Math.min(Math.max(360, rect.width), window.innerWidth - margin * 2);\n const height = Math.min(Math.max(380, rect.height), window.innerHeight - margin * 2);\n return {\n width,\n height,\n x: Math.max(margin, Math.min(rect.x, window.innerWidth - width - margin)),\n y: Math.max(margin, Math.min(rect.y, window.innerHeight - height - margin)),\n };\n};\n\nconst FloatingPanel: FC<Props> = (props) => {\n const { open, onMinimize, children, developer } = props;\n const [rect, setRect] = useState(() =>\n fit({\n x: window.innerWidth - 564,\n y: window.innerHeight - 744,\n width: 540,\n height: 720,\n }),\n );\n const [expanded, setExpanded] = useState(false);\n const [moving, setMoving] = useState(false);\n const panel = useRef<HTMLElement>(null);\n useOverlayScrollbars(panel, open);\n const gesture = useRef<{ x: number; y: number; rect: Rect; resize: boolean } | null>(null);\n useEffect(() => {\n const resize = () => setRect((current) => fit(current));\n window.addEventListener('resize', resize);\n return () => window.removeEventListener('resize', resize);\n }, []);\n useEffect(() => {\n if (open) panel.current?.focus({ preventScroll: true });\n }, [open]);\n const start = (event: PointerEvent<HTMLElement>, resize = false) => {\n if (expanded || event.button !== 0 || (event.target as HTMLElement).closest('button')) return;\n event.preventDefault();\n event.currentTarget.setPointerCapture(event.pointerId);\n gesture.current = { x: event.clientX, y: event.clientY, rect, resize };\n setMoving(true);\n };\n const move = (event: PointerEvent<HTMLElement>) => {\n const current = gesture.current;\n if (!current) return;\n const dx = event.clientX - current.x,\n dy = event.clientY - current.y;\n setRect(\n fit(\n current.resize\n ? {\n ...current.rect,\n width: Math.min(current.rect.width + dx, window.innerWidth - current.rect.x - margin),\n height: Math.min(\n current.rect.height + dy,\n window.innerHeight - current.rect.y - margin,\n ),\n }\n : { ...current.rect, x: current.rect.x + dx, y: current.rect.y + dy },\n ),\n );\n };\n const end = () => {\n gesture.current = null;\n setMoving(false);\n };\n return (\n <section\n ref={panel}\n id=\"research-assistant-window\"\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby=\"research-assistant-title\"\n tabIndex={-1}\n hidden={!open}\n data-research-assistant\n className={`research-assistant research-assistant__window${expanded ? ' is-expanded' : ''}${moving ? ' is-moving' : ''}`}\n style={\n expanded ? undefined : { left: rect.x, top: rect.y, width: rect.width, height: rect.height }\n }\n onKeyDown={(event) => {\n if (event.key === 'Escape' && event.target === event.currentTarget) onMinimize();\n }}\n >\n <header className=\"research-assistant__header\">\n <div\n className=\"research-assistant__drag\"\n tabIndex={0}\n role=\"group\"\n aria-label=\"移动小蜜窗口,使用方向键调整位置\"\n onPointerDown={start}\n onPointerMove={move}\n onPointerUp={end}\n onPointerCancel={end}\n onLostPointerCapture={end}\n onDoubleClick={() => setExpanded((value) => !value)}\n onKeyDown={(event) => {\n if (\n expanded ||\n !['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.key)\n )\n return;\n event.preventDefault();\n const amount = event.shiftKey ? 40 : 10;\n setRect((current) =>\n fit({\n ...current,\n x:\n current.x +\n (event.key === 'ArrowLeft' ? -amount : event.key === 'ArrowRight' ? amount : 0),\n y:\n current.y +\n (event.key === 'ArrowUp' ? -amount : event.key === 'ArrowDown' ? amount : 0),\n }),\n );\n }}\n >\n <AssistantAvatar />\n <div>\n <h2 id=\"research-assistant-title\">\n 研发小蜜 <span>{developer ? '开发助手' : '问题反馈'}</span>\n </h2>\n <p>{expanded ? '详细分析 · 专注每一处线索' : '陪你定位问题,留住每一处线索'}</p>\n </div>\n </div>\n <div className=\"research-assistant__window-actions\">\n <Button\n type=\"text\"\n aria-label={expanded ? '还原小窗' : '放大分析'}\n title={expanded ? '还原小窗' : '放大分析'}\n onClick={() => setExpanded((value) => !value)}\n >\n {expanded ? <FullscreenExitOutlined /> : <FullscreenOutlined />}\n </Button>\n <Button type=\"text\" aria-label=\"最小化研发小蜜\" title=\"最小化\" onClick={onMinimize}>\n <MinusOutlined />\n </Button>\n </div>\n </header>\n {children}\n <footer className=\"research-assistant__footer\">\n <span>\n <i />\n 仅在本地内存中记录\n </span>\n <span>{expanded ? '详细分析模式' : '拖动顶部移动 · 右下角调整大小'}</span>\n </footer>\n {!expanded && (\n <div\n className=\"research-assistant__resize\"\n role=\"group\"\n tabIndex={0}\n aria-label=\"调整小蜜窗口大小,使用方向键\"\n onPointerDown={(event) => start(event, true)}\n onPointerMove={move}\n onPointerUp={end}\n onPointerCancel={end}\n onLostPointerCapture={end}\n onKeyDown={(event) => {\n if (!['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.key)) return;\n event.preventDefault();\n setRect((current) =>\n fit({\n ...current,\n width: Math.min(\n current.width +\n (event.key === 'ArrowLeft' ? -20 : event.key === 'ArrowRight' ? 20 : 0),\n window.innerWidth - current.x - margin,\n ),\n height: Math.min(\n current.height +\n (event.key === 'ArrowUp' ? -20 : event.key === 'ArrowDown' ? 20 : 0),\n window.innerHeight - current.y - margin,\n ),\n }),\n );\n }}\n />\n )}\n </section>\n );\n};\nexport default FloatingPanel;\n","import { Alert, Tag } from '@chenhui996/gg-ui';\nimport { DashboardOutlined, BulbOutlined, LinkOutlined } from '@ant-design/icons';\nimport { diagnosePerformance, megabytes, type PerformanceEvidence } from './performance';\n\nexport default function PerformancePanel({\n metrics,\n data,\n now,\n paused,\n offline,\n}: {\n metrics: Record<string, number>;\n data: PerformanceEvidence;\n now: number;\n paused: boolean;\n offline: boolean;\n}) {\n const issues = diagnosePerformance(metrics, data, now);\n const samples = data.heapSamples;\n const last = samples.at(-1);\n const min = Math.min(...samples.map((s) => s.used));\n const max = Math.max(...samples.map((s) => s.used));\n const firstTime = samples[0]?.time ?? now;\n const points = samples\n .map(\n (s) =>\n `${4 + ((s.time - firstTime) / Math.max(1, (last?.time ?? now) - firstTime)) * 592},${76 - ((s.used - min) / Math.max(1048576, max - min)) * 60}`,\n )\n .join(' ');\n return (\n <div className=\"research-assistant__section\">\n <div className=\"research-assistant__section-heading\">\n <span className=\"research-assistant__heading-icon\">\n <DashboardOutlined />\n </span>\n <div>\n <h3>性能诊断</h3>\n <p>加载体验、主线程卡顿与内存增长风险</p>\n </div>\n <Tag>{offline ? '快照分析' : paused ? '采集已暂停' : '自动监测中'}</Tag>\n </div>\n <Alert\n showIcon\n type={issues.length ? 'warning' : 'info'}\n message={issues.length ? `${issues.length} 项需要关注` : '当前采样未触发告警'}\n description={\n offline\n ? '仅分析这份快照中的数据;旧快照可能没有连续内存采样。'\n : '小蜜收起时也会监测;告警显示在入口,并记录到时间线。未触发规则不代表不存在性能问题。'\n }\n />\n <div className=\"research-assistant__issue-list\">\n {issues.map((issue) => (\n <section\n key={issue.id}\n className=\"research-assistant__card research-assistant__performance-issue\"\n >\n <div className=\"research-assistant__card-heading\">\n <h3>\n <Tag color={issue.severity === 'error' ? 'red' : 'orange'}>\n {issue.severity === 'error' ? '较高风险' : '需关注'}\n </Tag>\n {issue.title}\n </h3>\n </div>\n <p>{issue.evidence}</p>\n <details>\n <summary>\n <BulbOutlined /> 排查建议与触发依据\n </summary>\n <ol>\n {issue.suggestions.map((suggestion) => (\n <li key={suggestion}>{suggestion}</li>\n ))}\n </ol>\n <p className=\"research-assistant__hint\">{issue.rule}</p>\n <a href={issue.url} target=\"_blank\" rel=\"noreferrer\">\n <LinkOutlined /> 查看官方排查文档\n </a>\n </details>\n </section>\n ))}\n </div>\n <section className=\"research-assistant__card\">\n <div className=\"research-assistant__card-heading\">\n <h3>JS 堆内存趋势</h3>\n <span>{last ? megabytes(last.used) : '暂无采样'}</span>\n </div>\n {samples.length > 1 ? (\n <>\n <svg\n className=\"research-assistant__memory-chart\"\n viewBox=\"0 0 600 90\"\n role=\"img\"\n aria-label={`内存趋势,最低 ${megabytes(min)},最高 ${megabytes(max)},当前 ${megabytes(last!.used)}`}\n >\n <path d=\"M4 76 H596\" stroke=\"currentColor\" opacity=\".2\" />\n <polyline\n points={points}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n vectorEffect=\"non-scaling-stroke\"\n />\n </svg>\n <div className=\"research-assistant__card-heading\">\n <span>\n {new Date(firstTime).toLocaleTimeString()} · {megabytes(min)}\n </span>\n <span>\n {new Date(last!.time).toLocaleTimeString()} · 峰值 {megabytes(max)}\n </span>\n </div>\n </>\n ) : (\n <p className=\"research-assistant__hint\">\n {last\n ? '正在积累连续采样,持续增长风险至少需要观察 60 秒。'\n : '当前没有可用的连续内存数据。浏览器不支持 performance.memory、采集暂停或旧快照均可能导致此状态。'}\n </p>\n )}\n <p className=\"research-assistant__hint\">\n 前台每 5 秒采样,最多保留 15 分钟。JS\n 堆统计是近似值,不含全部页面内存;增长告警仅提供线索,需通过 DevTools 堆快照确认泄漏。\n </p>\n </section>\n <h3 className=\"research-assistant__subheading\">\n <DashboardOutlined /> 页面指标\n </h3>\n <div className=\"research-assistant__metrics\">\n {[\n ['TTFB', '首字节'],\n ['FCP', '首次内容绘制'],\n ['LCP', '最大内容绘制'],\n ['CLS', '布局偏移'],\n ['DOMContentLoaded', 'DOM 就绪'],\n ['load', '页面加载'],\n ['longTasks', '长任务次数'],\n ['longTaskDuration', '长任务总耗时'],\n ].map(([key, label]) => (\n <div key={key}>\n <span>\n {label} · {key}\n </span>\n <strong>\n {metrics[key] == null\n ? '不可用'\n : key === 'CLS'\n ? metrics[key].toFixed(4)\n : `${Math.round(metrics[key])}${key === 'longTasks' ? ' 次' : ' ms'}`}\n </strong>\n </div>\n ))}\n </div>\n <p className=\"research-assistant__hint\">\n LCP / CLS\n 是当前文档生命周期内的观测,不随业务路由切换重置;浏览器不支持的指标显示“不可用”,尚未采集完整\n INP。\n </p>\n </div>\n );\n}\n","import { useEffect, useRef, useState, useSyncExternalStore } from 'react';\nimport { Tabs, Button, Input, Tag, Alert, Empty, Badge, Tooltip } from '@chenhui996/gg-ui';\nimport {\n PauseOutlined,\n PlayCircleOutlined,\n DeleteOutlined,\n SafetyCertificateOutlined,\n DownloadOutlined,\n CameraOutlined,\n UploadOutlined,\n CloseOutlined,\n MessageOutlined,\n ExperimentOutlined,\n LineChartOutlined,\n ReadOutlined,\n HistoryOutlined,\n ApiOutlined,\n DashboardOutlined,\n DesktopOutlined,\n WarningOutlined,\n FieldTimeOutlined,\n EditOutlined,\n FolderOpenOutlined,\n} from '@ant-design/icons';\nimport {\n assistantRuntime,\n captureSnapshot,\n environment,\n freezeSnapshot,\n type Snapshot,\n} from './runtime';\nimport { downloadSnapshot, parseSnapshot } from './snapshot';\nimport AutomationPanel from './automation/AutomationPanel';\nimport TimelinePanel from './TimelinePanel';\nimport { recorder } from './automation/recorder';\nimport AssistantAvatar from './AssistantAvatar';\nimport FloatingPanel from './FloatingPanel';\nimport PerformancePanel from './PerformancePanel';\nimport { diagnosePerformance, emptyPerformance } from './performance';\nimport './research-assistant.less';\n\nfunction JsonView({ value }: { value: unknown }) {\n return <pre className=\"research-assistant__json\">{JSON.stringify(value, null, 2)}</pre>;\n}\nconst timestamp = (time: number | string) =>\n new Date(time).toLocaleTimeString('zh-CN', { hour12: false });\n\nexport interface ResearchAssistantProps {\n developer?: boolean;\n bridgeUrl?: string;\n}\nexport default function ResearchAssistant({\n developer = true,\n bridgeUrl = '/__laya-pilot',\n}: ResearchAssistantProps = {}) {\n const state = useSyncExternalStore(assistantRuntime.subscribe, assistantRuntime.getState);\n const recording = useSyncExternalStore(recorder.subscribe, recorder.getState);\n const [open, setOpen] = useState(false),\n [tab, setTab] = useState('feedback');\n const [diagnosticTab, setDiagnosticTab] = useState('timeline');\n const launcher = useRef<HTMLButtonElement>(null);\n const minimize = () => {\n setOpen(false);\n requestAnimationFrame(() => launcher.current?.focus({ preventScroll: true }));\n };\n const [description, setDescription] = useState(''),\n [notice, setNotice] = useState('');\n const [imported, setImported] = useState<Snapshot | null>(null);\n const [mode, setMode] = useState<'live' | 'frozen' | 'imported'>('live');\n const timelineSession = 0;\n const [info, setInfo] = useState(environment);\n const fileInput = useRef<HTMLInputElement>(null);\n useEffect(() => {\n if (!open) return;\n const timer = setInterval(() => setInfo(environment()), 2000);\n return () => clearInterval(timer);\n }, [open]);\n const source = mode === 'imported' ? imported : mode === 'frozen' ? state.frozen : null;\n const events = source?.events ?? state.events,\n requests = source?.requests ?? state.requests;\n const metrics = source?.metrics ?? state.metrics,\n browser = source?.environment ?? info;\n const failure = state.frozen;\n const freeze = () => {\n freezeSnapshot('用户手动截取现场');\n setMode('frozen');\n setNotice('已冻结现场。后续操作不会改变这份快照。');\n };\n const exportFile = () => {\n // A recorded error takes precedence over an export-time snapshot in feedback mode.\n const snapshot = source ?? state.frozen ?? captureSnapshot();\n downloadSnapshot(snapshot, description);\n setNotice(`已导出 ${timestamp(snapshot.capturedAt)} 的快照,请将 JSON 文件发送给研发人员。`);\n };\n const feedback = (\n <div className=\"research-assistant__section\">\n <div className=\"research-assistant__intro\">\n <div className=\"research-assistant__eyebrow\">\n <SafetyCertificateOutlined />\n 你的问题排查工作台\n </div>\n <span>问题现场,一键留存</span>\n <p>操作轨迹、接口与异常,在这里串成线索。</p>\n </div>\n <div className=\"research-assistant__stats\">\n <div>\n <strong>\n {events.length}\n <small>条</small>\n </strong>\n <span className=\"research-assistant__stat-label\">\n <HistoryOutlined />\n 操作与事件\n </span>\n </div>\n <div>\n <strong>\n {requests.length}\n <small>条</small>\n </strong>\n <span className=\"research-assistant__stat-label\">\n <ApiOutlined />\n 接口记录\n </span>\n </div>\n <div className={requests.some((r) => r.failed) ? 'has-errors' : ''}>\n <strong>\n {requests.filter((r) => r.failed).length}\n <small>条</small>\n </strong>\n <span className=\"research-assistant__stat-label\">\n <WarningOutlined />\n 失败接口\n </span>\n </div>\n </div>\n <div className=\"research-assistant__button-row research-assistant__actions\">\n <Button type=\"primary\" icon={<CameraOutlined />} onClick={freeze}>\n 截取当前现场\n </Button>\n <Button icon={<DownloadOutlined />} onClick={exportFile}>\n 导出快照 JSON\n </Button>\n </div>\n <Alert\n type={failure ? 'warning' : 'info'}\n showIcon\n message={\n failure\n ? `已保留现场 · ${timestamp(failure.capturedAt)} · ${failure.reason}`\n : '异常时自动保留现场,刷新或关闭前请导出。'\n }\n />\n <div className=\"research-assistant__field\">\n <label htmlFor=\"research-feedback\">\n <EditOutlined />\n 问题描述\n </label>\n <Input.TextArea\n id=\"research-feedback\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n maxLength={1000}\n showCount\n rows={3}\n placeholder=\"例如:修改表单后点击保存,出现错误提示。\"\n />\n </div>\n <p className=\"research-assistant__hint\">\n {source\n ? `当前查看:${source.reason} · ${timestamp(source.capturedAt)}`\n : failure\n ? '直接导出会使用最近保留的现场。需要最新状态时,请先手动截取。'\n : '当前没有冻结现场,直接导出会截取此刻状态。'}\n </p>\n <details>\n <summary>快照包含哪些内容</summary>\n <p>\n 最近 15 分钟内最多 300 条事件、60\n 条接口记录,页面地址与布局信息、浏览器环境、性能指标及已脱敏的 JSON\n 正文。页面状态快照不包含屏幕截图或输入框值。\n </p>\n <p>\n 数据只在当前页面内存中保存,不自动上传。字段脱敏无法识别所有业务敏感内容,分享前可先查看导出的\n JSON。\n </p>\n </details>\n </div>\n );\n const timeline = (\n <TimelinePanel\n key={timelineSession + mode + (source?.capturedAt ?? 'live')}\n events={events}\n onDraft={() => setTab('automation')}\n />\n );\n const network = (\n <div className=\"research-assistant__section\">\n <div className=\"research-assistant__section-heading\">\n <span className=\"research-assistant__heading-icon\">\n <ApiOutlined />\n </span>\n <div>\n <h3>接口记录</h3>\n <p>查看请求状态、耗时与响应详情。</p>\n </div>\n <Tag>{requests.length} 条</Tag>\n </div>\n <p className=\"research-assistant__hint\">\n Fetch / XHR · 正文最多读取 16 KB · 认证接口不采集正文 ·\n 耗时为响应头到达(Fetch)或请求结束(XHR)\n </p>\n {!requests.length && <Empty description=\"暂无接口记录\" />}\n {requests\n .slice()\n .sort((a, b) => a.time - b.time)\n .map((r) => (\n <details key={r.id} className=\"research-assistant__request\">\n <summary>\n <span className=\"research-assistant__request-meta\">\n <Tag color={r.failed ? 'red' : 'green'}>{r.status || '失败'}</Tag>\n <b>{r.method}</b>{' '}\n <span>\n <FieldTimeOutlined />\n {Math.round(r.duration)} ms\n </span>\n </span>\n <span className=\"research-assistant__request-url\">{r.url}</span>\n </summary>\n <JsonView value={r} />\n </details>\n ))}\n </div>\n );\n const performanceData = source ? (source.performance ?? emptyPerformance()) : state.performance;\n const performanceNow = source ? Date.parse(source.capturedAt) : state.performanceUpdatedAt;\n const performanceIssues = diagnosePerformance(metrics, performanceData, performanceNow);\n const livePerformanceCount = diagnosePerformance(\n state.metrics,\n state.performance,\n state.performanceUpdatedAt,\n ).length;\n const performancePanel = (\n <PerformancePanel\n metrics={metrics}\n data={performanceData}\n now={performanceNow}\n paused={state.paused}\n offline={Boolean(source)}\n />\n );\n const dataPanel = (\n <div className=\"research-assistant__section\">\n <div className=\"research-assistant__section-heading\">\n <span className=\"research-assistant__heading-icon\">\n <DesktopOutlined />\n </span>\n <div>\n <h3>环境与数据</h3>\n <p>浏览器环境和现场信息,集中查看。</p>\n </div>\n </div>\n <Alert\n showIcon\n type=\"info\"\n message=\"只读浏览器信息;不采集 Cookie、localStorage、sessionStorage 的值。\"\n />\n <JsonView value={browser} />\n {source && (\n <>\n <h3>现场页面状态</h3>\n <JsonView value={source.page} />\n </>\n )}\n </div>\n );\n const knowledge = (\n <div className=\"research-assistant__section\">\n <Empty description=\"知识库问答待接入\" />\n <p className=\"research-assistant__hint\">\n 已预留问答适配接口。后续可接入使用手册、常见问题和研发文档;当前不会发送问题或快照到任何服务。\n </p>\n </div>\n );\n return (\n <div data-research-assistant>\n <div\n className={`research-assistant__dock${recording.recording ? ' is-recording' : ''}`}\n hidden={open}\n >\n <Tooltip\n title={\n recording.recording\n ? `研发小蜜 · 录制中 ${recording.draft.steps.length} 步`\n : livePerformanceCount\n ? `研发小蜜 · ${livePerformanceCount} 项性能告警`\n : state.frozen\n ? '研发小蜜 · 已保留异常现场'\n : '研发小蜜'\n }\n >\n <Badge\n dot={recording.recording || Boolean(state.frozen) || livePerformanceCount > 0}\n color={recording.recording ? 'red' : 'orange'}\n offset={[-5, 5]}\n >\n <Button\n ref={launcher}\n type=\"primary\"\n shape=\"circle\"\n className=\"research-assistant__launcher\"\n aria-label=\"打开研发小蜜\"\n aria-expanded={open}\n aria-controls=\"research-assistant-window\"\n onClick={() => {\n setOpen(true);\n setInfo(environment());\n }}\n icon={<AssistantAvatar />}\n />\n </Badge>\n </Tooltip>\n <span className=\"research-assistant__sr-only\" role=\"status\">\n {recording.recording\n ? `录制中 ${recording.draft.steps.length} 步`\n : livePerformanceCount\n ? `${livePerformanceCount} 项性能告警`\n : state.frozen\n ? '已保留异常现场'\n : ''}\n </span>\n </div>\n <FloatingPanel open={open} onMinimize={minimize} developer={developer}>\n <div data-research-assistant className=\"research-assistant__body\">\n <div className=\"research-assistant__toolbar\">\n <span>\n <i className={state.paused ? 'paused' : ''} />\n {source ? '查看离线现场' : state.paused ? '采集已暂停' : '正在采集 · 仅内存'}\n </span>\n <div className=\"research-assistant__button-row research-assistant__toolbar-actions\">\n <Button\n type=\"text\"\n size=\"small\"\n icon={state.paused ? <PlayCircleOutlined /> : <PauseOutlined />}\n onClick={() => assistantRuntime.pause(!state.paused)}\n >\n {state.paused ? '继续采集' : '暂停采集'}\n </Button>\n <Button\n size=\"small\"\n type=\"text\"\n icon={<DeleteOutlined />}\n onClick={() => {\n assistantRuntime.clear();\n setMode('live');\n setImported(null);\n setNotice('内存记录已清空');\n }}\n >\n 清空记录\n </Button>\n </div>\n </div>\n {notice && <Alert closable message={notice} type=\"info\" onClose={() => setNotice('')} />}\n {source?.feedback && (\n <Alert message=\"快照中的问题描述\" description={source.feedback} type=\"info\" />\n )}\n {developer && (\n <div className=\"research-assistant__sources\">\n <Button\n size=\"small\"\n icon={<HistoryOutlined />}\n type={mode === 'live' ? 'primary' : 'default'}\n onClick={() => setMode('live')}\n >\n 实时记录\n </Button>\n <Button\n size=\"small\"\n icon={<CameraOutlined />}\n disabled={!state.frozen}\n type={mode === 'frozen' ? 'primary' : 'default'}\n onClick={() => setMode('frozen')}\n >\n 已冻结现场\n </Button>\n <Button\n size=\"small\"\n icon={<UploadOutlined />}\n onClick={() => fileInput.current?.click()}\n >\n 导入 JSON\n </Button>\n {imported && (\n <>\n <Button\n size=\"small\"\n icon={<FolderOpenOutlined />}\n type={mode === 'imported' ? 'primary' : 'default'}\n onClick={() => setMode('imported')}\n >\n 导入的现场\n </Button>\n <Button\n aria-label=\"关闭导入现场\"\n size=\"small\"\n icon={<CloseOutlined />}\n onClick={() => {\n setImported(null);\n setMode('live');\n }}\n />\n </>\n )}\n <input\n ref={fileInput}\n hidden\n type=\"file\"\n accept=\".json,application/json\"\n onChange={async (e) => {\n const file = e.target.files?.[0];\n e.target.value = '';\n if (!file) return;\n try {\n if (file.size > 2 * 1024 * 1024) throw Error('快照不能超过 2 MB');\n setImported(parseSnapshot(await file.text()));\n setMode('imported');\n setTab('diagnostics');\n setDiagnosticTab('timeline');\n setNotice('已载入本地快照,未上传文件');\n } catch (error) {\n setNotice(error instanceof Error ? error.message : '快照读取失败');\n }\n }}\n />\n </div>\n )}\n {developer &&\n !source &&\n livePerformanceCount > 0 &&\n !(tab === 'diagnostics' && diagnosticTab === 'performance') && (\n <Alert\n showIcon\n type=\"warning\"\n message={`${livePerformanceCount} 项性能告警`}\n action={\n <Button\n size=\"small\"\n onClick={() => {\n setTab('diagnostics');\n setDiagnosticTab('performance');\n }}\n >\n 查看诊断\n </Button>\n }\n />\n )}\n <Tabs\n className=\"research-assistant__main-tabs\"\n activeKey={tab}\n onChange={setTab}\n items={[\n {\n key: 'feedback',\n label: '问题反馈',\n icon: <MessageOutlined aria-hidden />,\n children: feedback,\n },\n ...(developer\n ? [\n {\n key: 'automation',\n label: '自动化测试',\n icon: <ExperimentOutlined aria-hidden />,\n children: <AutomationPanel close={minimize} bridgeUrl={bridgeUrl} />,\n },\n {\n key: 'diagnostics',\n label: '诊断',\n icon: <LineChartOutlined aria-hidden />,\n children: (\n <Tabs\n className=\"research-assistant__diagnostic-tabs\"\n activeKey={diagnosticTab}\n onChange={setDiagnosticTab}\n items={[\n {\n key: 'timeline',\n label: '时间线',\n icon: <HistoryOutlined aria-hidden />,\n children: timeline,\n },\n {\n key: 'network',\n label: '接口',\n icon: <ApiOutlined aria-hidden />,\n children: network,\n },\n {\n key: 'performance',\n label: performanceIssues.length\n ? `性能 (${performanceIssues.length})`\n : '性能',\n icon: <DashboardOutlined aria-hidden />,\n children: performancePanel,\n },\n {\n key: 'data',\n label: '环境与数据',\n icon: <DesktopOutlined aria-hidden />,\n children: dataPanel,\n },\n ]}\n />\n ),\n },\n ]\n : []),\n {\n key: 'knowledge',\n label: '知识问答',\n icon: <ReadOutlined aria-hidden />,\n children: knowledge,\n },\n ]}\n />\n </div>\n </FloatingPanel>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;ACYA,SAAwB,GAAgB,EACtC,YACA,UACA,aACA,aACA,WACA,eAQC;CACD,IAAM,IAAK,EAAM,GACX,CAAC,GAAO,KAAY,EACxB,KAAW;EACT,MAAM;EACN,QAAQ;EACR,UAAU;EACV,UAAU;EACV,SAAS;CACX,CACF,GACM,CAAC,GAAO,KAAY,EAAS,CAAQ,GACrC,CAAC,GAAO,KAAY,EAAS,EAAE,GAC/B,KAAS,MAA8B,GAAU,OAAa;EAAE,GAAG;EAAS,GAAG;CAAM,EAAE;CAC7F,OACE,kBAAC,OAAD;EACE,WAAU;EACV,cAAY,IAAU,WAAW;YAFnC;GAIE,kBAAC,MAAD;IAAI,WAAU;cAAd,CACE,kBAAC,GAAD,CAAsB,CAAA,GACrB,IAAU,SAAS,MAClB;;GACJ,kBAAC,KAAD;IAAG,WAAU;cAA2B;GAErC,CAAA;GACH,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,SAAD;KAAO,SAAS,GAAG,EAAG;eAAQ;IAAW,CAAA,GACzC,kBAAC,GAAD;KACE,IAAI,GAAG,EAAG;KACV,aAAY;KACZ,OAAO,EAAM;KACb,WAAW;KACD;KACV,WAAW,MAAM,EAAM,EAAE,MAAM,EAAE,OAAO,MAAM,CAAC;IAChD,CAAA,CACE;;GACJ,CAAC,KACA,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,SAAD;KAAO,SAAS,GAAG,EAAG;eAAY;IAAW,CAAA,GAC7C,kBAAC,GAAD;KACE,IAAI,GAAG,EAAG;KACV,OAAO;KACG;KACV,UAAU;KACV,SAAS,CACP;MAAE,OAAO;MAAG,OAAO;KAAS,GAC5B,GAAG,EAAM,KAAK,GAAM,OAAW;MAC7B,OAAO,IAAQ;MACf,OAAO,KAAK,IAAQ,EAAE,SAAS,EAAK,WAAW,QAAQ,EAAK,QAAQ,SAAS,EAAK,SAAS,EAAK;KAClG,EAAE,CACJ;IACD,CAAA,CACE;;GAEP,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,SAAD;MAAO,SAAS,GAAG,EAAG;gBAAU;KAAW,CAAA,GAC3C,kBAAC,GAAD;MACE,IAAI,GAAG,EAAG;MACV,OAAO,EAAM;MACH;MACV,SAAS,OAAO,QAAQ,EAAA,gBAAgB,EAAE,KAAK,CAAC,GAAO,QAAY;OAAE;OAAO;MAAM,EAAE;MACpF,WAAW,MACT,EAAM;OACJ;OACA,WAAA,GAAA,EAAA,cAAuB,CAAM,EAAE;OAC/B,UAAU,MAAW,kBAAkB,MAAM;OAC7C,UAAU,EAAM,YAAY;MAC9B,CAAC;KAEJ,CAAA,CACE;QACL,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,SAAD;MAAO,SAAS,GAAG,EAAG;gBAAY;KAAW,CAAA,GAC7C,kBAAC,GAAD;MACE,IAAI,GAAG,EAAG;MACV,OAAO,EAAM;MACH;MACV,WAAW,MAAa,EAAM,EAAE,YAAS,CAAC;MAC1C,UAAA,GAAA,EAAA,cAAsB,EAAM,MAAM,EAAE,KAAK,OAAW;OAClD;OACA,OAAO,EAAA,mBAAmB;MAC5B,EAAE;KACH,CAAA,CACE;MACF;;GACJ,EAAM,WAAW,eAChB,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,SAAD;MAAO,SAAS,GAAG,EAAG;gBAAY;KAAgB,CAAA;KAClD,kBAAC,GAAD;MACE,IAAI,GAAG,EAAG;MACV,OAAO,EAAM;MACb,WAAW;MACX,aAAY;MACF;MACV,WAAW,MAAM,EAAM,EAAE,UAAU,EAAE,OAAO,MAAM,CAAC;KACpD,CAAA;KACD,kBAAC,KAAD;MAAG,WAAU;gBAA2B;KAErC,CAAA;IACA;;GAEN,EAAM,WAAW,mBAChB,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,SAAD;KAAO,SAAS,GAAG,EAAG;eAAY;IAAU,CAAA,GAC5C,kBAAC,GAAD;KACE,IAAI,GAAG,EAAG;KACV,OAAO,EAAM;KACb,WAAW;KACX,aAAa,EAAM,WAAW,kBAAkB,SAAS;KAC/C;KACV,WAAW,MAAM,EAAM,EAAE,UAAU,EAAE,OAAO,MAAM,CAAC;IACpD,CAAA,CACE;;GAEP,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,SAAD;KAAO,SAAS,GAAG,EAAG;eAAW;IAAiB,CAAA,GAClD,kBAAC,GAAD;KACE,IAAI,GAAG,EAAG;KACV,KAAK;KACL,KAAK;KACL,MAAM;KACN,OAAO,EAAM;KACH;KACV,WAAW,MAAY,EAAM,EAAE,SAAS,KAAW,IAAM,CAAC;IAC3D,CAAA,CACE;;GACJ,KAAS,kBAAC,GAAD;IAAO,UAAA;IAAS,MAAK;IAAQ,SAAS;GAAQ,CAAA;GACxD,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KACE,MAAM,kBAAC,GAAD,CAAe,CAAA;KACrB,MAAK;KACK;KACV,eAAe;MACb,IAAI;OACF,IAAM,KAAA,GAAA,EAAA,gBAA2B,CAAK;OACtC,IAAI,EAAU,UACZ,IAAI;QACF,SAAS,cAAc,EAAU,QAAQ;OAC3C,QAAQ;QACN,MAAM,MAAM,oBAAoB;OAClC;OAEF,EAAO,GAAW,KAAK,IAAI,GAAO,EAAM,MAAM,CAAC;MACjD,SAAS,GAAG;OACV,EAAS,aAAa,QAAQ,EAAE,UAAU,QAAQ;MACpD;KACF;eACD;IAEO,CAAA,GACR,kBAAC,GAAD;KAAQ,SAAS;eAAU;IAAU,CAAA,CAClC;;EACF;;AAET;;;ACjLA,SAAwB,GAAe,EACrC,SACA,aACA,cAKC;CACD,IAAM,IAAS,EAAM,GACf,CAAC,GAAM,KAAW,EAAuB,OAAO,GAChD,CAAC,GAAU,KAAe,EAAS,EAAE,GACzC,CAAC,GAAO,KAAY,EAAS,EAAE,GAC/B,CAAC,GAAO,KAAY,EAAS,EAAE,GAC3B,CAAC,GAAS,KAAc,EAAS,EAAI,GACzC,CAAC,GAAO,KAAY,EAAS,EAAE;CACjC,OACE,kBAAC,WAAD;EAAS,WAAU;YAAnB;GACE,kBAAC,WAAD,EAAA,UAAS,WAAiB,CAAA;GAC1B,kBAAC,KAAD;IAAG,WAAU;cAA2B;GAGrC,CAAA;GACH,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,SAAD;OAAO,SAAS;iBAAQ;MAAW,CAAA,GACnC,kBAAC,GAAD;OACE,IAAI;OACJ,cAAW;OACX,OAAO;OACG;OACV,UAAU;OACV,OAAO,EAAE,OAAO,OAAO;OACvB,SAAS;QACP;SAAE,OAAO;SAAS,OAAO;QAAK;QAC9B;SAAE,OAAO;SAAQ,OAAO;QAAK;QAC7B;SAAE,OAAO;SAAU,OAAO;QAAS;QACnC;SAAE,OAAO;SAAS,OAAO;QAAK;QAC9B;SAAE,OAAO;SAAS,OAAO;QAAK;QAC9B;SAAE,OAAO;SAAe,OAAO;QAAQ;OACzC;MACD,CAAA,CACE;;KACJ,MAAS,iBACR,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;MACE,QAAQ,kBAAC,GAAD,CAAe,CAAA;MACvB,cAAW;MACX,aAAY;MACZ,WAAW;MACX,OAAO;MACG;MACV,WAAW,MAAM,EAAY,EAAE,OAAO,KAAK;KAC5C,CAAA,GACD,kBAAC,GAAD;MACE,QAAQ,kBAAC,IAAD,CAAe,CAAA;MACvB,cAAW;MACX,aAAY;MACZ,WAAW;MACX,OAAO;MACG;MACV,WAAW,MAAM,EAAS,EAAE,OAAO,KAAK;KACzC,CAAA,CACD,EAAA,CAAA;KAEH;MAAC;MAAQ;MAAU;MAAS;KAAa,EAAE,SAAS,CAAI,KACvD,kBAAC,GAAD;MACE,cAAW;MACX,aAAa,MAAS,UAAU,yBAAyB;MACzD,WAAW;MACJ;MACG;MACV,WAAW,MAAM,EAAS,EAAE,OAAO,KAAK;KACzC,CAAA;KAEF,MAAS,WACR,kBAAC,SAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MACE,MAAK;MACI;MACC;MACV,WAAW,MAAM,EAAW,EAAE,OAAO,OAAO;KAC7C,CAAA,GAAC,IAEG,EAAA,CAAA;KAET,kBAAC,GAAD;MACE,MAAM,kBAAC,IAAD,CAAgB,CAAA;MACZ;MACV,eAAe;OACb,IAAI;QACF,IAAI,MAAS,eAAe;SAC1B,IAAI,CAAC,EAAS,KAAK,KAAK,CAAC,EAAM,KAAK,GAAG,MAAM,MAAM,YAAY;SAC/D,SAAS,cAAc,CAAQ;QACjC;QACA,IAAI,MAAS,iBAAiB,CAAC,EAAM,KAAK,GAAG,MAAM,MAAM,WAAW;QACpE,IAAI,MAAS,WAAW,CAAC;SAAC;SAAS;SAAU;QAAK,EAAE,SAAS,CAAK,GAChE,MAAM,MAAM,UAAU;QAWxB,AAVA,EAAQ;SACN;SACA,cAAc;SACd,GAAI,EAAK,gBAAgB,EAAE,eAAe,EAAK,cAAc,IAAI,CAAC;SAClE,GAAI,MAAS,gBAET,CAAC,IADD,EAAE,QAAQ;UAAE,UAAU,EAAS,KAAK;UAAG,OAAO,EAAM,KAAK;SAAE,EAAE;SAEjE,GAAI;UAAC;UAAQ;UAAU;UAAS;SAAa,EAAE,SAAS,CAAI,IAAI,EAAE,SAAM,IAAI,CAAC;SAC7E,GAAI,MAAS,UAAU,EAAE,WAAQ,IAAI,CAAC;QACxC,CAAC,GACD,EAAS,EAAE;OACb,SAAS,GAAO;QACd,EAAS,aAAiB,QAAQ,EAAM,UAAU,MAAM;OAC1D;MACF;gBACD;KAEO,CAAA;KACP,KAAS,kBAAC,QAAD;MAAM,MAAK;gBAAS;KAAY,CAAA;IACvC;;EACE;;AAEb;;;ACjGA,IAAM,KAAsC;CAC1C,OAAO;CACP,MAAM;CACN,QAAQ;CACR,OAAO;CACP,OAAO;CACP,eAAe;CACf,QAAQ;CACR,aAAa;AACf,GACM,KAAqB;CAAE,OAAO;CAAQ,MAAM;CAAG,OAAO;CAAG,SAAS;AAAO;AAC/E,eAAe,GAAO,GAAc,GAAgB,GAAgB;CAClE,IAAM,IAAW,MAAM,MACrB,GAAG,EAAK,QAAQ,OAAO,EAAE,EAAE,GAAG,KAC9B,MAAS,KAAA,IACL,CAAC,IACD;EACE,QAAQ;EACR,SAAS;GAAE,gBAAgB;GAAoB,gBAAgB;EAAmB;EAClF,MAAM,KAAK,UAAU,CAAI;CAC3B,CACN;CACA,IAAI,CAAC,EAAS,QAAQ,IAAI,cAAc,GAAG,SAAS,kBAAkB,GACpE,MAAM,MAAM,sBAAsB;CACpC,IAAM,IAAS,MAAM,EAAS,KAAK;CACnC,IAAI,CAAC,EAAS,IAAI,MAAM,MAAM,EAAO,WAAW,WAAW;CAC3D,OAAO;AACT;AAEA,SAAwB,GAAgB,EACtC,UACA,gBAIC;CACD,IAAM,IAAQ,EAAqB,EAAS,WAAW,EAAS,QAAQ,GAClE,CAAC,GAAQ,KAAa,EAAS,EAAE,GACjC,CAAC,GAAe,KAAoB,EACxC,IACF,GACM,IAAgB,EAAuB,IAAI,GAC3C,KAAiB,GAAkB,MAAkB;EAEzD,AADA,EAAiB;GAAE;GAAU;EAAK,CAAC,GACnC,4BACE,EAAc,SAAS,eAAe;GAAE,UAAU;GAAU,OAAO;EAAU,CAAC,CAChF;CACF,GACM,CAAC,GAAK,KAAU,EAAoB,EAAO,GAC3C,CAAC,GAAW,KAAgB,EAAS,EAAK,GAC1C,CAAC,GAAS,KAAc,EAAS,EAAK,GACtC,CAAC,GAAO,KAAY,EAAS,GAAI,GACjC,KAAO,EAAyB,IAAI;CAC1C,QAAgB;EACd,IAAI,IAAW,IACX,GACE,IAAO,YAAY;GACvB,IAAI;IACF,IAAM,IAAS,MAAM,GAAO,GAAW,QAAQ;IAC/C,AAAK,MACH,EAAO,CAAM,GACb,EAAa,EAAO,cAAc,EAAK;GAE3C,QAAQ;IACN,AAAK,KAAU,EAAa,EAAK;GACnC,UAAU;IACR,AAAK,MAAU,IAAQ,WAAW,GAAM,IAAI;GAC9C;EACF;EAEA,OADA,EAAU,SACG;GAEX,AADA,IAAW,IACX,aAAa,CAAK;EACpB;CACF,GAAG,CAAC,CAAS,CAAC;CACd,IAAM,IAAO,KAAW,EAAI,UAAU,WAChC,IAAM,OAAO,MAAmC;EACpD,IAAI;GAEF,AADA,EAAU,EAAE,GACZ,MAAM,EAAG;EACX,SAAS,GAAO;GACd,EAAU,aAAiB,QAAQ,EAAM,UAAU,MAAM;EAC3D;CACF,GACM,MAAc,GAAe,MACjC,EAAS,KAAK;EACZ,GAAG,EAAM;EACT,OAAO,EAAM,MAAM,MAAM,KAAK,GAAM,MAClC,MAAM,IAAQ;GAAE,GAAG;GAAM,GAAG;GAAO,cAAc;EAAK,IAAI,CAC5D;CACF,CAAC;CACH,OACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD;KAAM,WAAU;eACd,kBAAC,GAAD,CAAsB,CAAA;IAClB,CAAA,GACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAI,cAAe,CAAA,GACnB,kBAAC,KAAD,EAAA,UAAG,mBAAmB,CAAA,CACnB,EAAA,CAAA,CACF;;GACJ,CAAC,KACA,kBAAC,GAAD;IAAO,MAAK;IAAU,SAAQ;GAA2B,CAAA;GAE1D,KAAU,kBAAC,GAAD;IAAO,UAAA;IAAS,eAAe,EAAU,EAAE;IAAG,MAAK;IAAO,SAAS;GAAS,CAAA;GACvF,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,WAAD;MACE,WAAU;MACV,cAAW;gBAFb;OAIE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,MAAD,EAAA,UAAA,CACE,kBAAC,GAAD,CAAsB,CAAA,GAAC,MAErB,EAAA,CAAA,GACJ,kBAAC,GAAD;SAAK,OAAO,EAAM,YAAY,QAAQ;mBAAtC;UACG,EAAM,YAAY,QAAQ;UAAM;UAAI,EAAM,MAAM,MAAM;UAAO;SAC3D;UACF;;OACL,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SACE,MAAM,kBAAC,GAAD,CAAsB,CAAA;SAC5B,MAAK;SACL,UAAU,KAAQ,EAAM;SACxB,eACE,KAAK,QAAU;UAGb,AAFA,EAAiB,IAAI,GACrB,EAAS,MAAM,GACf,EAAM;SACR,CAAC;mBAEJ;QAEO,CAAA,GACR,kBAAC,GAAD;SACE,MAAM,kBAAC,GAAD,CAAe,CAAA;SACrB,UAAU,CAAC,EAAM;SACjB,eAAe,EAAS,KAAK;mBAC9B;QAEO,CAAA,CACL;;OACL,kBAAC,WAAD;QAAS,WAAU;kBAAnB;SACE,kBAAC,WAAD,EAAA,UAAA,CACE,kBAAC,IAAD,CAAqB,CAAA,GAAC,WAEf,EAAA,CAAA;SACT,kBAAC,KAAD;UAAG,WAAU;oBAA2B;SAErC,CAAA;SACH,kBAAC,KAAD;UAAG,WAAU;oBAA2B;SAGrC,CAAA;QACI;;MACF;;KACT,kBAAC,WAAD;MACE,WAAU;MACV,cAAW;gBAFb;OAIE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,MAAD,EAAA,UAAA,CACE,kBAAC,IAAD,CAAe,CAAA,GAAC,MAEd,EAAA,CAAA,GACJ,kBAAC,QAAD,EAAA,UAAA,CAAO,EAAM,MAAM,MAAM,QAAO,MAAU,EAAA,CAAA,CACvC;;OACL,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,SAAD;SAAO,SAAQ;mBAAsB;QAAW,CAAA,GAChD,kBAAC,GAAD;SACE,IAAG;SACH,QAAQ,kBAAC,GAAD,CAAmB,CAAA;SAC3B,cAAW;SACX,OAAO,EAAM,MAAM;SACnB,WAAW;SACX,UAAU,EAAM,aAAa;SAC7B,WAAW,MAAM,EAAS,KAAK;UAAE,GAAG,EAAM;UAAO,MAAM,EAAE,OAAO;SAAM,CAAC;QACxE,CAAA,CACE;;OACJ,CAAC,EAAM,MAAM,MAAM,UAClB,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,GAAD,CAAmB,CAAA;SACnB,kBAAC,QAAD,EAAA,UAAM,UAAa,CAAA;SACnB,kBAAC,KAAD,EAAA,UAAG,gBAAgB,CAAA;QAChB;;OAEP,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAM,MAAM,MAAM,KAAK,GAAM,MAC5B,kBAAC,MAAD,EAAA,UAAA;SACE,kBAAC,OAAD;UAAK,WAAU;oBAAf;WACE,kBAAC,QAAD;YAAM,WAAU;sBACb,OAAO,IAAQ,CAAC,EAAE,SAAS,GAAG,GAAG;WAC9B,CAAA;WACN,kBAAC,GAAD;YAAK,OAAO,EAAK,SAAS,gBAAgB,QAAQ;sBAAS,GAAM,EAAK;WAAW,CAAA;WACjF,kBAAC,UAAD,EAAA,UAAS,EAAK,WAAW,QAAQ,EAAK,QAAQ,SAAS,EAAK,MAAc,CAAA;WACzE,EAAK,iBAAiB,kBAAC,GAAD,EAAA,UAAA,CAAK,SAAM,EAAK,aAAmB,EAAA,CAAA;WACzD,EAAK,gBAAgB,kBAAC,GAAD;YAAK,OAAM;sBAAS;WAAS,CAAA;UAChD;;SACJ,EAAK,aACJ,kBAAC,OAAD;UAAK,WAAU;oBAAf;WACE,kBAAC,GAAD;YAAK,OAAM;sBAAS,EAAA,iBAAiB,EAAK,UAAU;WAAa,CAAA;WACjE,kBAAC,QAAD,EAAA,UAAA;YACG,EAAA,mBAAmB,EAAK,UAAU;YAAW;YAC7C,EAAK,UAAU,aAAa,KAAK,SAAS,EAAK,UAAU;WACtD,EAAA,CAAA;WACN,kBAAC,QAAD;YAAM,WAAU;sBAAhB;aAA2C;aACnC,EAAK,UAAU,UAAU;aAAK;YAChC;;WACL,EAAK,UAAU,YAAY,kBAAC,QAAD,EAAA,UAAO,EAAK,UAAU,SAAe,CAAA;UAC9D;;SAEN,EAAK,SAAS,iBACb,kBAAC,IAAD;UAEQ;UACN,UAAU,EAAM,aAAa;UAC7B,UAAU,MACR,EAAS,KAAK;WACZ,GAAG,EAAM;WACT,OAAO,EAAM,MAAM,MAAM,KAAK,GAAS,MACrC,MAAM,IAAQ,IAAc,CAC9B;UACF,CAAC;SAEJ,GAXM,KAAK,UAAU,CAAI,CAWzB;SAEF,EAAK,UAAU,KAAA,KAAa,EAAK,SAAS,iBACzC,kBAAC,GAAD;UACE,cAAY,KAAK,IAAQ,EAAE;UAC3B,OAAO,EAAK;UACZ,WAAW;UACX,UAAU,EAAM,aAAa;UAC7B,WAAW,MAAM,GAAW,GAAO,EAAE,OAAO,EAAE,OAAO,MAAM,CAAC;SAC7D,CAAA;SAEF,EAAK,SAAS,WAAW,kBAAC,QAAD,EAAA,UAAO,EAAK,UAAU,OAAO,OAAa,CAAA;SACnE,EAAK,UACJ,kBAAC,WAAD,EAAA,UAAA,CACE,kBAAC,WAAD,EAAA,UAAS,OAAa,CAAA,GACtB,kBAAC,QAAD,EAAA,UAAO,EAAK,OAAO,SAAe,CAAA,CAC3B,EAAA,CAAA;SAEX,kBAAC,OAAD;UAAK,WAAU;oBAAf;WACE,kBAAC,GAAD;YACE,MAAK;YACL,MAAM,kBAAC,GAAD,CAAsB,CAAA;YAC5B,UACE,EAAM,aACN,KACC,CAAC,EAAK,aAAa,EAAM,MAAM,MAAM,UAAU;YAElD,eAAe,EAAc,IAAQ,GAAG,EAAK,YAAY,IAAQ,KAAA,CAAS;sBAEzE,EAAK,YAAY,SAAS;WACrB,CAAA;WACR,kBAAC,GAAD;YACE,MAAM,kBAAC,GAAD,CAAe,CAAA;YACrB,MAAK;YACL,UAAU,EAAM,aAAa,KAAQ,EAAM,MAAM,MAAM,UAAU;YACjE,eAAe;aAEb,AADA,EAAiB,IAAI,GACrB,EAAS,KAAK;cACZ,GAAG,EAAM;cACT,OAAO;eACL,GAAG,EAAM,MAAM,MAAM,MAAM,GAAG,CAAK;eACnC;gBAAE,MAAM;gBAAe,OAAO;eAAY;eAC1C,GAAG,EAAM,MAAM,MAAM,MAAM,CAAK;cAClC;aACF,CAAC;YACH;sBAdF;aAeC;aACK,IAAQ;aAAE;YACR;;WACR,kBAAC,GAAD;YACE,MAAM,kBAAC,IAAD,CAAiB,CAAA;YACvB,QAAA;YACA,MAAK;YACL,UAAU,EAAM,aAAa;YAC7B,eAAe;aAEb,AADA,EAAiB,IAAI,GACrB,EAAS,KAAK;cACZ,GAAG,EAAM;cACT,OAAO,EAAM,MAAM,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAK;aACvD,CAAC;YACH;sBAXF;aAYC;aACM,IAAQ;aAAE;YACT;;UACL;;QACH,EAAA,GArGK,CAqGL,CACL;OACC,CAAA;OACH,EAAM,MAAM,YACX,kBAAC,WAAD,EAAA,UAAA;QACE,kBAAC,WAAD,EAAA,UAAA;SAAS;SAAQ,EAAM,MAAM,SAAS,OAAO;SAAO;QAAe,EAAA,CAAA;QACnE,kBAAC,KAAD,EAAA,UAAG,sCAAsC,CAAA;QACzC,kBAAC,OAAD;SAAK,WAAU;mBACZ,KAAK,UAAU,EAAM,MAAM,UAAU,MAAM,CAAC;QAC1C,CAAA;OACE,EAAA,CAAA;OAEX,kBAAC,OAAD;QAAK,KAAK;QAAe,WAAU;kBAAnC;SACE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,MAAD,EAAA,UAAA,CACE,kBAAC,GAAD,CAAsB,CAAA,GAAC,OACrB,EAAA,CAAA,GACJ,kBAAC,GAAD,EAAA,UAAA;WAEI,EAAM,MAAM,MAAM,QACf,MAAS,EAAK,SAAS,YAAY,EAAK,SAAS,aACpD,EAAE;WACF;WAAI;UAEH,EAAA,CAAA,CACF;;SACL,kBAAC,KAAD;UAAG,WAAU;oBAA2B;SAErC,CAAA;SACF,IACC,kBAAC,IAAD;UAEE,SACE,EAAc,SAAS,KAAA,IACnB,KAAA,IACA,EAAM,MAAM,MAAM,EAAc,OAAO;UAE7C,OAAO,EAAM,MAAM;UACnB,UAAU,EAAc;UACxB,UAAU,KAAQ,EAAM;UACxB,gBAAgB,EAAiB,IAAI;UACrC,SAAS,GAAW,MAAa;WAC/B,IAAM,IAAQ,CAAC,GAAG,EAAM,MAAM,KAAK;WAWnC,AAVI,EAAc,SAAS,KAAA,IACzB,EAAM,OAAO,GAAU,GAAG;YAAE,MAAM;YAAU;YAAW,cAAc;WAAK,CAAC,IAE3E,EAAM,EAAc,QAAQ;YAC1B,GAAG,EAAM,EAAc;YACvB,MAAM;YACN;YACA,cAAc;WAChB,GACF,EAAS,MAAA,GAAA,EAAA,WAAe;YAAE,GAAG,EAAM;YAAO;WAAM,CAAC,CAAC,GAClD,EAAiB,IAAI;UACvB;SACD,GAxBM,GAAG,EAAc,SAAS,GAAG,EAAc,QAAQ,OAwBzD,IAED,kBAAC,GAAD;UACE,MAAM,kBAAC,GAAD,CAAe,CAAA;UACrB,UAAU,KAAQ,EAAM,aAAa,EAAM,MAAM,MAAM,UAAU;UACjE,eAAe,EAAc,EAAM,MAAM,MAAM,MAAM;oBACtD;SAEO,CAAA;QAEP;;OACL,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,GAAD;UACE,MAAM,kBAAC,GAAD,CAAe,CAAA;UACrB,UAAU,EAAM,aAAa,KAAQ,CAAC,EAAM,MAAM,MAAM;UACxD,eACE,KAAK,QAAU;WACb,IAAM,KAAA,GAAA,EAAA,WAAqB,EAAM,KAAK;WACtC,IAAI,EAAS,MAAM,MAAM,MAAM,EAAE,SAAS,aAAa,GACrD,MAAM,MAAM,oBAAoB;WAElC,AADA,EAAS,KAAK,CAAQ,GACtB,EAAU,sBAAsB;UAClC,CAAC;oBAEJ;SAEO,CAAA;SACR,kBAAC,GAAD;UACE,MAAM,kBAAC,IAAD,CAAmB,CAAA;UACzB,UAAU,CAAC,EAAM;UACjB,eAAe;WACb,IAAM,IAAM,IAAI,gBACd,IAAI,KAAK,CAAC,KAAK,UAAU,EAAM,OAAO,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,mBAAmB,CAAC,CAC/E,GACM,IAAS,SAAS,cAAc,GAAG;WAMzC,AALA,EAAO,OAAO,GACd,EAAO,WAAW,eAClB,SAAS,KAAK,OAAO,CAAM,GAC3B,EAAO,MAAM,GACb,EAAO,OAAO,GACd,iBAAiB,IAAI,gBAAgB,CAAG,GAAG,GAAK;UAClD;oBACD;SAEO,CAAA;SACR,kBAAC,GAAD;UACE,MAAM,kBAAC,IAAD,CAAiB,CAAA;UACvB,UAAU,EAAM,aAAa;UAC7B,eAAe,GAAK,SAAS,MAAM;oBACpC;SAEO,CAAA;SACR,kBAAC,SAAD;UACE,KAAK;UACL,QAAA;UACA,MAAK;UACL,QAAO;UACP,WAAW,MAAM;WACf,IAAM,IAAW,EAAE,OAAO,QAAQ;WAElC,AADA,EAAE,OAAO,QAAQ,IACb,KACF,EAAS,YAAY;YACnB,IAAI,EAAS,OAAO,MAAM,MAAM,MAAM,MAAM,eAAe;YAG3D,AAFA,EAAS,MAAA,GAAA,EAAA,WAAe,KAAK,MAAM,MAAM,EAAS,KAAK,CAAC,CAAC,CAAC,GAC1D,EAAiB,IAAI,GACrB,EAAU,gBAAgB;WAC5B,CAAC;UACL;SACD,CAAA;QACE;;OACJ,EAAM,SACL,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACE,kBAAC,GAAD,CAAsB,CAAA;SAAC;SAClB,EAAM,MAAM;SAAK;SAAE,EAAM,MAAM,MAAM;SAAO;SAChD,KAAK,UAAU,EAAM,KAAK,MAAM,KAAK,UAAU,EAAM,KAAK,KACzD,kBAAC,GAAD;UAAK,OAAM;oBAAS;SAAa,CAAA;QAElC;;MAEE;;KACT,kBAAC,WAAD;MACE,WAAU;MACV,cAAW;gBAFb;OAIE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,MAAD,EAAA,UAAA,CACE,kBAAC,GAAD,CAAqB,CAAA,GAAC,MAEpB,EAAA,CAAA;OACD,CAAA;OACL,kBAAC,KAAD;QAAG,WAAU;kBAA2B;OAAwB,CAAA;OAChE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,SAAD;SAAO,SAAQ;mBAAf,CACE,kBAAC,GAAD,CAAsB,CAAA,GAAC,MAElB;YACP,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,SAAD;UACE,IAAG;UACH,cAAW;UACX,MAAK;UACL,KAAK;UACL,KAAK;UACL,MAAM;UACN,OAAO;UACP,UAAU;UACV,WAAW,MAAM,EAAS,OAAO,EAAE,OAAO,KAAK,CAAC;SACjD,CAAA,GACD,kBAAC,QAAD,EAAA,UAAM,KAAQ,CAAA,CACX;UACF;;OACL,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SACE,MAAM,kBAAC,GAAD,CAAqB,CAAA;SAC3B,MAAK;SACL,UACE,CAAC,KACD,CAAC,EAAM,SACP,EAAM,MAAM,MAAM,MAAM,MAAS,EAAK,SAAS,aAAa,KAC5D,EAAM,aACN,KACA,KAAK,UAAU,EAAM,KAAK,MAAM,KAAK,UAAU,EAAM,KAAK;SAE5D,eACE,KAAK,EAAI,YAAY;UACnB,EAAW,EAAI;UACf,IAAI;WACF,EACE,MAAM,GAAO,GAAW,OAAO;YAC7B,UAAU,EAAM;YAChB;YACA,QAAQ;WACV,CAAC,CACH;UACF,UAAU;WACR,EAAW,EAAK;UAClB;SACF,CAAC;mBAEJ;QAEO,CAAA,GACR,kBAAC,GAAD;SACE,MAAM,kBAAC,GAAD,CAAe,CAAA;SACrB,UAAU,EAAI,UAAU;SACxB,eACE,KAAK,EAAI,YAAY;UACnB,MAAM,GAAO,GAAW,QAAQ,CAAC,CAAC;SACpC,CAAC;mBAEJ;QAEO,CAAA,CACL;;OACL,kBAAC,GAAD;QACE,UAAA;QACA,MAAM,EAAI,UAAU,WAAW,UAAU,EAAI,UAAU,WAAW,YAAY;QAC9E,SAAS,GAAG,EAAI,KAAK,GAAG,EAAI,MAAM,KAAK,EAAI;OAC5C,CAAA;OACA,CAAC,CAAC,EAAI,YAAY,UACjB,kBAAC,OAAD;QAAK,WAAU;QAAwC,cAAW;kBAAlE,CACE,kBAAC,MAAD;SAAI,WAAU;mBAAd,CACE,kBAAC,GAAD,CAAsB,CAAA,GAAC,OACrB;YACH,EAAI,WAAW,KAAK,MACnB,kBAAC,OAAD;SAAuB,WAAU;mBAAjC;UACE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,UAAD,EAAA,UAAA;YAAQ;YACH,EAAO;YAAK;YAAM,EAAO;WACtB,EAAA,CAAA,GACR,kBAAC,GAAD;YAAK,OAAO,EAAO,SAAS,UAAU;sBACnC,EAAO,SAAS,OAAO;WACrB,CAAA,CACF;;UACL,kBAAC,MAAD,EAAA,UAAA;WACE,kBAAC,MAAD,EAAA,UAAI,KAAM,CAAA;WACV,kBAAC,MAAD,EAAA,UAAK,EAAO,SAAa,CAAA;WACzB,kBAAC,MAAD,EAAA,UAAI,KAAM,CAAA;WACV,kBAAC,MAAD,EAAA,UAAK,EAAO,UAAU,OAAW,CAAA;UAC/B,EAAA,CAAA;UACJ,kBAAC,QAAD;WAAM,WAAU;qBAAhB;YAA2C;YAAI,EAAO;YAAS;WAAS;;SACrE;WAhBK,EAAO,IAgBZ,CACN,CACE;;MAEA;;IACN;;EACF;;AAET;;;AC9iBA,SAAgB,GAAe,GAA0C;CACvE,IAAM,oBAAM,IAAI,IAAY;CAC5B,OAAO,EACJ,KAAK,MAAU;EACd,IAAI,CAAC,OAAO,cAAc,EAAM,EAAE,KAAK,EAAM,MAAM,KAAK,EAAI,IAAI,EAAM,EAAE,GACtE,MAAM,MAAM,gBAAgB;EAG9B,OAFA,EAAI,IAAI,EAAM,EAAE,GAET;GACL,IAAI,EAAM;GACV,MAAM,EAAM;GACZ,MAAM,EAAM;GACZ,OAAO,EAAS,EAAM,OAAO,GAAG;GAChC,MAAM,EAAQ,EAAM,IAAI;GACxB,GAAI,EAAM,WAAW,EAAE,UAAU,EAAM,SAAS,IAAI,CAAC;EACvD;CACF,CAAC,EACA,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;AAClD;AAEA,SAAgB,GAAc,GAA4B,GAAkB,GAAgB;CAC1F,IAAM,IAAQ,EAAO,WAAW,MAAM,EAAE,OAAO,CAAO,GACpD,IAAM,EAAO,WAAW,MAAM,EAAE,OAAO,CAAK;CAE9C,OADI,IAAQ,KAAK,IAAM,IAAc,CAAC,IAC/B,EAAO,MAAM,GAAO,IAAM,CAAC;AACpC;AAEA,SAAgB,GACd,GACA,GACA,GACU;CACV,IAAM,IAAW,GAAc,GAAQ,GAAS,CAAK;CACrD,IAAI,CAAC,EAAS,QAAQ,MAAM,MAAM,kBAAkB;CACpD,IAAM,IAAU,EAAS,QAAQ,MAAM;EAAC;EAAS;EAAS;CAAQ,EAAE,SAAS,EAAE,IAAI,CAAC;CACpF,IAAI,CAAC,EAAQ,QAAQ,MAAM,MAAM,yBAAyB;CAC1D,IAAI,EAAQ,UAAU,KAAK,MAAM,MAAM,4BAA4B;CACnE,IAAM,IAAQ,IAAI,IAAI,EAAQ,GAAG,IAAI;CACrC,IACE,CAAC,CAAC,SAAS,QAAQ,EAAE,SAAS,EAAM,QAAQ,KAC5C,EAAQ,MAAM,MAAM,IAAI,IAAI,EAAE,IAAI,EAAE,WAAW,EAAM,MAAM,GAE3D,MAAM,MAAM,aAAa;CAC3B,QAAA,GAAA,EAAA,WAAiB;EACf,QAAQ;EACR,SAAS;EACT,MAAM,UAAU,EAAQ,IAAI;EAC5B,MAAM,EAAM;EACZ,UAAU;GAAE,6BAAY,IAAI,KAAK,GAAE,YAAY;GAAG,QAAQ,gBAAgB,CAAQ;EAAE;EACpF,OAAO,CACL;GACE,MAAM;GACN,OACE;EACJ,GACA,GAAG,EAAQ,KAAK,OAAO;GACrB,MAAM;GACN,eAAe,EAAE;GACjB,OACE,EAAE,SAAS,WACP,oBAAoB,EAAE,MAAM,cAC5B,EAAE,SAAS,UACT,aAAa,EAAE,MAAM,eACrB,WAAW,EAAE,MAAM;EAC7B,EAAE,CACJ;CACF,CAAC;AACH;;;ACvDA,IAAM,KAAiC;CACrC,OAAO;CACP,OAAO;CACP,QAAQ;CACR,SAAS;CACT,OAAO;CACP,aAAa;AACf;AACA,SAAwB,GAAc,EACpC,WACA,cAIC;CACD,IAAM,IAAY,EAAqB,EAAS,WAAW,EAAS,QAAQ,GACtE,CAAC,GAAQ,KAAa,EAAoC,IAAI,GAC9D,CAAC,GAAO,KAAY,EAAiB,GACzC,CAAC,GAAK,KAAU,EAAiB,GAC7B,CAAC,GAAM,KAAW,EAAS,KAAK,GACpC,CAAC,GAAQ,KAAa,EAAS,EAAE,GAC7B,CAAC,GAAQ,KAAa,EAAS,EAAE,GACjC,IAAW,IAAS,GAAc,GAAQ,GAAO,CAAG,IAAI,CAAC,GACzD,IAAc,IAAI,IAAI,EAAS,KAAK,MAAM,EAAE,EAAE,CAAC,GAC/C,IAAQ,KAAU;CACxB,OACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD;KAAM,WAAU;eACd,kBAAC,GAAD,CAAkB,CAAA;IACd,CAAA,GACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAI,QAAS,CAAA,GACb,kBAAC,KAAD,EAAA,UAAG,oBAAoB,CAAA,CACpB,EAAA,CAAA,CACF;;GACL,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KACE,MAAM,kBAAC,IAAD,CAAkB,CAAA;KACxB,UAAU,EAAU,aAAa,CAAC,EAAO,UAAU,CAAC,CAAC;KACrD,eAAe;MACb,IAAI;OAIF,AAHA,EAAU,GAAe,CAAM,CAAC,GAChC,EAAS,KAAA,CAAS,GAClB,EAAO,KAAA,CAAS,GAChB,EAAU,EAAE;MACd,SAAS,GAAO;OACd,EAAW,EAAgB,OAAO;MACpC;KACF;eACD;IAEO,CAAA,GACP,KACC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;KACE,MAAM,kBAAC,IAAD,CAAgB,CAAA;KACtB,eAAe;MAIb,AAHA,EAAU,IAAI,GACd,EAAS,KAAA,CAAS,GAClB,EAAO,KAAA,CAAS,GAChB,EAAU,EAAE;KACd;eACD;IAEO,CAAA,GACR,kBAAC,GAAD;KACE,MAAM,kBAAC,IAAD,CAAkB,CAAA;KACxB,MAAK;KACL,UAAU,CAAC,EAAS,UAAU,EAAU;KACxC,eAAe;MACb,IAAI;OAEF,AADA,EAAS,UAAU,GAAkB,GAAQ,GAAQ,CAAI,CAAC,GAC1D,EAAQ;MACV,SAAS,GAAO;OACd,EAAW,EAAgB,OAAO;MACpC;KACF;eACD;IAEO,CAAA,CACR,EAAA,CAAA,CAED;;GACJ,KACC,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,OAAO,EAAO,OAAO,UAAU,IAAQ,MAAM,IAAQ,KAAK,QAAQ,IAAM,MAAM,IAAM,KAAK,MAAM,EAAS,OAAO;IACxH,aAAY;GACb,CAAA;GAEF,KAAU,kBAAC,GAAD;IAAO,MAAK;IAAU,SAAS;GAAS,CAAA;GAClD,CAAC,KACA,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,UAAD;KAAQ,cAAW;KAAO,OAAO;KAAM,WAAW,MAAM,EAAQ,EAAE,OAAO,KAAK;eAA9E,CACE,kBAAC,UAAD;MAAQ,OAAM;gBAAM;KAAY,CAAA,GAC/B,OAAO,QAAQ,EAAM,EAAE,KAAK,CAAC,GAAK,OACjC,kBAAC,UAAD;MAAkB,OAAO;gBACtB;KACK,GAFK,CAEL,CACT,CACK;QACR,kBAAC,GAAD;KACE,QAAQ,kBAAC,GAAD,CAAiB,CAAA;KACzB,cAAW;KACX,aAAY;KACZ,OAAO;KACP,WAAW,MAAM,EAAU,EAAE,OAAO,KAAK;KACzC,YAAA;IACD,CAAA,CACE;;GAEP,kBAAC,KAAD;IAAG,WAAU;cAA2B;GAGrC,CAAA;GACF,CAAC,EAAM,UAAU,kBAAC,GAAD,EAAO,aAAY,SAAU,CAAA;GAC/C,kBAAC,MAAD;IAAI,WAAU;cACX,EACE,QACE,MACC,CAAC,CAAC,MACA,MAAS,SAAS,EAAE,SAAS,OAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAM,CAC9E,EACC,MAAM,EACN,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAC7C,KAAK,MACJ,kBAAC,MAAD;KAAe,WAAW,EAAE,SAAS,UAAU,aAAa;eAA5D;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,GAAD;SAAK,OAAO,EAAE,SAAS,UAAU,QAAQ;mBAAS,GAAO,EAAE;QAAW,CAAA;QACtE,kBAAC,QAAD,EAAA,UAAO,IAAI,KAAK,EAAE,IAAI,EAAE,mBAAmB,SAAS,EAAE,QAAQ,GAAM,CAAC,EAAQ,CAAA;QAC7E,kBAAC,SAAD,EAAA,UAAA,CAAO,KAAE,EAAE,EAAU,EAAA,CAAA;QACpB,EAAY,IAAI,EAAE,EAAE,KAAK,kBAAC,GAAD;SAAK,OAAM;mBAAO;QAAO,CAAA;OAChD;;MACL,kBAAC,UAAD,EAAA,UAAS,EAAE,MAAc,CAAA;MACxB,KACC,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QACE,MAAM,kBAAC,IAAD,CAAe,CAAA;QACrB,MAAK;QACL,cAAY,OAAO,EAAE,GAAG;QACxB,eAAe;SAEb,AADA,EAAS,EAAE,EAAE,GACb,EAAO,KAAA,CAAS;QAClB;kBACD;OAEO,CAAA,GACR,kBAAC,GAAD;QACE,MAAM,kBAAC,GAAD,CAAsB,CAAA;QAC5B,MAAK;QACL,cAAY,OAAO,EAAE,GAAG;QACxB,UACE,MAAU,KAAA,KACV,EAAO,WAAW,MAAM,EAAE,OAAO,EAAE,EAAE,IACnC,EAAO,WAAW,MAAM,EAAE,OAAO,CAAK;QAE1C,eAAe,EAAO,EAAE,EAAE;kBAC3B;OAEO,CAAA,CACL;;MAEP,kBAAC,WAAD,EAAA,UAAA,CACE,kBAAC,WAAD,EAAA,UAAA,CAAS,MAAG,EAAE,WAAW,YAAY,EAAE,aAAa,EAAY,EAAA,CAAA,GAChE,kBAAC,OAAD;OAAK,WAAU;iBACZ,KAAK,UACJ;QAAE,MAAM,EAAE;QAAM,QAAQ,YAAY,IAAI,EAAE,SAAS,KAAA;OAAU,GAC7D,MACA,CACF;MACG,CAAA,CACE,EAAA,CAAA;KACP;OA9CK,EAAE,EA8CP,CACL;GACD,CAAA;EACD;;AAET;;;ACjMA,SAAwB,KAAkB;CACxC,OACE,kBAAC,QAAD;EAAM,WAAU;EAA6B,eAAY;YACvD,kBAAC,IAAD,CAAgB,CAAA;CACZ,CAAA;AAEV;;;ACFA,SAAgB,GAAqB,GAAwC,GAAe;CAC1F,QAAgB;EACd,IAAM,IAAO,EAAQ;EACrB,IAAI,CAAC,KAAQ,CAAC,GAAM;EACpB,IAAM,oBAAY,IAAI,IAA2B,GAC7C,IAAQ,GACN,UAAgB;GACpB,KAAK,IAAM,CAAC,GAAS,MAAa,GAChC,AAAK,EAAK,SAAS,CAAO,MACxB,EAAS,QAAQ,GACjB,EAAU,OAAO,CAAO;GAG5B,KAAK,IAAM,KAAW,EAAK,iBACzB,+HACF,GACM,EAAU,IAAI,CAAO,KACzB,EAAU,IACR,GACA,GACE;IAAE,QAAQ;IAAS,UAAU,EAAE,UAAU,EAAQ;GAAE,GACnD;IACE,UAAU;KAAE,GAAG;KAAU,GAAG;IAAS;IACrC,YAAY;KACV,OAAO;KACP,UAAU;KACV,eAAe;KACf,YAAY;IACd;GACF,CACF,CACF;EAEJ,GACM,IAAW,IAAI,uBAAuB;GAE1C,AADA,qBAAqB,CAAK,GAC1B,IAAQ,sBAAsB,CAAO;EACvC,CAAC;EAGD,OAFA,EAAS,QAAQ,GAAM;GAAE,WAAW;GAAM,SAAS;EAAK,CAAC,GACzD,EAAQ,SACK;GAGX,AAFA,EAAS,WAAW,GACpB,qBAAqB,CAAK,GAC1B,EAAU,SAAS,MAAa,EAAS,QAAQ,CAAC;EACpD;CACF,GAAG,CAAC,GAAS,CAAI,CAAC;AACpB;;;ACjCA,IAAM,IAAS,IACT,KAAO,MAAqB;CAChC,IAAM,IAAQ,KAAK,IAAI,KAAK,IAAI,KAAK,EAAK,KAAK,GAAG,OAAO,aAAa,IAAS,CAAC,GAC1E,IAAS,KAAK,IAAI,KAAK,IAAI,KAAK,EAAK,MAAM,GAAG,OAAO,cAAc,IAAS,CAAC;CACnF,OAAO;EACL;EACA;EACA,GAAG,KAAK,IAAI,GAAQ,KAAK,IAAI,EAAK,GAAG,OAAO,aAAa,IAAQ,CAAM,CAAC;EACxE,GAAG,KAAK,IAAI,GAAQ,KAAK,IAAI,EAAK,GAAG,OAAO,cAAc,IAAS,CAAM,CAAC;CAC5E;AACF,GAEM,MAA4B,MAAU;CAC1C,IAAM,EAAE,SAAM,eAAY,aAAU,iBAAc,GAC5C,CAAC,GAAM,KAAW,QACtB,EAAI;EACF,GAAG,OAAO,aAAa;EACvB,GAAG,OAAO,cAAc;EACxB,OAAO;EACP,QAAQ;CACV,CAAC,CACH,GACM,CAAC,GAAU,KAAe,EAAS,EAAK,GACxC,CAAC,GAAQ,KAAa,EAAS,EAAK,GACpC,IAAQ,EAAoB,IAAI;CACtC,GAAqB,GAAO,CAAI;CAChC,IAAM,IAAU,EAAqE,IAAI;CAMzF,AALA,QAAgB;EACd,IAAM,UAAe,GAAS,MAAY,EAAI,CAAO,CAAC;EAEtD,OADA,OAAO,iBAAiB,UAAU,CAAM,SAC3B,OAAO,oBAAoB,UAAU,CAAM;CAC1D,GAAG,CAAC,CAAC,GACL,QAAgB;EACd,AAAI,KAAM,EAAM,SAAS,MAAM,EAAE,eAAe,GAAK,CAAC;CACxD,GAAG,CAAC,CAAI,CAAC;CACT,IAAM,KAAS,GAAkC,IAAS,OAAU;EAC9D,KAAY,EAAM,WAAW,KAAM,EAAM,OAAuB,QAAQ,QAAQ,MACpF,EAAM,eAAe,GACrB,EAAM,cAAc,kBAAkB,EAAM,SAAS,GACrD,EAAQ,UAAU;GAAE,GAAG,EAAM;GAAS,GAAG,EAAM;GAAS;GAAM;EAAO,GACrE,EAAU,EAAI;CAChB,GACM,KAAQ,MAAqC;EACjD,IAAM,IAAU,EAAQ;EACxB,IAAI,CAAC,GAAS;EACd,IAAM,IAAK,EAAM,UAAU,EAAQ,GACjC,IAAK,EAAM,UAAU,EAAQ;EAC/B,EACE,EACE,EAAQ,SACJ;GACE,GAAG,EAAQ;GACX,OAAO,KAAK,IAAI,EAAQ,KAAK,QAAQ,GAAI,OAAO,aAAa,EAAQ,KAAK,IAAI,CAAM;GACpF,QAAQ,KAAK,IACX,EAAQ,KAAK,SAAS,GACtB,OAAO,cAAc,EAAQ,KAAK,IAAI,CACxC;EACF,IACA;GAAE,GAAG,EAAQ;GAAM,GAAG,EAAQ,KAAK,IAAI;GAAI,GAAG,EAAQ,KAAK,IAAI;EAAG,CACxE,CACF;CACF,GACM,UAAY;EAEhB,AADA,EAAQ,UAAU,MAClB,EAAU,EAAK;CACjB;CACA,OACE,kBAAC,WAAD;EACE,KAAK;EACL,IAAG;EACH,MAAK;EACL,cAAW;EACX,mBAAgB;EAChB,UAAU;EACV,QAAQ,CAAC;EACT,2BAAA;EACA,WAAW,gDAAgD,IAAW,iBAAiB,KAAK,IAAS,eAAe;EACpH,OACE,IAAW,KAAA,IAAY;GAAE,MAAM,EAAK;GAAG,KAAK,EAAK;GAAG,OAAO,EAAK;GAAO,QAAQ,EAAK;EAAO;EAE7F,YAAY,MAAU;GACpB,AAAI,EAAM,QAAQ,YAAY,EAAM,WAAW,EAAM,iBAAe,EAAW;EACjF;YAfF;GAiBE,kBAAC,UAAD;IAAQ,WAAU;cAAlB,CACE,kBAAC,OAAD;KACE,WAAU;KACV,UAAU;KACV,MAAK;KACL,cAAW;KACX,eAAe;KACf,eAAe;KACf,aAAa;KACb,iBAAiB;KACjB,sBAAsB;KACtB,qBAAqB,GAAa,MAAU,CAAC,CAAK;KAClD,YAAY,MAAU;MACpB,IACE,KACA,CAAC;OAAC;OAAa;OAAc;OAAW;MAAW,EAAE,SAAS,EAAM,GAAG,GAEvE;MACF,EAAM,eAAe;MACrB,IAAM,IAAS,EAAM,WAAW,KAAK;MACrC,GAAS,MACP,EAAI;OACF,GAAG;OACH,GACE,EAAQ,KACP,EAAM,QAAQ,cAAc,CAAC,IAAS,EAAM,QAAQ,eAAe,IAAS;OAC/E,GACE,EAAQ,KACP,EAAM,QAAQ,YAAY,CAAC,IAAS,EAAM,QAAQ,cAAc,IAAS;MAC9E,CAAC,CACH;KACF;eA9BF,CAgCE,kBAAC,IAAD,CAAkB,CAAA,GAClB,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;MAAI,IAAG;gBAAP,CAAkC,SAC3B,kBAAC,QAAD,EAAA,UAAO,IAAY,SAAS,OAAa,CAAA,CAC5C;SACJ,kBAAC,KAAD,EAAA,UAAI,IAAW,mBAAmB,iBAAoB,CAAA,CACnD,EAAA,CAAA,CACF;QACL,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,MAAK;MACL,cAAY,IAAW,SAAS;MAChC,OAAO,IAAW,SAAS;MAC3B,eAAe,GAAa,MAAU,CAAC,CAAK;gBAEhC,EAAX,IAAY,KAA6B,GAA9B,CAAyB,CAAyB;KACxD,CAAA,GACR,kBAAC,GAAD;MAAQ,MAAK;MAAO,cAAW;MAAU,OAAM;MAAM,SAAS;gBAC5D,kBAAC,GAAD,CAAgB,CAAA;KACV,CAAA,CACL;MACC;;GACP;GACD,kBAAC,UAAD;IAAQ,WAAU;cAAlB,CACE,kBAAC,QAAD,EAAA,UAAA,CACE,kBAAC,KAAD,CAAI,CAAA,GAAC,WAED,EAAA,CAAA,GACN,kBAAC,QAAD,EAAA,UAAO,IAAW,WAAW,mBAAyB,CAAA,CAChD;;GACP,CAAC,KACA,kBAAC,OAAD;IACE,WAAU;IACV,MAAK;IACL,UAAU;IACV,cAAW;IACX,gBAAgB,MAAU,EAAM,GAAO,EAAI;IAC3C,eAAe;IACf,aAAa;IACb,iBAAiB;IACjB,sBAAsB;IACtB,YAAY,MAAU;KACf;MAAC;MAAa;MAAc;MAAW;KAAW,EAAE,SAAS,EAAM,GAAG,MAC3E,EAAM,eAAe,GACrB,GAAS,MACP,EAAI;MACF,GAAG;MACH,OAAO,KAAK,IACV,EAAQ,SACL,EAAM,QAAQ,cAAc,MAAM,EAAM,QAAQ,eAAe,KAAK,IACvE,OAAO,aAAa,EAAQ,IAAI,CAClC;MACA,QAAQ,KAAK,IACX,EAAQ,UACL,EAAM,QAAQ,YAAY,MAAM,EAAM,QAAQ,cAAc,KAAK,IACpE,OAAO,cAAc,EAAQ,IAAI,CACnC;KACF,CAAC,CACH;IACF;GACD,CAAA;EAEI;;AAEb;;;ACnMA,SAAwB,GAAiB,EACvC,YACA,SACA,QACA,WACA,cAOC;CACD,IAAM,IAAS,EAAoB,GAAS,GAAM,CAAG,GAC/C,IAAU,EAAK,aACf,IAAO,EAAQ,GAAG,EAAE,GACpB,IAAM,KAAK,IAAI,GAAG,EAAQ,KAAK,MAAM,EAAE,IAAI,CAAC,GAC5C,IAAM,KAAK,IAAI,GAAG,EAAQ,KAAK,MAAM,EAAE,IAAI,CAAC,GAC5C,IAAY,EAAQ,IAAI,QAAQ,GAChC,IAAS,EACZ,KACE,MACC,GAAG,KAAM,EAAE,OAAO,KAAa,KAAK,IAAI,IAAI,GAAM,QAAQ,KAAO,CAAS,IAAK,IAAI,GAAG,MAAO,EAAE,OAAO,KAAO,KAAK,IAAI,SAAS,IAAM,CAAG,IAAK,IACjJ,EACC,KAAK,GAAG;CACX,OACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,QAAD;MAAM,WAAU;gBACd,kBAAC,GAAD,CAAoB,CAAA;KAChB,CAAA;KACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAI,OAAQ,CAAA,GACZ,kBAAC,KAAD,EAAA,UAAG,oBAAoB,CAAA,CACpB,EAAA,CAAA;KACL,kBAAC,GAAD,EAAA,UAAM,IAAU,SAAS,IAAS,UAAU,QAAa,CAAA;IACtD;;GACL,kBAAC,GAAD;IACE,UAAA;IACA,MAAM,EAAO,SAAS,YAAY;IAClC,SAAS,EAAO,SAAS,GAAG,EAAO,OAAO,UAAU;IACpD,aACE,IACI,+BACA;GAEP,CAAA;GACD,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAO,KAAK,MACX,kBAAC,WAAD;KAEE,WAAU;eAFZ;MAIE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,MAAD,EAAA,UAAA,CACE,kBAAC,GAAD;QAAK,OAAO,EAAM,aAAa,UAAU,QAAQ;kBAC9C,EAAM,aAAa,UAAU,SAAS;OACpC,CAAA,GACJ,EAAM,KACL,EAAA,CAAA;MACD,CAAA;MACL,kBAAC,KAAD,EAAA,UAAI,EAAM,SAAY,CAAA;MACtB,kBAAC,WAAD,EAAA,UAAA;OACE,kBAAC,WAAD,EAAA,UAAA,CACE,kBAAC,GAAD,CAAe,CAAA,GAAC,YACT,EAAA,CAAA;OACT,kBAAC,MAAD,EAAA,UACG,EAAM,YAAY,KAAK,MACtB,kBAAC,MAAD,EAAA,UAAsB,EAAe,GAA5B,CAA4B,CACtC,EACC,CAAA;OACJ,kBAAC,KAAD;QAAG,WAAU;kBAA4B,EAAM;OAAQ,CAAA;OACvD,kBAAC,KAAD;QAAG,MAAM,EAAM;QAAK,QAAO;QAAS,KAAI;kBAAxC,CACE,kBAAC,GAAD,CAAe,CAAA,GAAC,WACf;;MACI,EAAA,CAAA;KACF;OA1BF,EAAM,EA0BJ,CACV;GACE,CAAA;GACL,kBAAC,WAAD;IAAS,WAAU;cAAnB;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD,EAAA,UAAI,WAAY,CAAA,GAChB,kBAAC,QAAD,EAAA,UAAO,IAAO,EAAU,EAAK,IAAI,IAAI,OAAa,CAAA,CAC/C;;KACJ,EAAQ,SAAS,IAChB,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;MACE,WAAU;MACV,SAAQ;MACR,MAAK;MACL,cAAY,WAAW,EAAU,CAAG,EAAE,MAAM,EAAU,CAAG,EAAE,MAAM,EAAU,EAAM,IAAI;gBAJvF,CAME,kBAAC,QAAD;OAAM,GAAE;OAAa,QAAO;OAAe,SAAQ;MAAM,CAAA,GACzD,kBAAC,YAAD;OACU;OACR,MAAK;OACL,QAAO;OACP,aAAY;OACZ,cAAa;MACd,CAAA,CACE;SACL,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD,EAAA,UAAA;OACG,IAAI,KAAK,CAAS,EAAE,mBAAmB;OAAE;OAAI,EAAU,CAAG;MACvD,EAAA,CAAA,GACN,kBAAC,QAAD,EAAA,UAAA;OACG,IAAI,KAAK,EAAM,IAAI,EAAE,mBAAmB;OAAE;OAAO,EAAU,CAAG;MAC3D,EAAA,CAAA,CACH;OACL,EAAA,CAAA,IAEF,kBAAC,KAAD;MAAG,WAAU;gBACV,IACG,gCACA;KACH,CAAA;KAEL,kBAAC,KAAD;MAAG,WAAU;gBAA2B;KAGrC,CAAA;IACI;;GACT,kBAAC,MAAD;IAAI,WAAU;cAAd,CACE,kBAAC,GAAD,CAAoB,CAAA,GAAC,OACnB;;GACJ,kBAAC,OAAD;IAAK,WAAU;cACZ;KACC,CAAC,QAAQ,KAAK;KACd,CAAC,OAAO,QAAQ;KAChB,CAAC,OAAO,QAAQ;KAChB,CAAC,OAAO,MAAM;KACd,CAAC,oBAAoB,QAAQ;KAC7B,CAAC,QAAQ,MAAM;KACf,CAAC,aAAa,OAAO;KACrB,CAAC,oBAAoB,QAAQ;IAC/B,EAAE,KAAK,CAAC,GAAK,OACX,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,QAAD,EAAA,UAAA;KACG;KAAM;KAAI;IACP,EAAA,CAAA,GACN,kBAAC,UAAD,EAAA,UACG,EAAQ,MAAQ,OACb,QACA,MAAQ,QACN,EAAQ,GAAK,QAAQ,CAAC,IACtB,GAAG,KAAK,MAAM,EAAQ,EAAI,IAAI,MAAQ,cAAc,OAAO,QAC3D,CAAA,CACL,EAAA,GAXK,CAWL,CACN;GACE,CAAA;GACL,kBAAC,KAAD;IAAG,WAAU;cAA2B;GAIrC,CAAA;EACA;;AAET;;;ACxHA,SAAS,GAAS,EAAE,YAA6B;CAC/C,OAAO,kBAAC,OAAD;EAAK,WAAU;YAA4B,KAAK,UAAU,GAAO,MAAM,CAAC;CAAO,CAAA;AACxF;AACA,IAAM,KAAa,MACjB,IAAI,KAAK,CAAI,EAAE,mBAAmB,SAAS,EAAE,QAAQ,GAAM,CAAC;AAM9D,SAAwB,GAAkB,EACxC,eAAY,IACZ,eAAY,oBACc,CAAC,GAAG;CAC9B,IAAM,IAAQ,EAAqB,EAAiB,WAAW,EAAiB,QAAQ,GAClF,IAAY,EAAqB,EAAS,WAAW,EAAS,QAAQ,GACtE,CAAC,GAAM,KAAW,EAAS,EAAK,GACpC,CAAC,GAAK,KAAU,EAAS,UAAU,GAC/B,CAAC,IAAe,KAAoB,EAAS,UAAU,GACvD,IAAW,EAA0B,IAAI,GACzC,WAAiB;EAErB,AADA,EAAQ,EAAK,GACb,4BAA4B,EAAS,SAAS,MAAM,EAAE,eAAe,GAAK,CAAC,CAAC;CAC9E,GACM,CAAC,GAAa,MAAkB,EAAS,EAAE,GAC/C,CAAC,IAAQ,KAAa,EAAS,EAAE,GAC7B,CAAC,IAAU,KAAe,EAA0B,IAAI,GACxD,CAAC,GAAM,KAAW,EAAyC,MAAM,GAEjE,CAAC,IAAM,KAAW,EAAS,CAAW,GACtC,KAAY,EAAyB,IAAI;CAC/C,QAAgB;EACd,IAAI,CAAC,GAAM;EACX,IAAM,IAAQ,kBAAkB,EAAQ,EAAY,CAAC,GAAG,GAAI;EAC5D,aAAa,cAAc,CAAK;CAClC,GAAG,CAAC,CAAI,CAAC;CACT,IAAM,IAAS,MAAS,aAAa,KAAW,MAAS,WAAW,EAAM,SAAS,MAC7E,IAAS,GAAQ,UAAU,EAAM,QACrC,IAAW,GAAQ,YAAY,EAAM,UACjC,KAAU,GAAQ,WAAW,EAAM,SACvC,IAAU,GAAQ,eAAe,IAC7B,IAAU,EAAM,QAYhB,KACJ,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,IAAD,CAA4B,CAAA,GAAC,WAE1B;;KACL,kBAAC,QAAD,EAAA,UAAM,YAAe,CAAA;KACrB,kBAAC,KAAD,EAAA,UAAG,sBAAsB,CAAA;IACtB;;GACL,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,UAAD,EAAA,UAAA,CACG,EAAO,QACR,kBAAC,SAAD,EAAA,UAAO,IAAQ,CAAA,CACT,EAAA,CAAA,GACR,kBAAC,QAAD;MAAM,WAAU;gBAAhB,CACE,kBAAC,GAAD,CAAkB,CAAA,GAAC,OAEf;OACH,EAAA,CAAA;KACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,UAAD,EAAA,UAAA,CACG,EAAS,QACV,kBAAC,SAAD,EAAA,UAAO,IAAQ,CAAA,CACT,EAAA,CAAA,GACR,kBAAC,QAAD;MAAM,WAAU;gBAAhB,CACE,kBAAC,GAAD,CAAc,CAAA,GAAC,MAEX;OACH,EAAA,CAAA;KACL,kBAAC,OAAD;MAAK,WAAW,EAAS,MAAM,MAAM,EAAE,MAAM,IAAI,eAAe;gBAAhE,CACE,kBAAC,UAAD,EAAA,UAAA,CACG,EAAS,QAAQ,MAAM,EAAE,MAAM,EAAE,QAClC,kBAAC,SAAD,EAAA,UAAO,IAAQ,CAAA,CACT,EAAA,CAAA,GACR,kBAAC,QAAD;OAAM,WAAU;iBAAhB,CACE,kBAAC,IAAD,CAAkB,CAAA,GAAC,MAEf;QACH;;IACF;;GACL,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAQ,MAAK;KAAU,MAAM,kBAAC,IAAD,CAAiB,CAAA;KAAG,eAtDlC;MAGnB,AAFA,EAAe,UAAU,GACzB,EAAQ,QAAQ,GAChB,EAAU,qBAAqB;KACjC;eAkDwE;IAE1D,CAAA,GACR,kBAAC,GAAD;KAAQ,MAAM,kBAAC,IAAD,CAAmB,CAAA;KAAG,eApDjB;MAEvB,IAAM,IAAW,KAAU,EAAM,UAAU,EAAgB;MAE3D,AADA,EAAiB,GAAU,CAAW,GACtC,EAAU,OAAO,EAAU,EAAS,UAAU,EAAE,wBAAwB;KAC1E;eA+C+D;IAEjD,CAAA,CACL;;GACL,kBAAC,GAAD;IACE,MAAM,IAAU,YAAY;IAC5B,UAAA;IACA,SACE,IACI,WAAW,EAAU,EAAQ,UAAU,EAAE,KAAK,EAAQ,WACtD;GAEP,CAAA;GACD,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,SAAD;KAAO,SAAQ;eAAf,CACE,kBAAC,IAAD,CAAe,CAAA,GAAC,MAEX;QACP,kBAAC,EAAM,UAAP;KACE,IAAG;KACH,OAAO;KACP,WAAW,MAAM,GAAe,EAAE,OAAO,KAAK;KAC9C,WAAW;KACX,WAAA;KACA,MAAM;KACN,aAAY;IACb,CAAA,CACE;;GACL,kBAAC,KAAD;IAAG,WAAU;cACV,IACG,QAAQ,EAAO,OAAO,KAAK,EAAU,EAAO,UAAU,MACtD,IACE,mCACA;GACL,CAAA;GACH,kBAAC,WAAD,EAAA,UAAA;IACE,kBAAC,WAAD,EAAA,UAAS,WAAiB,CAAA;IAC1B,kBAAC,KAAD,EAAA,UAAG,qFAIA,CAAA;IACH,kBAAC,KAAD,EAAA,UAAG,wDAGA,CAAA;GACI,EAAA,CAAA;EACN;KAED,KACJ,kBAAC,IAAD;EAEU;EACR,eAAe,EAAO,YAAY;CACnC,GAHM,IAAkB,KAAQ,GAAQ,cAAc,OAGtD,GAEG,KACJ,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,QAAD;MAAM,WAAU;gBACd,kBAAC,GAAD,CAAc,CAAA;KACV,CAAA;KACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAI,OAAQ,CAAA,GACZ,kBAAC,KAAD,EAAA,UAAG,kBAAkB,CAAA,CAClB,EAAA,CAAA;KACL,kBAAC,GAAD,EAAA,UAAA,CAAM,EAAS,QAAO,IAAO,EAAA,CAAA;IAC1B;;GACL,kBAAC,KAAD;IAAG,WAAU;cAA2B;GAGrC,CAAA;GACF,CAAC,EAAS,UAAU,kBAAC,GAAD,EAAO,aAAY,SAAU,CAAA;GACjD,EACE,MAAM,EACN,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,EAC9B,KAAK,MACJ,kBAAC,WAAD;IAAoB,WAAU;cAA9B,CACE,kBAAC,WAAD,EAAA,UAAA,CACE,kBAAC,QAAD;KAAM,WAAU;eAAhB;MACE,kBAAC,GAAD;OAAK,OAAO,EAAE,SAAS,QAAQ;iBAAU,EAAE,UAAU;MAAU,CAAA;MAC/D,kBAAC,KAAD,EAAA,UAAI,EAAE,OAAU,CAAA;MAAE;MAClB,kBAAC,QAAD,EAAA,UAAA;OACE,kBAAC,IAAD,CAAoB,CAAA;OACnB,KAAK,MAAM,EAAE,QAAQ;OAAE;MACpB,EAAA,CAAA;KACF;QACN,kBAAC,QAAD;KAAM,WAAU;eAAmC,EAAE;IAAU,CAAA,CACxD,EAAA,CAAA,GACT,kBAAC,IAAD,EAAU,OAAO,EAAI,CAAA,CACd;MAbK,EAAE,EAaP,CACV;EACA;KAED,IAAkB,IAAU,EAAO,eAAe,EAAiB,IAAK,EAAM,aAC9E,KAAiB,IAAS,KAAK,MAAM,EAAO,UAAU,IAAI,EAAM,sBAChE,IAAoB,EAAoB,IAAS,GAAiB,EAAc,GAChF,IAAuB,EAC3B,EAAM,SACN,EAAM,aACN,EAAM,oBACR,EAAE,QACI,KACJ,kBAAC,IAAD;EACW;EACT,MAAM;EACN,KAAK;EACL,QAAQ,EAAM;EACd,SAAS,EAAQ;CAClB,CAAA,GAEG,KACJ,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD;KAAM,WAAU;eACd,kBAAC,IAAD,CAAkB,CAAA;IACd,CAAA,GACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAI,QAAS,CAAA,GACb,kBAAC,KAAD,EAAA,UAAG,mBAAmB,CAAA,CACnB,EAAA,CAAA,CACF;;GACL,kBAAC,GAAD;IACE,UAAA;IACA,MAAK;IACL,SAAQ;GACT,CAAA;GACD,kBAAC,IAAD,EAAU,OAAO,EAAU,CAAA;GAC1B,KACC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,MAAD,EAAA,UAAI,SAAU,CAAA,GACd,kBAAC,IAAD,EAAU,OAAO,EAAO,KAAO,CAAA,CAC/B,EAAA,CAAA;EAED;KAED,KACJ,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,GAAD,EAAO,aAAY,WAAY,CAAA,GAC/B,kBAAC,KAAD;GAAG,WAAU;aAA2B;EAErC,CAAA,CACA;;CAEP,OACE,kBAAC,OAAD;EAAK,2BAAA;YAAL,CACE,kBAAC,OAAD;GACE,WAAW,2BAA2B,EAAU,YAAY,kBAAkB;GAC9E,QAAQ;aAFV,CAIE,kBAAC,IAAD;IACE,OACE,EAAU,YACN,cAAc,EAAU,MAAM,MAAM,OAAO,MAC3C,IACE,UAAU,EAAqB,UAC/B,EAAM,SACJ,mBACA;cAGV,kBAAC,GAAD;KACE,KAAK,EAAU,aAAa,EAAQ,EAAM,UAAW,IAAuB;KAC5E,OAAO,EAAU,YAAY,QAAQ;KACrC,QAAQ,CAAC,IAAI,CAAC;eAEd,kBAAC,GAAD;MACE,KAAK;MACL,MAAK;MACL,OAAM;MACN,WAAU;MACV,cAAW;MACX,iBAAe;MACf,iBAAc;MACd,eAAe;OAEb,AADA,EAAQ,EAAI,GACZ,EAAQ,EAAY,CAAC;MACvB;MACA,MAAM,kBAAC,IAAD,CAAkB,CAAA;KACzB,CAAA;IACI,CAAA;GACA,CAAA,GACT,kBAAC,QAAD;IAAM,WAAU;IAA8B,MAAK;cAChD,EAAU,YACP,OAAO,EAAU,MAAM,MAAM,OAAO,MACpC,IACE,GAAG,EAAqB,UACxB,EAAM,SACJ,YACA;GACJ,CAAA,CACH;MACL,kBAAC,IAAD;GAAqB;GAAM,YAAY;GAAqB;aAC1D,kBAAC,OAAD;IAAK,2BAAA;IAAwB,WAAU;cAAvC;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD,EAAA,UAAA,CACE,kBAAC,KAAD,EAAG,WAAW,EAAM,SAAS,WAAW,GAAK,CAAA,GAC5C,IAAS,WAAW,EAAM,SAAS,UAAU,YAC1C,EAAA,CAAA,GACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QACE,MAAK;QACL,MAAK;QACL,MAAM,EAAM,SAAS,kBAAC,GAAD,CAAqB,CAAA,IAAI,kBAAC,IAAD,CAAgB,CAAA;QAC9D,eAAe,EAAiB,MAAM,CAAC,EAAM,MAAM;kBAElD,EAAM,SAAS,SAAS;OACnB,CAAA,GACR,kBAAC,GAAD;QACE,MAAK;QACL,MAAK;QACL,MAAM,kBAAC,IAAD,CAAiB,CAAA;QACvB,eAAe;SAIb,AAHA,EAAiB,MAAM,GACvB,EAAQ,MAAM,GACd,EAAY,IAAI,GAChB,EAAU,SAAS;QACrB;kBACD;OAEO,CAAA,CACL;QACF;;KACJ,MAAU,kBAAC,GAAD;MAAO,UAAA;MAAS,SAAS;MAAQ,MAAK;MAAO,eAAe,EAAU,EAAE;KAAI,CAAA;KACtF,GAAQ,YACP,kBAAC,GAAD;MAAO,SAAQ;MAAW,aAAa,EAAO;MAAU,MAAK;KAAQ,CAAA;KAEtE,KACC,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD;QACE,MAAK;QACL,MAAM,kBAAC,GAAD,CAAkB,CAAA;QACxB,MAAM,MAAS,SAAS,YAAY;QACpC,eAAe,EAAQ,MAAM;kBAC9B;OAEO,CAAA;OACR,kBAAC,GAAD;QACE,MAAK;QACL,MAAM,kBAAC,IAAD,CAAiB,CAAA;QACvB,UAAU,CAAC,EAAM;QACjB,MAAM,MAAS,WAAW,YAAY;QACtC,eAAe,EAAQ,QAAQ;kBAChC;OAEO,CAAA;OACR,kBAAC,GAAD;QACE,MAAK;QACL,MAAM,kBAAC,IAAD,CAAiB,CAAA;QACvB,eAAe,GAAU,SAAS,MAAM;kBACzC;OAEO,CAAA;OACP,MACC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;QACE,MAAK;QACL,MAAM,kBAAC,IAAD,CAAqB,CAAA;QAC3B,MAAM,MAAS,aAAa,YAAY;QACxC,eAAe,EAAQ,UAAU;kBAClC;OAEO,CAAA,GACR,kBAAC,GAAD;QACE,cAAW;QACX,MAAK;QACL,MAAM,kBAAC,IAAD,CAAgB,CAAA;QACtB,eAAe;SAEb,AADA,EAAY,IAAI,GAChB,EAAQ,MAAM;QAChB;OACD,CAAA,CACD,EAAA,CAAA;OAEJ,kBAAC,SAAD;QACE,KAAK;QACL,QAAA;QACA,MAAK;QACL,QAAO;QACP,UAAU,OAAO,MAAM;SACrB,IAAM,IAAO,EAAE,OAAO,QAAQ;SAC9B,MAAE,OAAO,QAAQ,IACZ,GACL,IAAI;UACF,IAAI,EAAK,OAAO,IAAI,OAAO,MAAM,MAAM,MAAM,aAAa;UAK1D,AAJA,EAAY,EAAc,MAAM,EAAK,KAAK,CAAC,CAAC,GAC5C,EAAQ,UAAU,GAClB,EAAO,aAAa,GACpB,EAAiB,UAAU,GAC3B,EAAU,eAAe;SAC3B,SAAS,GAAO;UACd,EAAU,aAAiB,QAAQ,EAAM,UAAU,QAAQ;SAC7D;QACF;OACD,CAAA;MACE;;KAEN,KACC,CAAC,KACD,IAAuB,KACvB,EAAE,MAAQ,iBAAiB,OAAkB,kBAC3C,kBAAC,GAAD;MACE,UAAA;MACA,MAAK;MACL,SAAS,GAAG,EAAqB;MACjC,QACE,kBAAC,GAAD;OACE,MAAK;OACL,eAAe;QAEb,AADA,EAAO,aAAa,GACpB,EAAiB,aAAa;OAChC;iBACD;MAEO,CAAA;KAEX,CAAA;KAEL,kBAAC,GAAD;MACE,WAAU;MACV,WAAW;MACX,UAAU;MACV,OAAO;OACL;QACE,KAAK;QACL,OAAO;QACP,MAAM,kBAAC,IAAD,EAAiB,eAAA,GAAa,CAAA;QACpC,UAAU;OACZ;OACA,GAAI,IACA,CACE;QACE,KAAK;QACL,OAAO;QACP,MAAM,kBAAC,IAAD,EAAoB,eAAA,GAAa,CAAA;QACvC,UAAU,kBAAC,IAAD;SAAiB,OAAO;SAAqB;QAAY,CAAA;OACrE,GACA;QACE,KAAK;QACL,OAAO;QACP,MAAM,kBAAC,IAAD,EAAmB,eAAA,GAAa,CAAA;QACtC,UACE,kBAAC,GAAD;SACE,WAAU;SACV,WAAW;SACX,UAAU;SACV,OAAO;UACL;WACE,KAAK;WACL,OAAO;WACP,MAAM,kBAAC,GAAD,EAAiB,eAAA,GAAa,CAAA;WACpC,UAAU;UACZ;UACA;WACE,KAAK;WACL,OAAO;WACP,MAAM,kBAAC,GAAD,EAAa,eAAA,GAAa,CAAA;WAChC,UAAU;UACZ;UACA;WACE,KAAK;WACL,OAAO,EAAkB,SACrB,OAAO,EAAkB,OAAO,KAChC;WACJ,MAAM,kBAAC,GAAD,EAAmB,eAAA,GAAa,CAAA;WACtC,UAAU;UACZ;UACA;WACE,KAAK;WACL,OAAO;WACP,MAAM,kBAAC,IAAD,EAAiB,eAAA,GAAa,CAAA;WACpC,UAAU;UACZ;SACF;QACD,CAAA;OAEL,CACF,IACA,CAAC;OACL;QACE,KAAK;QACL,OAAO;QACP,MAAM,kBAAC,IAAD,EAAc,eAAA,GAAa,CAAA;QACjC,UAAU;OACZ;MACF;KACD,CAAA;IACE;;EACQ,CAAA,CACZ;;AAET"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Assertion, type Step } from './schema';
|
|
2
|
+
export default function AssertionEditor({ initial, steps, position, disabled, onSave, onCancel, }: {
|
|
3
|
+
initial?: Assertion;
|
|
4
|
+
steps: Step[];
|
|
5
|
+
position: number;
|
|
6
|
+
disabled: boolean;
|
|
7
|
+
onSave: (assertion: Assertion, position: number) => void;
|
|
8
|
+
onCancel: () => void;
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { TestCase } from './schema';
|
|
2
|
+
export { privateInput, locate } from 'gz-laya-pilot/browser';
|
|
3
|
+
type State = {
|
|
4
|
+
recording: boolean;
|
|
5
|
+
draft: TestCase;
|
|
6
|
+
saved: TestCase | null;
|
|
7
|
+
};
|
|
8
|
+
export declare const recorder: {
|
|
9
|
+
subscribe(fn: () => void): () => void;
|
|
10
|
+
getState: () => State;
|
|
11
|
+
start(): void;
|
|
12
|
+
stop(): void;
|
|
13
|
+
edit(draft: TestCase): void;
|
|
14
|
+
loadDraft(draft: TestCase): void;
|
|
15
|
+
checkpoint(text: string): void;
|
|
16
|
+
save(value: TestCase): void;
|
|
17
|
+
clear(): void;
|
|
18
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from 'gz-laya-pilot/schema';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { TraceEvent } from '../runtime';
|
|
2
|
+
import { type TestCase, type TimelineEvidence } from './schema';
|
|
3
|
+
export declare function freezeTimeline(events: TraceEvent[]): TimelineEvidence[];
|
|
4
|
+
export declare function timelineRange(events: TimelineEvidence[], startId?: number, endId?: number): TimelineEvidence[];
|
|
5
|
+
export declare function buildTimelineCase(events: TimelineEvidence[], startId: number, endId: number): TestCase;
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { assistantRuntime, startAssistant, captureSnapshot, freezeSnapshot, reportError, } from './runtime';
|
|
2
|
+
export type { Snapshot, TraceEvent, NetworkRecord, AssistantOptions } from './runtime';
|
|
3
|
+
export { parseSnapshot, downloadSnapshot } from './snapshot';
|
|
4
|
+
export { recorder } from './automation/recorder';
|
|
5
|
+
export { parseCase, parseAssertion } from 'gz-laya-pilot/schema';
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { a as e, c as t, i as n, l as r, n as i, r as a, s as o, t as s } from "./recorder-Da1VSLid.js";
|
|
2
|
+
import { parseAssertion as c, parseCase as l } from "gz-laya-pilot/schema";
|
|
3
|
+
export { n as assistantRuntime, e as captureSnapshot, i as downloadSnapshot, o as freezeSnapshot, c as parseAssertion, l as parseCase, a as parseSnapshot, s as recorder, t as reportError, r as startAssistant };
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { t as e } from "./ResearchAssistant-DAsgcwcG.js";
|
|
2
|
+
import { a as t, c as n, i as r, l as i, n as a, r as o, s, t as c } from "./recorder-Da1VSLid.js";
|
|
3
|
+
import { parseAssertion as l, parseCase as u } from "./core.js";
|
|
4
|
+
export { e as ResearchAssistant, r as assistantRuntime, t as captureSnapshot, a as downloadSnapshot, s as freezeSnapshot, l as parseAssertion, u as parseCase, o as parseSnapshot, c as recorder, n as reportError, i as startAssistant };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Snapshot } from './runtime';
|
|
2
|
+
/** Future knowledge connector. No endpoint, uploads or automatic context transmission in phase one. */
|
|
3
|
+
export interface KnowledgeProvider {
|
|
4
|
+
ask(input: {
|
|
5
|
+
question: string;
|
|
6
|
+
snapshot?: Snapshot;
|
|
7
|
+
signal?: AbortSignal;
|
|
8
|
+
}): Promise<{
|
|
9
|
+
answer: string;
|
|
10
|
+
sources: {
|
|
11
|
+
title: string;
|
|
12
|
+
url?: string;
|
|
13
|
+
}[];
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface HeapSample {
|
|
2
|
+
time: number;
|
|
3
|
+
used: number;
|
|
4
|
+
limit: number;
|
|
5
|
+
}
|
|
6
|
+
export interface PerformanceEvidence {
|
|
7
|
+
heapSamples: HeapSample[];
|
|
8
|
+
longTasks: {
|
|
9
|
+
time: number;
|
|
10
|
+
duration: number;
|
|
11
|
+
}[];
|
|
12
|
+
}
|
|
13
|
+
export interface PerformanceIssue {
|
|
14
|
+
id: string;
|
|
15
|
+
severity: 'warning' | 'error';
|
|
16
|
+
title: string;
|
|
17
|
+
evidence: string;
|
|
18
|
+
rule: string;
|
|
19
|
+
suggestions: string[];
|
|
20
|
+
url: string;
|
|
21
|
+
}
|
|
22
|
+
export declare const emptyPerformance: () => PerformanceEvidence;
|
|
23
|
+
export declare const megabytes: (bytes: number) => string;
|
|
24
|
+
/** Local heuristics: heap growth is evidence to investigate, never proof of a leak. */
|
|
25
|
+
export declare function diagnosePerformance(metrics: Record<string, number>, data: PerformanceEvidence, now: number): PerformanceIssue[];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function safeText(value: string, limit?: number): string;
|
|
2
|
+
export declare function safeUrl(value: string): string;
|
|
3
|
+
export declare function sanitize(value: unknown, depth?: number, seen?: WeakSet<object>): unknown;
|
|
4
|
+
export declare function bodyPreview(body: unknown): unknown;
|
|
5
|
+
export declare function privateEndpoint(url: string): boolean;
|