Commit Graph
137 Commits
Author SHA1 Message Date
Lum1104andClaude Opus 4.6 4cb38ea360 feat(dashboard): add domain graph loading and view mode toggle pill
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 12:17:23 +08:00
Lum1104andClaude Opus 4.6 16f89c05b8 fix(dashboard): add const assertion, reset domain state in setGraph, add category comment
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 12:15:00 +08:00
Lum1104andClaude Opus 4.6 22fd49a821 feat(dashboard): add domain view state to store (viewMode, domainGraph, activeDomainId)
Add ViewMode type, DOMAIN_EDGE_TYPES, and domain/flow/step entries to
dashboard store, CustomNode, GraphView, and NodeInfo Record maps so the
dashboard compiles with the new core domain node and edge types.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 12:07:05 +08:00
Lum1104andClaude Opus 4.6 005758b922 fix(core): improve step ID normalization and add missing test coverage
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:51:12 +08:00
Lum1104andClaude Opus 4.6 9693e1efee fix(core): remove dead import and unnecessary type cast in domain persistence test
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:43:23 +08:00
Lum1104andClaude Opus 4.6 d89d7f6e93 feat(core): add domain/flow/step prefixes to node ID normalization
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:40:36 +08:00
Lum1104andClaude Opus 4.6 fe01ee0f85 feat(core): add saveDomainGraph/loadDomainGraph persistence functions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:29:26 +08:00
Lum1104andClaude Opus 4.6 37e56d62b3 feat(core): add domain/flow/step node types and domain edge types for business domain knowledge
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:08:52 +08:00
Yuxiang LinandGitHub efd4c483ec Merge pull request #65 from fishinakleinbottle/fix/normalization-for-generated-graph
fix(core): deterministic node ID normalization for parallel batch output
2026-04-01 21:12:45 +08:00
Lum1104andClaude Opus 4.6 6f443fbc14 fix(core): handle all 13 node types, edge cross-variant resolution, and dropped edge traceability
- Add all 13 node types (including non-code) to VALID_PREFIXES and TYPE_TO_PREFIX
  to prevent valid IDs like config:tsconfig.json from being stripped
- Add fallback normalizeNodeId on edge endpoints not found in idMap, fixing
  silent relationship loss when edges use different malformed variants than nodes
- Add DroppedEdge interface with source, target, type, and reason fields so
  callers can surface exactly which edges were lost and why
- Use honest Record<string, unknown>[] return types instead of unsafe type casts
- Align SKILL.md complexity aliases with COMPLEXITY_STRING_MAP
- Add 5 new tests for non-code types, cross-variant edges, dropped edge detail,
  and validateGraph integration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:10:43 +08:00
Sreeram 60c2ead398 fix(core): add deterministic normalization for parallel batch analyzer output
Parallel file-analyzer subagents can produce inconsistent node IDs
(project-name prefixed, double-prefixed, bare paths) and invalid
complexity values. Phase 3 ASSEMBLE now normalizes these deterministically
before merging, preventing cascading edge drops and dashboard load failures.

- Add normalize-graph.ts with normalizeNodeId, normalizeComplexity,
  and normalizeBatchOutput utilities
- Rewrite SKILL.md Phase 3 with 6-step normalization sequence
- Strengthen file-analyzer prompt with ID format warnings
- Add 32 normalization tests and 2 schema boundary tests
2026-03-31 16:34:04 +05:30
Pablo Speciale ee2c9c8dd7 fix: use POSIX-compatible pipe instead of bash herestring in hooks
The PostToolUse hook used `<<<` (bash herestring) which fails when
Claude Code runs hooks under `/bin/sh`. Replace with `echo | grep`
for POSIX compatibility.
2026-03-31 12:12:02 +02:00
43ab4fb893 fix: hide redundant bottom bar (CodeViewer) on node click, closes #55
Agent-Logs-Url: https://github.com/Lum1104/Understand-Anything/sessions/f2065131-263d-42f8-957c-4006b0954284

Co-authored-by: fishinakleinbottle <11816323+fishinakleinbottle@users.noreply.github.com>
2026-03-29 15:09:15 +00:00
Lum1104andClaude Opus 4.6 d4e5e7f875 fix(dashboard): make header legends horizontally scrollable on overflow
Split the header into three sections: fixed left (project name, persona),
scrollable middle (diff toggle, node type filters, layer legend), and
fixed right (filter, export, path, theme actions). Prevents toolbar
overflow when projects have many layers or node types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 11:18:22 +08:00
Lum1104andClaude Opus 4.6 8de31ea8e6 fix(dashboard): fix PNG export by replacing foreignObject with clean SVG primitives
The foreignObject approach caused canvas tainting — browsers block
canvas.toBlob() when the SVG contains embedded DOM content. Extracted
a shared buildCleanSvg() helper using only rect/line/text elements,
reused by both PNG and SVG export.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 11:13:57 +08:00
Lum1104andClaude Opus 4.6 4d92381da1 Merge main into feat/dashboard-export-filtering
Resolved conflicts by keeping main's features (ThemeProvider, TokenGate,
WarningBanner, graph validation, layer navigation, sidebar composing
behavior) and integrating PR's new features (FilterPanel, ExportMenu,
PathFinderModal, NodeTooltip, ProjectOverview stats) on top.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 11:02:15 +08:00
Lum1104andClaude Opus 4.6 41d72e32f1 chore: bump version to 2.0.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 23:30:34 +08:00
Lum1104andClaude Opus 4.6 40a460df48 fix(dashboard): reduce code viewer overlay height to avoid blocking nodes
Reduced from 40vh to 25vh so the overlay sits closer to the bottom
and leaves more room for graph nodes above.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 23:27:33 +08:00
Lum1104andClaude Opus 4.6 4d2cb32232 fix: address comprehensive code review findings for PR #51
Fix all issues from the 5-agent parallel code review of universal file
type support:

- Parser error handling: add console.warn in JSON/YAML catch blocks,
  warn on unbalanced braces in Protobuf/Terraform parsers
- Parser correctness: filter .PHONY special targets in Makefile parser,
  handle opening brace on next line in Shell parser, fix per-stage
  EXPOSE port assignment in Dockerfile parser
- Graph builder: use nodeType-based ID prefix instead of hardcoded
  "file:", warn on unknown definition kinds, detect duplicate node IDs
- Type safety: export NodeType alias, add ServiceInfo.lineRange, type
  dashboard color maps as Record<NodeType,...>, refactor
  getDirectionalLabel to Record<EdgeType,...>, consolidate NodeCategory
- Schema: add StrictLanguageConfigSchema with extensions/filenames
  refinement, fix Infrastructure/Schema-Data category comments
- Agent prompts: fix Jenkinsfile language ID (groovy → jenkinsfile),
  fix css.md edge type (configures → related), remove shell.md
  Makefile cross-reference
- Tests: 20+ new edge case tests across parsers, graph builder,
  language registry, and plugin registry
- Documentation: add JSDoc to all 12 parser classes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 21:55:20 +08:00
Berkcan Gümüşışık 30e6b87c7d Add filters, export, path finder & tooltips
Introduce interactive graph tools and UI improvements: add FilterPanel, ExportMenu, PathFinderModal and NodeTooltip components; extend CustomNode data with incoming/outgoing counts and tags. Wire new components into App (buttons + keyboard shortcuts F/E/P) and implement outside-click/escape handling. Update GraphView to apply persona + filter rules, compute connection counts, register ReactFlow instance, and render per-node tooltips. Add JSON/SVG/PNG export that respects persona/filters and a BFS-based path finder UI. Enhance ProjectOverview with complexity distribution, most-connected nodes and average connections. Extend store with FilterState, edge category types, reactFlowInstance and toggles.
2026-03-28 15:46:25 +03:00
Lum1104andClaude Opus 4.6 49bcfd604c chore: bump version to 1.4.0 for universal file type support
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 19:15:53 +08:00
Lum1104andClaude Opus 4.6 71468e8082 fix: address code review findings for universal file type support
- Expand persona filter in GraphView.tsx to show all 9 file-level node
  types (file, config, document, service, table, endpoint, pipeline,
  schema, resource) instead of only "file", fixing invisible nodes
- Add serves, provisions, and routes edge types with creation criteria
  to file-analyzer-prompt.md
- Fix related edge weight from 0.3 to 0.5 to match SKILL.md default
- Add filenames to openapiConfig for proper filename-based detection
- Add TODO comments to kubernetesConfig and jsonSchemaConfig explaining
  content-based detection limitations
- Clarify that module/concept types are reserved for higher-level agents
- Update language-registry tests for 38 built-in configs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 19:14:00 +08:00
Lum1104andClaude Opus 4.6 376c235d5e feat(pipeline): update main skill pipeline for non-code file analysis
Phase 1 (SCAN): Include non-code files in scan, add fileCategory to
batch metadata. Phase 2 (ANALYZE): Add batching strategy for non-code
files, group related infra/data/doc files together, pass fileCategory
per file. Phase 4 (ARCHITECTURE): Inject non-code language snippets
(markdown, yaml, dockerfile, sql, etc.), pass all node types and all
edge types to architecture analyzer. Phase 5 (TOUR): Include non-code
nodes in tour candidate pool, pass all edge types for topology analysis.
Update node type reference table (5 -> 13 types), edge type reference
table (18 -> 26 types), edge weight conventions, and inline validation
script to handle file-level non-code node types for layer coverage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:59:08 +08:00
Lum1104andClaude Opus 4.6 e7ebc600aa feat(agents): add language context snippets for 11 non-code file types
Add language context snippets for markdown, yaml, json, sql, dockerfile,
terraform, graphql, protobuf, shell, html, and css. Each snippet follows
the existing typescript.md/python.md pattern with Key Concepts, Notable
File Patterns, Edge Patterns, and Summary Style sections. These snippets
are injected into the architecture analyzer prompt to improve layer
assignments for non-code files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:56:14 +08:00
Lum1104andClaude Opus 4.6 8ac3a2096a feat(agents): update graph reviewer for new node/edge types
Add 8 new node types (config, document, service, table, endpoint,
pipeline, schema, resource) to valid type list, bringing total to 13.
Add 8 new edge types (deploys, serves, migrates, documents, provisions,
routes, defines_schema, triggers) to valid type list, bringing total to
26. Add quality checks: config nodes should have configures edges, doc
nodes should have documents edges, service nodes should have deploys
edges, etc. Add node type / ID prefix consistency check. Update layer
coverage to include all file-level node types.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:53:56 +08:00
Lum1104andClaude Opus 4.6 83040be895 feat(agents): extend tour builder for non-code file stops
Allow non-code files as tour stops: README.md as step 1, Dockerfile,
SQL migrations, CI configs, and other infrastructure files. Add non-code
file inventory computation to the topology script. Add languageLesson
concepts for Dockerfile (multi-stage builds), SQL (normalization), YAML
(CI/CD triggers), Terraform (state management), GraphQL (type system),
Protobuf (backward compatibility), and Kubernetes (deployments). Update
pedagogical flow to weave non-code stops into the narrative naturally.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:52:36 +08:00
Lum1104andClaude Opus 4.6 7c8f056447 feat(agents): add non-code pattern detection to architecture analyzer
Add deployment topology detection (Dockerfile -> compose -> K8s), data
pipeline detection (schema -> migration -> API -> client), documentation
coverage analysis, and cross-category dependency analysis. Update layer
hints for infrastructure, documentation, data, ci-cd, and configuration
layers. Expand directory pattern matching with non-code patterns. Increase
max layer count from 7 to 10 to accommodate non-code layers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:50:29 +08:00
Lum1104andClaude Opus 4.6 c1eda8395f feat(agents): add type-aware analysis prompts for non-code files
Update file-analyzer-prompt.md with category-specific extraction guidance
for config, docs, infra, data, script, and markup files. Add new output
fields (sections, definitions, services, endpoints, steps, resources) and
nodeType mapping from fileCategory to graph node types. Add edge generation
guidance for non-code relationships (configures, documents, deploys,
migrates, triggers, defines_schema). Expand tagging vocabulary with
infrastructure, database, ci-cd, deployment, and migration tags.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:48:21 +08:00
Lum1104andClaude Opus 4.6 642626653c feat(dashboard): add node type category filter controls
Add nodeTypeFilters state and toggleNodeTypeFilter action to the Zustand
store, apply category-based filtering in GraphView's useLayerDetailTopology,
and render filter toggle buttons in the App header for Code, Config, Docs,
Infra, and Data categories with colored indicator dots.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:48:08 +08:00
Lum1104andClaude Opus 4.6 78c8ce2602 feat(dashboard): add file type breakdown to ProjectOverview
Show a categorized count of node types (Code, Config, Docs, Infra, Data)
with colored dots matching node type colors. Only displayed when non-code
nodes are present in the graph.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:46:49 +08:00
Lum1104andClaude Opus 4.6 6e3213e849 feat(dashboard): add new node/edge type support to NodeInfo sidebar
Add badge colors for 8 new node types (config, document, service,
table, endpoint, pipeline, schema, resource) and directional labels
for 8 new edge types (deploys, serves, migrates, documents, provisions,
routes, defines_schema, triggers).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:46:11 +08:00
Lum1104andClaude Opus 4.6 07ac08248e feat(dashboard): add new node type colors to CustomNode
Add typeColors and typeTextColors entries for config, document, service,
table, endpoint, pipeline, schema, and resource node types.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:45:37 +08:00
Lum1104andClaude Opus 4.6 231ef484a0 feat(agents): update project-scanner to discover all file types
Remove the code-only file filter so the scanner discovers non-code files
(.md, .yaml, .json, .sql, .tf, Dockerfile, etc.). Add fileCategory field
to each discovered file (code/config/docs/infra/data/script/markup) with
extension-based category detection logic. Expand language detection table
to cover 26+ file types. Infrastructure tooling detection added to
framework detection step.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:45:20 +08:00
Lum1104andClaude Opus 4.6 10173b19c5 feat(dashboard): add 8 new node type colors to all theme presets
Add colors for config, document, service, table, endpoint, pipeline,
schema, and resource node types to all 5 theme presets (dark-gold,
dark-ocean, dark-forest, dark-rose, light-minimal) and register the
CSS variables in the Tailwind v4 @theme block.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:45:08 +08:00
Lum1104andClaude Opus 4.6 db572231f8 feat(core): export new types and parsers from core
Export all 12 non-code parsers (MarkdownParser, YAMLConfigParser,
JSONConfigParser, TOMLParser, EnvParser, DockerfileParser, SQLParser,
GraphQLParser, ProtobufParser, TerraformParser, MakefileParser,
ShellParser) and the registerAllParsers() helper from core index.

New type exports (SectionInfo, DefinitionInfo, ServiceInfo, etc.)
are already covered by the existing `export * from "./types.js"`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:40:55 +08:00
Lum1104andClaude Opus 4.6 2bb107e2d9 feat(core): add non-code file support to GraphBuilder
Add addNonCodeFile() and addNonCodeFileWithAnalysis() methods that create
graph nodes with the appropriate non-code types (document, config, service,
table, endpoint, pipeline, schema, resource).

addNonCodeFileWithAnalysis() creates child nodes for definitions, services,
endpoints, steps, and resources with "contains" edges to the parent file.

Add mapKindToNodeType() helper for mapping definition kinds to node types.
Extend EXTENSION_LANGUAGE map with all non-code file extensions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:40:04 +08:00
Lum1104andClaude Opus 4.6 3fd688ac37 feat(core): add 12 custom parsers for non-code file types
Add regex/parser-based analyzers for: Markdown, YAML, JSON, TOML, Env,
Dockerfile, SQL, GraphQL, Protobuf, Terraform, Makefile, Shell.

Each implements AnalyzerPlugin with analyzeFile() and optional
extractReferences(). Uses `yaml` npm package for YAML parsing,
built-in JSON.parse for JSON, regex for all others.

Add registerAllParsers() helper to register all parsers at once.
Add comprehensive test suite with 35 tests covering all parsers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:38:25 +08:00
Lum1104andClaude Opus 4.6 c76b0a1f2d feat(core): add 26 non-code language configs with filename-based detection
Add LanguageConfig files for: markdown, yaml, json, toml, env, xml,
dockerfile, sql, graphql, protobuf, terraform, github-actions, makefile,
shell, html, css, openapi, kubernetes, docker-compose, json-schema, csv,
restructuredtext, powershell, batch, jenkinsfile, plaintext.

Add filenames? field to LanguageConfigSchema for filename-based detection
(Dockerfile, Makefile, Jenkinsfile, docker-compose.yml, .env variants).

Update LanguageRegistry.getForFile() to check filename matches first
(more specific) before falling back to extension-based lookup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:34:16 +08:00
Lum1104andClaude Opus 4.6 9eb220c492 feat(core): make resolveImports optional on AnalyzerPlugin
Update PluginRegistry.resolveImports() to check for plugin.resolveImports
existence before calling it. Non-code plugins (e.g., markdown, dockerfile)
don't need import resolution, so this method is now optional.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:31:00 +08:00
Lum1104andClaude Opus 4.6 1f554146c0 feat(core): extend Zod schemas and aliases for 8 new node/edge types
Update EdgeTypeSchema with 8 new edge types (deploys, serves, migrates,
documents, provisions, routes, defines_schema, triggers).

Update GraphNodeSchema with 8 new node types (config, document, service,
table, endpoint, pipeline, schema, resource).

Add NODE_TYPE_ALIASES for non-code types (container->service, doc->document,
workflow->pipeline, etc.) and EDGE_TYPE_ALIASES (describes->documents,
creates->provisions, exposes->serves, etc.).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:30:17 +08:00
Lum1104andClaude Opus 4.6 b1f763adac feat(core): extend GraphNode/EdgeType/StructuralAnalysis for non-code file types
Add 8 new node types (config, document, service, table, endpoint,
pipeline, schema, resource) and 8 new edge types (deploys, serves,
migrates, documents, provisions, routes, defines_schema, triggers).

Add StructuralAnalysis sub-interfaces: SectionInfo, DefinitionInfo,
ServiceInfo, EndpointInfo, StepInfo, ResourceInfo, ReferenceResolution.

Make resolveImports optional on AnalyzerPlugin and add extractReferences.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:29:01 +08:00
Lum1104andClaude Opus 4.6 26cc41cf03 feat(dashboard): add token gate page for unauthenticated access
Visiting localhost:5173 without ?token= now shows a clean token input
page instead of a broken dashboard. Token is persisted in sessionStorage
so refreshes work within the same browser session.

Bump version to 1.3.1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 16:59:51 +08:00
Yuxiang LinandGitHub 07c49fd4b0 Merge pull request #44 from fishinakleinbottle/feat/improve-dashboard-ux
Dashboard Improvement: lens-based hierarchical graph navigation
2026-03-28 16:45:24 +08:00
Lum1104andClaude Opus 4.6 86be2da691 chore: bump version to 1.3.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 16:45:05 +08:00
Lum1104andClaude Opus 4.6 6fcee67214 fix(dashboard): review fixes for hierarchical navigation PR
- Restore topology/visual separation in useLayerDetailGraph to prevent
  dagre relayout on every selection/search change (perf regression)
- Remove unused tourHighlightedNodeIds from useOverviewGraph deps
- Remove dead code: showLayers/toggleLayers, zoomToNodeId,
  applyDagreLayoutAsync (Web Worker path)
- Replace direct useDashboardStore.setState() in NodeInfo with proper
  navigateToHistoryIndex store action
- Fix non-technical persona filter (was no-op due to prior type=file constraint)
- Integrate Escape-to-overview into App keyboard shortcuts (remove
  duplicate listener from Breadcrumb)
- Cap nodeHistory at 50 entries to prevent unbounded growth
- Add memo() to LayerClusterNode and PortalNode for render performance
- Make computePortals accept pre-computed aggregation to avoid redundant work
- Restore code viewer popup on node click
- Show NodeInfo above LearnPanel when a node is selected

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 16:44:15 +08:00
Lum1104 3cdc2ac71b Merge branch 'main' into pr44/improve-dashboard-ux
# Conflicts:
#	understand-anything-plugin/packages/dashboard/src/components/GraphView.tsx
#	understand-anything-plugin/packages/dashboard/src/components/LayerLegend.tsx
#	understand-anything-plugin/packages/dashboard/src/components/NodeInfo.tsx
2026-03-28 16:20:58 +08:00
Yuxiang LinandGitHub 710f312498 Merge pull request #41 from berkcangumusisik/test/improve-coverage
Expand core tests and add vitest coverage dep
2026-03-28 15:56:19 +08:00
Lum1104 34dcf1f16b Make persistence test compatible with current main 2026-03-28 15:55:15 +08:00
Lum1104 334ac871df Align persistence test with fatal validation behavior 2026-03-28 15:53:31 +08:00
Lum1104 e7ad9d6d69 Fix ImportResolution test fixture 2026-03-28 15:46:33 +08:00