From aa3e4369b763eb5691b80e32404343a9a7679a7a Mon Sep 17 00:00:00 2001 From: Josh Field <10372036+HexaField@users.noreply.github.com> Date: Tue, 28 Jul 2026 19:04:44 +1000 Subject: [PATCH 1/3] feat(assistant): AD4M AI-assistant UI (thread view, config, model selector) Additive AI-assistant surface for the AD4M-embedded assistant runtime. Renders threads/messages from perspective subject classes and lights up when the executor backend (separate PR on coasys/ad4m) writes replies into the perspective; makes no in-browser LLM call. Existing template-editor AiStore is untouched. - Subject classes: Assistant, Personality, Skill, McpServer, Thread, Message (we:// predicates) - AssistantStore + thread list / thread view / message (collapsible tool-call rendering) / config panel (Assistants/Personalities/Skills/MCP) - AiAssistant shell schema + sidebar nav + component/store registry wiring - Streaming via progressive Message.content updates under a live query (no separate token channel needed) Verified: Vite prod build of app-web PASS, @we/app-framework build+DTS PASS, app-framework tsc 0 errors, 62 unit tests pass. Live/visual verification pending a running executor + the backend runtime. Co-Authored-By: Claude Opus 4.8 --- .cursor/rules/we-schema.mdc | 49 +- .github/copilot-instructions.md | 49 +- CLAUDE.md | 49 +- packages/ai-context/context.json | 232 +++++- packages/ai-context/src/contextData.ts | 89 ++- packages/ai-context/src/schemaContext.ts | 2 +- .../assistant/AssistantConfigPanel.tsx | 521 ++++++++++++++ .../components/assistant/AssistantMessage.tsx | 170 +++++ .../assistant/AssistantThreadList.tsx | 105 +++ .../assistant/AssistantThreadView.tsx | 153 ++++ .../solid/layouts/TemplateLayout.tsx | 2 + .../solid/providers/StoreProvider.tsx | 5 +- .../solid/providers/TemplateProvider.tsx | 3 + .../solid/registries/componentRegistry.tsx | 8 + .../solid/stores/AssistantStore.tsx | 663 ++++++++++++++++++ .../src/frameworks/solid/stores/index.ts | 8 + .../src/frameworks/solid/types.ts | 12 +- .../app-framework/src/shared/schemas/index.ts | 1 + .../schemas/shell/AiAssistant.schema.ts | 49 ++ .../shared/schemas/shell/Sidebar.schema.ts | 12 + .../src/shared/schemas/shell/index.ts | 1 + .../app-framework/src/shared/sdnaModels.ts | 19 + packages/models/src/entities/Assistant.ts | 43 ++ packages/models/src/entities/McpServer.ts | 35 + packages/models/src/entities/Message.ts | 46 ++ packages/models/src/entities/Personality.ts | 20 + packages/models/src/entities/Skill.ts | 23 + packages/models/src/entities/Thread.ts | 41 ++ packages/models/src/entities/index.ts | 6 + packages/models/src/index.ts | 6 + 30 files changed, 2402 insertions(+), 20 deletions(-) create mode 100644 packages/app-framework/src/frameworks/solid/components/assistant/AssistantConfigPanel.tsx create mode 100644 packages/app-framework/src/frameworks/solid/components/assistant/AssistantMessage.tsx create mode 100644 packages/app-framework/src/frameworks/solid/components/assistant/AssistantThreadList.tsx create mode 100644 packages/app-framework/src/frameworks/solid/components/assistant/AssistantThreadView.tsx create mode 100644 packages/app-framework/src/frameworks/solid/stores/AssistantStore.tsx create mode 100644 packages/app-framework/src/shared/schemas/shell/AiAssistant.schema.ts create mode 100644 packages/models/src/entities/Assistant.ts create mode 100644 packages/models/src/entities/McpServer.ts create mode 100644 packages/models/src/entities/Message.ts create mode 100644 packages/models/src/entities/Personality.ts create mode 100644 packages/models/src/entities/Skill.ts create mode 100644 packages/models/src/entities/Thread.ts diff --git a/.cursor/rules/we-schema.mdc b/.cursor/rules/we-schema.mdc index dd29f1ac..cf7c0ef7 100644 --- a/.cursor/rules/we-schema.mdc +++ b/.cursor/rules/we-schema.mdc @@ -799,7 +799,7 @@ when `relative` is enabled. - Grid (DesignSystemElement) Props: template?: string, columns?: number, minChildWidth?: string - IconLabelButton - Props: icon: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, label: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, selected?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, iconWeight?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, onClick?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor<(() => void) | undefined>, class?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, styles?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor | undefined> + Props: icon: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, label: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, selected?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, iconWeight?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, onClick?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor<(() => void) | undefined>, class?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, styles?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor | undefined> - ImageCrop Props: src: string, fileName?: string, aspect?: number, maxSize?: number, outputType?: string, quality?: number, onReady?: ((ref: ImageCropRef) => void) - ImageLightbox @@ -1048,6 +1048,15 @@ AgentSettings extends Ad4mModel: - installedThemes: HasMany → Theme [we://installed_theme] - spaceTemplatePreferences: HasMany → SpaceTemplatePreference [we://space_template_preference] +Assistant extends WeNode: + Fields: + - name: string [we://name] + - modelId: string [we://model_id] + - systemPrompt: string [we://system_prompt] + - personalityIds: string [we://personality_ids] + - skillIds: string [we://skill_ids] + - mcpServerIds: string [we://mcp_server_ids] + AudioBlock extends WeNode: Fields: - title: string (required) [we://title] @@ -1157,6 +1166,28 @@ LocationBlock extends WeNode: - country: string [we://country] - version: number [we://version] +McpServer extends WeNode: + Fields: + - name: string [we://name] + - transport: string = 'stdio' [we://transport] + - url: string [we://url] + - command: string [we://command] + - auth: string [we://auth] + +Message extends WeNode: + Fields: + - threadId: string [we://thread_id] + - role: string [we://role] + - content: string [we://content] + - toolCalls: string [we://tool_calls] + - ts: string [we://ts] + - status: string [we://status] + +Personality extends WeNode: + Fields: + - name: string [we://name] + - body: string [we://body] + Signal extends Ad4mModel: Fields: - signalTypeId: string [we://signal_type_id] @@ -1179,6 +1210,12 @@ SignalType extends WeNode: - valueType: string = 'numeric' [we://signal_value_type] - schemaVersion: number = 1 [we://schema_version] +Skill extends WeNode: + Fields: + - name: string [we://name] + - description: string [we://description] + - body: string [we://body] + Space extends WeNode: Fields: - uuid: string [we://uuid] @@ -1255,6 +1292,16 @@ Theme extends WeNode: Relations: - screenshots: HasMany → ImageBlock [we://screenshot] +Thread extends WeNode: + Fields: + - title: string [we://title] + - assistantId: string [we://assistant_id] + - modelId: string [we://model_id] + - createdAt: string [we://created_at] + - updatedAt: string [we://updated_at] + Relations: + - messages: HasMany → Message [we://message] + VideoBlock extends WeNode: Fields: - title: string [we://title] diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index dd29f1ac..cf7c0ef7 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -799,7 +799,7 @@ when `relative` is enabled. - Grid (DesignSystemElement) Props: template?: string, columns?: number, minChildWidth?: string - IconLabelButton - Props: icon: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, label: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, selected?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, iconWeight?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, onClick?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor<(() => void) | undefined>, class?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, styles?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor | undefined> + Props: icon: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, label: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, selected?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, iconWeight?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, onClick?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor<(() => void) | undefined>, class?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, styles?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor | undefined> - ImageCrop Props: src: string, fileName?: string, aspect?: number, maxSize?: number, outputType?: string, quality?: number, onReady?: ((ref: ImageCropRef) => void) - ImageLightbox @@ -1048,6 +1048,15 @@ AgentSettings extends Ad4mModel: - installedThemes: HasMany → Theme [we://installed_theme] - spaceTemplatePreferences: HasMany → SpaceTemplatePreference [we://space_template_preference] +Assistant extends WeNode: + Fields: + - name: string [we://name] + - modelId: string [we://model_id] + - systemPrompt: string [we://system_prompt] + - personalityIds: string [we://personality_ids] + - skillIds: string [we://skill_ids] + - mcpServerIds: string [we://mcp_server_ids] + AudioBlock extends WeNode: Fields: - title: string (required) [we://title] @@ -1157,6 +1166,28 @@ LocationBlock extends WeNode: - country: string [we://country] - version: number [we://version] +McpServer extends WeNode: + Fields: + - name: string [we://name] + - transport: string = 'stdio' [we://transport] + - url: string [we://url] + - command: string [we://command] + - auth: string [we://auth] + +Message extends WeNode: + Fields: + - threadId: string [we://thread_id] + - role: string [we://role] + - content: string [we://content] + - toolCalls: string [we://tool_calls] + - ts: string [we://ts] + - status: string [we://status] + +Personality extends WeNode: + Fields: + - name: string [we://name] + - body: string [we://body] + Signal extends Ad4mModel: Fields: - signalTypeId: string [we://signal_type_id] @@ -1179,6 +1210,12 @@ SignalType extends WeNode: - valueType: string = 'numeric' [we://signal_value_type] - schemaVersion: number = 1 [we://schema_version] +Skill extends WeNode: + Fields: + - name: string [we://name] + - description: string [we://description] + - body: string [we://body] + Space extends WeNode: Fields: - uuid: string [we://uuid] @@ -1255,6 +1292,16 @@ Theme extends WeNode: Relations: - screenshots: HasMany → ImageBlock [we://screenshot] +Thread extends WeNode: + Fields: + - title: string [we://title] + - assistantId: string [we://assistant_id] + - modelId: string [we://model_id] + - createdAt: string [we://created_at] + - updatedAt: string [we://updated_at] + Relations: + - messages: HasMany → Message [we://message] + VideoBlock extends WeNode: Fields: - title: string [we://title] diff --git a/CLAUDE.md b/CLAUDE.md index dd29f1ac..cf7c0ef7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -799,7 +799,7 @@ when `relative` is enabled. - Grid (DesignSystemElement) Props: template?: string, columns?: number, minChildWidth?: string - IconLabelButton - Props: icon: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, label: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, selected?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, iconWeight?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, onClick?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor<(() => void) | undefined>, class?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor, styles?: import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor | undefined> + Props: icon: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, label: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, selected?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, iconWeight?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, onClick?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor<(() => void) | undefined>, class?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor, styles?: import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor | undefined> - ImageCrop Props: src: string, fileName?: string, aspect?: number, maxSize?: number, outputType?: string, quality?: number, onReady?: ((ref: ImageCropRef) => void) - ImageLightbox @@ -1048,6 +1048,15 @@ AgentSettings extends Ad4mModel: - installedThemes: HasMany → Theme [we://installed_theme] - spaceTemplatePreferences: HasMany → SpaceTemplatePreference [we://space_template_preference] +Assistant extends WeNode: + Fields: + - name: string [we://name] + - modelId: string [we://model_id] + - systemPrompt: string [we://system_prompt] + - personalityIds: string [we://personality_ids] + - skillIds: string [we://skill_ids] + - mcpServerIds: string [we://mcp_server_ids] + AudioBlock extends WeNode: Fields: - title: string (required) [we://title] @@ -1157,6 +1166,28 @@ LocationBlock extends WeNode: - country: string [we://country] - version: number [we://version] +McpServer extends WeNode: + Fields: + - name: string [we://name] + - transport: string = 'stdio' [we://transport] + - url: string [we://url] + - command: string [we://command] + - auth: string [we://auth] + +Message extends WeNode: + Fields: + - threadId: string [we://thread_id] + - role: string [we://role] + - content: string [we://content] + - toolCalls: string [we://tool_calls] + - ts: string [we://ts] + - status: string [we://status] + +Personality extends WeNode: + Fields: + - name: string [we://name] + - body: string [we://body] + Signal extends Ad4mModel: Fields: - signalTypeId: string [we://signal_type_id] @@ -1179,6 +1210,12 @@ SignalType extends WeNode: - valueType: string = 'numeric' [we://signal_value_type] - schemaVersion: number = 1 [we://schema_version] +Skill extends WeNode: + Fields: + - name: string [we://name] + - description: string [we://description] + - body: string [we://body] + Space extends WeNode: Fields: - uuid: string [we://uuid] @@ -1255,6 +1292,16 @@ Theme extends WeNode: Relations: - screenshots: HasMany → ImageBlock [we://screenshot] +Thread extends WeNode: + Fields: + - title: string [we://title] + - assistantId: string [we://assistant_id] + - modelId: string [we://model_id] + - createdAt: string [we://created_at] + - updatedAt: string [we://updated_at] + Relations: + - messages: HasMany → Message [we://message] + VideoBlock extends WeNode: Fields: - title: string [we://title] diff --git a/packages/ai-context/context.json b/packages/ai-context/context.json index 0a8881e8..c778cd5f 100644 --- a/packages/ai-context/context.json +++ b/packages/ai-context/context.json @@ -3212,37 +3212,37 @@ "props": [ { "name": "icon", - "type": "import(\"/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid\").MaybeAccessor", + "type": "import(\"/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid\").MaybeAccessor", "optional": false }, { "name": "label", - "type": "import(\"/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid\").MaybeAccessor", + "type": "import(\"/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid\").MaybeAccessor", "optional": false }, { "name": "selected", - "type": "import(\"/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid\").MaybeAccessor", + "type": "import(\"/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid\").MaybeAccessor", "optional": true }, { "name": "iconWeight", - "type": "import(\"/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid\").MaybeAccessor", + "type": "import(\"/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid\").MaybeAccessor", "optional": true }, { "name": "onClick", - "type": "import(\"/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid\").MaybeAccessor<(() => void) | undefined>", + "type": "import(\"/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid\").MaybeAccessor<(() => void) | undefined>", "optional": true }, { "name": "class", - "type": "import(\"/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid\").MaybeAccessor", + "type": "import(\"/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid\").MaybeAccessor", "optional": true }, { "name": "styles", - "type": "import(\"/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid\").MaybeAccessor | undefined>", + "type": "import(\"/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid\").MaybeAccessor | undefined>", "optional": true } ], @@ -3958,6 +3958,50 @@ } ] }, + { + "name": "Assistant", + "className": "Assistant", + "extends": "WeNode", + "fields": [ + { + "name": "name", + "type": "string", + "predicate": "we://name", + "required": false + }, + { + "name": "modelId", + "type": "string", + "predicate": "we://model_id", + "required": false + }, + { + "name": "systemPrompt", + "type": "string", + "predicate": "we://system_prompt", + "required": false + }, + { + "name": "personalityIds", + "type": "string", + "predicate": "we://personality_ids", + "required": false + }, + { + "name": "skillIds", + "type": "string", + "predicate": "we://skill_ids", + "required": false + }, + { + "name": "mcpServerIds", + "type": "string", + "predicate": "we://mcp_server_ids", + "required": false + } + ], + "relations": [] + }, { "name": "AudioBlock", "className": "AudioBlock", @@ -4476,6 +4520,109 @@ ], "relations": [] }, + { + "name": "McpServer", + "className": "McpServer", + "extends": "WeNode", + "fields": [ + { + "name": "name", + "type": "string", + "predicate": "we://name", + "required": false + }, + { + "name": "transport", + "type": "string", + "predicate": "we://transport", + "required": false, + "default": "'stdio'" + }, + { + "name": "url", + "type": "string", + "predicate": "we://url", + "required": false + }, + { + "name": "command", + "type": "string", + "predicate": "we://command", + "required": false + }, + { + "name": "auth", + "type": "string", + "predicate": "we://auth", + "required": false + } + ], + "relations": [] + }, + { + "name": "Message", + "className": "Message", + "extends": "WeNode", + "fields": [ + { + "name": "threadId", + "type": "string", + "predicate": "we://thread_id", + "required": false + }, + { + "name": "role", + "type": "string", + "predicate": "we://role", + "required": false + }, + { + "name": "content", + "type": "string", + "predicate": "we://content", + "required": false + }, + { + "name": "toolCalls", + "type": "string", + "predicate": "we://tool_calls", + "required": false + }, + { + "name": "ts", + "type": "string", + "predicate": "we://ts", + "required": false + }, + { + "name": "status", + "type": "string", + "predicate": "we://status", + "required": false + } + ], + "relations": [] + }, + { + "name": "Personality", + "className": "Personality", + "extends": "WeNode", + "fields": [ + { + "name": "name", + "type": "string", + "predicate": "we://name", + "required": false + }, + { + "name": "body", + "type": "string", + "predicate": "we://body", + "required": false + } + ], + "relations": [] + }, { "name": "Signal", "className": "Signal", @@ -4596,6 +4743,32 @@ ], "relations": [] }, + { + "name": "Skill", + "className": "Skill", + "extends": "WeNode", + "fields": [ + { + "name": "name", + "type": "string", + "predicate": "we://name", + "required": false + }, + { + "name": "description", + "type": "string", + "predicate": "we://description", + "required": false + }, + { + "name": "body", + "type": "string", + "predicate": "we://body", + "required": false + } + ], + "relations": [] + }, { "name": "Space", "className": "Space", @@ -4975,6 +5148,51 @@ } ] }, + { + "name": "Thread", + "className": "Thread", + "extends": "WeNode", + "fields": [ + { + "name": "title", + "type": "string", + "predicate": "we://title", + "required": false + }, + { + "name": "assistantId", + "type": "string", + "predicate": "we://assistant_id", + "required": false + }, + { + "name": "modelId", + "type": "string", + "predicate": "we://model_id", + "required": false + }, + { + "name": "createdAt", + "type": "string", + "predicate": "we://created_at", + "required": false + }, + { + "name": "updatedAt", + "type": "string", + "predicate": "we://updated_at", + "required": false + } + ], + "relations": [ + { + "name": "messages", + "kind": "HasMany", + "predicate": "we://message", + "target": "Message" + } + ] + }, { "name": "VideoBlock", "className": "VideoBlock", diff --git a/packages/ai-context/src/contextData.ts b/packages/ai-context/src/contextData.ts index c86764da..0dadbd0f 100644 --- a/packages/ai-context/src/contextData.ts +++ b/packages/ai-context/src/contextData.ts @@ -1168,37 +1168,37 @@ export const contextData: ContextData = { props: [ { name: 'icon', - type: 'import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor', + type: 'import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor', optional: false, }, { name: 'label', - type: 'import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor', + type: 'import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor', optional: false, }, { name: 'selected', - type: 'import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor', + type: 'import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor', optional: true, }, { name: 'iconWeight', - type: 'import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor', + type: 'import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor', optional: true, }, { name: 'onClick', - type: 'import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor<(() => void) | undefined>', + type: 'import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor<(() => void) | undefined>', optional: true, }, { name: 'class', - type: 'import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor', + type: 'import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor', optional: true, }, { name: 'styles', - type: 'import("/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid").MaybeAccessor | undefined>', + type: 'import("/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid").MaybeAccessor | undefined>', optional: true, }, ], @@ -1476,6 +1476,20 @@ export const contextData: ContextData = { }, ], }, + { + name: 'Assistant', + className: 'Assistant', + extends: 'WeNode', + fields: [ + { name: 'name', type: 'string', predicate: 'we://name', required: false }, + { name: 'modelId', type: 'string', predicate: 'we://model_id', required: false }, + { name: 'systemPrompt', type: 'string', predicate: 'we://system_prompt', required: false }, + { name: 'personalityIds', type: 'string', predicate: 'we://personality_ids', required: false }, + { name: 'skillIds', type: 'string', predicate: 'we://skill_ids', required: false }, + { name: 'mcpServerIds', type: 'string', predicate: 'we://mcp_server_ids', required: false }, + ], + relations: [], + }, { name: 'AudioBlock', className: 'AudioBlock', @@ -1646,6 +1660,43 @@ export const contextData: ContextData = { ], relations: [], }, + { + name: 'McpServer', + className: 'McpServer', + extends: 'WeNode', + fields: [ + { name: 'name', type: 'string', predicate: 'we://name', required: false }, + { name: 'transport', type: 'string', predicate: 'we://transport', required: false, default: "'stdio'" }, + { name: 'url', type: 'string', predicate: 'we://url', required: false }, + { name: 'command', type: 'string', predicate: 'we://command', required: false }, + { name: 'auth', type: 'string', predicate: 'we://auth', required: false }, + ], + relations: [], + }, + { + name: 'Message', + className: 'Message', + extends: 'WeNode', + fields: [ + { name: 'threadId', type: 'string', predicate: 'we://thread_id', required: false }, + { name: 'role', type: 'string', predicate: 'we://role', required: false }, + { name: 'content', type: 'string', predicate: 'we://content', required: false }, + { name: 'toolCalls', type: 'string', predicate: 'we://tool_calls', required: false }, + { name: 'ts', type: 'string', predicate: 'we://ts', required: false }, + { name: 'status', type: 'string', predicate: 'we://status', required: false }, + ], + relations: [], + }, + { + name: 'Personality', + className: 'Personality', + extends: 'WeNode', + fields: [ + { name: 'name', type: 'string', predicate: 'we://name', required: false }, + { name: 'body', type: 'string', predicate: 'we://body', required: false }, + ], + relations: [], + }, { name: 'Signal', className: 'Signal', @@ -1690,6 +1741,17 @@ export const contextData: ContextData = { ], relations: [], }, + { + name: 'Skill', + className: 'Skill', + extends: 'WeNode', + fields: [ + { name: 'name', type: 'string', predicate: 'we://name', required: false }, + { name: 'description', type: 'string', predicate: 'we://description', required: false }, + { name: 'body', type: 'string', predicate: 'we://body', required: false }, + ], + relations: [], + }, { name: 'Space', className: 'Space', @@ -1795,6 +1857,19 @@ export const contextData: ContextData = { ], relations: [{ name: 'screenshots', kind: 'HasMany', predicate: 'we://screenshot', target: 'ImageBlock' }], }, + { + name: 'Thread', + className: 'Thread', + extends: 'WeNode', + fields: [ + { name: 'title', type: 'string', predicate: 'we://title', required: false }, + { name: 'assistantId', type: 'string', predicate: 'we://assistant_id', required: false }, + { name: 'modelId', type: 'string', predicate: 'we://model_id', required: false }, + { name: 'createdAt', type: 'string', predicate: 'we://created_at', required: false }, + { name: 'updatedAt', type: 'string', predicate: 'we://updated_at', required: false }, + ], + relations: [{ name: 'messages', kind: 'HasMany', predicate: 'we://message', target: 'Message' }], + }, { name: 'VideoBlock', className: 'VideoBlock', diff --git a/packages/ai-context/src/schemaContext.ts b/packages/ai-context/src/schemaContext.ts index c78347c0..8cb8869c 100644 --- a/packages/ai-context/src/schemaContext.ts +++ b/packages/ai-context/src/schemaContext.ts @@ -1,4 +1,4 @@ // AUTO-GENERATED by packages/ai-context/src/generate.ts // Do not edit manually. Run: pnpm --filter @we/ai-context generate-context -export const schemaContext = "## Schema Structure\n\nA schema is a tree of nodes. Each node can have:\n- type: The component to render (string, e.g. \"we-button\", \"Column\")\n- props: An object of props for the component\n- children: An array of child nodes (or strings for text), or token objects like { $store: '...' } or { $concat: [...] }.\n- slots: Named slots for advanced composition (optional)\n- slot: The name of the slot this node should be rendered into (optional)\n- routes: For routing components, an array of nestable route objects (optional)\n- styles: Raw CSS escape hatch — Record applied as inline styles on a **wrapper div** that surrounds the component. Use only for CSS that must live on a wrapper: filter, clip-path, backdrop-filter, mix-blend-mode. When present the wrapper participates in layout (no display:contents), so CSS effects apply correctly. **Important:** this is NOT the same as props.styles. If you want to apply custom CSS to a Column, Row, or Grid's own element (e.g. a background image), put it in props.styles instead — node-level styles go on a wrapper div around the component and will be hidden behind the component's own background.\n\nExample node:\n{\n \"type\": \"we-button\",\n \"props\": {\n \"onClick\": { \"$action\": \"routeStore.navigate\", \"args\": [\"/home\"] }\n },\n \"children\": [\n { \"type\": \"we-icon\", \"props\": { \"name\": \"house\" } },\n { \"type\": \"we-text\", \"props\": { \"size\": \"600\" }, \"children\": [\"Home\"] }\n ]\n}\n\n## Prop-level Dynamic Logic & Expressions\n\nSpecial tokens in props enable dynamic, reactive, or computed behavior.\n\nStore reference:\n{ \"$store\": \"storeName.property.path\" }\nResolves a value from a named store, supporting nested paths.\n\nAction/event:\n{ \"$action\": \"storeName.method\", \"args\": [...] }\nCalls a method on a store, optionally with arguments (which can themselves be tokens).\nSupports async lifecycle callbacks — fired after the store method's Promise resolves/rejects:\n onSuccess: [...actions] — fired on resolve; '$result' (and '$result.') in args refers to the resolved value\n onError: [...actions] — fired on reject; '$result.message' etc. refers to the error object\n onFinally: [...actions] — fired regardless of outcome\nNon-promise (synchronous) methods are unaffected — lifecycle keys are ignored.\nExample — close modal after async submission:\n{ \"$action\": \"adamStore.createSpace\", \"args\": [...], \"onSuccess\": [{ \"$setLocal\": \"modalOpen\", \"value\": false }] }\nExample — navigate to newly created item:\n{ \"$action\": \"adamStore.createSpace\", \"args\": [...], \"onSuccess\": [{ \"$setLocal\": \"modalOpen\", \"value\": false }, { \"$action\": \"routeStore.navigate\", \"args\": [{ \"$concat\": [\"/space/\", \"$result.uuid\"] }] }] }\n\nModel mutations via $action (use these for creating/updating/deleting model instances):\nmodel.create — creates a model instance in the current perspective (default) or a specified one:\n{ \"$action\": \"model.create\", \"args\": [\"ModelName\", { \"field\": \"value\" }, { \"perspective\": \"adamStore.rootPerspective\" }] }\nThe third argument is an options object. Omit it to use the current space perspective.\n\nmodel.update — updates a model instance:\n{ \"$action\": \"model.update\", \"args\": [\"ModelName\", \"$item.id\", { \"field\": \"newValue\" }] }\nTo target a non-current perspective: { \"$action\": \"model.update\", \"args\": [\"ModelName\", \"$item.id\", { \"field\": \"value\" }, { \"perspective\": \"adamStore.rootPerspective\" }] }\n\nmodel.delete — deletes a model instance:\n{ \"$action\": \"model.delete\", \"args\": [\"ModelName\", \"$item.id\"] }\n\nUse perspective: 'adamStore.rootPerspective' for we-root models (AgentSettings, ChatSession, etc.).\nUse the default (no perspective) for space-scoped models (Space, Signal, etc.).\n\nConditional logic:\n{ \"$if\": { \"condition\": ..., \"then\": ..., \"else\": ... } }\nEvaluates condition; if truthy, returns then, else returns else.\n\nMap/iterate:\n{ \"$map\": { \"items\": { \"$store\": \"templateStore.templates\" }, \"select\": { ... } } }\nIterates over an array, mapping each item to a new object using the select mapping.\n\nPick:\n{ \"$pick\": { \"from\": { \"$store\": \"userStore.profile\" }, \"props\": [\"name\", \"email\"] } }\nPicks specific properties from an object.\n\nConcat (string building):\n{ \"$concat\": [\"part1\", \"$context.value\", \"part2\"] }\nJoins multiple parts into a single string.\n\nContext references:\nStrings starting with \"$\" followed by a context key resolve to context values.\nExample: \"$space.name\" resolves to the name property of the space context variable.\nDot paths supported: \"$item.profile.avatar\".\n\nEquality / inequality checks:\n{ \"$eq\": [a, b] } — strict equality\n{ \"$ne\": [a, b] } — strict inequality\n\nNumeric comparisons:\n{ \"$lt\": [a, b] } — a < b (less than)\n{ \"$gt\": [a, b] } — a > b (greater than)\nExample: { \"$gt\": [{ \"$count\": { \"items\": { \"$store\": \"listStore.items\" } } }, 0] }\n\nSet membership:\n{ \"$in\": [value, array] } — true if array contains value (false if second operand is not an array)\nExample: { \"$in\": [{ \"$store\": \"spaceStore.uuid\" }, { \"$store\": \"adamStore.systemPerspectiveUuids\" }] }\nExample: { \"$in\": [\"$item.role\", [\"admin\", \"moderator\"]] }\n\nBoolean logic:\n{ \"$and\": [a, b, ...] } — all truthy\n{ \"$or\": [a, b, ...] } — any truthy\n{ \"$not\": a } — negation\n\nArray operators:\n{ \"$filter\": { \"items\": , \"where\": { \"field\": \"value\", ... } } }\nFilters an array to items where all where conditions match. Mirrors the $query where operator set:\n\n { \"field\": \"value\" } — strict equality\n { \"field\": { \"not\": \"value\" } } — inequality; array form excludes multiple values\n { \"field\": { \"contains\": \"text\" } } — case-insensitive substring match (strings only)\n { \"field\": { \"exists\": true } } — non-null / non-undefined presence check\n { \"field\": { \"exists\": false } } — null or undefined check\n\nWhere values (including those inside operator objects) are resolved through the prop system,\nso $store, $local, and context refs like { \"$local\": \"searchText\" } all work.\n\n$query-only logical combinators (OR / AND / NOT) — NOT supported in $filter, only in $query's where:\n { \"OR\": [ { \"field\": \"value\" }, { \"field2\": \"value2\" } ] } — matches if ANY branch matches\n { \"AND\": [ { ... }, { ... } ] } — matches if ALL branches match (sibling keys at the\n same level are already implicitly ANDed — use AND\n to group a set of conditions alongside an OR/NOT)\n { \"NOT\": { \"field\": \"value\" } } — matches if the branch does NOT match\nBranches are full where-clause objects (can contain multiple fields, and can nest OR/AND/NOT inside each other).\nSibling keys alongside OR/AND/NOT at the same level are implicitly ANDed with it.\nExample — case-insensitive search across two fields:\n{\n \"$query\": {\n \"entity\": \"Space\",\n \"where\": {\n \"OR\": [\n { \"name\": { \"contains\": { \"$local\": \"searchText\" } } },\n { \"description\": { \"contains\": { \"$local\": \"searchText\" } } }\n ]\n }\n }\n}\nNote: using OR/AND/NOT disables the SPARQL-level sort/pagination pushdown (see count-projection and\nrelation-property ordering below) — those orderings silently stop working if combined with OR/AND/NOT in the\nsame query's where clause, because the fallback sort runs before the projection/relation data is attached.\n\nExamples:\n{ \"$filter\": { \"items\": { \"$store\": \"spaceStore.members\" }, \"where\": { \"role\": \"admin\" } } }\n{ \"$filter\": { \"items\": { \"$store\": \"spaceStore.members\" }, \"where\": { \"location\": { \"exists\": true }, \"handle\": { \"contains\": { \"$local\": \"searchText\" } } } } }\n\n{ \"$count\": { \"items\": } }\nReturns the length of an array.\nExample: { \"badge\": { \"$count\": { \"items\": { \"$store\": \"notificationStore.unread\" } } } }\n\n{ \"$find\": { \"items\": , \"where\"?: { ... }, \"select\"?: \"fieldName\" } }\nFinds the first matching item. where is optional (returns first item if omitted). select plucks a single field.\nExample: { \"$find\": { \"items\": { \"$store\": \"spaceStore.members\" }, \"where\": { \"id\": \"$item.creatorId\" }, \"select\": \"name\" } }\n\n{ \"$plural\": { \"count\": , \"one\": \"singular\", \"other\": \"plural\" } }\nReturns \"one\" when count === 1, otherwise \"other\". Use in children arrays for count-noun labels.\ncount is resolved through the prop system — any numeric expression ($count, $store, context ref) works.\nExample: { \"$plural\": { \"count\": { \"$count\": { \"items\": { \"$store\": \"spaceStore.members\" } } }, \"one\": \"Member\", \"other\": \"Members\" } }\nCompose with we-number for a full \"N Members\" display:\n we-number (value: { \"$count\": ... }, shorten: true) + we-text (children: [{ \"$plural\": { \"count\": { \"$count\": ... }, \"one\": \"Member\", \"other\": \"Members\" } }])\n\nQuery (data retrieval):\n{ \"$query\": { \"entity\": \"ModelName\", \"where\": { \"field\": \"value\" }, \"limit\": 10, \"order\": { \"field\": \"asc\" } } }\nQueries the current dataset for entity instances. Always returns an array.\nOptions: entity (required), where, order, limit, offset, include, scope, dataset, subscribe.\nsubscribe defaults to true — reactive live updates. Set subscribe: false to do a one-time fetch.\nBy default $query targets the current dataset ($currentDataset). Use dataset to query a different dataset —\nrequired when reading entities from an external app (e.g. Flux) that is open as a WE space:\n{ \"$query\": { \"entity\": \"Channel\", \"dataset\": \"$currentDataset\" } }\n\nBackend-neutral identity & dataset refs — prefer these over adamStore.* store paths inside $query and conditions:\n- $currentDataset — the currently active dataset (an AD4M perspective, in the AD4M backend). Use as a dataset value.\n- $me — the current agent's identity object. Use $me.did for their DID (ownership checks, author filters, e.g. { \"$eq\": [\"$post.author\", \"$me.did\"] }); $me.handle / $me.avatar for profile fields once loaded.\n\nEager-loading relations with include (most common relational pattern):\ninclude hydrates related model instances in the same query — no extra fetches needed.\nRelation names come from the HasMany relations listed for each model in externalModels.\n\nSimple include — hydrate all related instances:\n{ \"$query\": { \"entity\": \"Channel\", \"include\": { \"conversations\": true } } }\nEach item in the result will have a conversations array of hydrated Conversation objects.\n\nSub-query include — filter, sort, or limit the related records:\n{ \"$query\": { \"entity\": \"Channel\", \"include\": { \"conversations\": { \"order\": { \"createdAt\": \"desc\" }, \"limit\": 10 } } } }\n\nNested include — hydrate relations of relations:\n{ \"$query\": { \"entity\": \"Channel\", \"include\": { \"conversations\": { \"include\": { \"messages\": true } } } } }\nNesting can go as deep as needed. Each level adds one batched fetch (not N+1).\n\nCount projection — add a derived numeric field:\n{ \"$query\": { \"entity\": \"Post\", \"include\": { \"$likeCount\": { \"from\": \"likes\", \"count\": true } } } }\nThe $-prefixed key becomes a new field on each result item (e.g. item.$likeCount = 42).\n\nSorting by a count projection — order can reference a $-prefixed count key directly, sorting by the aggregate:\n{\n \"$query\": {\n \"entity\": \"Post\",\n \"limit\": 20,\n \"order\": { \"$likeCount\": \"desc\" },\n \"include\": { \"$likeCount\": { \"from\": \"likes\", \"count\": true } }\n }\n}\nRequirements: only a single order key is supported when it targets a projection (mixing it with a second sort key falls back\nto a plain property sort), and the query must also specify limit or offset — without one the count isn't computed yet at\nsort time and the order silently has no effect. Always pair count-projection ordering with a limit.\nCombine with $if for a user-togglable sort field (e.g. \"newest\" vs \"most liked\"):\n{\n \"order\": {\n \"$if\": {\n \"condition\": { \"$eq\": [{ \"$local\": \"sortField\" }, \"likes\"] },\n \"then\": { \"$likeCount\": { \"$local\": \"sortDirection\" } },\n \"else\": { \"createdAt\": { \"$local\": \"sortDirection\" } }\n }\n }\n}\n\nSorting by a related model property — order can reference a dotted \"relation.property\" path for a HasOne/HasMany\nrelation declared on the model, sorting by a scalar property on the related instance:\n{\n \"$query\": {\n \"entity\": \"Space\",\n \"limit\": 20,\n \"order\": { \"location.country\": \"asc\" },\n \"include\": { \"location\": true }\n }\n}\nSame requirements as count-projection ordering above: only a single order key, and pair with limit/offset — without\none the relation data isn't attached yet at sort time and the order silently has no effect. include isn't required\nfor the sort itself (the relation is resolved from the model's declared shape), but you'll usually want it anyway to\nread the field in the UI (e.g. \"$space.location.country\").\nCombine with $if the same way as count-projection ordering to let the user toggle between sort fields.\n\nSingle-item projection — add a derived field that resolves to one instance or null:\n{ \"$query\": { \"entity\": \"Post\", \"include\": { \"$myLike\": { \"from\": \"likes\", \"where\": { \"author\": \"$me.did\" }, \"limit\": 1 } } } }\nWith limit: 1 the field unwraps to T | null instead of an array.\n\ninclude only works with typed relations — ones where the target model class is known.\nFor WE models this is always the case. For external models, check the externalModels listing:\nrelations marked \"→ ModelName\" are typed (safe for include); relations marked \"parent query only\"\nare untyped and will crash at runtime if used with include — use a scope drill-down instead.\n\nRelational queries — fetch a parent record's children (drill-down navigation):\n{ \"$query\": { \"entity\": \"Conversation\", \"scope\": { \"anchor\": \"Channel\", \"via\": \"conversations\", \"anchorId\": \"$channel.id\" } } }\nscope.anchor is the parent entity type; scope.via is its relation whose targets are this query's entity (the\nHasMany relation listed for that entity in externalModels); scope.anchorId is the parent record's id (typically\nfrom a $each context variable or a route segment). The adapter resolves the relation to a backend handle —\nno protocol details live in the template.\nUse this pattern when navigating to a detail route and loading only that record's children.\nFor external-app datasets, always add dataset: \"$currentDataset\".\n\nLocal state (scoped ephemeral state):\nDeclare on any node: \"$localState\": { \"name\": { \"type\": \"string\", \"initial\": \"\" } }\nSupported types: \"string\", \"boolean\", \"number\", \"function\", \"object\".\nRead: { \"$local\": \"name\" } — returns the signal value (reactive).\n { \"$local\": \"name.nested.path\" } — dot-notation reads into object-typed fields (reactive).\nWrite: { \"$setLocal\": \"name\", \"from\": \"$event.target.value\" } — event handler that updates the signal.\n { \"$setLocal\": \"name\", \"value\": \"literal\" } — sets to a literal value (string, number, boolean, null, object).\n { \"$setLocal\": \"name\", \"merge\": { \"field\": \"$event.detail\" } } — shallow-merges fields into an object-typed signal. Values are resolved as event paths (e.g. \"$event.detail\") or passed as literals. Use for partial updates to object state.\nToggle: { \"$toggleLocal\": \"fieldName\" } — toggles a boolean field (equivalent to setting it to !current). Use for show/hide, open/close, expand/collapse patterns.\nCall function: { \"$callLocal\": \"fieldName\" } — event handler that calls the function stored in a function-typed local field.\n Used when a child component needs to trigger a callback passed in via $localState.\n The field must be declared as type: 'function' and set via $setLocal.\n Example: { \"onClick\": { \"$callLocal\": \"onConfirm\" } }\nState is created on mount and destroyed on unmount. Nested $localState declarations merge, inner fields shadow outer.\n$local values can be used in $action args: { \"$action\": \"store.method\", \"args\": [{ \"$local\": \"name\" }] }\n\nObject-typed local state (consolidating related scalar fields):\nWhen several related fields share a common condition on their initial values (e.g. all null/empty when a store value is absent), prefer a single \"object\" field seeded from the store, then read sub-fields with dot-notation and write with merge.\nExample — location object (replaces 5 separate scalar fields with $if guards):\n \"$localState\": { \"location\": { \"type\": \"object\", \"initial\": { \"$store\": \"spaceStore.currentSpace.location\" } } }\n Read: { \"$local\": \"location.latitude\" }, { \"$local\": \"location.city\" }\n Write (picker confirm): { \"$setLocal\": \"location\", \"from\": \"$event.detail\" }\n Write (partial edit): { \"$setLocal\": \"location\", \"merge\": { \"city\": \"$event.detail\" } }\n Write (clear): { \"$setLocal\": \"location\", \"value\": null }\n Condition (has location): { \"$local\": \"location\" }\nUse \"object\" whenever you would otherwise write 3+ related scalar fields each needing $if on their initial value.\n\nHoisted query state ($queries):\nDeclare on any node to run reactive subscriptions at the node root and expose results in $local.\nSolves two problems: avoids N duplicate subscriptions inside $each loops, and makes query results available for $if conditions.\n\"$queries\": { \"signalTypes\": { \"entity\": \"SignalType\", \"subscribe\": true } }\nResults are injected into $local as read-only reactive arrays, accessible via { \"$local\": \"signalTypes\" }.\nQuery options are identical to $each's $query prop (entity, where, order, limit, include, dataset, subscribe).\n$queries and $localState share the same $local namespace — avoid duplicate names across both.\n$setLocal will warn and no-op on $queries entries (they are read-only).\nUse with $count + $gt for conditional visibility:\n{ \"condition\": { \"$gt\": [{ \"$count\": { \"items\": { \"$local\": \"signalTypes\" } } }, 0] } }\nExample:\n{\n \"$queries\": { \"signalTypes\": { \"entity\": \"SignalType\", \"subscribe\": true } },\n \"type\": \"Column\",\n \"children\": [\n {\n \"type\": \"$each\",\n \"props\": { \"items\": { \"$local\": \"signalTypes\" }, \"as\": \"sig\" },\n \"children\": [...]\n }\n ]\n}\n\nBoolean toggle pattern (show/hide comments, expand/collapse sections, etc.):\n{\n \"$localState\": { \"showComments\": { \"type\": \"boolean\", \"initial\": false } },\n \"children\": [\n {\n \"type\": \"we-button\",\n \"props\": {\n \"variant\": \"ghost\",\n \"onClick\": { \"$toggleLocal\": \"showComments\" }\n },\n \"children\": [{ \"type\": \"we-icon\", \"props\": { \"name\": \"chat-circle\" } }]\n },\n {\n \"type\": \"$if\",\n \"props\": {\n \"condition\": { \"$local\": \"showComments\" },\n \"then\": { \"type\": \"Column\", \"children\": [{ \"type\": \"we-text\", \"children\": [\"Comments visible\"] }] }\n }\n }\n ]\n}\n\nForm validation (extends $localState):\nDeclare validation rules on fields:\n\"$localState\": {\n \"email\": {\n \"type\": \"string\",\n \"initial\": \"\",\n \"validate\": [\n { \"rule\": \"required\", \"message\": \"Email is required\" },\n { \"rule\": \"pattern\", \"value\": \"^[^@]+@[^@]+$\", \"message\": \"Invalid email\" }\n ]\n }\n}\n\nBuilt-in rules: required, minLength (value: N), maxLength (value: N), min (value: N), max (value: N), pattern (value: regex string), match (field: otherFieldName). All accept optional \"message\" override.\n\nRead tokens:\n{ \"$error\": \"fieldName\" } — first validation error message (only shown after field is touched), or \"\".\n{ \"$valid\": \"fieldName\" } — true if all rules pass (regardless of touched state).\n{ \"$touched\": \"fieldName\" } — true after the field has been blurred/touched.\n{ \"$formValid\": \"$scope\" } — true if ALL validated fields in the current $localState scope pass.\n\nAction tokens:\n{ \"$touch\": \"fieldName\" } — marks a single field as touched (use in onBlur).\n{ \"$touch\": \"$all\" } — marks all fields in scope as touched (use before submit guard).\n{ \"$resetLocal\": \"$scope\" } — resets all fields to initial values and clears touched state.\n\nHandler arrays (compose multiple actions on one event):\n{ \"onClick\": [{ \"$touch\": \"$all\" }, { \"$if\": { \"condition\": { \"$formValid\": \"$scope\" }, \"then\": { \"$action\": \"store.submit\", \"onSuccess\": [{ \"$setLocal\": \"modalOpen\", \"value\": false }] } } }] }\nArray entries execute sequentially. Non-function entries (e.g. $if with false condition) are skipped.\nPrefer onSuccess over a bare $setLocal before the $action — the bare form closes the modal immediately (losing the loading spinner); onSuccess waits for the Promise to resolve.\n\nTypical form pattern:\n{\n \"$localState\": { \"name\": { \"type\": \"string\", \"initial\": \"\", \"validate\": [{ \"rule\": \"required\" }] } },\n \"children\": [\n {\n \"type\": \"we-form-field\",\n \"props\": { \"label\": \"Name\", \"error\": { \"$error\": \"name\" } },\n \"children\": [{\n \"type\": \"we-input\",\n \"props\": {\n \"value\": { \"$local\": \"name\" },\n \"onInput\": { \"$setLocal\": \"name\", \"from\": \"$event.detail\" },\n \"onBlur\": { \"$touch\": \"name\" }\n }\n }]\n },\n {\n \"type\": \"we-button\",\n \"props\": {\n \"disabled\": { \"$not\": { \"$formValid\": \"$scope\" } },\n \"onClick\": [\n { \"$touch\": \"$all\" },\n { \"$if\": { \"condition\": { \"$formValid\": \"$scope\" }, \"then\": { \"$action\": \"store.save\", \"args\": [{ \"$local\": \"name\" }], \"onSuccess\": [{ \"$setLocal\": \"submitDone\", \"value\": true }] } } }\n ]\n },\n \"children\": [\"Submit\"]\n }\n ]\n}\n\n## Block-level Dynamic Structures\n\nBlock-level structures use \"type\" starting with \"$\" for dynamic rendering of schema nodes.\n\nEach loop:\n{ \"type\": \"$each\", \"props\": { \"items\": { \"$store\": \"storeName.arrayProperty\" }, \"as\": \"itemName\" }, \"children\": [ ... ] }\nRenders children once for each item. The \"as\" name becomes a context key. Defaults to \"item\" — omit \"as\" unless you need a different name.\n\nConditional rendering:\n{ \"type\": \"$if\", \"props\": { \"condition\": ..., \"then\": { ... }, \"else\": { ... } } }\nRenders \"then\" node if condition is truthy, else renders \"else\" node.\nSupports enterTransition / exitTransition for CSS animations when the node mounts/unmounts.\nTransitionConfig = TransitionEffect | TransitionEffect[]\nTransitionEffect = { type: 'fade'|'slide'|'scale'|'pulse', duration?: ms, easing?: string, delay?: ms, direction?: 'left'|'right'|'up'|'down', distance?: string }\nfade controls opacity only; slide/scale control transform only. pulse is a persistent looping animation (not a one-shot transition) — starts once entered, stops on exit; direction/distance don't apply (default duration 1200ms, easing 'ease-in-out'). Compose fade/slide/scale together in an array; pulse is typically used alone.\nExample: enterTransition: [{ type: 'fade', duration: 300 }, { type: 'slide', direction: 'up', distance: '40px', duration: 400 }]\nExample (pulse): enterTransition: { type: 'pulse', duration: 1500 }\n\nViewport / mount animation (child always in DOM):\n{ \"type\": \"$animate\", \"props\": { \"scrollReveal\"?: true | number, \"scrollLeave\"?: true | number, \"scrollPast\"?: string, \"enterTransition\"?: TransitionConfig, \"exitTransition\"?: TransitionConfig }, \"children\": [] }\nThe child is always mounted. fade/slide/scale are CSS transitions (opacity/transform); pulse is a real CSS @keyframes loop — use this for scroll-reveal effects.\nDo NOT use $animate when the child should be absent from the DOM. Use $if for conditional DOM presence.\nscrollReveal: true fires enterTransition when the element enters the viewport.\nscrollReveal: -100 fires 100px before the element would enter (negative = earlier reveal).\nscrollLeave fires exitTransition when the element leaves the viewport.\nscrollPast: \"element-id\" observes a sentinel element (by DOM id) instead of the $animate element itself.\n enterTransition fires when the sentinel leaves the viewport (user scrolled past it).\n exitTransition fires when the sentinel returns (user scrolled back up).\n Use this for sticky headers: place a zero-height sentinel div at the bottom of the non-sticky header section,\n then wrap the mini-profile in $animate with scrollPast pointing to that sentinel's id.\n scrollPast is mutually exclusive with scrollReveal/scrollLeave.\nWithout any scroll trigger, the enterTransition runs once on mount.\nOnly one child node is supported.\nExample (scroll-reveal):\n{\n \"type\": \"$animate\",\n \"props\": {\n \"scrollReveal\": -100,\n \"enterTransition\": [\n { \"type\": \"fade\", \"duration\": 600, \"easing\": \"ease-in-out\" },\n { \"type\": \"slide\", \"direction\": \"left\", \"distance\": \"200px\", \"duration\": 1000, \"easing\": \"ease-in-out\" }\n ]\n },\n \"children\": [{ \"type\": \"SomeCard\", \"children\": [] }]\n}\nExample (sticky header mini-profile):\nPlace a sentinel at the bottom of the header, reference it in the sticky nav:\n{ \"type\": \"div\", \"props\": { \"id\": \"header-sentinel\" }, \"styles\": { \"height\": \"0px\", \"pointerEvents\": \"none\" } }\n{\n \"type\": \"$animate\",\n \"props\": {\n \"scrollPast\": \"header-sentinel\",\n \"enterTransition\": { \"type\": \"fade\", \"duration\": 250 },\n \"exitTransition\": { \"type\": \"fade\", \"duration\": 200 }\n },\n \"children\": [{ \"type\": \"Row\", \"props\": { \"ay\": \"center\", \"gap\": \"300\" }, \"children\": [\n { \"type\": \"we-avatar\", \"props\": { \"image\": \"$space.avatar\", \"size\": \"sm\" } },\n { \"type\": \"we-text\", \"props\": { \"fontWeight\": \"600\" }, \"children\": [\"$space.name\"] }\n ]}]\n}\n\nSingle model item (load one record, render children with it in context):\n{\n \"type\": \"$single\",\n \"props\": {\n \"item\": { \"$query\": { \"entity\": \"ModelName\", \"params\": { ... }, \"subscribe\": true } },\n \"as\": \"profile\" // context key for children — default: 'item'\n },\n \"children\": [{ \"type\": \"we-text\", \"children\": [\"$profile.username\"] }]\n}\nRenders nothing until a matching record is found. Like $each but for a single result.\nquery options (entity, params, include, dataset, subscribe) work identically to $query.\n\nRoute outlet:\n{ \"type\": \"$routes\" }\nIndicates where nested routes should render within a layout.\n\n---\n\n## Component Registry\n\nMost @we/primitives also accept Design System Props (see next section for details and exceptions).\n\n@we/primitives:\n- we-alert (DesignSystemElement)\n Props: variant: 'neutral' | 'primary' | 'success' | 'warning' | 'danger' = 'primary', dismissible: boolean = false\n- we-audio (LayoutVisualElement)\n Props: src: string = '', controls: boolean = false, preload: 'none' | 'metadata' | 'auto' = 'metadata', autoplay: boolean = false, loop: boolean = false, muted: boolean = false\n- we-avatar (LayoutVisualElement)\n Props: image: string = '', hash: string = '', selected: boolean = false, online: boolean = false, initials: string = '', icon: string = '', size?: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | '{css-length}' | undefined, clickable: boolean = false\n- we-badge (DesignSystemElement)\n Props: variant: 'neutral' | 'primary' | 'success' | 'warning' | 'danger' = 'neutral', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-blockquote (DesignSystemElement)\n- we-button (DesignSystemElement)\n Props: variant: 'primary' | 'secondary' | 'ghost' | 'danger' | 'outline' = 'primary', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md', text?: string | undefined, href?: string | undefined, disabled: boolean = false, loading: boolean = false, gradient: boolean = false, square: boolean = false\n- we-checkbox (DesignSystemElement)\n Props: checked: boolean = false, disabled: boolean = false, name: string = '', value: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-code (DesignSystemElement)\n Props: block: boolean = false\n- we-color-picker (DesignSystemElement)\n Props: value: string = '#000000', disabled: boolean = false, name: string = '', palette: array = [ '#000000', '#434343', '#666666', '#999999', '#b7b7b7', '#cccccc', '#d9d9d9', '#ffffff', '#980000', '#ff0000', '#ff9900', '#ffff00', '#00ff00', '#00ffff', '#4a86e8', '#0000ff', '#9900ff', '#ff00ff', '#e6b8af', '#f4cccc', '#fce5cd', '#fff2cc', '#d9ead3', '#d0e0e3', '#c9daf8', '#cfe2f3', '#d9d2e9', '#ead1dc', ]\n- we-date-picker (DesignSystemElement)\n Props: value: string = '', placeholder: string = 'Select date', disabled: boolean = false, name: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-divider (LayoutElement)\n Props: orientation: 'horizontal' | 'vertical' = 'horizontal', variant: 'solid' | 'dashed' | 'dotted' = 'solid', color?: string | undefined, thickness?: string | undefined\n- we-drawer (OverlayElement)\n Props: hideclosebutton: boolean = false, close: () => void\n- we-file-upload (DesignSystemElement)\n Props: accept: string = '', multiple: boolean = false, disabled: boolean = false, name: string = ''\n- we-form-field (DesignSystemElement)\n Props: label: string = '', description: string = '', error: string = '', required: boolean = false, size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-html (DesignSystemElement) — Renders a raw HTML string safely via DOMPurify sanitization.\n\nUse this instead of `we-text` when content is stored as HTML (e.g. rich-text\neditor output such as Flux messages). The `content` prop accepts any HTML\nfragment; it is sanitized before rendering so XSS payloads are stripped.\n Props: content: string = ''\n- we-icon (LayoutElement)\n Props: name: string = '', color: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '{css-length}' = '', weight: 'thin' | 'light' | 'regular' | 'bold' | 'fill' | 'duotone' = 'regular', gradient: string = ''\n- we-icon-picker (DesignSystemElement)\n Props: value: string = '', disabled: boolean = false, name: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md', placeholder: string = 'Pick icon'\n- we-iframe (LayoutVisualElement)\n Props: src: string = '', title: string = 'Embedded content', allow: string = '', sandbox?: string | undefined\n- we-image (LayoutVisualElement)\n Props: src: string | File = '', alt: string = '', fit: '' | 'cover' | 'contain' | 'fill' | 'none' | 'scale-down' = '', loading: 'eager' | 'lazy' = 'eager', gradient: string = '', objectPosition: string = ''\n- we-input (DesignSystemElement)\n Props: value: string = '', max: string = '', min: string = '', maxlength: unknown = Infinity, minlength: number = 0, pattern: string = '', name: string = '', step: string = '', placeholder: string = '', autocomplete: string = '', autofocus: boolean = false, disabled: boolean = false, required: boolean = false, readonly: boolean = false, type: string = 'text', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-link (DesignSystemElement)\n Props: href: string = '', target: string = '', rel: string = '', download: string = '', disabled: boolean = false\n- we-location-picker (DesignSystemElement)\n Props: latitude?: number | undefined, longitude?: number | undefined, placeholder: string = 'Set location…', disabled: boolean = false, reverseGeocode: boolean = true\n- we-markdown (DesignSystemElement)\n Props: content: string = '', markdownGap: string = ''\n- we-menu (DesignSystemElement) — Vertical list container for menu items inside a popover.\nNot a standalone selector — wrap in we-popover for dropdown behavior.\n- we-menu-group (LayoutElement)\n Props: collapsible: boolean = false, open: boolean = false, title: string = ''\n- we-menu-item (DesignSystemElement) — Single actionable item inside a we-menu.\nSupports selected, active, and danger states.\n Props: selected: boolean = false, active: boolean = false, variant: 'default' | 'danger' = 'default', label: unknown, value: unknown\n- we-modal (OverlayElement)\n Props: hideclosebutton: boolean = false, close: () => void\n- we-number (DesignSystemElement) — Displays a number, optionally abbreviated (1 200 → 1.2K, 1 500 000 → 1.5M).\n Props: value: number = 0, shorten: boolean = false, precision: number = 1, locale: string = 'en', formattedValue: string\n- we-number-input (DesignSystemElement)\n Props: value: number = 0, min: number = -Infinity, max: unknown = Infinity, step: number = 1, disabled: boolean = false, name: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-pagination (DesignSystemElement)\n Props: page: number = 1, total: number = 1, siblings: number = 1, size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-popover (LayoutElement) — Low-level floating panel anchored to a trigger element.\nUse DropdownMenu component for dropdown menus.\n Props: open: boolean = false, placement: 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end' | 'right-start' | 'right-end' = 'bottom', popoverElement: HTMLElement, triggerElement: HTMLElement\n- we-progress-bar (DesignSystemElement)\n Props: value: number = 0, max: number = 100, variant: 'neutral' | 'primary' | 'success' | 'warning' | 'danger' = 'primary', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-radio (DesignSystemElement)\n Props: checked: boolean = false, disabled: boolean = false, name: string = '', value: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-scroll-area (DesignSystemElement)\n Props: maxHeight: string = '', maxWidth: string = ''\n- we-select (DesignSystemElement)\n Props: options: SelectOption[] = [], value: string = '', placeholder: string = '', disabled: boolean = false, searchable: boolean = false, name: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-select (DesignSystemElement) — Pick a single value from a list of options. Custom-rendered dropdown.\nUse for form fields, settings, filters. Set searchable=true for type-to-filter.\n Props: options: SelectOption[] = [], value: string = '', placeholder: string = '', disabled: boolean = false, searchable: boolean = false, name: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-skeleton (DesignSystemElement)\n Props: width: string = '100%', height: string = '20px', animation: 'pulse' | 'wave' = 'pulse'\n- we-slider (DesignSystemElement)\n Props: value: number = 0, min: number = 0, max: number = 100, step: number = 1, disabled: boolean = false, name: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md', showValue: boolean = false\n- we-sortable (DesignSystemElement) — Drag-to-reorder container primitive.\n\nUsage: wrap a list of elements that each have a `data-we-id` attribute.\nFires a `we-reorder` CustomEvent on drop with the new ordered\narray of IDs.\n Props: direction: 'vertical' | 'horizontal' = 'vertical', gap: string = ''\n- we-spinner (LayoutElement)\n Props: size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | (string & {}) = 'md', color: string = ''\n- we-switch (DesignSystemElement)\n Props: checked: boolean = false, disabled: boolean = false, name: string = '', value: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md', labelOff: string = '', labelOn: string = ''\n- we-tab (DesignSystemElement)\n Props: key: string = '', selected: boolean = false, label?: string | undefined, selectedProps?: Partial | undefined\n- we-tabs (DesignSystemElement)\n Props: selectedKey: string = ''\n- we-tag (DesignSystemElement)\n Props: variant: 'neutral' | 'primary' | 'success' | 'warning' | 'danger' = 'neutral', dismissible: boolean = false\n- we-text (DesignSystemElement)\n Props: text?: string | undefined, variant: '' | 'body' | 'label' | 'footnote' | 'subheading' | 'ingress' | 'heading-sm' | 'heading-md' | 'heading-lg' | 'heading-xl' = '', tag: 'p' | 'span' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'small' | 'b' | 'i' | 'label' | 'div' = 'span', inline: boolean = false, uppercase: boolean = false, italic: boolean = false, truncate: boolean = false, gradient: string = ''\n- we-textarea (DesignSystemElement)\n Props: value: string = '', name: string = '', placeholder: string = '', rows: number = 3, maxlength: unknown = Infinity, minlength: number = 0, disabled: boolean = false, required: boolean = false, readonly: boolean = false, resize: 'none' | 'vertical' | 'horizontal' | 'both' = 'vertical', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-timestamp (DesignSystemElement) — Displays a formatted or relative timestamp that self-updates each minute\nwhen `relative` is enabled.\n Props: value: string = '', relative: boolean = false, locale: string = 'en', dateStyle: Intl.DateTimeFormatOptions['dateStyle'] | null = null, timeStyle: Intl.DateTimeFormatOptions['timeStyle'] | null = null, weekday: Intl.DateTimeFormatOptions['weekday'] | null = null, year: Intl.DateTimeFormatOptions['year'] | null = null, month: Intl.DateTimeFormatOptions['month'] | null = null, day: Intl.DateTimeFormatOptions['day'] | null = null, hour: Intl.DateTimeFormatOptions['hour'] | null = null, minute: Intl.DateTimeFormatOptions['minute'] | null = null, second: Intl.DateTimeFormatOptions['second'] | null = null, timeZone: string | null = null, hourCycle: Intl.DateTimeFormatOptions['hourCycle'] | null = null, formattedTime: string\n- we-tooltip (LayoutElement)\n Props: open: boolean = false, title: string = '', placement: 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end' | 'right-start' | 'right-end' = 'top', tooltipEl: HTMLElement, triggerEl: HTMLElement, arrowEl: HTMLElement\n- we-video (LayoutVisualElement)\n Props: src: string = '', poster?: string | undefined, controls: boolean = false, preload: 'none' | 'metadata' | 'auto' = 'metadata', autoplay: boolean = false, loop: boolean = false, muted: boolean = false\n\n@we/components:\n- AudioDisplay\n Props: title: string | undefined, artist: string | undefined, audioUrl: string | undefined, duration: number | undefined, albumArt: string | undefined\n- AudioInput\n Props: title: string | undefined, artist: string | undefined, audioUrl: string | FileData | undefined, duration: number | undefined, albumArt: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- BlockComposer (DesignSystemElement)\n Props: editorState?: any, perspective?: PerspectiveProxy | null, onSave?: ((json: SerializedBlockNode) => void), onReady?: ((api: { save: () => void; }) => void)\n- BlockPlaceholder\n Props: icon: string, label: string, hint?: string, accept?: string, onFileDrop?: ((file: File) => void), onClick?: (() => void)\n- BlockRenderer (DesignSystemElement)\n Props: editorState?: any, perspective?: PerspectiveProxy | null, rootClass?: string\n- BlockToolbar\n Props: placement?: BlockToolbarPlacement, children: JSX.Element, stopPropagation?: boolean\n- CalloutDisplay\n Props: text: string | undefined, variant: string | undefined, icon: string | undefined\n- CalloutInput\n Props: text: string | undefined, variant: string | undefined, icon: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- CodeDisplay\n Props: code: string | undefined, language: string | undefined, title: string | undefined\n- CodeInput\n Props: code: string | undefined, language: string | undefined, title: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- CollectionDisplay\n Props: layout?: string, columnCount?: number, gap?: string, childEditorState?: any\n- CollectionInput\n Props: nodeKey: string, layout?: string, columnCount?: number, gap?: string, childEditorState?: any, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- DividerDisplay\n Props: style: \"solid\" | \"dashed\" | \"dotted\" | undefined\n- DividerInput\n Props: style: DividerVariant | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- EmbedDisplay\n Props: url: string | undefined, target: string | undefined, targetType: string | undefined, displayMode: string | undefined\n- EmbedInput\n Props: url: string | undefined, target: string | undefined, targetType: string | undefined, displayMode: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- EventDisplay\n Props: title: string | undefined, description: string | undefined, startDate: string | undefined, endDate: string | undefined, location: string | undefined, allDay: boolean | undefined\n- EventInput\n Props: title: string | undefined, description: string | undefined, startDate: string | undefined, endDate: string | undefined, location: string | undefined, allDay: boolean | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- FileDisplay\n Props: title: string | undefined, name: string | undefined, url: string | undefined, mimeType: string | undefined, size: number | undefined\n- FileInput\n Props: title: string | undefined, name: string | undefined, url: string | FileData | undefined, mimeType: string | undefined, size: number | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- ImageDisplay\n Props: src: string | undefined, altText: string | undefined, width: number | undefined, height: number | undefined\n- ImageInput\n Props: src: string | FileData | undefined, altText: string | undefined, width: number | undefined, height: number | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- LinkDisplay\n Props: url: string | undefined, title: string | undefined, description: string | undefined, thumbnail: string | undefined\n- LinkInput\n Props: url: string | undefined, title: string | undefined, description: string | undefined, thumbnail: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- LocationDisplay\n Props: name: string | undefined, latitude: number | undefined, longitude: number | undefined, address: string | undefined\n- LocationInput\n Props: name: string | undefined, latitude: number | undefined, longitude: number | undefined, address: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- TagDisplay\n Props: name: string | undefined, color: string | undefined\n- TagInput\n Props: name: string | undefined, color: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- TaskDisplay\n Props: title: string | undefined, description: string | undefined, status: string | undefined, priority: string | undefined, dueDate: string | undefined, assignee: string | undefined\n- TaskInput\n Props: title: string | undefined, description: string | undefined, status: string | undefined, priority: string | undefined, dueDate: string | undefined, assignee: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- VideoDisplay\n Props: url: string | undefined, title: string | undefined, thumbnail: string | undefined, provider: string | undefined, width: number | undefined\n- VideoInput\n Props: url: string | undefined, title: string | undefined, thumbnail: string | undefined, provider: string | undefined, width: number | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- Accordion\n Props: children?: JSX.Element, renderContent?: ((item: AccordionItem, index: number) => JSX.Element), onChange?: ((openItems: string[]) => void), items?: AccordionItem[], multiple?: boolean, styles?: Record\n- AudioVisualiser\n Props: src: string | undefined, bars?: number, height?: number, color?: string, activeColor?: string\n- AvatarStack\n Props: avatars: AvatarInfo[], max?: number, size?: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"xxs\" | \"xxl\", overlap?: number, ring?: string, styles?: Record\n- Breadcrumbs\n Props: onNavigate?: ((item: BreadcrumbItem, index: number) => void), items?: BreadcrumbItem[], separator?: string, styles?: Record\n- Calendar\n Props: onSelect?: ((date: string) => void), value?: string, events?: CalendarEvent[], styles?: Record\n- Card (DesignSystemElement)\n- CircleButton\n Props: label: string, icon?: string, image?: string, onClick?: (() => void), class?: string, styles?: Record\n- CodeEditor\n Props: code: string, language?: CodeEditorLanguage, readOnly?: boolean, onChange?: ((code: string) => void), onSave?: ((code: string) => void), styles?: Record\n- CollapsedContent\n Props: collapsed: boolean, onExpandClick?: (() => void), showToggle?: boolean, icon?: string, maxHeight?: string, fadeColor?: string, children?: JSX.Element, class?: string, styles?: Record\n- Column (DesignSystemElement)\n- Combobox (DesignSystemElement)\n Props: options: string[] | ComboboxOption[], value?: string, placeholder?: string, size?: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\", onChange?: ((value: string) => void)\n- DropdownMenu — Flexible dropdown menu for actions, toggles, and grouped items. Use for context menus, settings panels, layer controls, and command palettes.\n Props: class?: string, styles?: Record, placement?: Placement, triggerLabel?: string, triggerIcon?: string, items: SolidDropdownMenuEntry[]\n- EditableImage (DesignSystemElement)\n Props: src?: string, alt?: string, fit?: \"fill\" | \"cover\" | \"contain\" | \"none\" | \"scale-down\", placeholderIcon?: string, onImageChange?: ((file: File) => void), class?: string, aspect?: number, maxSize?: number\n- FlipCard\n Props: front?: JSX.Element, back?: JSX.Element, width?: string, height?: string, flipOnHover?: boolean, flipDuration?: string, wobbleOnHover?: boolean, wobbleDegree?: number, class?: string, styles?: Record\n- Grid (DesignSystemElement)\n Props: template?: string, columns?: number, minChildWidth?: string\n- IconLabelButton\n Props: icon: import(\"/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid\").MaybeAccessor, label: import(\"/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid\").MaybeAccessor, selected?: import(\"/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid\").MaybeAccessor, iconWeight?: import(\"/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid\").MaybeAccessor, onClick?: import(\"/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid\").MaybeAccessor<(() => void) | undefined>, class?: import(\"/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid\").MaybeAccessor, styles?: import(\"/home/james/Desktop/Coding/we/packages/design-system/utils/dist/solid\").MaybeAccessor | undefined>\n- ImageCrop\n Props: src: string, fileName?: string, aspect?: number, maxSize?: number, outputType?: string, quality?: number, onReady?: ((ref: ImageCropRef) => void)\n- ImageLightbox\n Props: srcs: string[], initialIndex: number, onClose: () => void\n- List\n Props: children?: JSX.Element, renderItem?: ((item: ListItem, index: number) => JSX.Element), items?: ListItem[], ordered?: boolean, gap?: string, styles?: Record\n- PostCard\n Props: creator?: { name: string; avatar: string; }, title: string, text: string, class?: string, styles?: Record\n- RerenderLog\n Props: location: string\n- Row (DesignSystemElement)\n- Search (DesignSystemElement)\n Props: placeholder?: string, value?: string, onSearch?: ((value: string) => void), debounce?: number\n- Select (DesignSystemElement)\n Props: options: SelectOption[], value?: string, placeholder?: string, searchable?: boolean, label?: string, size?: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\", onChange?: ((value: string) => void)\n- SignalControl\n Props: signalType: SignalTypeData, signals?: SignalData[], myDid?: string, onSignal?: ((value: number) => void), disabled?: boolean, preview?: boolean, class?: string, styles?: Record\n- Stepper\n Props: onStepClick?: ((index: number) => void), steps?: StepperStep[], activeStep?: number, orientation?: \"horizontal\" | \"vertical\", styles?: Record\n- Table\n Props: renderCell?: ((row: Record, column: TableColumn, index: number) => JSX.Element), columns: TableColumn[], rows: Record[], striped?: boolean, bordered?: boolean, styles?: Record\n- Timeline\n Props: children?: JSX.Element, renderItem?: ((item: TimelineItem, index: number) => JSX.Element), items?: TimelineItem[], styles?: Record\n- ToastContainer\n Props: position?: \"top-right\" | \"top-left\" | \"bottom-right\" | \"bottom-left\" | \"top-center\" | \"bottom-center\", styles?: Record\n\n@we/widgets:\n- CesiumGlobe — 3D globe widget using CesiumJS with a modular layer system.\nLayers are injected via factory functions (planet surface + background).\nRequires a layer factory registry mapping string names to factory functions.\nNot schema-renderable — used directly in application code.\n Props: ionAccessToken?: string, planetLayers?: LayerConfig[], backgroundLayers?: LayerConfig[], layerFactoryRegistry: Record>\n- CollapsibleSidebar\n Props: header?: JSX.Element, footer?: JSX.Element, items: CollapsibleSidebarItem[], footerItems?: CollapsibleSidebarItem[], side?: \"left\" | \"right\", position?: \"static\" | \"absolute\" | \"fixed\", zIndex?: number, collapsedWidth?: string, expandedWidth?: string, defaultExpanded?: boolean, expandOnHover?: boolean, transitionDuration?: number, bg?: string, border?: string, padding?: string, gap?: string, centerItems?: boolean, itemColor?: string, itemColorHover?: string, itemColorActive?: string, itemBg?: string, itemBgHover?: string, itemBgActive?: string, itemPadding?: string, itemGap?: string, badgeBg?: string, badgeColor?: string, iconSize?: IconSize, onItemClick?: ((item: CollapsibleSidebarItem) => void), onExpandedChange?: ((expanded: boolean) => void)\n- GraphWidget — 2D force-directed graph visualization using D3-force layout and Canvas rendering.\nDisplays typed nodes (user, space, post) and edges (follows, member-of, etc.)\nwith configurable styling, layout forces, and interaction handlers.\n Props: data: GraphData, width?: string | number, height?: string | number, nodeStyle?: NodeStyleConfig, edgeStyle?: EdgeStyleConfig, layout?: LayoutConfig, interactions?: InteractionConfig\n- SpaceSidebarWidget\n Props: name: string, description?: string, class?: string, style?: Record\n\n---\n\n## Design System Props\n\nMost @we/primitives inherit **all** layers below. Props use design token values — not raw CSS.\n\n### Token Value Reference\n\n| Token Type | Valid Values |\n|---|---|\n| SpaceValue | \"0\", \"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", \"900\", \"1000\" (or CSS length e.g. \"16px\") |\n| ColorValue | \"{hue}-{shade}\" where hue = neutral, primary, success, warning, danger and shade = 0, 25, 50, 75, 100, 200–900, 1000. Also \"white\", \"black\". (or CSS color) |\n| RadiusValue | \"0\", \"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", \"900\", \"pill\", \"full\" (or CSS length) |\n| ShadowValue | \"sm\", \"md\", \"lg\", \"xl\" |\n| FontSizeValue | \"base\", \"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", \"900\", \"1000\" (or CSS length) |\n| FontFamilyValue | \"base\" (or CSS font-family) |\n| LineHeightValue | \"none\", \"tight\", \"snug\", \"normal\", \"relaxed\", \"loose\" (or CSS value) |\n| LetterSpacingValue | \"tighter\", \"tight\", \"normal\", \"wide\", \"wider\", \"widest\" (or CSS value) |\n| FontWeightValue | Named tokens: \"regular\" (400), \"medium\" (500), \"semibold\" (600), \"bold\" (700). Numeric: \"100\"–\"900\". CSS pass-through: \"light\", \"normal\", \"bolder\". |\n\n**Layout-only primitives** — these accept only Layout props (not Visual, Flex, Typography, or State):\nwe-divider, we-icon, we-menu-group, we-popover, we-spinner, we-tooltip\n\n### Layout\n\n| Prop | Type | Description |\n|------|------|-------------|\n| width | string | Element width |\n| height | string | Element height |\n| minWidth | string | Minimum width |\n| minHeight | string | Minimum height |\n| maxWidth | string | Maximum width |\n| maxHeight | string | Maximum height |\n| position | \"relative\" \\| \"absolute\" \\| \"fixed\" \\| \"sticky\" | CSS position |\n| top | string | Top offset |\n| right | string | Right offset |\n| bottom | string | Bottom offset |\n| left | string | Left offset |\n| zIndex | number | Stack order |\n| display | \"flex\" \\| \"block\" \\| \"inline\" \\| \"inline-block\" \\| \"grid\" \\| \"inline-flex\" | Display mode |\n| flex | string | Flex shorthand (e.g. \"1\", \"0 0 auto\", \"none\") — controls grow/shrink/basis |\n| alignSelf | string | Override parent cross-axis alignment for this child |\n| overflow | \"hidden\" \\| \"auto\" | Overflow behavior |\n| m | SpaceValue | Margin (all sides) |\n| mx | SpaceValue | Margin left + right |\n| my | SpaceValue | Margin top + bottom |\n| mt | SpaceValue | Margin top |\n| mr | SpaceValue | Margin right |\n| mb | SpaceValue | Margin bottom |\n| ml | SpaceValue | Margin left |\n\n### Visual\n\n| Prop | Type | Description |\n|------|------|-------------|\n| bg | ColorValue | Background color (token) |\n| bgImage | string | Background image URL — sets background-image, defaults background-size to cover, background-position to center, background-repeat to no-repeat |\n| bgFit | \"cover\" \\| \"contain\" | Background image sizing (default: \"cover\") — only meaningful with bgImage |\n| bgPosition | string | Background image position (default: \"center\", e.g. \"top\", \"50% 20%\") — only meaningful with bgImage |\n| bgImageOpacity | number | Fades bgImage only (0–1), independent of the element's own content/opacity — only meaningful with bgImage |\n| bgImageTint | ColorValue | Color bgImage fades toward as bgImageOpacity decreases (default: the element's own `bg`, or neutral-0) — only meaningful with bgImageOpacity |\n| color | ColorValue | Text/foreground color (token) |\n| opacity | number | Opacity (0–1) |\n| border | string | Border shorthand (e.g. \"1px solid neutral-200\" — color tokens are resolved) |\n| borderColor | ColorValue | Border color (token, e.g. \"neutral-200\", \"primary-500\") |\n| borderTop | string | Top border shorthand (color tokens resolved) |\n| borderRight | string | Right border shorthand (color tokens resolved) |\n| borderBottom | string | Bottom border shorthand (color tokens resolved) |\n| borderLeft | string | Left border shorthand (color tokens resolved) |\n| borderWidth | string | Border width (raw CSS, e.g. \"1px\", \"2px 0\") |\n| shadow | \"sm\" \\| \"md\" \\| \"lg\" \\| \"xl\" | Shadow token |\n| cursor | \"pointer\" \\| \"default\" \\| \"text\" \\| \"not-allowed\" | Cursor style |\n| pointerEvents | \"none\" \\| \"auto\" | Pointer events |\n| transform | string | CSS transform |\n| transition | string | CSS transition |\n| r | RadiusValue | Border radius (all corners) |\n| rt | RadiusValue | Border radius top |\n| rb | RadiusValue | Border radius bottom |\n| rl | RadiusValue | Border radius left |\n| rr | RadiusValue | Border radius right |\n| rtl | RadiusValue | Border radius top-left |\n| rtr | RadiusValue | Border radius top-right |\n| rbr | RadiusValue | Border radius bottom-right |\n| rbl | RadiusValue | Border radius bottom-left |\n\n### Flex (Container)\n\n| Prop | Type | Description |\n|------|------|-------------|\n| direction | \"row\" \\| \"row-reverse\" \\| \"column\" \\| \"column-reverse\" | Flex direction |\n| ax | \"start\" \\| \"center\" \\| \"end\" \\| \"between\" \\| \"around\" \\| \"even\" \\| \"stretch\" | Main-axis alignment |\n| ay | \"start\" \\| \"center\" \\| \"end\" \\| \"between\" \\| \"around\" \\| \"even\" \\| \"stretch\" | Cross-axis alignment |\n| wrap | boolean | Enable flex wrap |\n| gap | SpaceValue | Gap between children (token) |\n| p | SpaceValue | Padding (all sides) |\n| px | SpaceValue | Padding left + right |\n| py | SpaceValue | Padding top + bottom |\n| pt | SpaceValue | Padding top |\n| pr | SpaceValue | Padding right |\n| pb | SpaceValue | Padding bottom |\n| pl | SpaceValue | Padding left |\n\n### Typography\n\n| Prop | Type | Description |\n|------|------|-------------|\n| textAlign | \"left\" \\| \"center\" \\| \"right\" \\| \"justify\" | Text alignment |\n| fontFamily | \"base\" \\| {css-font-family} | Font family token |\n| fontWeight | \"regular\" \\| \"medium\" \\| \"semibold\" \\| \"bold\" (named tokens) or \"100\"–\"900\" (numeric) or \"light\" \\| \"normal\" \\| \"bolder\" (CSS pass-through) | Font weight |\n| fontSize | \"base\" \\| \"100\"–\"1000\" \\| {css-length} | Font size token |\n| lineHeight | \"none\" \\| \"tight\" \\| \"snug\" \\| \"normal\" \\| \"relaxed\" \\| \"loose\" | Line height token |\n| letterSpacing | \"tighter\" \\| \"tight\" \\| \"normal\" \\| \"wide\" \\| \"wider\" \\| \"widest\" | Letter spacing token |\n| textDecoration | \"underline\" \\| \"line-through\" \\| \"overline\" \\| \"none\" | Text decoration |\n| textTransform | \"uppercase\" \\| \"lowercase\" \\| \"capitalize\" \\| \"none\" | Text transform |\n\n**Typography defaults:** fontSize and fontWeight have **no built-in defaults** — omitting them inherits from parent elements (browser default is ~16px / normal weight). Do not set fontSize or fontWeight unless you need a non-default value. For example, `fontSize: '300'` (16px) and `fontWeight: '500'` (normal) are the inherited defaults — omit them.\n\n`we-text` variants (set via the `variant` prop) bundle typography presets. Always pair with a semantic `tag` prop for correct HTML structure:\nbody (300, tag: p/span), label (200 + medium, tag: span), footnote (100, tag: span), subheading (400 + medium, tag: h5/p), ingress (400 + lineHeight 1.6, tag: p), heading-sm (500 + bold, tag: h4), heading-md (600 + bold, tag: h3), heading-lg (700 + bold, tag: h2), heading-xl (800 + bold, tag: h1).\nVariants set size and weight only — color is always inherited or set explicitly. For muted footnote text add `color=\"neutral-400\"` explicitly.\n\n### State\n\n| Prop | Type | Description |\n|------|------|-------------|\n| hoverProps | Partial\\ | Styles on :hover |\n| activeProps | Partial\\ | Styles on :active |\n| focusProps | Partial\\ | Styles on :focus |\n| disabledProps | Partial\\ | Styles when disabled |\n\n### Additional\n\n| Prop | Type | Description |\n|------|------|-------------|\n| styles | Record\\ | Inline CSS applied directly to the component's own element (raw CSS values allowed). For Column, Row, Grid — use this when you need CSS the DS props don't cover. **Do not confuse with node-level styles** (see Schema Structure) which applies to a wrapper div, not the component. |\n| onClick | ActionToken | Event handler (see dynamic logic) |\n\n---\n\n## Design Tokens\n\nUse design tokens for spacing, color, radius, etc. Do not use raw CSS values unless using the styles prop.\n\nanimation.transition: '0', '100', '200', '300', '400', '500'\n\navatarSize: 'xxs', 'xs', 'sm', 'md', 'lg', 'xl', 'xxl'\n\nborder.color: 'base', 'strong'\n\ncolor.base: 'white', 'black'\n\ncolor.config: 'multiplier', 'subtractor', 'saturation', 'neutralSaturation'\n\ncolor.hues: 'neutral', 'primary', 'success', 'warning', 'danger'\n\ncolor.lightness: '0', '25', '50', '75', '100', '200', '300', '400', '500', '600', '700', '800', '900', '1000'\n\ncomponent.scrollbar: 'width', 'backgroundImage', 'background', 'cornerBackground', 'thumbBoxShadow', 'thumbBorderRadius', 'thumbBackground'\n\ncomponentHeight: 'xs', 'sm', 'md', 'lg', 'xl'\n\neffect.depth: '100', '200', '300', '400', '500', 'none'\n\nfont.family: 'base', 'mozilla', 'boldonse'\n\nfont.letterSpacing: 'tighter', 'tight', 'normal', 'wide', 'wider', 'widest'\n\nfont.lineHeight: 'none', 'tight', 'snug', 'normal', 'relaxed', 'loose'\n\nfont.size: '100', '200', '300', '400', '500', '600', '700', '800', '900', '1000', 'base'\n\nfont.weight: '100', '200', '300', '400', '500', '600', '700', '800', '900', 'regular', 'medium', 'semibold', 'bold'\n\nlayout: 'xs', 'sm', 'md', 'lg'\n\nradius: '0', '100', '200', '300', '400', '500', '600', '700', '800', '900', 'pill', 'full'\n\nshadow: 'sm', 'md', 'lg', 'xl'\n\nsize: 'xxs', 'xs', 'sm', 'md', 'lg', 'xl', 'xxl'\n\nspace: '0', '100', '200', '300', '400', '500', '600', '700', '800', '900', '1000'\n\nzIndex: 'dropdown', 'sticky', 'modal', 'popover', 'toast', 'tooltip'\n\n---\n\n## Block & Entity Models\n\nAvailable data models for $query and store data:\n\nAgentSettings extends Ad4mModel:\n Fields:\n - currentTemplateId: string = 'default' [we://current_template]\n - defaultTemplateId: string = 'default' [we://default_template]\n - currentThemeId: string = 'default' [we://current_theme]\n - defaultThemeId: string = 'default' [we://default_theme]\n - claudeApiKey: string [we://claude_api_key]\n - perspectiveOrder: string [we://perspective_order]\n - globalSpaceJoined: boolean = false [we://global_space_joined]\n - globalSpaceUrl: string [we://global_space_url]\n - useSpaceTemplate: boolean = true [we://use_space_template]\n Relations:\n - installedTemplates: HasMany → Template [we://installed_template]\n - installedThemes: HasMany → Theme [we://installed_theme]\n - spaceTemplatePreferences: HasMany → SpaceTemplatePreference [we://space_template_preference]\n\nAudioBlock extends WeNode:\n Fields:\n - title: string (required) [we://title]\n - artist: string [we://artist]\n - audioUrl: string (required) [we://audio_url]\n - duration: number [we://duration]\n - albumArt: string [we://album_art]\n - version: number [we://version]\n\nCalloutBlock extends WeNode:\n Fields:\n - text: string [we://text]\n - variant: string = info [we://variant]\n - icon: string [we://icon]\n - version: number [we://version]\n\nChatMessage extends WeNode:\n Fields:\n - role: string [we://role]\n - content: string [we://content]\n\nChatSession extends WeNode:\n Fields:\n - name: string [we://name]\n - templateId: string [we://template_id]\n Relations:\n - messages: HasMany → ChatMessage [we://chat_message]\n\nCodeBlock extends WeNode:\n Fields:\n - code: string (required) [we://code]\n - language: string [we://language]\n - title: string [we://title]\n - version: number [we://version]\n\nCollectionBlock extends WeNode:\n Fields:\n - editorState: string = null [we://editor_state]\n - type: string [we://type]\n - display: string [we://display]\n - direction: string [we://direction]\n - format: string [we://format]\n - indent: number [we://indent]\n - columns: number [we://columns]\n - gap: string [we://gap]\n - version: number [we://version]\n - textContent: string [we://text_content]\n Relations:\n - children: HasMany [we://children]\n\nDividerBlock extends WeNode:\n Fields:\n - style: string = solid [we://style]\n - version: number [we://version]\n\nEmbedBlock extends WeNode:\n Fields:\n - url: string [we://url]\n - target: string [we://target]\n - targetType: string [we://target_type]\n - displayMode: string = card [we://display_mode]\n - version: number [we://version]\n\nEventBlock extends WeNode:\n Fields:\n - title: string (required) [we://title]\n - description: string [we://description]\n - startDate: string (required) [we://start_date]\n - endDate: string [we://end_date]\n - location: string [we://location]\n - allDay: boolean = false [we://all_day]\n - version: number [we://version]\n\nFileBlock extends WeNode:\n Fields:\n - title: string [we://title]\n - name: string (required) [we://name]\n - url: string (required) [we://url]\n - mimeType: string [we://mime_type]\n - size: number [we://size]\n - version: number [we://version]\n\nImageBlock extends WeNode:\n Fields:\n - src: string (required) [we://src]\n - altText: string [we://altText]\n - width: number [we://width]\n - height: number [we://height]\n - version: number [we://version]\n\nLinkBlock extends WeNode:\n Fields:\n - url: string (required) [we://url]\n - title: string [we://title]\n - description: string [we://description]\n - thumbnail: string [we://thumbnail]\n - version: number [we://version]\n\nLocationBlock extends WeNode:\n Fields:\n - name: string [we://name]\n - latitude: number (required) [we://latitude]\n - longitude: number (required) [we://longitude]\n - address: string [we://address]\n - city: string [we://city]\n - countryCode: string [we://country_code]\n - country: string [we://country]\n - version: number [we://version]\n\nSignal extends Ad4mModel:\n Fields:\n - signalTypeId: string [we://signal_type_id]\n - value: number [we://value]\n\nSignalType extends WeNode:\n Fields:\n - name: string [we://name]\n - slug: string [we://slug]\n - description: string [we://description]\n - icon: string [we://icon]\n - iconSecondary: string [we://icon_secondary]\n - step: number = 1 [we://step]\n - rangeMin: number [we://range_min]\n - rangeMax: number = 1 [we://range_max]\n - mode: SignalMode = 'toggle' [we://mode]\n - aggregate: SignalAggregate = 'count' [we://aggregate]\n - semantic: SignalSemantic = 'custom' [we://semantic]\n - allowChange: boolean = true [we://allow_change]\n - valueType: string = 'numeric' [we://signal_value_type]\n - schemaVersion: number = 1 [we://schema_version]\n\nSpace extends WeNode:\n Fields:\n - uuid: string [we://uuid]\n - url: string [we://url]\n - name: string (required) [we://name]\n - description: string (required) [we://description]\n - access: string = 'personal' [we://access]\n - discovery: string = 'hidden' [we://discovery]\n - avatar: string [we://image]\n - coverImage: string [we://thumbnail]\n - defaultTemplateId: string [we://default_template_id]\n - defaultThemeId: string [we://default_theme_id]\n Relations:\n - location: HasOne [we://location]\n\nSpaceTemplatePreference extends WeNode:\n Fields:\n - spaceUrl: string [we://space_url]\n - preference: string [we://preference]\n\nTagBlock extends WeNode:\n Fields:\n - name: string (required) [we://name]\n - color: string [we://color]\n - version: number [we://version]\n\nTaskBlock extends WeNode:\n Fields:\n - title: string (required) [we://title]\n - description: string [we://description]\n - status: string = todo [we://status]\n - priority: string = medium [we://priority]\n - dueDate: string [we://due_date]\n - assignee: string [we://assignee]\n - version: number [we://version]\n\nTemplate extends WeNode:\n Fields:\n - name: string [we://name]\n - description: string [we://description]\n - icon: string [we://icon]\n - origin: string [we://origin]\n - version: number = 1 [we://version]\n - slug: string [we://slug]\n - schema: string = null [we://template_schema]\n - themeId: string [we://theme_id]\n Relations:\n - screenshots: HasMany → ImageBlock [we://screenshot]\n\nTextBlock extends WeNode:\n Fields:\n - type: string [we://type]\n - direction: string [we://direction]\n - format: string [we://format]\n - indent: number [we://indent]\n - textFormat: number [we://textFormat]\n - textStyle: string [we://textStyle]\n - listType: string [we://listType]\n - start: number [we://start]\n - tag: string [we://tag]\n - text: string [we://text]\n - version: number [we://version]\n\nTheme extends WeNode:\n Fields:\n - name: string [we://name]\n - description: string [we://description]\n - icon: string [we://icon]\n - origin: string [we://origin]\n - slug: string [we://slug]\n - version: number = 1 [we://version]\n - css: string = null [we://stylesheet]\n - overrides: string = null [we://token_overrides]\n Relations:\n - screenshots: HasMany → ImageBlock [we://screenshot]\n\nVideoBlock extends WeNode:\n Fields:\n - title: string [we://title]\n - url: string (required) [we://url]\n - duration: number [we://duration]\n - thumbnail: string [we://thumbnail]\n - provider: string [we://provider]\n - version: number [we://version]\n\nWeNode extends Ad4mModel:\n Relations:\n - comments: HasMany [we://comment]\n - signals: HasMany → Signal [we://signal]\n\n---\n\n## Stores\n\nStores provide state (readable values) and actions (methods) for dynamic logic in schemas.\nAccess state with $store and call actions with $action.\nFor ephemeral/form state, use $localState/$local/$setLocal instead of stores (see Dynamic Logic).\n\nAdamStore:\n- State:\n - adamClient: Ad4mClient | undefined\n - me: Agent | undefined\n - allPerspectives: array of PerspectiveProxy objects (all AD4M perspectives)\n - currentPerspective: PerspectiveProxy | null (the perspective currently being viewed)\n - currentPerspectiveModels: ModelManifestEntry[] (non-WE SHACL models from the current perspective; injected as externalModels into AI messages)\n - isWeSpace: boolean — true once the current perspective is confirmed to have WE's Space SDNA installed (false for a joined-but-foreign perspective, e.g. one synced in from Flux)\n - personalSpaces: array of Space objects (local/personal spaces)\n - sharedSpaces: array of Space objects (shared/neighbourhood spaces)\n - bootState: string\n - passwordError: string | undefined\n - loginLoading: boolean\n - creatingSpace: boolean (true while a new space is being created)\n - agents: AgentProfileSummary[] — cache of all fetched agent profiles (did, firstName, lastName, handle, bio, avatar, coverImage, location)\n - ownAgent: AgentProfileSummary | undefined — reactive accessor for the current user's own profile (derived from agents cache)\n - orderedSidebarItems: array of sidebar items in user-defined order (uuid, name, avatar, spaceId) — personal + shared spaces merged\n- Actions:\n - navigate(to: string, options?): navigates to a route\n - addNewSpace(space: Space): adds a new space\n - createSpace(name: string, description: string, shared: boolean, imageFile?: File): creates a new space with full setup\n - initializeAsWeSpace(name: string, description: string, avatarValue?: File | string | null): installs WE's Space SDNA into the current, already-joined, foreign-native perspective (e.g. one synced in from Flux) and creates a Space entity in place — access is always 'shared' since the perspective is already a published neighbourhood\n - switchPerspective(uuid: string): switches to a perspective by UUID, registers its SHACL models as dynamic model classes, and populates currentPerspectiveModels\n - removePerspective(uuid: string): removes a perspective by UUID\n - reorderPerspectives(newOrder: string[]): reorders the sidebar items by UUID array\n - login(password: string): logs in the agent with password\n - logout(): locks the agent and returns to login screen\n - fetchAgent(did: string): fetches and caches an agent's profile from their public AD4M perspective\n - updateOwnProfile(fields: { firstName?, lastName?, handle?, bio? }): updates own profile text fields and publishes to public perspective\n - updateProfileImage(field: \"avatar\" | \"coverImage\", imageFile: File): uploads image to FILE_STORAGE_LANGUAGE and publishes expression URL to public perspective\n - updateAgentLocation(update: { latitude?, longitude?, city?, country?, countryCode? }): merges location update into cache and publishes to public perspective\n - cleanupSpaceSdna(uuid?: string): one-time remediation for a perspective that accumulated duplicate SDNA installs (e.g. from before joinSpace checked for existing SDNA before installing) — removes the redundant duplicate link copies. Defaults to the current perspective. Returns a display-ready summary string naming how many links were removed and the DIDs that authored them (your own DID annotated with \"(you)\"), or an empty string if nothing needed cleaning up\n\nRouteStore:\n- State:\n - currentPath: string (the current route path)\n - segments: string[] (currentPath split by \"/\", e.g. [\"/foo/bar\"] → [\"foo\", \"bar\"])\n- Actions:\n - navigate(to: string, options?): navigates to a route\n\nThemeStore:\n- State:\n - builtInThemes: array of ThemeData objects — built-in registry themes (origin: \"built-in\", always available)\n - installedThemes: array of ThemeData objects — user-installed themes from root perspective (origin: \"custom\" | \"marketplace\")\n - spaceThemes: array of ThemeData objects — themes stored in the current space perspective (origin: \"custom\")\n - allThemes: array of ThemeData objects — union of builtInThemes + visible installedThemes + spaceThemes (hidden themes filtered out)\n - currentThemeId: string — id of the currently active theme\n - currentTheme: ThemeData — the currently active theme object (id, name, icon, origin)\n - defaultThemeId: string — id of the user's preferred default theme (used for bootscreen, shell, and future space-override). Persisted to AgentSettings.defaultThemeId\n - themeManagementList: ThemeManagementItem[] — flat list of all themes (built-in + all custom) with management metadata (id, name, icon, isBuiltIn, isInstalled, isDefault)\n- Actions:\n - setCurrentTheme(themeId: string): sets and persists the active theme\n - setDefaultTheme(themeId: string): sets the preferred default theme (persists to AgentSettings.defaultThemeId)\n - toggleThemeInstalled(themeId: string): toggles a custom theme visible/hidden in pickers; does not delete the theme\n - installFromMarketplace(marketplaceThemeId: string): installs a marketplace theme into installedThemes\n - uninstallTheme(themeId: string): removes an installed theme (deletes the model)\n - deleteTheme(themeId: string): permanently deletes a custom theme\n\nTemplateStore:\n- State:\n - personalTemplates: array of TemplateSchema objects — core templates plus user's installed custom templates (excludes space templates)\n - spaceTemplates: array of TemplateSchema objects — templates loaded from the current space perspective\n - builtInTemplates: array of TemplateSchema objects — built-in system templates (always available)\n - myTemplates: array of TemplateSchema objects — user's installed custom templates only (excludes built-in and space templates)\n - allTemplates: array of TemplateSchema objects — union of built-in + personal + space templates\n - shellTemplates: array of TemplateSchema objects (static system pages: profile, settings, tests)\n - currentTemplate: TemplateSchema (the active template)\n - operationLoading: unknown\n - activeShellView: string | null (id of the currently open shell overlay: 'profile' | 'settings' | 'schema-tests' | 'landing-page' | null)\n - templateManagementList: TemplateManagementItem[] — flat list of all templates with management metadata (id, name, icon, description, isBuiltIn, isInstalled, isDefault)\n - switcherGroups: TemplateSwitcherGroup[] — pre-grouped flat items for the template switcher UI; each group has { label: string, items: { id, name, icon }[] }. Groups: \"Space templates\", \"My templates\", \"Built-in\". Use $filter where: { name: { contains: ... } } for search since items have a flat name field.\n- Actions:\n - updateTemplate(newTemplate: TemplateSchema): updates the current template\n - switchTemplate(newTemplateId: string): switches to another template\n - removeTemplate(): removes the current template\n - saveTemplate(name: string): saves the current template\n - toggleInstalled(): unknown\n - setDefaultTemplate(): unknown\n - deleteTemplate(): unknown\n - openShellView(id: string): opens a shell overlay by id ('profile' | 'settings' | 'schema-tests' | 'landing-page')\n - closeShellView(): closes the currently open shell overlay\n\nSpaceStore:\n- State:\n - memberDids: string[] — DIDs of all members in the current space (includes own DID)\n - members: AgentProfileSummary[] — cached profiles for all memberDids\n - spaceDefaultTemplateId: string — the current space's default template ID (empty string when no space is active)\n - currentSpace: Space | null — the current space model (uuid, name, description, avatar, defaultTemplateId)\n - foreignSpacePrefill: { name, description, avatar } | null — detected from a foreign app's own model (e.g. Flux's Community) for prefilling the \"Initialize as WE space\" gate; null once the perspective is a WE space or no recognized foreign model is found\n - signalTypes: array of SignalType objects (community-created reaction/vote types)\n - signalTypesBySlug: Record — computed map; access via { $store: \"spaceStore.signalTypesBySlug.\" }; use .id for the UUID\n- Actions:\n - createPost(editorState: unknown): creates a new post\n - updatePost(postId: string, editorState: unknown): reconciles an edited post against its existing blocks — updates/reuses blocks whose id survived the edit, creates new ones, deletes ones no longer present\n - deletePost(postId: string): permanently deletes a post and all of its contained blocks (recursive, atomic)\n - updateSpaceImage(field: \"avatar\" | \"coverImage\", imageFile: File): uploads and sets the space avatar or cover image\n - createSignalType(config: Partial): creates a new signal type in the community; slug auto-derived from name if blank\n - upsertSignal(nodeId: string, signalTypeId: string, value: number): adds or updates a signal on a node; value=0 deletes it\n - navigateToSpace(spaceId: string, view?: string): navigates to a space — accepts a perspective UUID or a neighbourhood CID (sharedUrl without the neighbourhood:// prefix); pre-loads space templates before switching so the template and data arrive together\n\nAiStore:\n- State:\n - models: array of Model objects\n - tasks: array of AITask objects\n - isOpen: unknown\n - messages: unknown\n - isStreaming: unknown\n - streamingContent: unknown\n - apiKeyConfigured: unknown\n - templateName: unknown\n - templateIcon: unknown\n - isReadOnly: unknown\n - hasPendingChanges: unknown\n - pickerOpen: unknown\n - pickerAction: unknown\n - pickerDefaultName: unknown\n - pickerDefaultIcon: unknown\n - pickerShowDestination: unknown\n - sessions: unknown\n - activeSessionId: unknown\n - panelMode: unknown\n - schemaJson: unknown\n - operationLoading: unknown\n - canUndo: boolean (true when there are schema edits that can be undone)\n - canRedo: boolean (true when there are undone schema edits that can be redone)\n- Actions:\n - handleSchemaPrompt(prompt: string): generates a schema from a prompt\n - sendMessage(): unknown\n - close(): unknown\n - toggle(): toggles the AI chat panel open/closed\n - setApiKey(): unknown\n - startFork(): unknown\n - startFresh(): unknown\n - confirmPicker(): unknown\n - cancelPicker(): unknown\n - newChat(): unknown\n - switchSession(): unknown\n - deleteSession(): unknown\n - setPanelMode(): unknown\n - onSchemaEdit(): unknown\n - undo(): undoes the last schema edit\n - redo(): redoes the last undone schema edit\n\nAppStore:\n- State:\n - apps: RegisteredApp[] — list of registered external apps (id, name, image)\n - appsWithWe: unknown\n - activeAppId: string | null — id of the currently active app, or null if none\n- Actions:\n - activateApp(id: string): activates an app and switches to its view\n - deactivateApp(): deactivates the current app and returns to the template view\n\n---\n\n## Store Usage Patterns\n\nReading state:\n{ \"$store\": \"storeName.property\" }\nExample: { \"$store\": \"routeStore.currentPath\" }\n\nCalling actions:\n{ \"$action\": \"storeName.method\", \"args\": [...] }\nExample: { \"$action\": \"routeStore.navigate\", \"args\": [\"/home\"] }\n\nIterating over store data:\n{\n \"type\": \"$each\",\n \"props\": { \"items\": { \"$store\": \"adamStore.personalSpaces\" }, \"as\": \"space\" },\n \"children\": [\n {\n \"type\": \"CircleButton\",\n \"props\": {\n \"label\": \"$space.name\",\n \"onClick\": { \"$action\": \"routeStore.navigate\", \"args\": [{ \"$concat\": [\"/space/\", \"$space.uuid\"] }] }\n }\n }\n ]\n}\n\nConditional rendering from store:\n{\n \"type\": \"$if\",\n \"props\": {\n \"condition\": { \"$eq\": [{ \"$store\": \"routeStore.currentPath\" }, \"/\"] },\n \"then\": { \"type\": \"we-text\", \"children\": [\"Home\"] },\n \"else\": { \"type\": \"we-text\", \"children\": [\"Not home\"] }\n }\n}\n\nDeriving options from store:\n{\n \"$map\": {\n \"items\": { \"$store\": \"templateStore.templates\" },\n \"select\": { \"name\": \"$item.meta.name\", \"icon\": \"$item.meta.icon\" }\n }\n}\n\nQuerying model data:\n{\n \"$query\": { \"entity\": \"TaskBlock\", \"where\": { \"status\": \"todo\" } }\n}\n\nEager-loading relations with include (most common relational pattern):\nWhen you need related data displayed alongside a list, use include to hydrate relations in one query.\n\nExample — Channel list with conversation count and latest conversation:\n{\n \"type\": \"$each\",\n \"props\": {\n \"items\": {\n \"$query\": {\n \"entity\": \"Channel\",\n \"dataset\": \"$currentDataset\",\n \"include\": {\n \"$conversationCount\": { \"from\": \"conversations\", \"count\": true },\n \"$latestConversation\": { \"from\": \"conversations\", \"order\": { \"createdAt\": \"desc\" }, \"limit\": 1 }\n }\n }\n },\n \"as\": \"channel\"\n },\n \"children\": [{\n \"type\": \"Row\",\n \"children\": [\n { \"type\": \"we-text\", \"children\": [\"$channel.name\"] },\n { \"type\": \"we-text\", \"children\": [\"$channel.$conversationCount\"] }\n ]\n }]\n}\n\nExample — Nested include (Conversations with their messages):\n{\n \"$query\": {\n \"entity\": \"Conversation\",\n \"dataset\": \"$currentDataset\",\n \"include\": {\n \"messages\": {\n \"order\": { \"createdAt\": \"desc\" },\n \"limit\": 20\n }\n }\n }\n}\nEach conversation in the result has a messages array of hydrated Message instances.\nNesting works to any depth: \"include\": { \"messages\": { \"include\": { \"reactions\": true } } }\n\nRelational drill-down (master-detail navigation across entity relations):\nUse routes + a $query `scope` when you navigate to a detail route and need only that record's children.\nscope.anchor is the parent entity type; scope.via is its HasMany relation (see externalModels) whose targets\nare the query's entity; scope.anchorId is the parent record's id. The adapter resolves the relation to a\nbackend handle, so no protocol details live in the template.\nrouteStore.segments.N extracts the Nth dynamic path segment (segments splits currentPath by \"/\").\n\nExample — Channel list → Conversation list:\n{\n \"routes\": [\n {\n \"path\": \"/\",\n \"type\": \"Column\",\n \"props\": { \"gap\": \"300\", \"p\": \"400\" },\n \"children\": [{\n \"type\": \"$each\",\n \"props\": {\n \"items\": { \"$query\": { \"entity\": \"Channel\", \"dataset\": \"$currentDataset\" } },\n \"as\": \"channel\"\n },\n \"children\": [{\n \"type\": \"we-button\",\n \"props\": {\n \"variant\": \"ghost\",\n \"onClick\": { \"$action\": \"routeStore.navigate\", \"args\": [{ \"$concat\": [\"/channels/\", \"$channel.id\"] }] }\n },\n \"children\": [\"$channel.name\"]\n }]\n }]\n },\n {\n \"path\": \"/channels/:channelId\",\n \"type\": \"Column\",\n \"props\": { \"gap\": \"300\", \"p\": \"400\" },\n \"children\": [{\n \"type\": \"$each\",\n \"props\": {\n \"items\": {\n \"$query\": {\n \"entity\": \"Conversation\",\n \"scope\": { \"anchor\": \"Channel\", \"via\": \"conversations\", \"anchorId\": { \"$store\": \"routeStore.segments.1\" } },\n \"dataset\": \"$currentDataset\"\n }\n },\n \"as\": \"convo\"\n },\n \"children\": [{\n \"type\": \"we-text\",\n \"children\": [\"$convo.conversationName\"]\n }]\n }]\n }\n ]\n}\nNotes:\n- Use include when you need related data displayed inline (e.g. a post with its comments, a channel with its conversation count).\n- Use a scope drill-down when you're on a detail route and want only children belonging to the current record.\n- dataset must point to the dataset that holds the data. For external apps (e.g. Flux) opened as a WE space, use \"$currentDataset\".\n- The relation name (in include, or scope.via) is the HasMany field name on the parent entity.\n\nLocal state (form with validation):\n{\n \"type\": \"Column\",\n \"$localState\": {\n \"name\": {\n \"type\": \"string\",\n \"initial\": \"\",\n \"validate\": [{ \"rule\": \"required\" }, { \"rule\": \"minLength\", \"value\": 2 }]\n },\n \"loading\": { \"type\": \"boolean\", \"initial\": false }\n },\n \"children\": [\n {\n \"type\": \"we-form-field\",\n \"props\": { \"label\": \"Name\", \"error\": { \"$error\": \"name\" } },\n \"children\": [{\n \"type\": \"we-input\",\n \"props\": {\n \"value\": { \"$local\": \"name\" },\n \"onInput\": { \"$setLocal\": \"name\", \"from\": \"$event.detail\" },\n \"onBlur\": { \"$touch\": \"name\" }\n }\n }]\n },\n {\n \"type\": \"we-button\",\n \"props\": {\n \"text\": \"Submit\",\n \"loading\": { \"$local\": \"loading\" },\n \"disabled\": { \"$not\": { \"$formValid\": \"$scope\" } },\n \"onClick\": [\n { \"$touch\": \"$all\" },\n { \"$if\": { \"condition\": { \"$formValid\": \"$scope\" }, \"then\": { \"$action\": \"myStore.submit\", \"args\": [{ \"$local\": \"name\" }] } } }\n ]\n }\n }\n ]\n}\n\nRepeating lists with $each:\nALWAYS use $each for lists of similar items — never duplicate the same node structure.\nWrite the template once; $each renders it for each item.\n\nUse literal arrays for fixed/sample data:\n{\n \"type\": \"$each\",\n \"props\": {\n \"items\": [\n { \"title\": \"First Post\", \"text\": \"Hello world.\", \"author\": \"Alice\" },\n { \"title\": \"Second Post\", \"text\": \"Another update.\", \"author\": \"Bob\" }\n ],\n \"as\": \"post\"\n },\n \"children\": [\n {\n \"type\": \"Column\",\n \"props\": { \"bg\": \"neutral-0\", \"r\": \"400\", \"border\": \"1px solid neutral-200\", \"p\": \"400\", \"gap\": \"300\" },\n \"children\": [\n {\n \"type\": \"Row\",\n \"props\": { \"gap\": \"300\", \"ay\": \"center\" },\n \"children\": [\n { \"type\": \"we-avatar\", \"props\": { \"initials\": \"$post.author\", \"size\": \"sm\" } },\n { \"type\": \"we-text\", \"props\": { \"variant\": \"label\" }, \"children\": [\"$post.author\"] }\n ]\n },\n { \"type\": \"we-text\", \"props\": { \"variant\": \"heading-sm\" }, \"children\": [\"$post.title\"] },\n { \"type\": \"we-text\", \"children\": [\"$post.text\"] }\n ]\n }\n ]\n}\n\nUse $query or $store for dynamic data (more common in production):\n{ \"type\": \"$each\", \"props\": { \"items\": { \"$query\": { \"entity\": \"TextBlock\" } }, \"as\": \"post\" }, \"children\": [...] }\n{ \"type\": \"$each\", \"props\": { \"items\": { \"$store\": \"spaceStore.posts\" }, \"as\": \"post\" }, \"children\": [...] }\n\nPer-item customization inside $each:\nTo style or highlight specific items, add a data flag to those items and use $if on the flag inside the template. Do NOT use $eq: [\"$index\", N] comparisons — they are fragile, repetitive, and break when items are reordered.\nExample: add \"highlighted\": true to one item's data, then use $if on \"$post.highlighted\" in the template:\n{ \"type\": \"$if\", \"props\": { \"condition\": \"$post.highlighted\", \"then\": { \"type\": \"we-badge\", \"props\": { \"variant\": \"primary\" }, \"children\": [\"Featured\"] } } }\nFor conditional props (e.g. different bg on highlighted items):\n{ \"bg\": { \"$if\": { \"condition\": \"$post.highlighted\", \"then\": \"primary-50\", \"else\": \"neutral-0\" } } }\n\nBoolean toggle (show/hide, expand/collapse):\n{\n \"type\": \"Column\",\n \"$localState\": { \"showDetails\": { \"type\": \"boolean\", \"initial\": false } },\n \"children\": [\n { \"type\": \"we-button\", \"props\": { \"variant\": \"ghost\", \"onClick\": { \"$toggleLocal\": \"showDetails\" } }, \"children\": [\"Toggle Details\"] },\n { \"type\": \"$if\", \"props\": { \"condition\": { \"$local\": \"showDetails\" }, \"then\": { \"type\": \"we-text\", \"children\": [\"Details content here\"] } } }\n ]\n}\n\nSignal types (community-specific reactions/votes):\nSignal types are created per-community by the user. Never hardcode signal type UUIDs in schemas.\nInstead reference them by slug through spaceStore.signalTypesBySlug.\n\nALWAYS ask the user: \"What slug should I use? (e.g. 'like', 'upvote', 'star')\"\nThen use that slug in the pattern below.\n\nPattern — live wired SignalControl (inside a $each over a model with $query include):\n{\n \"type\": \"$each\",\n \"props\": {\n \"items\": {\n \"$query\": {\n \"entity\": \"MyBlock\",\n \"include\": {\n \"$totalLikeCount\": {\n \"from\": \"signals\",\n \"where\": { \"signalTypeId\": { \"$store\": \"spaceStore.signalTypesBySlug.like.id\" } },\n \"count\": true\n },\n \"$myLikeSignal\": {\n \"from\": \"signals\",\n \"where\": {\n \"signalTypeId\": { \"$store\": \"spaceStore.signalTypesBySlug.like.id\" },\n \"author\": \"$me.did\"\n },\n \"limit\": 1\n }\n }\n }\n },\n \"as\": \"item\"\n },\n \"children\": [\n {\n \"type\": \"$if\",\n \"props\": {\n \"condition\": { \"$store\": \"spaceStore.signalTypesBySlug.like\" },\n \"then\": {\n \"type\": \"SignalControl\",\n \"props\": {\n \"signalType\": { \"$store\": \"spaceStore.signalTypesBySlug.like\" },\n \"myValue\": \"$item.$myLikeSignal.value\",\n \"aggregate\": \"$item.$totalLikeCount\",\n \"onSignal\": {\n \"$action\": \"spaceStore.upsertSignal\",\n \"args\": [\"$item.id\", { \"$store\": \"spaceStore.signalTypesBySlug.like.id\" }, \"$arg\"]\n }\n }\n }\n }\n }\n ]\n}\n\nNotes:\n- The $if guard hides SignalControl if the community hasn't created a signal type with that slug.\n- Replace \"like\" with the user's slug throughout (in $store paths and args).\n- $query include adds $totalLikeCount and $myLikeSignal as computed properties on each item.\n- signalType prop accepts the full SignalType object (provides icon, mode, range to the UI component).\n\nPreview / mockup mode (static, no store wiring):\n{\n \"type\": \"SignalControl\",\n \"props\": {\n \"preview\": true,\n \"signalType\": { \"icon\": \"❤️\", \"mode\": \"toggle\", \"rangeMin\": 0, \"rangeMax\": 1 }\n }\n}\nUse preview: true when sketching a layout without real data. Remove it (and add the full wiring above) when going live.\n\n---\n\n## Routing Structure\n\nDefine nested routes using the \"routes\" array at the root node of the schema.\nEach route object describes a path and the UI node to render when that path is active.\nRoutes can be nested to support sub-pages and layouts.\n\nRoute objects follow the same structure as schema nodes, with an additional \"path\" property.\n\n- The \"routes\" array MUST be placed on the ROOT template node (or on a route node for nested routing). The router only reads routes from these positions — placing routes on an arbitrary child node means the router will never find them and nothing will render.\n- Use \"path: '*'\" or \"path: '/*'\" for catch-all/not-found routes.\n- Use \":paramName\" for dynamic route parameters (e.g. \"/space/:spaceId\").\n- Use nested \"routes\" arrays for sub-pages and layouts.\n- Use { \"type\": \"$routes\" } in children to indicate where nested routes should render. The $routes outlet can be deeply nested — only the routes array placement matters.\n- EVERY { \"type\": \"$routes\" } outlet MUST have a \"routes\" array defined on the same node or an ancestor node. A $routes outlet without a routes array is invalid and will fail validation.\n- NEVER duplicate a route path — every route in the same \"routes\" array MUST have a unique path.\n- When using tabs, each tab's key and navigate path MUST have a matching route. Ensure a 1:1 correspondence between tabs and routes.\n\n### Tabs + Routing\n\nIMPORTANT: we-tabs only manages visual selection — clicking a tab does NOT navigate automatically.\nEach we-tab MUST have an onClick with { \"$action\": \"routeStore.navigate\" } to trigger route changes.\nBind we-tabs selectedKey to the matching route segment so the active tab stays in sync.\n(Alternatively, a single onChange on we-tabs can replace per-tab onClick — see onChange pattern below.)\n\nRecommended pattern — header above tabs (routes on ROOT, $routes outlet nested inside):\n{\n \"type\": \"Column\",\n \"routes\": [\n { \"path\": \"/\", \"type\": \"we-text\", \"children\": [\"Select a tab\"] },\n { \"path\": \"/posts\", \"type\": \"Column\", \"children\": [{ \"type\": \"we-text\", \"children\": [\"Posts content\"] }] },\n { \"path\": \"/articles\", \"type\": \"Column\", \"children\": [{ \"type\": \"we-text\", \"children\": [\"Articles content\"] }] }\n ],\n \"children\": [\n { \"type\": \"Row\", \"props\": { \"p\": \"300\", \"ax\": \"between\" }, \"children\": [\n { \"type\": \"we-text\", \"props\": { \"variant\": \"heading-lg\" }, \"children\": [\"My App\"] }\n ]},\n {\n \"type\": \"we-tabs\",\n \"props\": { \"selectedKey\": { \"$store\": \"routeStore.segments.0\" } },\n \"children\": [\n { \"type\": \"we-tab\", \"props\": { \"key\": \"posts\", \"label\": \"Posts\", \"onClick\": { \"$action\": \"routeStore.navigate\", \"args\": [\"/posts\"] } } },\n { \"type\": \"we-tab\", \"props\": { \"key\": \"articles\", \"label\": \"Articles\", \"onClick\": { \"$action\": \"routeStore.navigate\", \"args\": [\"/articles\"] } } }\n ]\n },\n { \"type\": \"$routes\" }\n ]\n}\nNote: \"routes\" is on the root Column, NOT on a child. The $routes outlet is a child — that's fine. Only the routes array placement matters.\n\nWRONG — two common mistakes that produce empty tabs (validator will catch both):\n{\n // MISTAKE 1: routes defined on an inner child node, not the root.\n // The router never inspects children for routes arrays — this routes array is invisible.\n \"type\": \"Column\",\n \"children\": [\n { \"type\": \"we-tabs\", \"children\": [\"...tabs...\"] },\n {\n \"type\": \"Column\",\n \"routes\": [ // ← WRONG: router never reads this\n { \"path\": \"/posts\", \"type\": \"Column\", \"children\": [\"...\"] }\n ],\n \"children\": [{ \"type\": \"$routes\" }] // ← outlet here does nothing without a live routes array\n }\n ]\n}\n\n{\n // MISTAKE 2: using { type: \"$routes\" } as a route entry's component type.\n // $routes is an outlet slot marker — as a leaf route entry it has no children injected,\n // so it returns null. Every tab navigates to a route that renders nothing.\n \"type\": \"Column\",\n \"routes\": [\n { \"path\": \"/posts\", \"type\": \"$routes\" } // ← WRONG: renders null, use a real component\n ],\n \"children\": [{ \"type\": \"$routes\" }]\n}\n\nAlternative: single onChange on we-tabs (fires with $event.detail.value = selected key):\n{ \"onChange\": { \"$action\": \"routeStore.navigate\", \"args\": [{ \"$concat\": [\"/\", \"$arg.detail.value\"] }] } }\nThis replaces all per-tab onClick handlers but requires $concat to build the path.\n\nNested routing example:\n{\n \"routes\": [\n { \"path\": \"*\", \"type\": \"Column\", \"props\": { \"ax\": \"center\", \"p\": \"500\" }, \"children\": [{ \"type\": \"we-text\", \"children\": [\"Page not found\"] }] },\n { \"path\": \"/\", \"type\": \"Column\", \"props\": { \"ax\": \"center\", \"p\": \"500\" }, \"children\": [{ \"type\": \"we-text\", \"children\": [\"Home page\"] }] },\n {\n \"path\": \"/space/:spaceId\",\n \"type\": \"Row\",\n \"children\": [{ \"type\": \"$routes\" }],\n \"routes\": [\n { \"path\": \"/*\", \"type\": \"we-text\", \"children\": [\"Space page not found\"] },\n { \"path\": \"/\", \"type\": \"we-text\", \"children\": [\"About sub-page\"] },\n { \"path\": \"/posts\", \"type\": \"Column\", \"children\": [{ \"type\": \"$routes\" }],\n \"routes\": [\n { \"path\": \"/*\", \"type\": \"we-text\", \"children\": [\"Post not found\"] },\n { \"path\": \"/\", \"type\": \"we-text\", \"children\": [\"No posts selected\"] },\n { \"path\": \"/1\", \"type\": \"we-text\", \"children\": [\"Post 1 page\"] }\n ]\n }\n ]\n }\n ]\n}\n\n---\n\n## Rules & Best Practices\n\n- Always use the correct prop names and value types for each component.\n- Never use null as a value in any children array. Only use valid schema nodes or strings.\n- Each item in a children array must be either a valid schema node object or a string.\n- Use design tokens for spacing, color, radius, etc. (do not use raw CSS except in styles).\n- Use the styles prop for custom inline CSS (e.g., { \"width\": \"100px\" }).\n- Use hoverProps for hover state overrides, activeProps for pressed state, focusProps for focus state. Supported on @we/primitives (we-text, we-button, etc.) and layout components (Column, Row).\n- Use dynamic logic tokens ($store, $if, $action, etc.) for reactivity and conditional behavior.\n- Nest components using children or slots as needed.\n- For routes, use the routes array with path and child nodes.\n- Do not invent new components or props — use only those listed in the component registry.\n- Do not set props to their default/inherited values — omit them. fontSize and fontWeight inherit from parents (~16px / normal), so only set them when you need a different value.\n- Omit empty `props` and `children` — both are optional. Do not write `props: {}` or `children: []`.\n- Do not use `as const` on schema node `type` fields — `SchemaNode.type` is `string`, so it is never needed.\n- For icon-only buttons, nest a `we-icon` child inside `we-button` rather than using a `text` prop with a Unicode character. **Omit the `size` prop on `we-icon` when nesting inside sized primitives** (`we-button`, `we-input`, `we-badge`, `we-textarea`) — these components auto-size nested icons via `--we-context-icon-size` (xs→12px, sm→16px, md→24px, lg→32px, xl→40px). Only set an explicit icon `size` if you need to override the automatic sizing. Example: `{ type: 'we-button', props: { variant: 'ghost', size: 'sm' }, children: [{ type: 'we-icon', props: { name: 'x' } }] }`.\n- NEVER pass a bare number like \"16\" as a size or dimension prop — it is not valid CSS. Always check the component's declared prop type: if it's a string union, use one of the listed values; if it accepts arbitrary strings, include a CSS unit (e.g. \"16px\", \"2rem\").\n- For interactive list items and selectable options, use `we-button` with variant switching (e.g., `secondary` when selected, `ghost` when not) instead of manually styling `Row` with cursor, bg, and onClick. Buttons provide hover, focus, and active states for free.\n- For card-like layouts, compose from `Column` with DS props (bg, r, border, p, gap). This gives full control over spacing and appearance.\n- When rendering lists of similar items (posts, cards, users, etc.), ALWAYS use `$each` with a single template child — never duplicate the same node structure multiple times. Use literal arrays in `items` for static data, or `$store`/`$query` for dynamic data.\n\n### Icon Names (Phosphor Icons)\n\nwe-icon uses **Phosphor Icons** (v2.1). Do NOT use Heroicons, Material, or FontAwesome names.\nPhosphor names are lowercase-kebab-case. The `weight` prop controls style: \"regular\" (default), \"bold\", \"fill\", \"light\", \"thin\", \"duotone\".\n\nCommon Phosphor icon names (use these, NOT Heroicons equivalents):\n- Navigation: house, arrow-left, arrow-right, caret-left, caret-right, caret-down, caret-up, arrows-clockwise\n- Actions: plus, minus, x, check, pencil-simple, trash, copy, download, upload, share, link, magnifying-glass, funnel, sliders-horizontal\n- Communication: chat-circle, chat-dots, envelope-simple, paper-plane-tilt, bell, megaphone\n- Social: heart, thumbs-up, thumbs-down, star, share-network, users, user, user-plus\n- Media: image, camera, play, pause, stop, microphone, speaker-high, video-camera\n- Files: file, file-text, folder, folder-open, clipboard-text, note\n- UI: list, squares-four, gear, dots-three, dots-three-vertical, warning, info, question, check-circle, x-circle, eye, eye-slash\n- Misc: lightning, rocket, globe, map-pin, calendar, clock, tag, bookmark, flag, lock, shield-check\n\nWRONG icon names (Heroicons/Material — do NOT use):\n- \"chat-bubble-left\" → use \"chat-circle\"\n- \"chevron-right\" → use \"caret-right\"\n- \"cog\" / \"settings\" → use \"gear\"\n- \"trash-can\" → use \"trash\"\n- \"magnifying-glass-circle\" → use \"magnifying-glass\"\n- \"home\" → use \"house\"\n- \"favorite\" → use \"heart\"\n- \"delete\" → use \"trash\"\n- \"search\" → use \"magnifying-glass\"\n- \"close\" → use \"x\"\n- \"menu\" → use \"list\"\n- All schemas must be valid JSON with property names and string values in double quotes.\n- The meta property at the root is required: { \"meta\": { \"name\": \"...\", \"description\": \"...\", \"icon\": \"...\" } }\n- Always set `bg: 'neutral-50'` on root-level schema nodes (templates, pages). This ensures proper background in all themes — without it, dark mode renders white backgrounds.\n\nMost @we/primitives inherit all Design System Props documented above (layout, visual, flex, typography, state).\nSome layout-only primitives (we-avatar, we-icon, we-image, we-spinner, etc.) only accept Layout props — see the Design System Props section for the full list.\n\nNative HTML elements (lowercase tags render directly without registry entries):\n- Layout: div, section, article, aside, main, nav, header, footer\n- Text: p, span, h1-h6, pre, code, blockquote\n- Lists: ul, ol, li\n- Forms: form, input, button, label, select, textarea\n- Media: img, video, audio, canvas, figure, figcaption\n- Other: a, table, tr, td, th, details, summary, dialog\n\n## Schema Validation\n\nRun `we-validate-schemas` (or `node packages/schema-system/shared/dist/cli/we-validate-schemas.js`) from the monorepo root to validate all `.schema.ts` files.\nFor a specific file: `we-validate-schemas packages/app-framework/src/shared/schemas/MyTemplate.schema.ts`\n\nAfter creating or modifying a `.schema.ts` file, always run validation to catch:\n- Unknown component types (typos, missing registry entries)\n- Invalid or misspelled props (with \"did you mean?\" suggestions)\n- Prop type mismatches (e.g., number where string expected)\n- Missing required `meta` field on root TemplateSchema nodes\n- `$routes` outlet without a `routes` array on an ancestor\n- Orphan `$local` / `$setLocal` references without a `$localState` ancestor\n- DS layer consistency (mixing props from layers the component doesn't support)"; +export const schemaContext = "## Schema Structure\n\nA schema is a tree of nodes. Each node can have:\n- type: The component to render (string, e.g. \"we-button\", \"Column\")\n- props: An object of props for the component\n- children: An array of child nodes (or strings for text), or token objects like { $store: '...' } or { $concat: [...] }.\n- slots: Named slots for advanced composition (optional)\n- slot: The name of the slot this node should be rendered into (optional)\n- routes: For routing components, an array of nestable route objects (optional)\n- styles: Raw CSS escape hatch — Record applied as inline styles on a **wrapper div** that surrounds the component. Use only for CSS that must live on a wrapper: filter, clip-path, backdrop-filter, mix-blend-mode. When present the wrapper participates in layout (no display:contents), so CSS effects apply correctly. **Important:** this is NOT the same as props.styles. If you want to apply custom CSS to a Column, Row, or Grid's own element (e.g. a background image), put it in props.styles instead — node-level styles go on a wrapper div around the component and will be hidden behind the component's own background.\n\nExample node:\n{\n \"type\": \"we-button\",\n \"props\": {\n \"onClick\": { \"$action\": \"routeStore.navigate\", \"args\": [\"/home\"] }\n },\n \"children\": [\n { \"type\": \"we-icon\", \"props\": { \"name\": \"house\" } },\n { \"type\": \"we-text\", \"props\": { \"size\": \"600\" }, \"children\": [\"Home\"] }\n ]\n}\n\n## Prop-level Dynamic Logic & Expressions\n\nSpecial tokens in props enable dynamic, reactive, or computed behavior.\n\nStore reference:\n{ \"$store\": \"storeName.property.path\" }\nResolves a value from a named store, supporting nested paths.\n\nAction/event:\n{ \"$action\": \"storeName.method\", \"args\": [...] }\nCalls a method on a store, optionally with arguments (which can themselves be tokens).\nSupports async lifecycle callbacks — fired after the store method's Promise resolves/rejects:\n onSuccess: [...actions] — fired on resolve; '$result' (and '$result.') in args refers to the resolved value\n onError: [...actions] — fired on reject; '$result.message' etc. refers to the error object\n onFinally: [...actions] — fired regardless of outcome\nNon-promise (synchronous) methods are unaffected — lifecycle keys are ignored.\nExample — close modal after async submission:\n{ \"$action\": \"adamStore.createSpace\", \"args\": [...], \"onSuccess\": [{ \"$setLocal\": \"modalOpen\", \"value\": false }] }\nExample — navigate to newly created item:\n{ \"$action\": \"adamStore.createSpace\", \"args\": [...], \"onSuccess\": [{ \"$setLocal\": \"modalOpen\", \"value\": false }, { \"$action\": \"routeStore.navigate\", \"args\": [{ \"$concat\": [\"/space/\", \"$result.uuid\"] }] }] }\n\nModel mutations via $action (use these for creating/updating/deleting model instances):\nmodel.create — creates a model instance in the current perspective (default) or a specified one:\n{ \"$action\": \"model.create\", \"args\": [\"ModelName\", { \"field\": \"value\" }, { \"perspective\": \"adamStore.rootPerspective\" }] }\nThe third argument is an options object. Omit it to use the current space perspective.\n\nmodel.update — updates a model instance:\n{ \"$action\": \"model.update\", \"args\": [\"ModelName\", \"$item.id\", { \"field\": \"newValue\" }] }\nTo target a non-current perspective: { \"$action\": \"model.update\", \"args\": [\"ModelName\", \"$item.id\", { \"field\": \"value\" }, { \"perspective\": \"adamStore.rootPerspective\" }] }\n\nmodel.delete — deletes a model instance:\n{ \"$action\": \"model.delete\", \"args\": [\"ModelName\", \"$item.id\"] }\n\nUse perspective: 'adamStore.rootPerspective' for we-root models (AgentSettings, ChatSession, etc.).\nUse the default (no perspective) for space-scoped models (Space, Signal, etc.).\n\nConditional logic:\n{ \"$if\": { \"condition\": ..., \"then\": ..., \"else\": ... } }\nEvaluates condition; if truthy, returns then, else returns else.\n\nMap/iterate:\n{ \"$map\": { \"items\": { \"$store\": \"templateStore.templates\" }, \"select\": { ... } } }\nIterates over an array, mapping each item to a new object using the select mapping.\n\nPick:\n{ \"$pick\": { \"from\": { \"$store\": \"userStore.profile\" }, \"props\": [\"name\", \"email\"] } }\nPicks specific properties from an object.\n\nConcat (string building):\n{ \"$concat\": [\"part1\", \"$context.value\", \"part2\"] }\nJoins multiple parts into a single string.\n\nContext references:\nStrings starting with \"$\" followed by a context key resolve to context values.\nExample: \"$space.name\" resolves to the name property of the space context variable.\nDot paths supported: \"$item.profile.avatar\".\n\nEquality / inequality checks:\n{ \"$eq\": [a, b] } — strict equality\n{ \"$ne\": [a, b] } — strict inequality\n\nNumeric comparisons:\n{ \"$lt\": [a, b] } — a < b (less than)\n{ \"$gt\": [a, b] } — a > b (greater than)\nExample: { \"$gt\": [{ \"$count\": { \"items\": { \"$store\": \"listStore.items\" } } }, 0] }\n\nSet membership:\n{ \"$in\": [value, array] } — true if array contains value (false if second operand is not an array)\nExample: { \"$in\": [{ \"$store\": \"spaceStore.uuid\" }, { \"$store\": \"adamStore.systemPerspectiveUuids\" }] }\nExample: { \"$in\": [\"$item.role\", [\"admin\", \"moderator\"]] }\n\nBoolean logic:\n{ \"$and\": [a, b, ...] } — all truthy\n{ \"$or\": [a, b, ...] } — any truthy\n{ \"$not\": a } — negation\n\nArray operators:\n{ \"$filter\": { \"items\": , \"where\": { \"field\": \"value\", ... } } }\nFilters an array to items where all where conditions match. Mirrors the $query where operator set:\n\n { \"field\": \"value\" } — strict equality\n { \"field\": { \"not\": \"value\" } } — inequality; array form excludes multiple values\n { \"field\": { \"contains\": \"text\" } } — case-insensitive substring match (strings only)\n { \"field\": { \"exists\": true } } — non-null / non-undefined presence check\n { \"field\": { \"exists\": false } } — null or undefined check\n\nWhere values (including those inside operator objects) are resolved through the prop system,\nso $store, $local, and context refs like { \"$local\": \"searchText\" } all work.\n\n$query-only logical combinators (OR / AND / NOT) — NOT supported in $filter, only in $query's where:\n { \"OR\": [ { \"field\": \"value\" }, { \"field2\": \"value2\" } ] } — matches if ANY branch matches\n { \"AND\": [ { ... }, { ... } ] } — matches if ALL branches match (sibling keys at the\n same level are already implicitly ANDed — use AND\n to group a set of conditions alongside an OR/NOT)\n { \"NOT\": { \"field\": \"value\" } } — matches if the branch does NOT match\nBranches are full where-clause objects (can contain multiple fields, and can nest OR/AND/NOT inside each other).\nSibling keys alongside OR/AND/NOT at the same level are implicitly ANDed with it.\nExample — case-insensitive search across two fields:\n{\n \"$query\": {\n \"entity\": \"Space\",\n \"where\": {\n \"OR\": [\n { \"name\": { \"contains\": { \"$local\": \"searchText\" } } },\n { \"description\": { \"contains\": { \"$local\": \"searchText\" } } }\n ]\n }\n }\n}\nNote: using OR/AND/NOT disables the SPARQL-level sort/pagination pushdown (see count-projection and\nrelation-property ordering below) — those orderings silently stop working if combined with OR/AND/NOT in the\nsame query's where clause, because the fallback sort runs before the projection/relation data is attached.\n\nExamples:\n{ \"$filter\": { \"items\": { \"$store\": \"spaceStore.members\" }, \"where\": { \"role\": \"admin\" } } }\n{ \"$filter\": { \"items\": { \"$store\": \"spaceStore.members\" }, \"where\": { \"location\": { \"exists\": true }, \"handle\": { \"contains\": { \"$local\": \"searchText\" } } } } }\n\n{ \"$count\": { \"items\": } }\nReturns the length of an array.\nExample: { \"badge\": { \"$count\": { \"items\": { \"$store\": \"notificationStore.unread\" } } } }\n\n{ \"$find\": { \"items\": , \"where\"?: { ... }, \"select\"?: \"fieldName\" } }\nFinds the first matching item. where is optional (returns first item if omitted). select plucks a single field.\nExample: { \"$find\": { \"items\": { \"$store\": \"spaceStore.members\" }, \"where\": { \"id\": \"$item.creatorId\" }, \"select\": \"name\" } }\n\n{ \"$plural\": { \"count\": , \"one\": \"singular\", \"other\": \"plural\" } }\nReturns \"one\" when count === 1, otherwise \"other\". Use in children arrays for count-noun labels.\ncount is resolved through the prop system — any numeric expression ($count, $store, context ref) works.\nExample: { \"$plural\": { \"count\": { \"$count\": { \"items\": { \"$store\": \"spaceStore.members\" } } }, \"one\": \"Member\", \"other\": \"Members\" } }\nCompose with we-number for a full \"N Members\" display:\n we-number (value: { \"$count\": ... }, shorten: true) + we-text (children: [{ \"$plural\": { \"count\": { \"$count\": ... }, \"one\": \"Member\", \"other\": \"Members\" } }])\n\nQuery (data retrieval):\n{ \"$query\": { \"entity\": \"ModelName\", \"where\": { \"field\": \"value\" }, \"limit\": 10, \"order\": { \"field\": \"asc\" } } }\nQueries the current dataset for entity instances. Always returns an array.\nOptions: entity (required), where, order, limit, offset, include, scope, dataset, subscribe.\nsubscribe defaults to true — reactive live updates. Set subscribe: false to do a one-time fetch.\nBy default $query targets the current dataset ($currentDataset). Use dataset to query a different dataset —\nrequired when reading entities from an external app (e.g. Flux) that is open as a WE space:\n{ \"$query\": { \"entity\": \"Channel\", \"dataset\": \"$currentDataset\" } }\n\nBackend-neutral identity & dataset refs — prefer these over adamStore.* store paths inside $query and conditions:\n- $currentDataset — the currently active dataset (an AD4M perspective, in the AD4M backend). Use as a dataset value.\n- $me — the current agent's identity object. Use $me.did for their DID (ownership checks, author filters, e.g. { \"$eq\": [\"$post.author\", \"$me.did\"] }); $me.handle / $me.avatar for profile fields once loaded.\n\nEager-loading relations with include (most common relational pattern):\ninclude hydrates related model instances in the same query — no extra fetches needed.\nRelation names come from the HasMany relations listed for each model in externalModels.\n\nSimple include — hydrate all related instances:\n{ \"$query\": { \"entity\": \"Channel\", \"include\": { \"conversations\": true } } }\nEach item in the result will have a conversations array of hydrated Conversation objects.\n\nSub-query include — filter, sort, or limit the related records:\n{ \"$query\": { \"entity\": \"Channel\", \"include\": { \"conversations\": { \"order\": { \"createdAt\": \"desc\" }, \"limit\": 10 } } } }\n\nNested include — hydrate relations of relations:\n{ \"$query\": { \"entity\": \"Channel\", \"include\": { \"conversations\": { \"include\": { \"messages\": true } } } } }\nNesting can go as deep as needed. Each level adds one batched fetch (not N+1).\n\nCount projection — add a derived numeric field:\n{ \"$query\": { \"entity\": \"Post\", \"include\": { \"$likeCount\": { \"from\": \"likes\", \"count\": true } } } }\nThe $-prefixed key becomes a new field on each result item (e.g. item.$likeCount = 42).\n\nSorting by a count projection — order can reference a $-prefixed count key directly, sorting by the aggregate:\n{\n \"$query\": {\n \"entity\": \"Post\",\n \"limit\": 20,\n \"order\": { \"$likeCount\": \"desc\" },\n \"include\": { \"$likeCount\": { \"from\": \"likes\", \"count\": true } }\n }\n}\nRequirements: only a single order key is supported when it targets a projection (mixing it with a second sort key falls back\nto a plain property sort), and the query must also specify limit or offset — without one the count isn't computed yet at\nsort time and the order silently has no effect. Always pair count-projection ordering with a limit.\nCombine with $if for a user-togglable sort field (e.g. \"newest\" vs \"most liked\"):\n{\n \"order\": {\n \"$if\": {\n \"condition\": { \"$eq\": [{ \"$local\": \"sortField\" }, \"likes\"] },\n \"then\": { \"$likeCount\": { \"$local\": \"sortDirection\" } },\n \"else\": { \"createdAt\": { \"$local\": \"sortDirection\" } }\n }\n }\n}\n\nSorting by a related model property — order can reference a dotted \"relation.property\" path for a HasOne/HasMany\nrelation declared on the model, sorting by a scalar property on the related instance:\n{\n \"$query\": {\n \"entity\": \"Space\",\n \"limit\": 20,\n \"order\": { \"location.country\": \"asc\" },\n \"include\": { \"location\": true }\n }\n}\nSame requirements as count-projection ordering above: only a single order key, and pair with limit/offset — without\none the relation data isn't attached yet at sort time and the order silently has no effect. include isn't required\nfor the sort itself (the relation is resolved from the model's declared shape), but you'll usually want it anyway to\nread the field in the UI (e.g. \"$space.location.country\").\nCombine with $if the same way as count-projection ordering to let the user toggle between sort fields.\n\nSingle-item projection — add a derived field that resolves to one instance or null:\n{ \"$query\": { \"entity\": \"Post\", \"include\": { \"$myLike\": { \"from\": \"likes\", \"where\": { \"author\": \"$me.did\" }, \"limit\": 1 } } } }\nWith limit: 1 the field unwraps to T | null instead of an array.\n\ninclude only works with typed relations — ones where the target model class is known.\nFor WE models this is always the case. For external models, check the externalModels listing:\nrelations marked \"→ ModelName\" are typed (safe for include); relations marked \"parent query only\"\nare untyped and will crash at runtime if used with include — use a scope drill-down instead.\n\nRelational queries — fetch a parent record's children (drill-down navigation):\n{ \"$query\": { \"entity\": \"Conversation\", \"scope\": { \"anchor\": \"Channel\", \"via\": \"conversations\", \"anchorId\": \"$channel.id\" } } }\nscope.anchor is the parent entity type; scope.via is its relation whose targets are this query's entity (the\nHasMany relation listed for that entity in externalModels); scope.anchorId is the parent record's id (typically\nfrom a $each context variable or a route segment). The adapter resolves the relation to a backend handle —\nno protocol details live in the template.\nUse this pattern when navigating to a detail route and loading only that record's children.\nFor external-app datasets, always add dataset: \"$currentDataset\".\n\nLocal state (scoped ephemeral state):\nDeclare on any node: \"$localState\": { \"name\": { \"type\": \"string\", \"initial\": \"\" } }\nSupported types: \"string\", \"boolean\", \"number\", \"function\", \"object\".\nRead: { \"$local\": \"name\" } — returns the signal value (reactive).\n { \"$local\": \"name.nested.path\" } — dot-notation reads into object-typed fields (reactive).\nWrite: { \"$setLocal\": \"name\", \"from\": \"$event.target.value\" } — event handler that updates the signal.\n { \"$setLocal\": \"name\", \"value\": \"literal\" } — sets to a literal value (string, number, boolean, null, object).\n { \"$setLocal\": \"name\", \"merge\": { \"field\": \"$event.detail\" } } — shallow-merges fields into an object-typed signal. Values are resolved as event paths (e.g. \"$event.detail\") or passed as literals. Use for partial updates to object state.\nToggle: { \"$toggleLocal\": \"fieldName\" } — toggles a boolean field (equivalent to setting it to !current). Use for show/hide, open/close, expand/collapse patterns.\nCall function: { \"$callLocal\": \"fieldName\" } — event handler that calls the function stored in a function-typed local field.\n Used when a child component needs to trigger a callback passed in via $localState.\n The field must be declared as type: 'function' and set via $setLocal.\n Example: { \"onClick\": { \"$callLocal\": \"onConfirm\" } }\nState is created on mount and destroyed on unmount. Nested $localState declarations merge, inner fields shadow outer.\n$local values can be used in $action args: { \"$action\": \"store.method\", \"args\": [{ \"$local\": \"name\" }] }\n\nObject-typed local state (consolidating related scalar fields):\nWhen several related fields share a common condition on their initial values (e.g. all null/empty when a store value is absent), prefer a single \"object\" field seeded from the store, then read sub-fields with dot-notation and write with merge.\nExample — location object (replaces 5 separate scalar fields with $if guards):\n \"$localState\": { \"location\": { \"type\": \"object\", \"initial\": { \"$store\": \"spaceStore.currentSpace.location\" } } }\n Read: { \"$local\": \"location.latitude\" }, { \"$local\": \"location.city\" }\n Write (picker confirm): { \"$setLocal\": \"location\", \"from\": \"$event.detail\" }\n Write (partial edit): { \"$setLocal\": \"location\", \"merge\": { \"city\": \"$event.detail\" } }\n Write (clear): { \"$setLocal\": \"location\", \"value\": null }\n Condition (has location): { \"$local\": \"location\" }\nUse \"object\" whenever you would otherwise write 3+ related scalar fields each needing $if on their initial value.\n\nHoisted query state ($queries):\nDeclare on any node to run reactive subscriptions at the node root and expose results in $local.\nSolves two problems: avoids N duplicate subscriptions inside $each loops, and makes query results available for $if conditions.\n\"$queries\": { \"signalTypes\": { \"entity\": \"SignalType\", \"subscribe\": true } }\nResults are injected into $local as read-only reactive arrays, accessible via { \"$local\": \"signalTypes\" }.\nQuery options are identical to $each's $query prop (entity, where, order, limit, include, dataset, subscribe).\n$queries and $localState share the same $local namespace — avoid duplicate names across both.\n$setLocal will warn and no-op on $queries entries (they are read-only).\nUse with $count + $gt for conditional visibility:\n{ \"condition\": { \"$gt\": [{ \"$count\": { \"items\": { \"$local\": \"signalTypes\" } } }, 0] } }\nExample:\n{\n \"$queries\": { \"signalTypes\": { \"entity\": \"SignalType\", \"subscribe\": true } },\n \"type\": \"Column\",\n \"children\": [\n {\n \"type\": \"$each\",\n \"props\": { \"items\": { \"$local\": \"signalTypes\" }, \"as\": \"sig\" },\n \"children\": [...]\n }\n ]\n}\n\nBoolean toggle pattern (show/hide comments, expand/collapse sections, etc.):\n{\n \"$localState\": { \"showComments\": { \"type\": \"boolean\", \"initial\": false } },\n \"children\": [\n {\n \"type\": \"we-button\",\n \"props\": {\n \"variant\": \"ghost\",\n \"onClick\": { \"$toggleLocal\": \"showComments\" }\n },\n \"children\": [{ \"type\": \"we-icon\", \"props\": { \"name\": \"chat-circle\" } }]\n },\n {\n \"type\": \"$if\",\n \"props\": {\n \"condition\": { \"$local\": \"showComments\" },\n \"then\": { \"type\": \"Column\", \"children\": [{ \"type\": \"we-text\", \"children\": [\"Comments visible\"] }] }\n }\n }\n ]\n}\n\nForm validation (extends $localState):\nDeclare validation rules on fields:\n\"$localState\": {\n \"email\": {\n \"type\": \"string\",\n \"initial\": \"\",\n \"validate\": [\n { \"rule\": \"required\", \"message\": \"Email is required\" },\n { \"rule\": \"pattern\", \"value\": \"^[^@]+@[^@]+$\", \"message\": \"Invalid email\" }\n ]\n }\n}\n\nBuilt-in rules: required, minLength (value: N), maxLength (value: N), min (value: N), max (value: N), pattern (value: regex string), match (field: otherFieldName). All accept optional \"message\" override.\n\nRead tokens:\n{ \"$error\": \"fieldName\" } — first validation error message (only shown after field is touched), or \"\".\n{ \"$valid\": \"fieldName\" } — true if all rules pass (regardless of touched state).\n{ \"$touched\": \"fieldName\" } — true after the field has been blurred/touched.\n{ \"$formValid\": \"$scope\" } — true if ALL validated fields in the current $localState scope pass.\n\nAction tokens:\n{ \"$touch\": \"fieldName\" } — marks a single field as touched (use in onBlur).\n{ \"$touch\": \"$all\" } — marks all fields in scope as touched (use before submit guard).\n{ \"$resetLocal\": \"$scope\" } — resets all fields to initial values and clears touched state.\n\nHandler arrays (compose multiple actions on one event):\n{ \"onClick\": [{ \"$touch\": \"$all\" }, { \"$if\": { \"condition\": { \"$formValid\": \"$scope\" }, \"then\": { \"$action\": \"store.submit\", \"onSuccess\": [{ \"$setLocal\": \"modalOpen\", \"value\": false }] } } }] }\nArray entries execute sequentially. Non-function entries (e.g. $if with false condition) are skipped.\nPrefer onSuccess over a bare $setLocal before the $action — the bare form closes the modal immediately (losing the loading spinner); onSuccess waits for the Promise to resolve.\n\nTypical form pattern:\n{\n \"$localState\": { \"name\": { \"type\": \"string\", \"initial\": \"\", \"validate\": [{ \"rule\": \"required\" }] } },\n \"children\": [\n {\n \"type\": \"we-form-field\",\n \"props\": { \"label\": \"Name\", \"error\": { \"$error\": \"name\" } },\n \"children\": [{\n \"type\": \"we-input\",\n \"props\": {\n \"value\": { \"$local\": \"name\" },\n \"onInput\": { \"$setLocal\": \"name\", \"from\": \"$event.detail\" },\n \"onBlur\": { \"$touch\": \"name\" }\n }\n }]\n },\n {\n \"type\": \"we-button\",\n \"props\": {\n \"disabled\": { \"$not\": { \"$formValid\": \"$scope\" } },\n \"onClick\": [\n { \"$touch\": \"$all\" },\n { \"$if\": { \"condition\": { \"$formValid\": \"$scope\" }, \"then\": { \"$action\": \"store.save\", \"args\": [{ \"$local\": \"name\" }], \"onSuccess\": [{ \"$setLocal\": \"submitDone\", \"value\": true }] } } }\n ]\n },\n \"children\": [\"Submit\"]\n }\n ]\n}\n\n## Block-level Dynamic Structures\n\nBlock-level structures use \"type\" starting with \"$\" for dynamic rendering of schema nodes.\n\nEach loop:\n{ \"type\": \"$each\", \"props\": { \"items\": { \"$store\": \"storeName.arrayProperty\" }, \"as\": \"itemName\" }, \"children\": [ ... ] }\nRenders children once for each item. The \"as\" name becomes a context key. Defaults to \"item\" — omit \"as\" unless you need a different name.\n\nConditional rendering:\n{ \"type\": \"$if\", \"props\": { \"condition\": ..., \"then\": { ... }, \"else\": { ... } } }\nRenders \"then\" node if condition is truthy, else renders \"else\" node.\nSupports enterTransition / exitTransition for CSS animations when the node mounts/unmounts.\nTransitionConfig = TransitionEffect | TransitionEffect[]\nTransitionEffect = { type: 'fade'|'slide'|'scale'|'pulse', duration?: ms, easing?: string, delay?: ms, direction?: 'left'|'right'|'up'|'down', distance?: string }\nfade controls opacity only; slide/scale control transform only. pulse is a persistent looping animation (not a one-shot transition) — starts once entered, stops on exit; direction/distance don't apply (default duration 1200ms, easing 'ease-in-out'). Compose fade/slide/scale together in an array; pulse is typically used alone.\nExample: enterTransition: [{ type: 'fade', duration: 300 }, { type: 'slide', direction: 'up', distance: '40px', duration: 400 }]\nExample (pulse): enterTransition: { type: 'pulse', duration: 1500 }\n\nViewport / mount animation (child always in DOM):\n{ \"type\": \"$animate\", \"props\": { \"scrollReveal\"?: true | number, \"scrollLeave\"?: true | number, \"scrollPast\"?: string, \"enterTransition\"?: TransitionConfig, \"exitTransition\"?: TransitionConfig }, \"children\": [] }\nThe child is always mounted. fade/slide/scale are CSS transitions (opacity/transform); pulse is a real CSS @keyframes loop — use this for scroll-reveal effects.\nDo NOT use $animate when the child should be absent from the DOM. Use $if for conditional DOM presence.\nscrollReveal: true fires enterTransition when the element enters the viewport.\nscrollReveal: -100 fires 100px before the element would enter (negative = earlier reveal).\nscrollLeave fires exitTransition when the element leaves the viewport.\nscrollPast: \"element-id\" observes a sentinel element (by DOM id) instead of the $animate element itself.\n enterTransition fires when the sentinel leaves the viewport (user scrolled past it).\n exitTransition fires when the sentinel returns (user scrolled back up).\n Use this for sticky headers: place a zero-height sentinel div at the bottom of the non-sticky header section,\n then wrap the mini-profile in $animate with scrollPast pointing to that sentinel's id.\n scrollPast is mutually exclusive with scrollReveal/scrollLeave.\nWithout any scroll trigger, the enterTransition runs once on mount.\nOnly one child node is supported.\nExample (scroll-reveal):\n{\n \"type\": \"$animate\",\n \"props\": {\n \"scrollReveal\": -100,\n \"enterTransition\": [\n { \"type\": \"fade\", \"duration\": 600, \"easing\": \"ease-in-out\" },\n { \"type\": \"slide\", \"direction\": \"left\", \"distance\": \"200px\", \"duration\": 1000, \"easing\": \"ease-in-out\" }\n ]\n },\n \"children\": [{ \"type\": \"SomeCard\", \"children\": [] }]\n}\nExample (sticky header mini-profile):\nPlace a sentinel at the bottom of the header, reference it in the sticky nav:\n{ \"type\": \"div\", \"props\": { \"id\": \"header-sentinel\" }, \"styles\": { \"height\": \"0px\", \"pointerEvents\": \"none\" } }\n{\n \"type\": \"$animate\",\n \"props\": {\n \"scrollPast\": \"header-sentinel\",\n \"enterTransition\": { \"type\": \"fade\", \"duration\": 250 },\n \"exitTransition\": { \"type\": \"fade\", \"duration\": 200 }\n },\n \"children\": [{ \"type\": \"Row\", \"props\": { \"ay\": \"center\", \"gap\": \"300\" }, \"children\": [\n { \"type\": \"we-avatar\", \"props\": { \"image\": \"$space.avatar\", \"size\": \"sm\" } },\n { \"type\": \"we-text\", \"props\": { \"fontWeight\": \"600\" }, \"children\": [\"$space.name\"] }\n ]}]\n}\n\nSingle model item (load one record, render children with it in context):\n{\n \"type\": \"$single\",\n \"props\": {\n \"item\": { \"$query\": { \"entity\": \"ModelName\", \"params\": { ... }, \"subscribe\": true } },\n \"as\": \"profile\" // context key for children — default: 'item'\n },\n \"children\": [{ \"type\": \"we-text\", \"children\": [\"$profile.username\"] }]\n}\nRenders nothing until a matching record is found. Like $each but for a single result.\nquery options (entity, params, include, dataset, subscribe) work identically to $query.\n\nRoute outlet:\n{ \"type\": \"$routes\" }\nIndicates where nested routes should render within a layout.\n\n---\n\n## Component Registry\n\nMost @we/primitives also accept Design System Props (see next section for details and exceptions).\n\n@we/primitives:\n- we-alert (DesignSystemElement)\n Props: variant: 'neutral' | 'primary' | 'success' | 'warning' | 'danger' = 'primary', dismissible: boolean = false\n- we-audio (LayoutVisualElement)\n Props: src: string = '', controls: boolean = false, preload: 'none' | 'metadata' | 'auto' = 'metadata', autoplay: boolean = false, loop: boolean = false, muted: boolean = false\n- we-avatar (LayoutVisualElement)\n Props: image: string = '', hash: string = '', selected: boolean = false, online: boolean = false, initials: string = '', icon: string = '', size?: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | '{css-length}' | undefined, clickable: boolean = false\n- we-badge (DesignSystemElement)\n Props: variant: 'neutral' | 'primary' | 'success' | 'warning' | 'danger' = 'neutral', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-blockquote (DesignSystemElement)\n- we-button (DesignSystemElement)\n Props: variant: 'primary' | 'secondary' | 'ghost' | 'danger' | 'outline' = 'primary', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md', text?: string | undefined, href?: string | undefined, disabled: boolean = false, loading: boolean = false, gradient: boolean = false, square: boolean = false\n- we-checkbox (DesignSystemElement)\n Props: checked: boolean = false, disabled: boolean = false, name: string = '', value: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-code (DesignSystemElement)\n Props: block: boolean = false\n- we-color-picker (DesignSystemElement)\n Props: value: string = '#000000', disabled: boolean = false, name: string = '', palette: array = [ '#000000', '#434343', '#666666', '#999999', '#b7b7b7', '#cccccc', '#d9d9d9', '#ffffff', '#980000', '#ff0000', '#ff9900', '#ffff00', '#00ff00', '#00ffff', '#4a86e8', '#0000ff', '#9900ff', '#ff00ff', '#e6b8af', '#f4cccc', '#fce5cd', '#fff2cc', '#d9ead3', '#d0e0e3', '#c9daf8', '#cfe2f3', '#d9d2e9', '#ead1dc', ]\n- we-date-picker (DesignSystemElement)\n Props: value: string = '', placeholder: string = 'Select date', disabled: boolean = false, name: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-divider (LayoutElement)\n Props: orientation: 'horizontal' | 'vertical' = 'horizontal', variant: 'solid' | 'dashed' | 'dotted' = 'solid', color?: string | undefined, thickness?: string | undefined\n- we-drawer (OverlayElement)\n Props: hideclosebutton: boolean = false, close: () => void\n- we-file-upload (DesignSystemElement)\n Props: accept: string = '', multiple: boolean = false, disabled: boolean = false, name: string = ''\n- we-form-field (DesignSystemElement)\n Props: label: string = '', description: string = '', error: string = '', required: boolean = false, size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-html (DesignSystemElement) — Renders a raw HTML string safely via DOMPurify sanitization.\n\nUse this instead of `we-text` when content is stored as HTML (e.g. rich-text\neditor output such as Flux messages). The `content` prop accepts any HTML\nfragment; it is sanitized before rendering so XSS payloads are stripped.\n Props: content: string = ''\n- we-icon (LayoutElement)\n Props: name: string = '', color: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '{css-length}' = '', weight: 'thin' | 'light' | 'regular' | 'bold' | 'fill' | 'duotone' = 'regular', gradient: string = ''\n- we-icon-picker (DesignSystemElement)\n Props: value: string = '', disabled: boolean = false, name: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md', placeholder: string = 'Pick icon'\n- we-iframe (LayoutVisualElement)\n Props: src: string = '', title: string = 'Embedded content', allow: string = '', sandbox?: string | undefined\n- we-image (LayoutVisualElement)\n Props: src: string | File = '', alt: string = '', fit: '' | 'cover' | 'contain' | 'fill' | 'none' | 'scale-down' = '', loading: 'eager' | 'lazy' = 'eager', gradient: string = '', objectPosition: string = ''\n- we-input (DesignSystemElement)\n Props: value: string = '', max: string = '', min: string = '', maxlength: unknown = Infinity, minlength: number = 0, pattern: string = '', name: string = '', step: string = '', placeholder: string = '', autocomplete: string = '', autofocus: boolean = false, disabled: boolean = false, required: boolean = false, readonly: boolean = false, type: string = 'text', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-link (DesignSystemElement)\n Props: href: string = '', target: string = '', rel: string = '', download: string = '', disabled: boolean = false\n- we-location-picker (DesignSystemElement)\n Props: latitude?: number | undefined, longitude?: number | undefined, placeholder: string = 'Set location…', disabled: boolean = false, reverseGeocode: boolean = true\n- we-markdown (DesignSystemElement)\n Props: content: string = '', markdownGap: string = ''\n- we-menu (DesignSystemElement) — Vertical list container for menu items inside a popover.\nNot a standalone selector — wrap in we-popover for dropdown behavior.\n- we-menu-group (LayoutElement)\n Props: collapsible: boolean = false, open: boolean = false, title: string = ''\n- we-menu-item (DesignSystemElement) — Single actionable item inside a we-menu.\nSupports selected, active, and danger states.\n Props: selected: boolean = false, active: boolean = false, variant: 'default' | 'danger' = 'default', label: unknown, value: unknown\n- we-modal (OverlayElement)\n Props: hideclosebutton: boolean = false, close: () => void\n- we-number (DesignSystemElement) — Displays a number, optionally abbreviated (1 200 → 1.2K, 1 500 000 → 1.5M).\n Props: value: number = 0, shorten: boolean = false, precision: number = 1, locale: string = 'en', formattedValue: string\n- we-number-input (DesignSystemElement)\n Props: value: number = 0, min: number = -Infinity, max: unknown = Infinity, step: number = 1, disabled: boolean = false, name: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-pagination (DesignSystemElement)\n Props: page: number = 1, total: number = 1, siblings: number = 1, size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-popover (LayoutElement) — Low-level floating panel anchored to a trigger element.\nUse DropdownMenu component for dropdown menus.\n Props: open: boolean = false, placement: 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end' | 'right-start' | 'right-end' = 'bottom', popoverElement: HTMLElement, triggerElement: HTMLElement\n- we-progress-bar (DesignSystemElement)\n Props: value: number = 0, max: number = 100, variant: 'neutral' | 'primary' | 'success' | 'warning' | 'danger' = 'primary', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-radio (DesignSystemElement)\n Props: checked: boolean = false, disabled: boolean = false, name: string = '', value: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-scroll-area (DesignSystemElement)\n Props: maxHeight: string = '', maxWidth: string = ''\n- we-select (DesignSystemElement)\n Props: options: SelectOption[] = [], value: string = '', placeholder: string = '', disabled: boolean = false, searchable: boolean = false, name: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-select (DesignSystemElement) — Pick a single value from a list of options. Custom-rendered dropdown.\nUse for form fields, settings, filters. Set searchable=true for type-to-filter.\n Props: options: SelectOption[] = [], value: string = '', placeholder: string = '', disabled: boolean = false, searchable: boolean = false, name: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-skeleton (DesignSystemElement)\n Props: width: string = '100%', height: string = '20px', animation: 'pulse' | 'wave' = 'pulse'\n- we-slider (DesignSystemElement)\n Props: value: number = 0, min: number = 0, max: number = 100, step: number = 1, disabled: boolean = false, name: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md', showValue: boolean = false\n- we-sortable (DesignSystemElement) — Drag-to-reorder container primitive.\n\nUsage: wrap a list of elements that each have a `data-we-id` attribute.\nFires a `we-reorder` CustomEvent on drop with the new ordered\narray of IDs.\n Props: direction: 'vertical' | 'horizontal' = 'vertical', gap: string = ''\n- we-spinner (LayoutElement)\n Props: size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | (string & {}) = 'md', color: string = ''\n- we-switch (DesignSystemElement)\n Props: checked: boolean = false, disabled: boolean = false, name: string = '', value: string = '', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md', labelOff: string = '', labelOn: string = ''\n- we-tab (DesignSystemElement)\n Props: key: string = '', selected: boolean = false, label?: string | undefined, selectedProps?: Partial | undefined\n- we-tabs (DesignSystemElement)\n Props: selectedKey: string = ''\n- we-tag (DesignSystemElement)\n Props: variant: 'neutral' | 'primary' | 'success' | 'warning' | 'danger' = 'neutral', dismissible: boolean = false\n- we-text (DesignSystemElement)\n Props: text?: string | undefined, variant: '' | 'body' | 'label' | 'footnote' | 'subheading' | 'ingress' | 'heading-sm' | 'heading-md' | 'heading-lg' | 'heading-xl' = '', tag: 'p' | 'span' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'small' | 'b' | 'i' | 'label' | 'div' = 'span', inline: boolean = false, uppercase: boolean = false, italic: boolean = false, truncate: boolean = false, gradient: string = ''\n- we-textarea (DesignSystemElement)\n Props: value: string = '', name: string = '', placeholder: string = '', rows: number = 3, maxlength: unknown = Infinity, minlength: number = 0, disabled: boolean = false, required: boolean = false, readonly: boolean = false, resize: 'none' | 'vertical' | 'horizontal' | 'both' = 'vertical', size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'md'\n- we-timestamp (DesignSystemElement) — Displays a formatted or relative timestamp that self-updates each minute\nwhen `relative` is enabled.\n Props: value: string = '', relative: boolean = false, locale: string = 'en', dateStyle: Intl.DateTimeFormatOptions['dateStyle'] | null = null, timeStyle: Intl.DateTimeFormatOptions['timeStyle'] | null = null, weekday: Intl.DateTimeFormatOptions['weekday'] | null = null, year: Intl.DateTimeFormatOptions['year'] | null = null, month: Intl.DateTimeFormatOptions['month'] | null = null, day: Intl.DateTimeFormatOptions['day'] | null = null, hour: Intl.DateTimeFormatOptions['hour'] | null = null, minute: Intl.DateTimeFormatOptions['minute'] | null = null, second: Intl.DateTimeFormatOptions['second'] | null = null, timeZone: string | null = null, hourCycle: Intl.DateTimeFormatOptions['hourCycle'] | null = null, formattedTime: string\n- we-tooltip (LayoutElement)\n Props: open: boolean = false, title: string = '', placement: 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end' | 'right-start' | 'right-end' = 'top', tooltipEl: HTMLElement, triggerEl: HTMLElement, arrowEl: HTMLElement\n- we-video (LayoutVisualElement)\n Props: src: string = '', poster?: string | undefined, controls: boolean = false, preload: 'none' | 'metadata' | 'auto' = 'metadata', autoplay: boolean = false, loop: boolean = false, muted: boolean = false\n\n@we/components:\n- AudioDisplay\n Props: title: string | undefined, artist: string | undefined, audioUrl: string | undefined, duration: number | undefined, albumArt: string | undefined\n- AudioInput\n Props: title: string | undefined, artist: string | undefined, audioUrl: string | FileData | undefined, duration: number | undefined, albumArt: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- BlockComposer (DesignSystemElement)\n Props: editorState?: any, perspective?: PerspectiveProxy | null, onSave?: ((json: SerializedBlockNode) => void), onReady?: ((api: { save: () => void; }) => void)\n- BlockPlaceholder\n Props: icon: string, label: string, hint?: string, accept?: string, onFileDrop?: ((file: File) => void), onClick?: (() => void)\n- BlockRenderer (DesignSystemElement)\n Props: editorState?: any, perspective?: PerspectiveProxy | null, rootClass?: string\n- BlockToolbar\n Props: placement?: BlockToolbarPlacement, children: JSX.Element, stopPropagation?: boolean\n- CalloutDisplay\n Props: text: string | undefined, variant: string | undefined, icon: string | undefined\n- CalloutInput\n Props: text: string | undefined, variant: string | undefined, icon: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- CodeDisplay\n Props: code: string | undefined, language: string | undefined, title: string | undefined\n- CodeInput\n Props: code: string | undefined, language: string | undefined, title: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- CollectionDisplay\n Props: layout?: string, columnCount?: number, gap?: string, childEditorState?: any\n- CollectionInput\n Props: nodeKey: string, layout?: string, columnCount?: number, gap?: string, childEditorState?: any, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- DividerDisplay\n Props: style: \"solid\" | \"dashed\" | \"dotted\" | undefined\n- DividerInput\n Props: style: DividerVariant | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- EmbedDisplay\n Props: url: string | undefined, target: string | undefined, targetType: string | undefined, displayMode: string | undefined\n- EmbedInput\n Props: url: string | undefined, target: string | undefined, targetType: string | undefined, displayMode: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- EventDisplay\n Props: title: string | undefined, description: string | undefined, startDate: string | undefined, endDate: string | undefined, location: string | undefined, allDay: boolean | undefined\n- EventInput\n Props: title: string | undefined, description: string | undefined, startDate: string | undefined, endDate: string | undefined, location: string | undefined, allDay: boolean | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- FileDisplay\n Props: title: string | undefined, name: string | undefined, url: string | undefined, mimeType: string | undefined, size: number | undefined\n- FileInput\n Props: title: string | undefined, name: string | undefined, url: string | FileData | undefined, mimeType: string | undefined, size: number | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- ImageDisplay\n Props: src: string | undefined, altText: string | undefined, width: number | undefined, height: number | undefined\n- ImageInput\n Props: src: string | FileData | undefined, altText: string | undefined, width: number | undefined, height: number | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- LinkDisplay\n Props: url: string | undefined, title: string | undefined, description: string | undefined, thumbnail: string | undefined\n- LinkInput\n Props: url: string | undefined, title: string | undefined, description: string | undefined, thumbnail: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- LocationDisplay\n Props: name: string | undefined, latitude: number | undefined, longitude: number | undefined, address: string | undefined\n- LocationInput\n Props: name: string | undefined, latitude: number | undefined, longitude: number | undefined, address: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- TagDisplay\n Props: name: string | undefined, color: string | undefined\n- TagInput\n Props: name: string | undefined, color: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- TaskDisplay\n Props: title: string | undefined, description: string | undefined, status: string | undefined, priority: string | undefined, dueDate: string | undefined, assignee: string | undefined\n- TaskInput\n Props: title: string | undefined, description: string | undefined, status: string | undefined, priority: string | undefined, dueDate: string | undefined, assignee: string | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- VideoDisplay\n Props: url: string | undefined, title: string | undefined, thumbnail: string | undefined, provider: string | undefined, width: number | undefined\n- VideoInput\n Props: url: string | undefined, title: string | undefined, thumbnail: string | undefined, provider: string | undefined, width: number | undefined, onChange: (property: string, value: unknown) => void, isSelected: () => boolean\n- Accordion\n Props: children?: JSX.Element, renderContent?: ((item: AccordionItem, index: number) => JSX.Element), onChange?: ((openItems: string[]) => void), items?: AccordionItem[], multiple?: boolean, styles?: Record\n- AudioVisualiser\n Props: src: string | undefined, bars?: number, height?: number, color?: string, activeColor?: string\n- AvatarStack\n Props: avatars: AvatarInfo[], max?: number, size?: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"xxs\" | \"xxl\", overlap?: number, ring?: string, styles?: Record\n- Breadcrumbs\n Props: onNavigate?: ((item: BreadcrumbItem, index: number) => void), items?: BreadcrumbItem[], separator?: string, styles?: Record\n- Calendar\n Props: onSelect?: ((date: string) => void), value?: string, events?: CalendarEvent[], styles?: Record\n- Card (DesignSystemElement)\n- CircleButton\n Props: label: string, icon?: string, image?: string, onClick?: (() => void), class?: string, styles?: Record\n- CodeEditor\n Props: code: string, language?: CodeEditorLanguage, readOnly?: boolean, onChange?: ((code: string) => void), onSave?: ((code: string) => void), styles?: Record\n- CollapsedContent\n Props: collapsed: boolean, onExpandClick?: (() => void), showToggle?: boolean, icon?: string, maxHeight?: string, fadeColor?: string, children?: JSX.Element, class?: string, styles?: Record\n- Column (DesignSystemElement)\n- Combobox (DesignSystemElement)\n Props: options: string[] | ComboboxOption[], value?: string, placeholder?: string, size?: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\", onChange?: ((value: string) => void)\n- DropdownMenu — Flexible dropdown menu for actions, toggles, and grouped items. Use for context menus, settings panels, layer controls, and command palettes.\n Props: class?: string, styles?: Record, placement?: Placement, triggerLabel?: string, triggerIcon?: string, items: SolidDropdownMenuEntry[]\n- EditableImage (DesignSystemElement)\n Props: src?: string, alt?: string, fit?: \"fill\" | \"cover\" | \"contain\" | \"none\" | \"scale-down\", placeholderIcon?: string, onImageChange?: ((file: File) => void), class?: string, aspect?: number, maxSize?: number\n- FlipCard\n Props: front?: JSX.Element, back?: JSX.Element, width?: string, height?: string, flipOnHover?: boolean, flipDuration?: string, wobbleOnHover?: boolean, wobbleDegree?: number, class?: string, styles?: Record\n- Grid (DesignSystemElement)\n Props: template?: string, columns?: number, minChildWidth?: string\n- IconLabelButton\n Props: icon: import(\"/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid\").MaybeAccessor, label: import(\"/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid\").MaybeAccessor, selected?: import(\"/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid\").MaybeAccessor, iconWeight?: import(\"/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid\").MaybeAccessor, onClick?: import(\"/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid\").MaybeAccessor<(() => void) | undefined>, class?: import(\"/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid\").MaybeAccessor, styles?: import(\"/home/josh/workspaces/coasys/we/packages/design-system/utils/dist/solid\").MaybeAccessor | undefined>\n- ImageCrop\n Props: src: string, fileName?: string, aspect?: number, maxSize?: number, outputType?: string, quality?: number, onReady?: ((ref: ImageCropRef) => void)\n- ImageLightbox\n Props: srcs: string[], initialIndex: number, onClose: () => void\n- List\n Props: children?: JSX.Element, renderItem?: ((item: ListItem, index: number) => JSX.Element), items?: ListItem[], ordered?: boolean, gap?: string, styles?: Record\n- PostCard\n Props: creator?: { name: string; avatar: string; }, title: string, text: string, class?: string, styles?: Record\n- RerenderLog\n Props: location: string\n- Row (DesignSystemElement)\n- Search (DesignSystemElement)\n Props: placeholder?: string, value?: string, onSearch?: ((value: string) => void), debounce?: number\n- Select (DesignSystemElement)\n Props: options: SelectOption[], value?: string, placeholder?: string, searchable?: boolean, label?: string, size?: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\", onChange?: ((value: string) => void)\n- SignalControl\n Props: signalType: SignalTypeData, signals?: SignalData[], myDid?: string, onSignal?: ((value: number) => void), disabled?: boolean, preview?: boolean, class?: string, styles?: Record\n- Stepper\n Props: onStepClick?: ((index: number) => void), steps?: StepperStep[], activeStep?: number, orientation?: \"horizontal\" | \"vertical\", styles?: Record\n- Table\n Props: renderCell?: ((row: Record, column: TableColumn, index: number) => JSX.Element), columns: TableColumn[], rows: Record[], striped?: boolean, bordered?: boolean, styles?: Record\n- Timeline\n Props: children?: JSX.Element, renderItem?: ((item: TimelineItem, index: number) => JSX.Element), items?: TimelineItem[], styles?: Record\n- ToastContainer\n Props: position?: \"top-right\" | \"top-left\" | \"bottom-right\" | \"bottom-left\" | \"top-center\" | \"bottom-center\", styles?: Record\n\n@we/widgets:\n- CesiumGlobe — 3D globe widget using CesiumJS with a modular layer system.\nLayers are injected via factory functions (planet surface + background).\nRequires a layer factory registry mapping string names to factory functions.\nNot schema-renderable — used directly in application code.\n Props: ionAccessToken?: string, planetLayers?: LayerConfig[], backgroundLayers?: LayerConfig[], layerFactoryRegistry: Record>\n- CollapsibleSidebar\n Props: header?: JSX.Element, footer?: JSX.Element, items: CollapsibleSidebarItem[], footerItems?: CollapsibleSidebarItem[], side?: \"left\" | \"right\", position?: \"static\" | \"absolute\" | \"fixed\", zIndex?: number, collapsedWidth?: string, expandedWidth?: string, defaultExpanded?: boolean, expandOnHover?: boolean, transitionDuration?: number, bg?: string, border?: string, padding?: string, gap?: string, centerItems?: boolean, itemColor?: string, itemColorHover?: string, itemColorActive?: string, itemBg?: string, itemBgHover?: string, itemBgActive?: string, itemPadding?: string, itemGap?: string, badgeBg?: string, badgeColor?: string, iconSize?: IconSize, onItemClick?: ((item: CollapsibleSidebarItem) => void), onExpandedChange?: ((expanded: boolean) => void)\n- GraphWidget — 2D force-directed graph visualization using D3-force layout and Canvas rendering.\nDisplays typed nodes (user, space, post) and edges (follows, member-of, etc.)\nwith configurable styling, layout forces, and interaction handlers.\n Props: data: GraphData, width?: string | number, height?: string | number, nodeStyle?: NodeStyleConfig, edgeStyle?: EdgeStyleConfig, layout?: LayoutConfig, interactions?: InteractionConfig\n- SpaceSidebarWidget\n Props: name: string, description?: string, class?: string, style?: Record\n\n---\n\n## Design System Props\n\nMost @we/primitives inherit **all** layers below. Props use design token values — not raw CSS.\n\n### Token Value Reference\n\n| Token Type | Valid Values |\n|---|---|\n| SpaceValue | \"0\", \"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", \"900\", \"1000\" (or CSS length e.g. \"16px\") |\n| ColorValue | \"{hue}-{shade}\" where hue = neutral, primary, success, warning, danger and shade = 0, 25, 50, 75, 100, 200–900, 1000. Also \"white\", \"black\". (or CSS color) |\n| RadiusValue | \"0\", \"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", \"900\", \"pill\", \"full\" (or CSS length) |\n| ShadowValue | \"sm\", \"md\", \"lg\", \"xl\" |\n| FontSizeValue | \"base\", \"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", \"900\", \"1000\" (or CSS length) |\n| FontFamilyValue | \"base\" (or CSS font-family) |\n| LineHeightValue | \"none\", \"tight\", \"snug\", \"normal\", \"relaxed\", \"loose\" (or CSS value) |\n| LetterSpacingValue | \"tighter\", \"tight\", \"normal\", \"wide\", \"wider\", \"widest\" (or CSS value) |\n| FontWeightValue | Named tokens: \"regular\" (400), \"medium\" (500), \"semibold\" (600), \"bold\" (700). Numeric: \"100\"–\"900\". CSS pass-through: \"light\", \"normal\", \"bolder\". |\n\n**Layout-only primitives** — these accept only Layout props (not Visual, Flex, Typography, or State):\nwe-divider, we-icon, we-menu-group, we-popover, we-spinner, we-tooltip\n\n### Layout\n\n| Prop | Type | Description |\n|------|------|-------------|\n| width | string | Element width |\n| height | string | Element height |\n| minWidth | string | Minimum width |\n| minHeight | string | Minimum height |\n| maxWidth | string | Maximum width |\n| maxHeight | string | Maximum height |\n| position | \"relative\" \\| \"absolute\" \\| \"fixed\" \\| \"sticky\" | CSS position |\n| top | string | Top offset |\n| right | string | Right offset |\n| bottom | string | Bottom offset |\n| left | string | Left offset |\n| zIndex | number | Stack order |\n| display | \"flex\" \\| \"block\" \\| \"inline\" \\| \"inline-block\" \\| \"grid\" \\| \"inline-flex\" | Display mode |\n| flex | string | Flex shorthand (e.g. \"1\", \"0 0 auto\", \"none\") — controls grow/shrink/basis |\n| alignSelf | string | Override parent cross-axis alignment for this child |\n| overflow | \"hidden\" \\| \"auto\" | Overflow behavior |\n| m | SpaceValue | Margin (all sides) |\n| mx | SpaceValue | Margin left + right |\n| my | SpaceValue | Margin top + bottom |\n| mt | SpaceValue | Margin top |\n| mr | SpaceValue | Margin right |\n| mb | SpaceValue | Margin bottom |\n| ml | SpaceValue | Margin left |\n\n### Visual\n\n| Prop | Type | Description |\n|------|------|-------------|\n| bg | ColorValue | Background color (token) |\n| bgImage | string | Background image URL — sets background-image, defaults background-size to cover, background-position to center, background-repeat to no-repeat |\n| bgFit | \"cover\" \\| \"contain\" | Background image sizing (default: \"cover\") — only meaningful with bgImage |\n| bgPosition | string | Background image position (default: \"center\", e.g. \"top\", \"50% 20%\") — only meaningful with bgImage |\n| bgImageOpacity | number | Fades bgImage only (0–1), independent of the element's own content/opacity — only meaningful with bgImage |\n| bgImageTint | ColorValue | Color bgImage fades toward as bgImageOpacity decreases (default: the element's own `bg`, or neutral-0) — only meaningful with bgImageOpacity |\n| color | ColorValue | Text/foreground color (token) |\n| opacity | number | Opacity (0–1) |\n| border | string | Border shorthand (e.g. \"1px solid neutral-200\" — color tokens are resolved) |\n| borderColor | ColorValue | Border color (token, e.g. \"neutral-200\", \"primary-500\") |\n| borderTop | string | Top border shorthand (color tokens resolved) |\n| borderRight | string | Right border shorthand (color tokens resolved) |\n| borderBottom | string | Bottom border shorthand (color tokens resolved) |\n| borderLeft | string | Left border shorthand (color tokens resolved) |\n| borderWidth | string | Border width (raw CSS, e.g. \"1px\", \"2px 0\") |\n| shadow | \"sm\" \\| \"md\" \\| \"lg\" \\| \"xl\" | Shadow token |\n| cursor | \"pointer\" \\| \"default\" \\| \"text\" \\| \"not-allowed\" | Cursor style |\n| pointerEvents | \"none\" \\| \"auto\" | Pointer events |\n| transform | string | CSS transform |\n| transition | string | CSS transition |\n| r | RadiusValue | Border radius (all corners) |\n| rt | RadiusValue | Border radius top |\n| rb | RadiusValue | Border radius bottom |\n| rl | RadiusValue | Border radius left |\n| rr | RadiusValue | Border radius right |\n| rtl | RadiusValue | Border radius top-left |\n| rtr | RadiusValue | Border radius top-right |\n| rbr | RadiusValue | Border radius bottom-right |\n| rbl | RadiusValue | Border radius bottom-left |\n\n### Flex (Container)\n\n| Prop | Type | Description |\n|------|------|-------------|\n| direction | \"row\" \\| \"row-reverse\" \\| \"column\" \\| \"column-reverse\" | Flex direction |\n| ax | \"start\" \\| \"center\" \\| \"end\" \\| \"between\" \\| \"around\" \\| \"even\" \\| \"stretch\" | Main-axis alignment |\n| ay | \"start\" \\| \"center\" \\| \"end\" \\| \"between\" \\| \"around\" \\| \"even\" \\| \"stretch\" | Cross-axis alignment |\n| wrap | boolean | Enable flex wrap |\n| gap | SpaceValue | Gap between children (token) |\n| p | SpaceValue | Padding (all sides) |\n| px | SpaceValue | Padding left + right |\n| py | SpaceValue | Padding top + bottom |\n| pt | SpaceValue | Padding top |\n| pr | SpaceValue | Padding right |\n| pb | SpaceValue | Padding bottom |\n| pl | SpaceValue | Padding left |\n\n### Typography\n\n| Prop | Type | Description |\n|------|------|-------------|\n| textAlign | \"left\" \\| \"center\" \\| \"right\" \\| \"justify\" | Text alignment |\n| fontFamily | \"base\" \\| {css-font-family} | Font family token |\n| fontWeight | \"regular\" \\| \"medium\" \\| \"semibold\" \\| \"bold\" (named tokens) or \"100\"–\"900\" (numeric) or \"light\" \\| \"normal\" \\| \"bolder\" (CSS pass-through) | Font weight |\n| fontSize | \"base\" \\| \"100\"–\"1000\" \\| {css-length} | Font size token |\n| lineHeight | \"none\" \\| \"tight\" \\| \"snug\" \\| \"normal\" \\| \"relaxed\" \\| \"loose\" | Line height token |\n| letterSpacing | \"tighter\" \\| \"tight\" \\| \"normal\" \\| \"wide\" \\| \"wider\" \\| \"widest\" | Letter spacing token |\n| textDecoration | \"underline\" \\| \"line-through\" \\| \"overline\" \\| \"none\" | Text decoration |\n| textTransform | \"uppercase\" \\| \"lowercase\" \\| \"capitalize\" \\| \"none\" | Text transform |\n\n**Typography defaults:** fontSize and fontWeight have **no built-in defaults** — omitting them inherits from parent elements (browser default is ~16px / normal weight). Do not set fontSize or fontWeight unless you need a non-default value. For example, `fontSize: '300'` (16px) and `fontWeight: '500'` (normal) are the inherited defaults — omit them.\n\n`we-text` variants (set via the `variant` prop) bundle typography presets. Always pair with a semantic `tag` prop for correct HTML structure:\nbody (300, tag: p/span), label (200 + medium, tag: span), footnote (100, tag: span), subheading (400 + medium, tag: h5/p), ingress (400 + lineHeight 1.6, tag: p), heading-sm (500 + bold, tag: h4), heading-md (600 + bold, tag: h3), heading-lg (700 + bold, tag: h2), heading-xl (800 + bold, tag: h1).\nVariants set size and weight only — color is always inherited or set explicitly. For muted footnote text add `color=\"neutral-400\"` explicitly.\n\n### State\n\n| Prop | Type | Description |\n|------|------|-------------|\n| hoverProps | Partial\\ | Styles on :hover |\n| activeProps | Partial\\ | Styles on :active |\n| focusProps | Partial\\ | Styles on :focus |\n| disabledProps | Partial\\ | Styles when disabled |\n\n### Additional\n\n| Prop | Type | Description |\n|------|------|-------------|\n| styles | Record\\ | Inline CSS applied directly to the component's own element (raw CSS values allowed). For Column, Row, Grid — use this when you need CSS the DS props don't cover. **Do not confuse with node-level styles** (see Schema Structure) which applies to a wrapper div, not the component. |\n| onClick | ActionToken | Event handler (see dynamic logic) |\n\n---\n\n## Design Tokens\n\nUse design tokens for spacing, color, radius, etc. Do not use raw CSS values unless using the styles prop.\n\nanimation.transition: '0', '100', '200', '300', '400', '500'\n\navatarSize: 'xxs', 'xs', 'sm', 'md', 'lg', 'xl', 'xxl'\n\nborder.color: 'base', 'strong'\n\ncolor.base: 'white', 'black'\n\ncolor.config: 'multiplier', 'subtractor', 'saturation', 'neutralSaturation'\n\ncolor.hues: 'neutral', 'primary', 'success', 'warning', 'danger'\n\ncolor.lightness: '0', '25', '50', '75', '100', '200', '300', '400', '500', '600', '700', '800', '900', '1000'\n\ncomponent.scrollbar: 'width', 'backgroundImage', 'background', 'cornerBackground', 'thumbBoxShadow', 'thumbBorderRadius', 'thumbBackground'\n\ncomponentHeight: 'xs', 'sm', 'md', 'lg', 'xl'\n\neffect.depth: '100', '200', '300', '400', '500', 'none'\n\nfont.family: 'base', 'mozilla', 'boldonse'\n\nfont.letterSpacing: 'tighter', 'tight', 'normal', 'wide', 'wider', 'widest'\n\nfont.lineHeight: 'none', 'tight', 'snug', 'normal', 'relaxed', 'loose'\n\nfont.size: '100', '200', '300', '400', '500', '600', '700', '800', '900', '1000', 'base'\n\nfont.weight: '100', '200', '300', '400', '500', '600', '700', '800', '900', 'regular', 'medium', 'semibold', 'bold'\n\nlayout: 'xs', 'sm', 'md', 'lg'\n\nradius: '0', '100', '200', '300', '400', '500', '600', '700', '800', '900', 'pill', 'full'\n\nshadow: 'sm', 'md', 'lg', 'xl'\n\nsize: 'xxs', 'xs', 'sm', 'md', 'lg', 'xl', 'xxl'\n\nspace: '0', '100', '200', '300', '400', '500', '600', '700', '800', '900', '1000'\n\nzIndex: 'dropdown', 'sticky', 'modal', 'popover', 'toast', 'tooltip'\n\n---\n\n## Block & Entity Models\n\nAvailable data models for $query and store data:\n\nAgentSettings extends Ad4mModel:\n Fields:\n - currentTemplateId: string = 'default' [we://current_template]\n - defaultTemplateId: string = 'default' [we://default_template]\n - currentThemeId: string = 'default' [we://current_theme]\n - defaultThemeId: string = 'default' [we://default_theme]\n - claudeApiKey: string [we://claude_api_key]\n - perspectiveOrder: string [we://perspective_order]\n - globalSpaceJoined: boolean = false [we://global_space_joined]\n - globalSpaceUrl: string [we://global_space_url]\n - useSpaceTemplate: boolean = true [we://use_space_template]\n Relations:\n - installedTemplates: HasMany → Template [we://installed_template]\n - installedThemes: HasMany → Theme [we://installed_theme]\n - spaceTemplatePreferences: HasMany → SpaceTemplatePreference [we://space_template_preference]\n\nAssistant extends WeNode:\n Fields:\n - name: string [we://name]\n - modelId: string [we://model_id]\n - systemPrompt: string [we://system_prompt]\n - personalityIds: string [we://personality_ids]\n - skillIds: string [we://skill_ids]\n - mcpServerIds: string [we://mcp_server_ids]\n\nAudioBlock extends WeNode:\n Fields:\n - title: string (required) [we://title]\n - artist: string [we://artist]\n - audioUrl: string (required) [we://audio_url]\n - duration: number [we://duration]\n - albumArt: string [we://album_art]\n - version: number [we://version]\n\nCalloutBlock extends WeNode:\n Fields:\n - text: string [we://text]\n - variant: string = info [we://variant]\n - icon: string [we://icon]\n - version: number [we://version]\n\nChatMessage extends WeNode:\n Fields:\n - role: string [we://role]\n - content: string [we://content]\n\nChatSession extends WeNode:\n Fields:\n - name: string [we://name]\n - templateId: string [we://template_id]\n Relations:\n - messages: HasMany → ChatMessage [we://chat_message]\n\nCodeBlock extends WeNode:\n Fields:\n - code: string (required) [we://code]\n - language: string [we://language]\n - title: string [we://title]\n - version: number [we://version]\n\nCollectionBlock extends WeNode:\n Fields:\n - editorState: string = null [we://editor_state]\n - type: string [we://type]\n - display: string [we://display]\n - direction: string [we://direction]\n - format: string [we://format]\n - indent: number [we://indent]\n - columns: number [we://columns]\n - gap: string [we://gap]\n - version: number [we://version]\n - textContent: string [we://text_content]\n Relations:\n - children: HasMany [we://children]\n\nDividerBlock extends WeNode:\n Fields:\n - style: string = solid [we://style]\n - version: number [we://version]\n\nEmbedBlock extends WeNode:\n Fields:\n - url: string [we://url]\n - target: string [we://target]\n - targetType: string [we://target_type]\n - displayMode: string = card [we://display_mode]\n - version: number [we://version]\n\nEventBlock extends WeNode:\n Fields:\n - title: string (required) [we://title]\n - description: string [we://description]\n - startDate: string (required) [we://start_date]\n - endDate: string [we://end_date]\n - location: string [we://location]\n - allDay: boolean = false [we://all_day]\n - version: number [we://version]\n\nFileBlock extends WeNode:\n Fields:\n - title: string [we://title]\n - name: string (required) [we://name]\n - url: string (required) [we://url]\n - mimeType: string [we://mime_type]\n - size: number [we://size]\n - version: number [we://version]\n\nImageBlock extends WeNode:\n Fields:\n - src: string (required) [we://src]\n - altText: string [we://altText]\n - width: number [we://width]\n - height: number [we://height]\n - version: number [we://version]\n\nLinkBlock extends WeNode:\n Fields:\n - url: string (required) [we://url]\n - title: string [we://title]\n - description: string [we://description]\n - thumbnail: string [we://thumbnail]\n - version: number [we://version]\n\nLocationBlock extends WeNode:\n Fields:\n - name: string [we://name]\n - latitude: number (required) [we://latitude]\n - longitude: number (required) [we://longitude]\n - address: string [we://address]\n - city: string [we://city]\n - countryCode: string [we://country_code]\n - country: string [we://country]\n - version: number [we://version]\n\nMcpServer extends WeNode:\n Fields:\n - name: string [we://name]\n - transport: string = 'stdio' [we://transport]\n - url: string [we://url]\n - command: string [we://command]\n - auth: string [we://auth]\n\nMessage extends WeNode:\n Fields:\n - threadId: string [we://thread_id]\n - role: string [we://role]\n - content: string [we://content]\n - toolCalls: string [we://tool_calls]\n - ts: string [we://ts]\n - status: string [we://status]\n\nPersonality extends WeNode:\n Fields:\n - name: string [we://name]\n - body: string [we://body]\n\nSignal extends Ad4mModel:\n Fields:\n - signalTypeId: string [we://signal_type_id]\n - value: number [we://value]\n\nSignalType extends WeNode:\n Fields:\n - name: string [we://name]\n - slug: string [we://slug]\n - description: string [we://description]\n - icon: string [we://icon]\n - iconSecondary: string [we://icon_secondary]\n - step: number = 1 [we://step]\n - rangeMin: number [we://range_min]\n - rangeMax: number = 1 [we://range_max]\n - mode: SignalMode = 'toggle' [we://mode]\n - aggregate: SignalAggregate = 'count' [we://aggregate]\n - semantic: SignalSemantic = 'custom' [we://semantic]\n - allowChange: boolean = true [we://allow_change]\n - valueType: string = 'numeric' [we://signal_value_type]\n - schemaVersion: number = 1 [we://schema_version]\n\nSkill extends WeNode:\n Fields:\n - name: string [we://name]\n - description: string [we://description]\n - body: string [we://body]\n\nSpace extends WeNode:\n Fields:\n - uuid: string [we://uuid]\n - url: string [we://url]\n - name: string (required) [we://name]\n - description: string (required) [we://description]\n - access: string = 'personal' [we://access]\n - discovery: string = 'hidden' [we://discovery]\n - avatar: string [we://image]\n - coverImage: string [we://thumbnail]\n - defaultTemplateId: string [we://default_template_id]\n - defaultThemeId: string [we://default_theme_id]\n Relations:\n - location: HasOne [we://location]\n\nSpaceTemplatePreference extends WeNode:\n Fields:\n - spaceUrl: string [we://space_url]\n - preference: string [we://preference]\n\nTagBlock extends WeNode:\n Fields:\n - name: string (required) [we://name]\n - color: string [we://color]\n - version: number [we://version]\n\nTaskBlock extends WeNode:\n Fields:\n - title: string (required) [we://title]\n - description: string [we://description]\n - status: string = todo [we://status]\n - priority: string = medium [we://priority]\n - dueDate: string [we://due_date]\n - assignee: string [we://assignee]\n - version: number [we://version]\n\nTemplate extends WeNode:\n Fields:\n - name: string [we://name]\n - description: string [we://description]\n - icon: string [we://icon]\n - origin: string [we://origin]\n - version: number = 1 [we://version]\n - slug: string [we://slug]\n - schema: string = null [we://template_schema]\n - themeId: string [we://theme_id]\n Relations:\n - screenshots: HasMany → ImageBlock [we://screenshot]\n\nTextBlock extends WeNode:\n Fields:\n - type: string [we://type]\n - direction: string [we://direction]\n - format: string [we://format]\n - indent: number [we://indent]\n - textFormat: number [we://textFormat]\n - textStyle: string [we://textStyle]\n - listType: string [we://listType]\n - start: number [we://start]\n - tag: string [we://tag]\n - text: string [we://text]\n - version: number [we://version]\n\nTheme extends WeNode:\n Fields:\n - name: string [we://name]\n - description: string [we://description]\n - icon: string [we://icon]\n - origin: string [we://origin]\n - slug: string [we://slug]\n - version: number = 1 [we://version]\n - css: string = null [we://stylesheet]\n - overrides: string = null [we://token_overrides]\n Relations:\n - screenshots: HasMany → ImageBlock [we://screenshot]\n\nThread extends WeNode:\n Fields:\n - title: string [we://title]\n - assistantId: string [we://assistant_id]\n - modelId: string [we://model_id]\n - createdAt: string [we://created_at]\n - updatedAt: string [we://updated_at]\n Relations:\n - messages: HasMany → Message [we://message]\n\nVideoBlock extends WeNode:\n Fields:\n - title: string [we://title]\n - url: string (required) [we://url]\n - duration: number [we://duration]\n - thumbnail: string [we://thumbnail]\n - provider: string [we://provider]\n - version: number [we://version]\n\nWeNode extends Ad4mModel:\n Relations:\n - comments: HasMany [we://comment]\n - signals: HasMany → Signal [we://signal]\n\n---\n\n## Stores\n\nStores provide state (readable values) and actions (methods) for dynamic logic in schemas.\nAccess state with $store and call actions with $action.\nFor ephemeral/form state, use $localState/$local/$setLocal instead of stores (see Dynamic Logic).\n\nAdamStore:\n- State:\n - adamClient: Ad4mClient | undefined\n - me: Agent | undefined\n - allPerspectives: array of PerspectiveProxy objects (all AD4M perspectives)\n - currentPerspective: PerspectiveProxy | null (the perspective currently being viewed)\n - currentPerspectiveModels: ModelManifestEntry[] (non-WE SHACL models from the current perspective; injected as externalModels into AI messages)\n - isWeSpace: boolean — true once the current perspective is confirmed to have WE's Space SDNA installed (false for a joined-but-foreign perspective, e.g. one synced in from Flux)\n - personalSpaces: array of Space objects (local/personal spaces)\n - sharedSpaces: array of Space objects (shared/neighbourhood spaces)\n - bootState: string\n - passwordError: string | undefined\n - loginLoading: boolean\n - creatingSpace: boolean (true while a new space is being created)\n - agents: AgentProfileSummary[] — cache of all fetched agent profiles (did, firstName, lastName, handle, bio, avatar, coverImage, location)\n - ownAgent: AgentProfileSummary | undefined — reactive accessor for the current user's own profile (derived from agents cache)\n - orderedSidebarItems: array of sidebar items in user-defined order (uuid, name, avatar, spaceId) — personal + shared spaces merged\n- Actions:\n - navigate(to: string, options?): navigates to a route\n - addNewSpace(space: Space): adds a new space\n - createSpace(name: string, description: string, shared: boolean, imageFile?: File): creates a new space with full setup\n - initializeAsWeSpace(name: string, description: string, avatarValue?: File | string | null): installs WE's Space SDNA into the current, already-joined, foreign-native perspective (e.g. one synced in from Flux) and creates a Space entity in place — access is always 'shared' since the perspective is already a published neighbourhood\n - switchPerspective(uuid: string): switches to a perspective by UUID, registers its SHACL models as dynamic model classes, and populates currentPerspectiveModels\n - removePerspective(uuid: string): removes a perspective by UUID\n - reorderPerspectives(newOrder: string[]): reorders the sidebar items by UUID array\n - login(password: string): logs in the agent with password\n - logout(): locks the agent and returns to login screen\n - fetchAgent(did: string): fetches and caches an agent's profile from their public AD4M perspective\n - updateOwnProfile(fields: { firstName?, lastName?, handle?, bio? }): updates own profile text fields and publishes to public perspective\n - updateProfileImage(field: \"avatar\" | \"coverImage\", imageFile: File): uploads image to FILE_STORAGE_LANGUAGE and publishes expression URL to public perspective\n - updateAgentLocation(update: { latitude?, longitude?, city?, country?, countryCode? }): merges location update into cache and publishes to public perspective\n - cleanupSpaceSdna(uuid?: string): one-time remediation for a perspective that accumulated duplicate SDNA installs (e.g. from before joinSpace checked for existing SDNA before installing) — removes the redundant duplicate link copies. Defaults to the current perspective. Returns a display-ready summary string naming how many links were removed and the DIDs that authored them (your own DID annotated with \"(you)\"), or an empty string if nothing needed cleaning up\n\nRouteStore:\n- State:\n - currentPath: string (the current route path)\n - segments: string[] (currentPath split by \"/\", e.g. [\"/foo/bar\"] → [\"foo\", \"bar\"])\n- Actions:\n - navigate(to: string, options?): navigates to a route\n\nThemeStore:\n- State:\n - builtInThemes: array of ThemeData objects — built-in registry themes (origin: \"built-in\", always available)\n - installedThemes: array of ThemeData objects — user-installed themes from root perspective (origin: \"custom\" | \"marketplace\")\n - spaceThemes: array of ThemeData objects — themes stored in the current space perspective (origin: \"custom\")\n - allThemes: array of ThemeData objects — union of builtInThemes + visible installedThemes + spaceThemes (hidden themes filtered out)\n - currentThemeId: string — id of the currently active theme\n - currentTheme: ThemeData — the currently active theme object (id, name, icon, origin)\n - defaultThemeId: string — id of the user's preferred default theme (used for bootscreen, shell, and future space-override). Persisted to AgentSettings.defaultThemeId\n - themeManagementList: ThemeManagementItem[] — flat list of all themes (built-in + all custom) with management metadata (id, name, icon, isBuiltIn, isInstalled, isDefault)\n- Actions:\n - setCurrentTheme(themeId: string): sets and persists the active theme\n - setDefaultTheme(themeId: string): sets the preferred default theme (persists to AgentSettings.defaultThemeId)\n - toggleThemeInstalled(themeId: string): toggles a custom theme visible/hidden in pickers; does not delete the theme\n - installFromMarketplace(marketplaceThemeId: string): installs a marketplace theme into installedThemes\n - uninstallTheme(themeId: string): removes an installed theme (deletes the model)\n - deleteTheme(themeId: string): permanently deletes a custom theme\n\nTemplateStore:\n- State:\n - personalTemplates: array of TemplateSchema objects — core templates plus user's installed custom templates (excludes space templates)\n - spaceTemplates: array of TemplateSchema objects — templates loaded from the current space perspective\n - builtInTemplates: array of TemplateSchema objects — built-in system templates (always available)\n - myTemplates: array of TemplateSchema objects — user's installed custom templates only (excludes built-in and space templates)\n - allTemplates: array of TemplateSchema objects — union of built-in + personal + space templates\n - shellTemplates: array of TemplateSchema objects (static system pages: profile, settings, tests)\n - currentTemplate: TemplateSchema (the active template)\n - operationLoading: unknown\n - activeShellView: string | null (id of the currently open shell overlay: 'profile' | 'settings' | 'schema-tests' | 'landing-page' | null)\n - templateManagementList: TemplateManagementItem[] — flat list of all templates with management metadata (id, name, icon, description, isBuiltIn, isInstalled, isDefault)\n - switcherGroups: TemplateSwitcherGroup[] — pre-grouped flat items for the template switcher UI; each group has { label: string, items: { id, name, icon }[] }. Groups: \"Space templates\", \"My templates\", \"Built-in\". Use $filter where: { name: { contains: ... } } for search since items have a flat name field.\n- Actions:\n - updateTemplate(newTemplate: TemplateSchema): updates the current template\n - switchTemplate(newTemplateId: string): switches to another template\n - removeTemplate(): removes the current template\n - saveTemplate(name: string): saves the current template\n - toggleInstalled(): unknown\n - setDefaultTemplate(): unknown\n - deleteTemplate(): unknown\n - openShellView(id: string): opens a shell overlay by id ('profile' | 'settings' | 'schema-tests' | 'landing-page')\n - closeShellView(): closes the currently open shell overlay\n\nSpaceStore:\n- State:\n - memberDids: string[] — DIDs of all members in the current space (includes own DID)\n - members: AgentProfileSummary[] — cached profiles for all memberDids\n - spaceDefaultTemplateId: string — the current space's default template ID (empty string when no space is active)\n - currentSpace: Space | null — the current space model (uuid, name, description, avatar, defaultTemplateId)\n - foreignSpacePrefill: { name, description, avatar } | null — detected from a foreign app's own model (e.g. Flux's Community) for prefilling the \"Initialize as WE space\" gate; null once the perspective is a WE space or no recognized foreign model is found\n - signalTypes: array of SignalType objects (community-created reaction/vote types)\n - signalTypesBySlug: Record — computed map; access via { $store: \"spaceStore.signalTypesBySlug.\" }; use .id for the UUID\n- Actions:\n - createPost(editorState: unknown): creates a new post\n - updatePost(postId: string, editorState: unknown): reconciles an edited post against its existing blocks — updates/reuses blocks whose id survived the edit, creates new ones, deletes ones no longer present\n - deletePost(postId: string): permanently deletes a post and all of its contained blocks (recursive, atomic)\n - updateSpaceImage(field: \"avatar\" | \"coverImage\", imageFile: File): uploads and sets the space avatar or cover image\n - createSignalType(config: Partial): creates a new signal type in the community; slug auto-derived from name if blank\n - upsertSignal(nodeId: string, signalTypeId: string, value: number): adds or updates a signal on a node; value=0 deletes it\n - navigateToSpace(spaceId: string, view?: string): navigates to a space — accepts a perspective UUID or a neighbourhood CID (sharedUrl without the neighbourhood:// prefix); pre-loads space templates before switching so the template and data arrive together\n\nAiStore:\n- State:\n - models: array of Model objects\n - tasks: array of AITask objects\n - isOpen: unknown\n - messages: unknown\n - isStreaming: unknown\n - streamingContent: unknown\n - apiKeyConfigured: unknown\n - templateName: unknown\n - templateIcon: unknown\n - isReadOnly: unknown\n - hasPendingChanges: unknown\n - pickerOpen: unknown\n - pickerAction: unknown\n - pickerDefaultName: unknown\n - pickerDefaultIcon: unknown\n - pickerShowDestination: unknown\n - sessions: unknown\n - activeSessionId: unknown\n - panelMode: unknown\n - schemaJson: unknown\n - operationLoading: unknown\n - canUndo: boolean (true when there are schema edits that can be undone)\n - canRedo: boolean (true when there are undone schema edits that can be redone)\n- Actions:\n - handleSchemaPrompt(prompt: string): generates a schema from a prompt\n - sendMessage(): unknown\n - close(): unknown\n - toggle(): toggles the AI chat panel open/closed\n - setApiKey(): unknown\n - startFork(): unknown\n - startFresh(): unknown\n - confirmPicker(): unknown\n - cancelPicker(): unknown\n - newChat(): unknown\n - switchSession(): unknown\n - deleteSession(): unknown\n - setPanelMode(): unknown\n - onSchemaEdit(): unknown\n - undo(): undoes the last schema edit\n - redo(): redoes the last undone schema edit\n\nAppStore:\n- State:\n - apps: RegisteredApp[] — list of registered external apps (id, name, image)\n - appsWithWe: unknown\n - activeAppId: string | null — id of the currently active app, or null if none\n- Actions:\n - activateApp(id: string): activates an app and switches to its view\n - deactivateApp(): deactivates the current app and returns to the template view\n\n---\n\n## Store Usage Patterns\n\nReading state:\n{ \"$store\": \"storeName.property\" }\nExample: { \"$store\": \"routeStore.currentPath\" }\n\nCalling actions:\n{ \"$action\": \"storeName.method\", \"args\": [...] }\nExample: { \"$action\": \"routeStore.navigate\", \"args\": [\"/home\"] }\n\nIterating over store data:\n{\n \"type\": \"$each\",\n \"props\": { \"items\": { \"$store\": \"adamStore.personalSpaces\" }, \"as\": \"space\" },\n \"children\": [\n {\n \"type\": \"CircleButton\",\n \"props\": {\n \"label\": \"$space.name\",\n \"onClick\": { \"$action\": \"routeStore.navigate\", \"args\": [{ \"$concat\": [\"/space/\", \"$space.uuid\"] }] }\n }\n }\n ]\n}\n\nConditional rendering from store:\n{\n \"type\": \"$if\",\n \"props\": {\n \"condition\": { \"$eq\": [{ \"$store\": \"routeStore.currentPath\" }, \"/\"] },\n \"then\": { \"type\": \"we-text\", \"children\": [\"Home\"] },\n \"else\": { \"type\": \"we-text\", \"children\": [\"Not home\"] }\n }\n}\n\nDeriving options from store:\n{\n \"$map\": {\n \"items\": { \"$store\": \"templateStore.templates\" },\n \"select\": { \"name\": \"$item.meta.name\", \"icon\": \"$item.meta.icon\" }\n }\n}\n\nQuerying model data:\n{\n \"$query\": { \"entity\": \"TaskBlock\", \"where\": { \"status\": \"todo\" } }\n}\n\nEager-loading relations with include (most common relational pattern):\nWhen you need related data displayed alongside a list, use include to hydrate relations in one query.\n\nExample — Channel list with conversation count and latest conversation:\n{\n \"type\": \"$each\",\n \"props\": {\n \"items\": {\n \"$query\": {\n \"entity\": \"Channel\",\n \"dataset\": \"$currentDataset\",\n \"include\": {\n \"$conversationCount\": { \"from\": \"conversations\", \"count\": true },\n \"$latestConversation\": { \"from\": \"conversations\", \"order\": { \"createdAt\": \"desc\" }, \"limit\": 1 }\n }\n }\n },\n \"as\": \"channel\"\n },\n \"children\": [{\n \"type\": \"Row\",\n \"children\": [\n { \"type\": \"we-text\", \"children\": [\"$channel.name\"] },\n { \"type\": \"we-text\", \"children\": [\"$channel.$conversationCount\"] }\n ]\n }]\n}\n\nExample — Nested include (Conversations with their messages):\n{\n \"$query\": {\n \"entity\": \"Conversation\",\n \"dataset\": \"$currentDataset\",\n \"include\": {\n \"messages\": {\n \"order\": { \"createdAt\": \"desc\" },\n \"limit\": 20\n }\n }\n }\n}\nEach conversation in the result has a messages array of hydrated Message instances.\nNesting works to any depth: \"include\": { \"messages\": { \"include\": { \"reactions\": true } } }\n\nRelational drill-down (master-detail navigation across entity relations):\nUse routes + a $query `scope` when you navigate to a detail route and need only that record's children.\nscope.anchor is the parent entity type; scope.via is its HasMany relation (see externalModels) whose targets\nare the query's entity; scope.anchorId is the parent record's id. The adapter resolves the relation to a\nbackend handle, so no protocol details live in the template.\nrouteStore.segments.N extracts the Nth dynamic path segment (segments splits currentPath by \"/\").\n\nExample — Channel list → Conversation list:\n{\n \"routes\": [\n {\n \"path\": \"/\",\n \"type\": \"Column\",\n \"props\": { \"gap\": \"300\", \"p\": \"400\" },\n \"children\": [{\n \"type\": \"$each\",\n \"props\": {\n \"items\": { \"$query\": { \"entity\": \"Channel\", \"dataset\": \"$currentDataset\" } },\n \"as\": \"channel\"\n },\n \"children\": [{\n \"type\": \"we-button\",\n \"props\": {\n \"variant\": \"ghost\",\n \"onClick\": { \"$action\": \"routeStore.navigate\", \"args\": [{ \"$concat\": [\"/channels/\", \"$channel.id\"] }] }\n },\n \"children\": [\"$channel.name\"]\n }]\n }]\n },\n {\n \"path\": \"/channels/:channelId\",\n \"type\": \"Column\",\n \"props\": { \"gap\": \"300\", \"p\": \"400\" },\n \"children\": [{\n \"type\": \"$each\",\n \"props\": {\n \"items\": {\n \"$query\": {\n \"entity\": \"Conversation\",\n \"scope\": { \"anchor\": \"Channel\", \"via\": \"conversations\", \"anchorId\": { \"$store\": \"routeStore.segments.1\" } },\n \"dataset\": \"$currentDataset\"\n }\n },\n \"as\": \"convo\"\n },\n \"children\": [{\n \"type\": \"we-text\",\n \"children\": [\"$convo.conversationName\"]\n }]\n }]\n }\n ]\n}\nNotes:\n- Use include when you need related data displayed inline (e.g. a post with its comments, a channel with its conversation count).\n- Use a scope drill-down when you're on a detail route and want only children belonging to the current record.\n- dataset must point to the dataset that holds the data. For external apps (e.g. Flux) opened as a WE space, use \"$currentDataset\".\n- The relation name (in include, or scope.via) is the HasMany field name on the parent entity.\n\nLocal state (form with validation):\n{\n \"type\": \"Column\",\n \"$localState\": {\n \"name\": {\n \"type\": \"string\",\n \"initial\": \"\",\n \"validate\": [{ \"rule\": \"required\" }, { \"rule\": \"minLength\", \"value\": 2 }]\n },\n \"loading\": { \"type\": \"boolean\", \"initial\": false }\n },\n \"children\": [\n {\n \"type\": \"we-form-field\",\n \"props\": { \"label\": \"Name\", \"error\": { \"$error\": \"name\" } },\n \"children\": [{\n \"type\": \"we-input\",\n \"props\": {\n \"value\": { \"$local\": \"name\" },\n \"onInput\": { \"$setLocal\": \"name\", \"from\": \"$event.detail\" },\n \"onBlur\": { \"$touch\": \"name\" }\n }\n }]\n },\n {\n \"type\": \"we-button\",\n \"props\": {\n \"text\": \"Submit\",\n \"loading\": { \"$local\": \"loading\" },\n \"disabled\": { \"$not\": { \"$formValid\": \"$scope\" } },\n \"onClick\": [\n { \"$touch\": \"$all\" },\n { \"$if\": { \"condition\": { \"$formValid\": \"$scope\" }, \"then\": { \"$action\": \"myStore.submit\", \"args\": [{ \"$local\": \"name\" }] } } }\n ]\n }\n }\n ]\n}\n\nRepeating lists with $each:\nALWAYS use $each for lists of similar items — never duplicate the same node structure.\nWrite the template once; $each renders it for each item.\n\nUse literal arrays for fixed/sample data:\n{\n \"type\": \"$each\",\n \"props\": {\n \"items\": [\n { \"title\": \"First Post\", \"text\": \"Hello world.\", \"author\": \"Alice\" },\n { \"title\": \"Second Post\", \"text\": \"Another update.\", \"author\": \"Bob\" }\n ],\n \"as\": \"post\"\n },\n \"children\": [\n {\n \"type\": \"Column\",\n \"props\": { \"bg\": \"neutral-0\", \"r\": \"400\", \"border\": \"1px solid neutral-200\", \"p\": \"400\", \"gap\": \"300\" },\n \"children\": [\n {\n \"type\": \"Row\",\n \"props\": { \"gap\": \"300\", \"ay\": \"center\" },\n \"children\": [\n { \"type\": \"we-avatar\", \"props\": { \"initials\": \"$post.author\", \"size\": \"sm\" } },\n { \"type\": \"we-text\", \"props\": { \"variant\": \"label\" }, \"children\": [\"$post.author\"] }\n ]\n },\n { \"type\": \"we-text\", \"props\": { \"variant\": \"heading-sm\" }, \"children\": [\"$post.title\"] },\n { \"type\": \"we-text\", \"children\": [\"$post.text\"] }\n ]\n }\n ]\n}\n\nUse $query or $store for dynamic data (more common in production):\n{ \"type\": \"$each\", \"props\": { \"items\": { \"$query\": { \"entity\": \"TextBlock\" } }, \"as\": \"post\" }, \"children\": [...] }\n{ \"type\": \"$each\", \"props\": { \"items\": { \"$store\": \"spaceStore.posts\" }, \"as\": \"post\" }, \"children\": [...] }\n\nPer-item customization inside $each:\nTo style or highlight specific items, add a data flag to those items and use $if on the flag inside the template. Do NOT use $eq: [\"$index\", N] comparisons — they are fragile, repetitive, and break when items are reordered.\nExample: add \"highlighted\": true to one item's data, then use $if on \"$post.highlighted\" in the template:\n{ \"type\": \"$if\", \"props\": { \"condition\": \"$post.highlighted\", \"then\": { \"type\": \"we-badge\", \"props\": { \"variant\": \"primary\" }, \"children\": [\"Featured\"] } } }\nFor conditional props (e.g. different bg on highlighted items):\n{ \"bg\": { \"$if\": { \"condition\": \"$post.highlighted\", \"then\": \"primary-50\", \"else\": \"neutral-0\" } } }\n\nBoolean toggle (show/hide, expand/collapse):\n{\n \"type\": \"Column\",\n \"$localState\": { \"showDetails\": { \"type\": \"boolean\", \"initial\": false } },\n \"children\": [\n { \"type\": \"we-button\", \"props\": { \"variant\": \"ghost\", \"onClick\": { \"$toggleLocal\": \"showDetails\" } }, \"children\": [\"Toggle Details\"] },\n { \"type\": \"$if\", \"props\": { \"condition\": { \"$local\": \"showDetails\" }, \"then\": { \"type\": \"we-text\", \"children\": [\"Details content here\"] } } }\n ]\n}\n\nSignal types (community-specific reactions/votes):\nSignal types are created per-community by the user. Never hardcode signal type UUIDs in schemas.\nInstead reference them by slug through spaceStore.signalTypesBySlug.\n\nALWAYS ask the user: \"What slug should I use? (e.g. 'like', 'upvote', 'star')\"\nThen use that slug in the pattern below.\n\nPattern — live wired SignalControl (inside a $each over a model with $query include):\n{\n \"type\": \"$each\",\n \"props\": {\n \"items\": {\n \"$query\": {\n \"entity\": \"MyBlock\",\n \"include\": {\n \"$totalLikeCount\": {\n \"from\": \"signals\",\n \"where\": { \"signalTypeId\": { \"$store\": \"spaceStore.signalTypesBySlug.like.id\" } },\n \"count\": true\n },\n \"$myLikeSignal\": {\n \"from\": \"signals\",\n \"where\": {\n \"signalTypeId\": { \"$store\": \"spaceStore.signalTypesBySlug.like.id\" },\n \"author\": \"$me.did\"\n },\n \"limit\": 1\n }\n }\n }\n },\n \"as\": \"item\"\n },\n \"children\": [\n {\n \"type\": \"$if\",\n \"props\": {\n \"condition\": { \"$store\": \"spaceStore.signalTypesBySlug.like\" },\n \"then\": {\n \"type\": \"SignalControl\",\n \"props\": {\n \"signalType\": { \"$store\": \"spaceStore.signalTypesBySlug.like\" },\n \"myValue\": \"$item.$myLikeSignal.value\",\n \"aggregate\": \"$item.$totalLikeCount\",\n \"onSignal\": {\n \"$action\": \"spaceStore.upsertSignal\",\n \"args\": [\"$item.id\", { \"$store\": \"spaceStore.signalTypesBySlug.like.id\" }, \"$arg\"]\n }\n }\n }\n }\n }\n ]\n}\n\nNotes:\n- The $if guard hides SignalControl if the community hasn't created a signal type with that slug.\n- Replace \"like\" with the user's slug throughout (in $store paths and args).\n- $query include adds $totalLikeCount and $myLikeSignal as computed properties on each item.\n- signalType prop accepts the full SignalType object (provides icon, mode, range to the UI component).\n\nPreview / mockup mode (static, no store wiring):\n{\n \"type\": \"SignalControl\",\n \"props\": {\n \"preview\": true,\n \"signalType\": { \"icon\": \"❤️\", \"mode\": \"toggle\", \"rangeMin\": 0, \"rangeMax\": 1 }\n }\n}\nUse preview: true when sketching a layout without real data. Remove it (and add the full wiring above) when going live.\n\n---\n\n## Routing Structure\n\nDefine nested routes using the \"routes\" array at the root node of the schema.\nEach route object describes a path and the UI node to render when that path is active.\nRoutes can be nested to support sub-pages and layouts.\n\nRoute objects follow the same structure as schema nodes, with an additional \"path\" property.\n\n- The \"routes\" array MUST be placed on the ROOT template node (or on a route node for nested routing). The router only reads routes from these positions — placing routes on an arbitrary child node means the router will never find them and nothing will render.\n- Use \"path: '*'\" or \"path: '/*'\" for catch-all/not-found routes.\n- Use \":paramName\" for dynamic route parameters (e.g. \"/space/:spaceId\").\n- Use nested \"routes\" arrays for sub-pages and layouts.\n- Use { \"type\": \"$routes\" } in children to indicate where nested routes should render. The $routes outlet can be deeply nested — only the routes array placement matters.\n- EVERY { \"type\": \"$routes\" } outlet MUST have a \"routes\" array defined on the same node or an ancestor node. A $routes outlet without a routes array is invalid and will fail validation.\n- NEVER duplicate a route path — every route in the same \"routes\" array MUST have a unique path.\n- When using tabs, each tab's key and navigate path MUST have a matching route. Ensure a 1:1 correspondence between tabs and routes.\n\n### Tabs + Routing\n\nIMPORTANT: we-tabs only manages visual selection — clicking a tab does NOT navigate automatically.\nEach we-tab MUST have an onClick with { \"$action\": \"routeStore.navigate\" } to trigger route changes.\nBind we-tabs selectedKey to the matching route segment so the active tab stays in sync.\n(Alternatively, a single onChange on we-tabs can replace per-tab onClick — see onChange pattern below.)\n\nRecommended pattern — header above tabs (routes on ROOT, $routes outlet nested inside):\n{\n \"type\": \"Column\",\n \"routes\": [\n { \"path\": \"/\", \"type\": \"we-text\", \"children\": [\"Select a tab\"] },\n { \"path\": \"/posts\", \"type\": \"Column\", \"children\": [{ \"type\": \"we-text\", \"children\": [\"Posts content\"] }] },\n { \"path\": \"/articles\", \"type\": \"Column\", \"children\": [{ \"type\": \"we-text\", \"children\": [\"Articles content\"] }] }\n ],\n \"children\": [\n { \"type\": \"Row\", \"props\": { \"p\": \"300\", \"ax\": \"between\" }, \"children\": [\n { \"type\": \"we-text\", \"props\": { \"variant\": \"heading-lg\" }, \"children\": [\"My App\"] }\n ]},\n {\n \"type\": \"we-tabs\",\n \"props\": { \"selectedKey\": { \"$store\": \"routeStore.segments.0\" } },\n \"children\": [\n { \"type\": \"we-tab\", \"props\": { \"key\": \"posts\", \"label\": \"Posts\", \"onClick\": { \"$action\": \"routeStore.navigate\", \"args\": [\"/posts\"] } } },\n { \"type\": \"we-tab\", \"props\": { \"key\": \"articles\", \"label\": \"Articles\", \"onClick\": { \"$action\": \"routeStore.navigate\", \"args\": [\"/articles\"] } } }\n ]\n },\n { \"type\": \"$routes\" }\n ]\n}\nNote: \"routes\" is on the root Column, NOT on a child. The $routes outlet is a child — that's fine. Only the routes array placement matters.\n\nWRONG — two common mistakes that produce empty tabs (validator will catch both):\n{\n // MISTAKE 1: routes defined on an inner child node, not the root.\n // The router never inspects children for routes arrays — this routes array is invisible.\n \"type\": \"Column\",\n \"children\": [\n { \"type\": \"we-tabs\", \"children\": [\"...tabs...\"] },\n {\n \"type\": \"Column\",\n \"routes\": [ // ← WRONG: router never reads this\n { \"path\": \"/posts\", \"type\": \"Column\", \"children\": [\"...\"] }\n ],\n \"children\": [{ \"type\": \"$routes\" }] // ← outlet here does nothing without a live routes array\n }\n ]\n}\n\n{\n // MISTAKE 2: using { type: \"$routes\" } as a route entry's component type.\n // $routes is an outlet slot marker — as a leaf route entry it has no children injected,\n // so it returns null. Every tab navigates to a route that renders nothing.\n \"type\": \"Column\",\n \"routes\": [\n { \"path\": \"/posts\", \"type\": \"$routes\" } // ← WRONG: renders null, use a real component\n ],\n \"children\": [{ \"type\": \"$routes\" }]\n}\n\nAlternative: single onChange on we-tabs (fires with $event.detail.value = selected key):\n{ \"onChange\": { \"$action\": \"routeStore.navigate\", \"args\": [{ \"$concat\": [\"/\", \"$arg.detail.value\"] }] } }\nThis replaces all per-tab onClick handlers but requires $concat to build the path.\n\nNested routing example:\n{\n \"routes\": [\n { \"path\": \"*\", \"type\": \"Column\", \"props\": { \"ax\": \"center\", \"p\": \"500\" }, \"children\": [{ \"type\": \"we-text\", \"children\": [\"Page not found\"] }] },\n { \"path\": \"/\", \"type\": \"Column\", \"props\": { \"ax\": \"center\", \"p\": \"500\" }, \"children\": [{ \"type\": \"we-text\", \"children\": [\"Home page\"] }] },\n {\n \"path\": \"/space/:spaceId\",\n \"type\": \"Row\",\n \"children\": [{ \"type\": \"$routes\" }],\n \"routes\": [\n { \"path\": \"/*\", \"type\": \"we-text\", \"children\": [\"Space page not found\"] },\n { \"path\": \"/\", \"type\": \"we-text\", \"children\": [\"About sub-page\"] },\n { \"path\": \"/posts\", \"type\": \"Column\", \"children\": [{ \"type\": \"$routes\" }],\n \"routes\": [\n { \"path\": \"/*\", \"type\": \"we-text\", \"children\": [\"Post not found\"] },\n { \"path\": \"/\", \"type\": \"we-text\", \"children\": [\"No posts selected\"] },\n { \"path\": \"/1\", \"type\": \"we-text\", \"children\": [\"Post 1 page\"] }\n ]\n }\n ]\n }\n ]\n}\n\n---\n\n## Rules & Best Practices\n\n- Always use the correct prop names and value types for each component.\n- Never use null as a value in any children array. Only use valid schema nodes or strings.\n- Each item in a children array must be either a valid schema node object or a string.\n- Use design tokens for spacing, color, radius, etc. (do not use raw CSS except in styles).\n- Use the styles prop for custom inline CSS (e.g., { \"width\": \"100px\" }).\n- Use hoverProps for hover state overrides, activeProps for pressed state, focusProps for focus state. Supported on @we/primitives (we-text, we-button, etc.) and layout components (Column, Row).\n- Use dynamic logic tokens ($store, $if, $action, etc.) for reactivity and conditional behavior.\n- Nest components using children or slots as needed.\n- For routes, use the routes array with path and child nodes.\n- Do not invent new components or props — use only those listed in the component registry.\n- Do not set props to their default/inherited values — omit them. fontSize and fontWeight inherit from parents (~16px / normal), so only set them when you need a different value.\n- Omit empty `props` and `children` — both are optional. Do not write `props: {}` or `children: []`.\n- Do not use `as const` on schema node `type` fields — `SchemaNode.type` is `string`, so it is never needed.\n- For icon-only buttons, nest a `we-icon` child inside `we-button` rather than using a `text` prop with a Unicode character. **Omit the `size` prop on `we-icon` when nesting inside sized primitives** (`we-button`, `we-input`, `we-badge`, `we-textarea`) — these components auto-size nested icons via `--we-context-icon-size` (xs→12px, sm→16px, md→24px, lg→32px, xl→40px). Only set an explicit icon `size` if you need to override the automatic sizing. Example: `{ type: 'we-button', props: { variant: 'ghost', size: 'sm' }, children: [{ type: 'we-icon', props: { name: 'x' } }] }`.\n- NEVER pass a bare number like \"16\" as a size or dimension prop — it is not valid CSS. Always check the component's declared prop type: if it's a string union, use one of the listed values; if it accepts arbitrary strings, include a CSS unit (e.g. \"16px\", \"2rem\").\n- For interactive list items and selectable options, use `we-button` with variant switching (e.g., `secondary` when selected, `ghost` when not) instead of manually styling `Row` with cursor, bg, and onClick. Buttons provide hover, focus, and active states for free.\n- For card-like layouts, compose from `Column` with DS props (bg, r, border, p, gap). This gives full control over spacing and appearance.\n- When rendering lists of similar items (posts, cards, users, etc.), ALWAYS use `$each` with a single template child — never duplicate the same node structure multiple times. Use literal arrays in `items` for static data, or `$store`/`$query` for dynamic data.\n\n### Icon Names (Phosphor Icons)\n\nwe-icon uses **Phosphor Icons** (v2.1). Do NOT use Heroicons, Material, or FontAwesome names.\nPhosphor names are lowercase-kebab-case. The `weight` prop controls style: \"regular\" (default), \"bold\", \"fill\", \"light\", \"thin\", \"duotone\".\n\nCommon Phosphor icon names (use these, NOT Heroicons equivalents):\n- Navigation: house, arrow-left, arrow-right, caret-left, caret-right, caret-down, caret-up, arrows-clockwise\n- Actions: plus, minus, x, check, pencil-simple, trash, copy, download, upload, share, link, magnifying-glass, funnel, sliders-horizontal\n- Communication: chat-circle, chat-dots, envelope-simple, paper-plane-tilt, bell, megaphone\n- Social: heart, thumbs-up, thumbs-down, star, share-network, users, user, user-plus\n- Media: image, camera, play, pause, stop, microphone, speaker-high, video-camera\n- Files: file, file-text, folder, folder-open, clipboard-text, note\n- UI: list, squares-four, gear, dots-three, dots-three-vertical, warning, info, question, check-circle, x-circle, eye, eye-slash\n- Misc: lightning, rocket, globe, map-pin, calendar, clock, tag, bookmark, flag, lock, shield-check\n\nWRONG icon names (Heroicons/Material — do NOT use):\n- \"chat-bubble-left\" → use \"chat-circle\"\n- \"chevron-right\" → use \"caret-right\"\n- \"cog\" / \"settings\" → use \"gear\"\n- \"trash-can\" → use \"trash\"\n- \"magnifying-glass-circle\" → use \"magnifying-glass\"\n- \"home\" → use \"house\"\n- \"favorite\" → use \"heart\"\n- \"delete\" → use \"trash\"\n- \"search\" → use \"magnifying-glass\"\n- \"close\" → use \"x\"\n- \"menu\" → use \"list\"\n- All schemas must be valid JSON with property names and string values in double quotes.\n- The meta property at the root is required: { \"meta\": { \"name\": \"...\", \"description\": \"...\", \"icon\": \"...\" } }\n- Always set `bg: 'neutral-50'` on root-level schema nodes (templates, pages). This ensures proper background in all themes — without it, dark mode renders white backgrounds.\n\nMost @we/primitives inherit all Design System Props documented above (layout, visual, flex, typography, state).\nSome layout-only primitives (we-avatar, we-icon, we-image, we-spinner, etc.) only accept Layout props — see the Design System Props section for the full list.\n\nNative HTML elements (lowercase tags render directly without registry entries):\n- Layout: div, section, article, aside, main, nav, header, footer\n- Text: p, span, h1-h6, pre, code, blockquote\n- Lists: ul, ol, li\n- Forms: form, input, button, label, select, textarea\n- Media: img, video, audio, canvas, figure, figcaption\n- Other: a, table, tr, td, th, details, summary, dialog\n\n## Schema Validation\n\nRun `we-validate-schemas` (or `node packages/schema-system/shared/dist/cli/we-validate-schemas.js`) from the monorepo root to validate all `.schema.ts` files.\nFor a specific file: `we-validate-schemas packages/app-framework/src/shared/schemas/MyTemplate.schema.ts`\n\nAfter creating or modifying a `.schema.ts` file, always run validation to catch:\n- Unknown component types (typos, missing registry entries)\n- Invalid or misspelled props (with \"did you mean?\" suggestions)\n- Prop type mismatches (e.g., number where string expected)\n- Missing required `meta` field on root TemplateSchema nodes\n- `$routes` outlet without a `routes` array on an ancestor\n- Orphan `$local` / `$setLocal` references without a `$localState` ancestor\n- DS layer consistency (mixing props from layers the component doesn't support)"; diff --git a/packages/app-framework/src/frameworks/solid/components/assistant/AssistantConfigPanel.tsx b/packages/app-framework/src/frameworks/solid/components/assistant/AssistantConfigPanel.tsx new file mode 100644 index 00000000..663e0daa --- /dev/null +++ b/packages/app-framework/src/frameworks/solid/components/assistant/AssistantConfigPanel.tsx @@ -0,0 +1,521 @@ +import { Column, Row } from '@we/components/solid'; +import { tokenVar } from '@we/design-utils'; +import type { Assistant } from '@we/models'; +import { createEffect, createSignal, For, Show } from 'solid-js'; + +import { parseIdList, useAssistantStore } from '../../stores/AssistantStore'; + +type Tab = 'assistants' | 'personalities' | 'skills' | 'mcp'; + +/** + * Right pane of the AI-assistant surface: manage the personal assistant configuration + * (assistants + their model, system prompt and granted personalities/skills/MCP servers) + * and the reusable libraries (personalities, skills, MCP servers). All data lives in the + * personal we-root perspective. + */ +export function AssistantConfigPanel() { + const [tab, setTab] = createSignal('assistants'); + + const tabs: { id: Tab; label: string; icon: string }[] = [ + { id: 'assistants', label: 'Assistants', icon: 'sparkle' }, + { id: 'personalities', label: 'Personalities', icon: 'mask-happy' }, + { id: 'skills', label: 'Skills', icon: 'lightning' }, + { id: 'mcp', label: 'MCP', icon: 'plugs' }, + ]; + + return ( + + {/* Tab bar */} + + + {(t) => ( + setTab(t.id)} + styles={{ 'flex-shrink': '0' }} + > + + + {t.label} + + + )} + + + + + + + + + + + + + + + + + + + ); +} + +// --------------------------------------------------------------------------- Assistants + +function AssistantsSection() { + const store = useAssistantStore(); + const [selectedId, setSelectedId] = createSignal(null); + + const selected = () => store.assistants().find((a) => a.id === selectedId()) ?? store.activeAssistant(); + + // Editable buffers, re-seeded when the selected assistant changes. + const [name, setName] = createSignal(''); + const [modelId, setModelId] = createSignal(''); + const [systemPrompt, setSystemPrompt] = createSignal(''); + createEffect(() => { + const a = selected(); + setName(a?.name ?? ''); + setModelId(a?.modelId ?? ''); + setSystemPrompt(a?.systemPrompt ?? ''); + }); + + async function addAssistant() { + const id = await store.createAssistant({ name: 'New assistant' }); + if (id) setSelectedId(id); + } + + async function save() { + const a = selected(); + if (!a) return; + await store.updateAssistant(a.id, { name: name(), modelId: modelId(), systemPrompt: systemPrompt() }); + } + + return ( + + + + Assistants + + + + New + + + + {/* Assistant picker */} + 0} + fallback={} + > + + + + {(a) => ( + + + setName(e.detail as string)} /> + + + + setModelId(e.currentTarget.value)} + style={inputStyle()} + /> + + {(m) => + + + + + setSystemPrompt(e.detail as string)} + /> + + + + + Save changes + + void store.deleteAssistant(a().id)}> + + + Delete + + + + + {/* Grants */} + + + + + )} + + + + ); +} + +function GrantGroup(props: { + title: string; + field: 'personalityIds' | 'skillIds' | 'mcpServerIds'; + assistant: Assistant; + items: { id: string; name: string }[]; +}) { + const store = useAssistantStore(); + // Read reactively from the live assistant record so toggles reflect immediately. + const grantedSet = () => new Set(parseIdList(store.assistants().find((a) => a.id === props.assistant.id)?.[props.field])); + + return ( + + + {props.title} + + 0} fallback={{`No ${props.title.toLowerCase()} defined`}}> + + + {(item) => { + const on = () => grantedSet().has(item.id); + return ( + void store.toggleGrant(props.assistant.id, props.field, item.id)} + > + + + {item.name || 'Untitled'} + + + ); + }} + + + + + ); +} + +// --------------------------------------------------------------------------- Personalities + +function PersonalitySection() { + const store = useAssistantStore(); + const [name, setName] = createSignal(''); + const [body, setBody] = createSignal(''); + const [editingId, setEditingId] = createSignal(null); + + function reset() { + setName(''); + setBody(''); + setEditingId(null); + } + + async function submit() { + if (!name().trim() && !body().trim()) return; + const id = editingId(); + if (id) await store.updatePersonality(id, { name: name(), body: body() }); + else await store.createPersonality({ name: name(), body: body() }); + reset(); + } + + return ( + + + Personalities + + + Reusable guidance blocks that can be granted to an assistant. + + + 0} fallback={}> + + + {(p) => ( + { + setEditingId(p.id); + setName(p.name); + setBody(p.body); + }} + onDelete={() => void store.deletePersonality(p.id)} + /> + )} + + + + + + setName(e.detail as string)} /> + setBody(e.detail as string)} /> + + + + ); +} + +// --------------------------------------------------------------------------- Skills + +function SkillSection() { + const store = useAssistantStore(); + const [name, setName] = createSignal(''); + const [description, setDescription] = createSignal(''); + const [body, setBody] = createSignal(''); + const [editingId, setEditingId] = createSignal(null); + + function reset() { + setName(''); + setDescription(''); + setBody(''); + setEditingId(null); + } + + async function submit() { + if (!name().trim()) return; + const id = editingId(); + if (id) await store.updateSkill(id, { name: name(), description: description(), body: body() }); + else await store.createSkill({ name: name(), description: description(), body: body() }); + reset(); + } + + return ( + + + Skills + + + Named capabilities the AD4M backend can equip an assistant with. + + + 0} fallback={}> + + + {(s) => ( + { + setEditingId(s.id); + setName(s.name); + setDescription(s.description); + setBody(s.body); + }} + onDelete={() => void store.deleteSkill(s.id)} + /> + )} + + + + + + setName(e.detail as string)} /> + setDescription(e.detail as string)} /> + setBody(e.detail as string)} /> + + + + ); +} + +// --------------------------------------------------------------------------- MCP servers + +function McpSection() { + const store = useAssistantStore(); + const [name, setName] = createSignal(''); + const [transport, setTransport] = createSignal('stdio'); + const [url, setUrl] = createSignal(''); + const [command, setCommand] = createSignal(''); + const [auth, setAuth] = createSignal(''); + const [editingId, setEditingId] = createSignal(null); + + function reset() { + setName(''); + setTransport('stdio'); + setUrl(''); + setCommand(''); + setAuth(''); + setEditingId(null); + } + + async function submit() { + if (!name().trim()) return; + const data = { name: name(), transport: transport(), url: url(), command: command(), auth: auth() }; + const id = editingId(); + if (id) await store.updateMcpServer(id, data); + else await store.createMcpServer(data); + reset(); + } + + const isStdio = () => transport() === 'stdio'; + + return ( + + + MCP servers + + + Model Context Protocol servers the backend connects to on an assistant's behalf. + + + 0} fallback={}> + + + {(m) => ( + { + setEditingId(m.id); + setName(m.name); + setTransport(m.transport || 'stdio'); + setUrl(m.url); + setCommand(m.command); + setAuth(m.auth); + }} + onDelete={() => void store.deleteMcpServer(m.id)} + /> + )} + + + + + + setName(e.detail as string)} /> + + + + setUrl(e.detail as string)} />} + > + setCommand(e.detail as string)} /> + + setAuth(e.detail as string)} /> + + + + ); +} + +// --------------------------------------------------------------------------- Shared UI bits + +function Field(props: { label: string; children: unknown }) { + return ( + + + {props.label} + + {props.children as never} + + ); +} + +function ListRow(props: { title: string; subtitle?: string; onEdit: () => void; onDelete: () => void }) { + return ( + + + + {props.title || 'Untitled'} + + + + {props.subtitle} + + + + + + + + + + + ); +} + +function EditorCard(props: { title: string; children: unknown }) { + return ( + + + {props.title} + + {props.children as never} + + ); +} + +function EditorActions(props: { editing: boolean; onSubmit: () => void; onCancel: () => void }) { + return ( + + + {props.editing ? 'Save' : 'Add'} + + + + Cancel + + + + ); +} + +function Empty(props: { text: string }) { + return ( + + {props.text} + + ); +} + +function inputStyle(): Record { + return { + 'font-size': '13px', + padding: '6px 10px', + 'border-radius': '6px', + border: `1px solid ${tokenVar('color', 'ui-200')}`, + background: tokenVar('color', 'neutral-0'), + color: tokenVar('color', 'neutral-800'), + width: '100%', + }; +} diff --git a/packages/app-framework/src/frameworks/solid/components/assistant/AssistantMessage.tsx b/packages/app-framework/src/frameworks/solid/components/assistant/AssistantMessage.tsx new file mode 100644 index 00000000..fa7cf194 --- /dev/null +++ b/packages/app-framework/src/frameworks/solid/components/assistant/AssistantMessage.tsx @@ -0,0 +1,170 @@ +import { Column, Row } from '@we/components/solid'; +import { tokenVar } from '@we/design-utils'; +import type { Message } from '@we/models'; +import { createSignal, For, Show } from 'solid-js'; + +import { parseToolCalls, type ToolCall } from '../../stores/AssistantStore'; + +/** + * Renders a single assistant-thread message. Handles the four roles + * (user / assistant / tool / system), markdown content, a live streaming + * indicator, and collapsible tool-call invocation/result blocks. + */ +export function AssistantMessage(props: { message: Message }) { + const role = () => props.message.role || 'assistant'; + const isUser = () => role() === 'user'; + const isTool = () => role() === 'tool'; + const isSystem = () => role() === 'system'; + const isStreaming = () => props.message.status === 'streaming'; + const toolCalls = () => parseToolCalls(props.message.toolCalls); + const hasContent = () => !!props.message.content?.trim(); + + return ( + + + {props.message.content} + + + } + > + + {/* Role label for assistant/tool turns */} + + + + + {isTool() ? 'Tool' : 'Assistant'} + + + + streaming… + + + + + + {/* Streaming placeholder before any tokens have arrived */} + + + Thinking… + + + + {/* Message body */} + + } + > + + + + + {/* Tool calls */} + 0}> + + {(call) => } + + + + + + The assistant reported an error. + + + + + ); +} + +/** A collapsible tool invocation with its arguments and (once available) result. */ +function ToolCallBlock(props: { call: ToolCall }) { + const [open, setOpen] = createSignal(false); + const status = () => props.call.status ?? (props.call.result !== undefined ? 'complete' : 'pending'); + const statusColor = () => + status() === 'error' ? 'danger-500' : status() === 'complete' ? 'success-500' : 'warning-500'; + + return ( + + setOpen((v) => !v)} + > + + + + {props.call.name || 'tool'} + + + {status()} + + + + + + Arguments + + + + + Result + + + + + + + ); +} + +function CodeBlock(props: { text: string }) { + return ( +
+ {props.text} +
+ ); +} + +function formatJson(value: unknown): string { + if (value === undefined || value === null) return ''; + if (typeof value === 'string') return value; + try { + return JSON.stringify(value, null, 2); + } catch { + return String(value); + } +} diff --git a/packages/app-framework/src/frameworks/solid/components/assistant/AssistantThreadList.tsx b/packages/app-framework/src/frameworks/solid/components/assistant/AssistantThreadList.tsx new file mode 100644 index 00000000..fc92b013 --- /dev/null +++ b/packages/app-framework/src/frameworks/solid/components/assistant/AssistantThreadList.tsx @@ -0,0 +1,105 @@ +import { Column, Row } from '@we/components/solid'; +import { tokenVar } from '@we/design-utils'; +import { For, Show } from 'solid-js'; + +import { useAssistantStore } from '../../stores/AssistantStore'; + +/** + * Left pane of the AI-assistant surface: the thread list for the current neighbourhood, + * plus a new-chat action. Many threads per neighbourhood; selecting one drives the + * centre thread view. + */ +export function AssistantThreadList() { + const store = useAssistantStore(); + + async function newChat() { + await store.createThread(); + } + + return ( + + {/* Header */} + + + Chats + + + + + + + + + {/* Thread list */} + + 0} + fallback={ + + + No chats yet + + + + New chat + + + } + > + + {(thread) => { + const active = () => thread.id === store.activeThreadId(); + return ( + store.selectThread(thread.id)} + > + + + {thread.title || 'Untitled'} + + { + e.stopPropagation(); + void store.deleteThread(thread.id); + }} + > + + + + ); + }} + + + + + ); +} diff --git a/packages/app-framework/src/frameworks/solid/components/assistant/AssistantThreadView.tsx b/packages/app-framework/src/frameworks/solid/components/assistant/AssistantThreadView.tsx new file mode 100644 index 00000000..bb8e6af1 --- /dev/null +++ b/packages/app-framework/src/frameworks/solid/components/assistant/AssistantThreadView.tsx @@ -0,0 +1,153 @@ +import { Column, Row } from '@we/components/solid'; +import { tokenVar } from '@we/design-utils'; +import { createEffect, createSignal, For, Show } from 'solid-js'; + +import { useAssistantStore } from '../../stores/AssistantStore'; +import { AssistantMessage } from './AssistantMessage'; + +/** + * Centre pane of the AI-assistant surface: the active thread's message list (with live + * streaming + tool-call rendering) and the composer. Sending writes a user Message into + * the thread's perspective; the assistant's reply arrives from the AD4M backend via the + * store's live subscription. + */ +export function AssistantThreadView() { + const store = useAssistantStore(); + const [input, setInput] = createSignal(''); + let endRef: HTMLDivElement | undefined; + + // Auto-scroll to the latest message / streaming update. + createEffect(() => { + void store.messages().length; + void store.messages().find((m) => m.status === 'streaming')?.content; + requestAnimationFrame(() => endRef?.scrollIntoView({ behavior: 'smooth' })); + }); + + function handleSend() { + const text = input().trim(); + if (!text || !store.activeThreadId()) return; + void store.sendMessage(text); + setInput(''); + } + + const effectiveModel = () => { + const thread = store.activeThread(); + return thread?.modelId || store.activeAssistant()?.modelId || ''; + }; + + return ( + + + + No conversation selected + + + Create a new chat to talk to an assistant. + + + } + > + {(thread) => ( + + {/* Header */} + + + + {thread().title || 'Untitled'} + + + {store.activeAssistant()?.name ?? 'No assistant'} + + + + {/* Per-thread model override */} + + + + + + + {/* Messages */} + + 0} + fallback={ + + + Send a message to begin. + + + Replies are produced by the AD4M assistant backend. + + + } + > + {(msg) => } + +
+ + + {/* Composer */} + + setInput(e.detail as string)} + onKeyDown={(e: KeyboardEvent) => { + if (e.key === 'Enter' && !e.shiftKey) { + e.preventDefault(); + handleSend(); + } + }} + styles={{ 'overflow-y': 'auto' }} + /> + + + + + + )} + + ); +} + +function selectStyle(): Record { + return { + 'font-size': '12px', + padding: '4px 8px', + 'border-radius': '6px', + border: `1px solid ${tokenVar('color', 'ui-200')}`, + background: tokenVar('color', 'neutral-0'), + color: tokenVar('color', 'neutral-700'), + 'max-width': '220px', + cursor: 'pointer', + }; +} diff --git a/packages/app-framework/src/frameworks/solid/layouts/TemplateLayout.tsx b/packages/app-framework/src/frameworks/solid/layouts/TemplateLayout.tsx index 2640a096..b475620d 100644 --- a/packages/app-framework/src/frameworks/solid/layouts/TemplateLayout.tsx +++ b/packages/app-framework/src/frameworks/solid/layouts/TemplateLayout.tsx @@ -21,6 +21,7 @@ */ import { isValidThemeKey } from '@shared/registries/themeRegistry'; import { + aiAssistantTemplate, landingPageTemplate, marketplaceTemplate, profileTemplate, @@ -90,6 +91,7 @@ type ShellViewEntry = { const shellViews: Record = { 'landing-page': { schema: landingPageTemplate }, marketplace: { schema: marketplaceTemplate }, + 'ai-assistant': { schema: aiAssistantTemplate }, profile: { schema: profileTemplate }, settings: { schema: settingsTemplate }, 'schema-tests': { diff --git a/packages/app-framework/src/frameworks/solid/providers/StoreProvider.tsx b/packages/app-framework/src/frameworks/solid/providers/StoreProvider.tsx index 3ef42caf..850939b2 100644 --- a/packages/app-framework/src/frameworks/solid/providers/StoreProvider.tsx +++ b/packages/app-framework/src/frameworks/solid/providers/StoreProvider.tsx @@ -2,6 +2,7 @@ import { AdamStoreProvider, AiStoreProvider, AppStoreProvider, + AssistantStoreProvider, RouteStoreProvider, SpaceStoreProvider, TemplateStoreProvider, @@ -17,7 +18,9 @@ export default function StoreProvider(props: ParentProps) { - {props.children} + + {props.children} + diff --git a/packages/app-framework/src/frameworks/solid/providers/TemplateProvider.tsx b/packages/app-framework/src/frameworks/solid/providers/TemplateProvider.tsx index 82d8c408..ec7e3233 100644 --- a/packages/app-framework/src/frameworks/solid/providers/TemplateProvider.tsx +++ b/packages/app-framework/src/frameworks/solid/providers/TemplateProvider.tsx @@ -8,6 +8,7 @@ import { useAdamStore, useAiStore, useAppStore, + useAssistantStore, useRouteStore, useSpaceStore, useTemplateStore, @@ -30,6 +31,7 @@ export default function TemplateProvider() { const adamStore = useAdamStore(); const aiStore = useAiStore(); const appStore = useAppStore(); + const assistantStore = useAssistantStore(); const spaceStore = useSpaceStore(); const themeStore = useThemeStore(); const templateStore = useTemplateStore(); @@ -72,6 +74,7 @@ export default function TemplateProvider() { adamStore, aiStore, appStore, + assistantStore, spaceStore, themeStore, templateStore, diff --git a/packages/app-framework/src/frameworks/solid/registries/componentRegistry.tsx b/packages/app-framework/src/frameworks/solid/registries/componentRegistry.tsx index 20aa4fc9..cb6b561e 100644 --- a/packages/app-framework/src/frameworks/solid/registries/componentRegistry.tsx +++ b/packages/app-framework/src/frameworks/solid/registries/componentRegistry.tsx @@ -54,6 +54,9 @@ import type { ComponentRegistry } from '@we/schema-solid'; import { CesiumGlobe, CollapsibleSidebar, GraphWidget, mockGraphData, SpaceSidebarWidget } from '@we/widgets/solid'; import WeCube from '../components/3d/WeCube'; +import { AssistantConfigPanel } from '../components/assistant/AssistantConfigPanel'; +import { AssistantThreadList } from '../components/assistant/AssistantThreadList'; +import { AssistantThreadView } from '../components/assistant/AssistantThreadView'; import { AiPanel } from '../components/editor/AiPanel'; import { DesignToolbar } from '../components/editor/DesignToolbar'; import { RightPanelContainer } from '../components/editor/RightPanelContainer'; @@ -128,6 +131,11 @@ export const componentRegistry: ComponentRegistry = { // Shell DesignToolbar, + // AI assistant surface + AssistantThreadList, + AssistantThreadView, + AssistantConfigPanel, + // Testing RerenderLog, diff --git a/packages/app-framework/src/frameworks/solid/stores/AssistantStore.tsx b/packages/app-framework/src/frameworks/solid/stores/AssistantStore.tsx new file mode 100644 index 00000000..16890a11 --- /dev/null +++ b/packages/app-framework/src/frameworks/solid/stores/AssistantStore.tsx @@ -0,0 +1,663 @@ +/** + * AssistantStore — state + actions for the AD4M AI-assistant surface. + * + * This store is the front end for AI assistants whose replies are produced by the + * AD4M backend, NOT by any in-browser model call. The flow is: + * + * 1. The user writes a `Message` (role 'user') into the active thread's perspective. + * 2. The AD4M backend observes the perspective, runs the assistant, and writes back + * an assistant `Message` — creating it with `status: 'streaming'` and appending to + * its `content` (and `toolCalls`) as tokens arrive, then flipping `status` to + * 'complete'. Tool results may arrive as additional `role: 'tool'` messages. + * 3. This store subscribes to the thread's messages via the subject-class ORM + * (`Model.query(p).subscribe(cb)`), so the UI re-renders on every write — the token + * stream is simply the assistant message's `content` growing under an open + * subscription. Nothing here calls an LLM. + * + * Data lives in two perspectives: + * - Personal config (we-root): Assistant, Personality, Skill, McpServer. + * - Neighbourhood (current space, falling back to we-root): Thread, Message. + */ +import { Assistant, McpServer, Message, Personality, Skill, Thread } from '@we/models'; +import { + Accessor, + createContext, + createEffect, + createMemo, + createSignal, + onCleanup, + onMount, + ParentProps, + useContext, +} from 'solid-js'; + +import { useAdamStore } from './AdamStore'; + +/** Minimal structural view of an AD4M `ModelQueryBuilder` — the three methods this store uses. */ +interface LiveQueryBuilder { + subscribe(cb: (rows: T[]) => void): Promise; + get(): Promise; + dispose(): void; +} + +/** A parsed tool call, as rendered by the thread view. Serialised into `Message.toolCalls` (JSON). */ +export interface ToolCall { + id?: string; + name: string; + /** Tool input arguments (any JSON value). */ + input?: unknown; + /** Tool result once the backend has run it (any JSON value). */ + result?: unknown; + /** 'pending' while running, 'complete' when a result is in, 'error' on failure. */ + status?: 'pending' | 'complete' | 'error'; +} + +export interface AssistantStore { + // --- Threads (current neighbourhood) --- + threads: Accessor; + activeThreadId: Accessor; + activeThread: Accessor; + selectThread: (id: string) => void; + createThread: (title?: string, assistantId?: string) => Promise; + deleteThread: (id: string) => Promise; + renameThread: (id: string, title: string) => Promise; + setThreadModel: (id: string, modelId: string) => Promise; + + // --- Messages (active thread) --- + messages: Accessor; + streamingMessageId: Accessor; + sendMessage: (text: string) => Promise; + + // --- Assistants (personal config) --- + assistants: Accessor; + activeAssistant: Accessor; + createAssistant: (data: { name: string; modelId?: string; systemPrompt?: string }) => Promise; + updateAssistant: ( + id: string, + updates: Partial<{ name: string; modelId: string; systemPrompt: string }>, + ) => Promise; + deleteAssistant: (id: string) => Promise; + /** Toggle a Personality / Skill / McpServer grant on an assistant (rewrites the JSON id list). */ + toggleGrant: (assistantId: string, field: 'personalityIds' | 'skillIds' | 'mcpServerIds', itemId: string) => Promise; + assistantHasGrant: (assistant: Assistant, field: 'personalityIds' | 'skillIds' | 'mcpServerIds', itemId: string) => boolean; + + // --- Personalities --- + personalities: Accessor; + createPersonality: (data: { name: string; body: string }) => Promise; + updatePersonality: (id: string, updates: Partial<{ name: string; body: string }>) => Promise; + deletePersonality: (id: string) => Promise; + + // --- Skills --- + skills: Accessor; + createSkill: (data: { name: string; description: string; body: string }) => Promise; + updateSkill: (id: string, updates: Partial<{ name: string; description: string; body: string }>) => Promise; + deleteSkill: (id: string) => Promise; + + // --- MCP servers --- + mcpServers: Accessor; + createMcpServer: (data: { + name: string; + transport: string; + url?: string; + command?: string; + auth?: string; + }) => Promise; + updateMcpServer: ( + id: string, + updates: Partial<{ name: string; transport: string; url: string; command: string; auth: string }>, + ) => Promise; + deleteMcpServer: (id: string) => Promise; + + // --- Models --- + models: Accessor; + refreshModels: () => Promise; +} + +/** Parse a JSON-encoded id list (used for Assistant grant fields). Tolerant of '' and bad JSON. */ +export function parseIdList(json: string | undefined): string[] { + if (!json) return []; + try { + const parsed = JSON.parse(json); + return Array.isArray(parsed) ? parsed.filter((x): x is string => typeof x === 'string') : []; + } catch { + return []; + } +} + +/** Parse a Message's toolCalls JSON into a ToolCall[] for rendering. Never throws. */ +export function parseToolCalls(json: string | undefined): ToolCall[] { + if (!json) return []; + try { + const parsed = JSON.parse(json); + if (Array.isArray(parsed)) return parsed as ToolCall[]; + return []; + } catch { + return []; + } +} + +const AssistantContext = createContext(); + +export function AssistantStoreProvider(props: ParentProps) { + const adamStore = useAdamStore(); + + // Threads + messages live in the active neighbourhood, falling back to the personal + // root perspective so assistants work before any space is opened. + const threadPerspective = () => adamStore.currentPerspective() ?? adamStore.rootPerspective(); + // Assistant configuration is personal — always the root perspective. + const configPerspective = () => adamStore.rootPerspective(); + + const [threads, setThreads] = createSignal([]); + const [activeThreadId, setActiveThreadId] = createSignal(null); + const [messages, setMessages] = createSignal([]); + const [assistants, setAssistants] = createSignal([]); + const [personalities, setPersonalities] = createSignal([]); + const [skills, setSkills] = createSignal([]); + const [mcpServers, setMcpServers] = createSignal([]); + const [models, setModels] = createSignal([]); + + /** + * Open a live subscription. Returns a disposer. Falls back to a single `.get()` if the + * executor rejects the live subscription (e.g. live queries unavailable), so the UI still + * populates once even without push updates. + */ + function liveQuery(make: () => LiveQueryBuilder, onRows: (rows: T[]) => void): () => void { + let disposed = false; + const builder = make(); + builder + .subscribe((rows) => { + if (!disposed) onRows(rows); + }) + .catch((err) => { + console.warn('[AssistantStore] live subscribe failed; falling back to one-shot query', err); + if (disposed) return; + make() + .get() + .then((rows) => { + if (!disposed) onRows(rows); + }) + .catch((e) => console.warn('[AssistantStore] fallback query failed', e)); + }); + return () => { + disposed = true; + try { + builder.dispose(); + } catch { + /* dispose is best-effort */ + } + }; + } + + // Threads for the active neighbourhood, newest activity first. + createEffect(() => { + const p = threadPerspective(); + if (!p) { + setThreads([]); + return; + } + const dispose = liveQuery( + () => Thread.query(p).order({ updatedAt: 'DESC' }) as unknown as LiveQueryBuilder, + setThreads, + ); + onCleanup(dispose); + }); + + // Messages for the active thread, chronological. + createEffect(() => { + const p = threadPerspective(); + const tid = activeThreadId(); + if (!p || !tid) { + setMessages([]); + return; + } + const dispose = liveQuery( + () => Message.query(p).where({ threadId: tid }).order({ ts: 'ASC' }) as unknown as LiveQueryBuilder, + setMessages, + ); + onCleanup(dispose); + }); + + // Personal config: assistants, personalities, skills, MCP servers. + createEffect(() => { + const p = configPerspective(); + if (!p) { + setAssistants([]); + setPersonalities([]); + setSkills([]); + setMcpServers([]); + return; + } + const disposers = [ + liveQuery( + () => Assistant.query(p).order({ name: 'ASC' }) as unknown as LiveQueryBuilder, + setAssistants, + ), + liveQuery( + () => Personality.query(p).order({ name: 'ASC' }) as unknown as LiveQueryBuilder, + setPersonalities, + ), + liveQuery(() => Skill.query(p).order({ name: 'ASC' }) as unknown as LiveQueryBuilder, setSkills), + liveQuery( + () => McpServer.query(p).order({ name: 'ASC' }) as unknown as LiveQueryBuilder, + setMcpServers, + ), + ]; + onCleanup(() => disposers.forEach((d) => d())); + }); + + // Keep an active thread selected: adopt the newest when none is chosen, and recover if the + // active thread is deleted out from under us. + createEffect(() => { + const list = threads(); + const active = activeThreadId(); + if (!active && list.length > 0) { + setActiveThreadId(list[0].id); + } else if (active && !list.some((t) => t.id === active)) { + setActiveThreadId(list[0]?.id ?? null); + } + }); + + const activeThread = createMemo(() => threads().find((t) => t.id === activeThreadId()) ?? null); + + const activeAssistant = createMemo(() => { + const thread = activeThread(); + const list = assistants(); + if (thread?.assistantId) { + const match = list.find((a) => a.id === thread.assistantId); + if (match) return match; + } + return list[0] ?? null; + }); + + const streamingMessageId = createMemo(() => messages().find((m) => m.status === 'streaming')?.id ?? null); + + // ---------------------------------------------------------------- Thread actions + + function selectThread(id: string) { + setActiveThreadId(id); + } + + async function createThread(title?: string, assistantId?: string): Promise { + const p = threadPerspective(); + if (!p) return null; + const now = new Date().toISOString(); + const aId = assistantId ?? activeAssistant()?.id ?? assistants()[0]?.id ?? ''; + try { + const thread = await Thread.create(p, { + title: title?.trim() || 'New chat', + assistantId: aId, + modelId: '', + createdAt: now, + updatedAt: now, + }); + setActiveThreadId(thread.id); + return thread.id; + } catch (err) { + console.error('[AssistantStore] createThread failed', err); + return null; + } + } + + async function deleteThread(id: string): Promise { + const p = threadPerspective(); + if (!p) return; + try { + const msgs = await Message.findAll(p, { where: { threadId: id } }); + for (const m of msgs) await m.delete().catch((e) => console.warn('[AssistantStore] delete message failed', e)); + const thread = threads().find((t) => t.id === id); + if (thread) await thread.delete(); + if (activeThreadId() === id) setActiveThreadId(null); + } catch (err) { + console.error('[AssistantStore] deleteThread failed', err); + } + } + + async function renameThread(id: string, title: string): Promise { + const thread = threads().find((t) => t.id === id); + if (!thread) return; + try { + thread.title = title.trim() || thread.title; + thread.updatedAt = new Date().toISOString(); + await thread.save(); + } catch (err) { + console.error('[AssistantStore] renameThread failed', err); + } + } + + async function setThreadModel(id: string, modelId: string): Promise { + const thread = threads().find((t) => t.id === id); + if (!thread) return; + try { + thread.modelId = modelId; + await thread.save(); + } catch (err) { + console.error('[AssistantStore] setThreadModel failed', err); + } + } + + // ---------------------------------------------------------------- Messaging + + /** + * Write a user message into the active thread's perspective. This is the ONLY write the UI + * makes on send — the assistant's reply comes from the AD4M backend, which observes the + * perspective and writes the response back (picked up by the messages subscription). + */ + async function sendMessage(text: string): Promise { + const p = threadPerspective(); + const tid = activeThreadId(); + const content = text.trim(); + if (!p || !tid || !content) return; + const now = new Date().toISOString(); + try { + await Message.create( + p, + { threadId: tid, role: 'user', content, ts: now, status: 'complete', toolCalls: '' }, + { parent: { model: Thread, id: tid } }, + ); + // Bump the thread's updatedAt so it sorts to the top and the backend has a clear "last active". + const thread = threads().find((t) => t.id === tid); + if (thread) { + thread.updatedAt = now; + await thread.save().catch((e) => console.warn('[AssistantStore] thread bump failed', e)); + } + } catch (err) { + console.error('[AssistantStore] sendMessage failed', err); + } + } + + // ---------------------------------------------------------------- Assistant CRUD + + async function createAssistant(data: { + name: string; + modelId?: string; + systemPrompt?: string; + }): Promise { + const p = configPerspective(); + if (!p) return null; + try { + const assistant = await Assistant.create(p, { + name: data.name.trim() || 'Assistant', + modelId: data.modelId ?? models()[0] ?? '', + systemPrompt: data.systemPrompt ?? '', + personalityIds: '[]', + skillIds: '[]', + mcpServerIds: '[]', + }); + return assistant.id; + } catch (err) { + console.error('[AssistantStore] createAssistant failed', err); + return null; + } + } + + async function updateAssistant( + id: string, + updates: Partial<{ name: string; modelId: string; systemPrompt: string }>, + ): Promise { + const assistant = assistants().find((a) => a.id === id); + if (!assistant) return; + try { + Object.assign(assistant, updates); + await assistant.save(); + } catch (err) { + console.error('[AssistantStore] updateAssistant failed', err); + } + } + + async function deleteAssistant(id: string): Promise { + const assistant = assistants().find((a) => a.id === id); + if (!assistant) return; + try { + await assistant.delete(); + } catch (err) { + console.error('[AssistantStore] deleteAssistant failed', err); + } + } + + function assistantHasGrant( + assistant: Assistant, + field: 'personalityIds' | 'skillIds' | 'mcpServerIds', + itemId: string, + ): boolean { + return parseIdList(assistant[field]).includes(itemId); + } + + async function toggleGrant( + assistantId: string, + field: 'personalityIds' | 'skillIds' | 'mcpServerIds', + itemId: string, + ): Promise { + const assistant = assistants().find((a) => a.id === assistantId); + if (!assistant) return; + const current = parseIdList(assistant[field]); + const next = current.includes(itemId) ? current.filter((x) => x !== itemId) : [...current, itemId]; + try { + assistant[field] = JSON.stringify(next); + await assistant.save(); + } catch (err) { + console.error('[AssistantStore] toggleGrant failed', err); + } + } + + // ---------------------------------------------------------------- Personality CRUD + + async function createPersonality(data: { name: string; body: string }): Promise { + const p = configPerspective(); + if (!p) return; + try { + await Personality.create(p, { name: data.name.trim() || 'Personality', body: data.body }); + } catch (err) { + console.error('[AssistantStore] createPersonality failed', err); + } + } + + async function updatePersonality(id: string, updates: Partial<{ name: string; body: string }>): Promise { + const item = personalities().find((x) => x.id === id); + if (!item) return; + try { + Object.assign(item, updates); + await item.save(); + } catch (err) { + console.error('[AssistantStore] updatePersonality failed', err); + } + } + + async function deletePersonality(id: string): Promise { + const item = personalities().find((x) => x.id === id); + if (!item) return; + try { + await item.delete(); + } catch (err) { + console.error('[AssistantStore] deletePersonality failed', err); + } + } + + // ---------------------------------------------------------------- Skill CRUD + + async function createSkill(data: { name: string; description: string; body: string }): Promise { + const p = configPerspective(); + if (!p) return; + try { + await Skill.create(p, { + name: data.name.trim() || 'Skill', + description: data.description, + body: data.body, + }); + } catch (err) { + console.error('[AssistantStore] createSkill failed', err); + } + } + + async function updateSkill( + id: string, + updates: Partial<{ name: string; description: string; body: string }>, + ): Promise { + const item = skills().find((x) => x.id === id); + if (!item) return; + try { + Object.assign(item, updates); + await item.save(); + } catch (err) { + console.error('[AssistantStore] updateSkill failed', err); + } + } + + async function deleteSkill(id: string): Promise { + const item = skills().find((x) => x.id === id); + if (!item) return; + try { + await item.delete(); + } catch (err) { + console.error('[AssistantStore] deleteSkill failed', err); + } + } + + // ---------------------------------------------------------------- MCP server CRUD + + async function createMcpServer(data: { + name: string; + transport: string; + url?: string; + command?: string; + auth?: string; + }): Promise { + const p = configPerspective(); + if (!p) return; + try { + await McpServer.create(p, { + name: data.name.trim() || 'MCP server', + transport: data.transport || 'stdio', + url: data.url ?? '', + command: data.command ?? '', + auth: data.auth ?? '', + }); + } catch (err) { + console.error('[AssistantStore] createMcpServer failed', err); + } + } + + async function updateMcpServer( + id: string, + updates: Partial<{ name: string; transport: string; url: string; command: string; auth: string }>, + ): Promise { + const item = mcpServers().find((x) => x.id === id); + if (!item) return; + try { + Object.assign(item, updates); + await item.save(); + } catch (err) { + console.error('[AssistantStore] updateMcpServer failed', err); + } + } + + async function deleteMcpServer(id: string): Promise { + const item = mcpServers().find((x) => x.id === id); + if (!item) return; + try { + await item.delete(); + } catch (err) { + console.error('[AssistantStore] deleteMcpServer failed', err); + } + } + + // ---------------------------------------------------------------- Models + + /** + * Discover model ids from the AD4M backend's OpenAI-compatible `/v1/models` endpoint. + * Best-effort: on web the executor may not be directly reachable, so on any failure we fall + * back to the union of model ids already referenced by assistants. The UI additionally lets a + * user type a model id, so an empty list never blocks configuration. + */ + async function refreshModels(): Promise { + const port = adamStore.ad4mPort(); + const token = adamStore.ad4mToken(); + if (port) { + try { + const res = await fetch(`http://localhost:${port}/v1/models`, { + headers: token ? { Authorization: `Bearer ${token}` } : undefined, + }); + if (res.ok) { + const json = (await res.json()) as { data?: Array<{ id?: string }>; models?: Array<{ id?: string; name?: string }> }; + const ids = Array.isArray(json?.data) + ? json.data.map((m) => m.id).filter((x): x is string => !!x) + : Array.isArray(json?.models) + ? json.models.map((m) => m.id ?? m.name).filter((x): x is string => !!x) + : []; + if (ids.length) { + setModels(ids); + return; + } + } + } catch (err) { + console.warn('[AssistantStore] /v1/models unavailable; using referenced models', err); + } + } + const used = Array.from(new Set(assistants().map((a) => a.modelId).filter((x): x is string => !!x))); + setModels(used); + } + + let modelFallbackTried = false; + onMount(() => { + void refreshModels(); + }); + // Once assistants load, retry discovery a single time if we still have no models — handles + // the executor port not being ready at mount. Guarded so a persistently empty /v1/models + // (which re-sets an empty array each call) can't spin this into a refetch loop. + createEffect(() => { + if (!modelFallbackTried && models().length === 0 && assistants().length > 0) { + modelFallbackTried = true; + void refreshModels(); + } + }); + + const store: AssistantStore = { + threads, + activeThreadId, + activeThread, + selectThread, + createThread, + deleteThread, + renameThread, + setThreadModel, + + messages, + streamingMessageId, + sendMessage, + + assistants, + activeAssistant, + createAssistant, + updateAssistant, + deleteAssistant, + toggleGrant, + assistantHasGrant, + + personalities, + createPersonality, + updatePersonality, + deletePersonality, + + skills, + createSkill, + updateSkill, + deleteSkill, + + mcpServers, + createMcpServer, + updateMcpServer, + deleteMcpServer, + + models, + refreshModels, + }; + + return {props.children}; +} + +export function useAssistantStore(): AssistantStore { + const ctx = useContext(AssistantContext); + if (!ctx) throw new Error('useAssistantStore must be used within an AssistantStoreProvider'); + return ctx; +} + +export default AssistantStoreProvider; diff --git a/packages/app-framework/src/frameworks/solid/stores/index.ts b/packages/app-framework/src/frameworks/solid/stores/index.ts index dc986ddc..f6785d72 100644 --- a/packages/app-framework/src/frameworks/solid/stores/index.ts +++ b/packages/app-framework/src/frameworks/solid/stores/index.ts @@ -4,5 +4,13 @@ export { type ThemeStore, type EditingTheme, useThemeStore, ThemeStoreProvider } export { type TemplateStore, useTemplateStore, TemplateStoreProvider } from './TemplateStore'; export { type RouteStore, useRouteStore, RouteStoreProvider } from './RouteStore'; export { type AiStore, useAiStore, AiStoreProvider } from './AiStore'; +export { + type AssistantStore, + type ToolCall, + useAssistantStore, + AssistantStoreProvider, + parseIdList, + parseToolCalls, +} from './AssistantStore'; export { type AppStore, useAppStore, AppStoreProvider } from './AppStore'; export { useShellRouteStore, ShellRouteStoreProvider, ShellRouterRoot } from './ShellRouteStore'; diff --git a/packages/app-framework/src/frameworks/solid/types.ts b/packages/app-framework/src/frameworks/solid/types.ts index a73d2e0a..7064b02e 100644 --- a/packages/app-framework/src/frameworks/solid/types.ts +++ b/packages/app-framework/src/frameworks/solid/types.ts @@ -1,5 +1,14 @@ import type { Ad4mModel } from '@coasys/ad4m'; -import type { AdamStore, AiStore, AppStore, RouteStore, SpaceStore, TemplateStore, ThemeStore } from '@solid/stores'; +import type { + AdamStore, + AiStore, + AppStore, + AssistantStore, + RouteStore, + SpaceStore, + TemplateStore, + ThemeStore, +} from '@solid/stores'; import type { QueryAdapter, RendererStores } from '@we/schema-shared'; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -43,6 +52,7 @@ export interface Stores extends RendererStores { adamStore: AdamStore; aiStore: AiStore; appStore: AppStore; + assistantStore: AssistantStore; spaceStore: SpaceStore; themeStore: ThemeStore; templateStore: TemplateStore; diff --git a/packages/app-framework/src/shared/schemas/index.ts b/packages/app-framework/src/shared/schemas/index.ts index fabe9804..a7a26ffa 100644 --- a/packages/app-framework/src/shared/schemas/index.ts +++ b/packages/app-framework/src/shared/schemas/index.ts @@ -4,6 +4,7 @@ export { twitterTemplate } from './TwitterTemplate.schema'; // Shell export { + aiAssistantTemplate, bootScreen, createTestStore, landingPageTemplate, diff --git a/packages/app-framework/src/shared/schemas/shell/AiAssistant.schema.ts b/packages/app-framework/src/shared/schemas/shell/AiAssistant.schema.ts new file mode 100644 index 00000000..3b6fb499 --- /dev/null +++ b/packages/app-framework/src/shared/schemas/shell/AiAssistant.schema.ts @@ -0,0 +1,49 @@ +/** + * AI Assistant — shell view for the AD4M AI-assistant surface. + * + * Composed declaratively from three registered components (all backed by `assistantStore`): + * - AssistantThreadList — threads in the current neighbourhood + create-thread + * - AssistantThreadView — active thread: messages, tool calls, live stream, composer + * - AssistantConfigPanel — assistants, model selector, personalities, skills, MCP servers + * + * Opened via `templateStore.openShellView('ai-assistant')` (see TemplateLayout's shellViews + * registry and the sidebar entry). Assistant replies are written into the perspective by the + * AD4M backend and surface here through the store's live subscriptions — this UI never calls + * a model itself. + */ +import type { TemplateSchema } from '@we/schema-shared'; + +export const aiAssistantTemplate: TemplateSchema = { + meta: { name: 'AI Assistant', description: 'Chat with AD4M AI assistants', icon: 'sparkle' }, + type: 'Column', + props: { width: '100%', height: '100%', bg: 'neutral-0' }, + children: [ + // Header + { + type: 'Row', + props: { + ay: 'center', + gap: '200', + px: '400', + py: '300', + borderBottom: '1px solid neutral-200', + styles: { 'flex-shrink': '0' }, + }, + children: [ + { type: 'we-icon', props: { name: 'sparkle', size: 'md' } }, + { type: 'we-text', props: { variant: 'heading-sm', fontWeight: '600' }, children: ['AI Assistant'] }, + ], + }, + + // Body: thread list | thread view | config panel + { + type: 'Row', + props: { flex: '1', width: '100%', styles: { 'min-height': '0' } }, + children: [ + { type: 'AssistantThreadList' }, + { type: 'AssistantThreadView' }, + { type: 'AssistantConfigPanel' }, + ], + }, + ], +}; diff --git a/packages/app-framework/src/shared/schemas/shell/Sidebar.schema.ts b/packages/app-framework/src/shared/schemas/shell/Sidebar.schema.ts index 9a39d8c7..08b92540 100644 --- a/packages/app-framework/src/shared/schemas/shell/Sidebar.schema.ts +++ b/packages/app-framework/src/shared/schemas/shell/Sidebar.schema.ts @@ -71,6 +71,18 @@ export const sidebar: SchemaNode = { ], }, + // AI Assistant + { + id: 'ai-assistant', + icon: 'sparkle', + label: 'AI Assistant', + active: { $eq: [{ $store: 'templateStore.activeShellView' }, 'ai-assistant'] }, + onClick: [ + { $action: 'appStore.deactivateApp' }, + { $action: 'templateStore.openShellView', args: ['ai-assistant'] }, + ], + }, + // Spaces { type: 'group', diff --git a/packages/app-framework/src/shared/schemas/shell/index.ts b/packages/app-framework/src/shared/schemas/shell/index.ts index 416e8324..3fc9576b 100644 --- a/packages/app-framework/src/shared/schemas/shell/index.ts +++ b/packages/app-framework/src/shared/schemas/shell/index.ts @@ -1,3 +1,4 @@ +export { aiAssistantTemplate } from './AiAssistant.schema'; export { bootScreen } from './BootScreen.schema'; export { templateEditor } from './TemplateEditor.schema'; export { landingPageTemplate } from './about'; diff --git a/packages/app-framework/src/shared/sdnaModels.ts b/packages/app-framework/src/shared/sdnaModels.ts index 05fdd4fb..d86b9a90 100644 --- a/packages/app-framework/src/shared/sdnaModels.ts +++ b/packages/app-framework/src/shared/sdnaModels.ts @@ -1,6 +1,7 @@ import { Ad4mModel, type LinkExpression, LinkQuery, Literal, PerspectiveProxy } from '@coasys/ad4m'; import { AgentSettings, + Assistant, AudioBlock, CalloutBlock, ChatMessage, @@ -14,8 +15,12 @@ import { ImageBlock, LinkBlock, LocationBlock, + McpServer, + Message, + Personality, Signal, SignalType, + Skill, Space, SpaceTemplatePreference, TagBlock, @@ -23,6 +28,7 @@ import { Template, TextBlock, Theme, + Thread, VideoBlock, WeNode, } from '@we/models'; @@ -40,6 +46,16 @@ export const ROOT_MODELS = [ Template, Theme, LocationBlock, + // AI assistant configuration (personal): reusable assistants and the + // personalities / skills / MCP servers granted to them. + Assistant, + Personality, + Skill, + McpServer, + // Threads + messages so a personal (non-shared) perspective can also host + // assistant conversations, not only shared neighbourhoods. + Thread, + Message, ] as const; export function getModelTargetClass(m: typeof Ad4mModel): string | undefined { @@ -146,6 +162,9 @@ export const SPACE_MODELS = [ TaskBlock, TextBlock, VideoBlock, + // Assistant conversations live in the neighbourhood they were created in. + Thread, + Message, ] as const; /** diff --git a/packages/models/src/entities/Assistant.ts b/packages/models/src/entities/Assistant.ts new file mode 100644 index 00000000..a68326e4 --- /dev/null +++ b/packages/models/src/entities/Assistant.ts @@ -0,0 +1,43 @@ +import { Flag, Model, Property } from '@coasys/ad4m'; + +import { WeNode } from '../WeNode'; + +/** + * An AI assistant configuration. Lives in the personal (we-root) perspective and + * is referenced by `Thread.assistantId` when a conversation is opened with it. + * + * `personalityIds`, `skillIds` and `mcpServerIds` are JSON-encoded `string[]`s of + * the ids of the granted {@link Personality} / {@link Skill} / {@link McpServer} + * records (all in the same perspective). JSON arrays — rather than AD4M HasMany + * link relations — keep the grant set a single atomic property that any backend + * can read/write in one write, mirroring how `AgentSettings.perspectiveOrder` + * stores an id list. Use the empty string or `"[]"` for "none". + */ +@Model({ name: 'Assistant' }) +export class Assistant extends WeNode { + @Flag({ through: 'we://flag', value: 'we://assistant' }) + flag: string = ''; + + @Property({ through: 'we://name' }) + name: string = ''; + + /** Model identifier the assistant runs on (e.g. an id from the backend's /v1/models). */ + @Property({ through: 'we://model_id' }) + modelId: string = ''; + + /** Optional base system prompt, prepended ahead of any granted personalities. */ + @Property({ through: 'we://system_prompt' }) + systemPrompt: string = ''; + + /** JSON-encoded string[] of granted Personality ids. */ + @Property({ through: 'we://personality_ids' }) + personalityIds: string = ''; + + /** JSON-encoded string[] of granted Skill ids. */ + @Property({ through: 'we://skill_ids' }) + skillIds: string = ''; + + /** JSON-encoded string[] of granted McpServer ids. */ + @Property({ through: 'we://mcp_server_ids' }) + mcpServerIds: string = ''; +} diff --git a/packages/models/src/entities/McpServer.ts b/packages/models/src/entities/McpServer.ts new file mode 100644 index 00000000..ba43906f --- /dev/null +++ b/packages/models/src/entities/McpServer.ts @@ -0,0 +1,35 @@ +import { Flag, Model, Property } from '@coasys/ad4m'; + +import { WeNode } from '../WeNode'; + +/** + * An MCP (Model Context Protocol) server an AI assistant can be granted access + * to. The AD4M backend is responsible for connecting to it; this record only + * stores the connection descriptor. + * + * `transport` is one of 'stdio' | 'sse' | 'http' | 'websocket'. + * `url` is used for network transports (sse/http/websocket); `command` for + * 'stdio'. `auth` holds an optional JSON-encoded auth descriptor (e.g. a bearer + * token or header map) — kept as an opaque string so the shape stays open. + * Lives in the personal (we-root) perspective. + */ +@Model({ name: 'McpServer' }) +export class McpServer extends WeNode { + @Flag({ through: 'we://flag', value: 'we://mcp_server' }) + flag: string = ''; + + @Property({ through: 'we://name' }) + name: string = ''; + + @Property({ through: 'we://transport' }) + transport: string = 'stdio'; + + @Property({ through: 'we://url' }) + url: string = ''; + + @Property({ through: 'we://command' }) + command: string = ''; + + @Property({ through: 'we://auth' }) + auth: string = ''; +} diff --git a/packages/models/src/entities/Message.ts b/packages/models/src/entities/Message.ts new file mode 100644 index 00000000..c98cd7b4 --- /dev/null +++ b/packages/models/src/entities/Message.ts @@ -0,0 +1,46 @@ +import { Flag, Model, Property } from '@coasys/ad4m'; + +import { WeNode } from '../WeNode'; + +/** + * A single message in an assistant {@link Thread}. Belongs to the same + * (neighbourhood) perspective as its thread. + * + * `threadId` is the canonical join back to the owning Thread and is what the UI + * queries on — every message MUST carry it. The Thread also links messages via a + * HasMany relation for ORM navigation, but `threadId` is the source of truth for + * "which thread is this in", so a backend only needs to set this one scalar. + * + * `role` is 'user' | 'assistant' | 'tool' | 'system'. + * `toolCalls` is an optional JSON-encoded array describing tool invocations/results + * (see the AssistantStore doc for the shape the UI renders). + * `ts` is an ISO-8601 timestamp (lexicographically sortable → chronological order). + * `status` is '' | 'streaming' | 'complete' | 'error'. While an assistant reply is + * being produced the backend sets 'streaming' and appends to `content`; the UI + * subscription re-renders on each update, giving a live token stream. The backend + * flips it to 'complete' when done. + */ +@Model({ name: 'Message' }) +export class Message extends WeNode { + @Flag({ through: 'we://flag', value: 'we://message' }) + flag: string = ''; + + @Property({ through: 'we://thread_id' }) + threadId: string = ''; + + @Property({ through: 'we://role' }) + role: string = ''; + + @Property({ through: 'we://content' }) + content: string = ''; + + /** Optional JSON-encoded array of tool invocations/results. */ + @Property({ through: 'we://tool_calls' }) + toolCalls: string = ''; + + @Property({ through: 'we://ts' }) + ts: string = ''; + + @Property({ through: 'we://status' }) + status: string = ''; +} diff --git a/packages/models/src/entities/Personality.ts b/packages/models/src/entities/Personality.ts new file mode 100644 index 00000000..33d7ea6a --- /dev/null +++ b/packages/models/src/entities/Personality.ts @@ -0,0 +1,20 @@ +import { Flag, Model, Property } from '@coasys/ad4m'; + +import { WeNode } from '../WeNode'; + +/** + * A reusable personality an AI assistant can adopt — a named block of guidance + * text merged into the assistant's system prompt. Lives in the personal + * (we-root) perspective and can be granted to any assistant. + */ +@Model({ name: 'Personality' }) +export class Personality extends WeNode { + @Flag({ through: 'we://flag', value: 'we://personality' }) + flag: string = ''; + + @Property({ through: 'we://name' }) + name: string = ''; + + @Property({ through: 'we://body' }) + body: string = ''; +} diff --git a/packages/models/src/entities/Skill.ts b/packages/models/src/entities/Skill.ts new file mode 100644 index 00000000..09a10da1 --- /dev/null +++ b/packages/models/src/entities/Skill.ts @@ -0,0 +1,23 @@ +import { Flag, Model, Property } from '@coasys/ad4m'; + +import { WeNode } from '../WeNode'; + +/** + * A named capability an AI assistant can be granted. `body` holds the skill's + * instructions/definition (interpreted by the AD4M backend); `description` is a + * short human summary. Lives in the personal (we-root) perspective. + */ +@Model({ name: 'Skill' }) +export class Skill extends WeNode { + @Flag({ through: 'we://flag', value: 'we://skill' }) + flag: string = ''; + + @Property({ through: 'we://name' }) + name: string = ''; + + @Property({ through: 'we://description' }) + description: string = ''; + + @Property({ through: 'we://body' }) + body: string = ''; +} diff --git a/packages/models/src/entities/Thread.ts b/packages/models/src/entities/Thread.ts new file mode 100644 index 00000000..de6b23dc --- /dev/null +++ b/packages/models/src/entities/Thread.ts @@ -0,0 +1,41 @@ +import { Flag, HasMany, HasManyMethods, Model, Property } from '@coasys/ad4m'; + +import { WeNode } from '../WeNode'; +import { Message } from './Message'; + +/** + * An assistant conversation. Belongs to a neighbourhood perspective — the space + * it was created in — so a neighbourhood can hold many threads. `assistantId` + * references an {@link Assistant} in the personal (we-root) perspective; + * `modelId` is an optional per-thread model override (falls back to the + * assistant's `modelId` when empty). + * + * Messages are queried by `Message.threadId` (the canonical join); the HasMany + * relation here exists for ORM navigation and parent-linked creation. + */ +@Model({ name: 'Thread' }) +export class Thread extends WeNode { + @Flag({ through: 'we://flag', value: 'we://thread' }) + flag: string = ''; + + @Property({ through: 'we://title' }) + title: string = ''; + + @Property({ through: 'we://assistant_id' }) + assistantId: string = ''; + + /** Optional per-thread model override; empty → use the assistant's modelId. */ + @Property({ through: 'we://model_id' }) + modelId: string = ''; + + @Property({ through: 'we://created_at' }) + createdAt: string = ''; + + @Property({ through: 'we://updated_at' }) + updatedAt: string = ''; + + @HasMany(() => Message, { through: 'we://message' }) + messages: Message[] = []; +} + +export interface Thread extends HasManyMethods<'messages'> {} diff --git a/packages/models/src/entities/index.ts b/packages/models/src/entities/index.ts index 2d78e883..8cb81d0a 100644 --- a/packages/models/src/entities/index.ts +++ b/packages/models/src/entities/index.ts @@ -1,7 +1,13 @@ export { AgentSettings } from './AgentSettings'; +export { Assistant } from './Assistant'; export { ChatMessage } from './ChatMessage'; export { ChatSession } from './ChatSession'; +export { McpServer } from './McpServer'; +export { Message } from './Message'; +export { Personality } from './Personality'; export { Signal } from './Signal'; +export { Skill } from './Skill'; +export { Thread } from './Thread'; export { SignalType } from './SignalType'; export type { SignalMode, SignalAggregate, SignalSemantic } from './SignalType'; export { Space } from './Space'; diff --git a/packages/models/src/index.ts b/packages/models/src/index.ts index d3a83668..2875d8cb 100644 --- a/packages/models/src/index.ts +++ b/packages/models/src/index.ts @@ -1,14 +1,20 @@ export { WeNode } from './WeNode'; export { AgentSettings, + Assistant, ChatMessage, ChatSession, + McpServer, + Message, + Personality, Signal, SignalType, + Skill, Space, SpaceTemplatePreference, Template, Theme, + Thread, } from './entities'; export type { ThemeData } from './entities/Theme'; export { modelToThemeData } from './entities/Theme'; From 73caf23db78395fc4c18a4b8bd33167ddf054f6a Mon Sep 17 00:00:00 2001 From: Josh Field <10372036+HexaField@users.noreply.github.com> Date: Tue, 28 Jul 2026 22:25:21 +1000 Subject: [PATCH 2/3] test(assistant): component tests + screenshots for the assistant UI Vitest + @solidjs/testing-library component tests (30) for the assistant surface: message roles + the collapsible tool-call block (Arguments/Result), thread view + model selector + composer, thread list, config panel tabs (Assistants/Personalities/Skills/MCP) + grant toggles, and AssistantStore helpers. Adds a scoped vitest 'dom' project (single solid-js instance, jsdom); exports AssistantContext + data-testids for testability; guards scrollIntoView for jsdom. Verified by rendering the real components in headless Electron (surface, expanded tool-call, config tabs all render valid + styled). Full app-framework suite: 92 tests pass; we-web Vite build green; tsc 0 errors in the assistant code. Co-Authored-By: Claude Opus 4.8 --- packages/app-framework/package.json | 3 + .../assistant/AssistantConfigPanel.tsx | 2 + .../components/assistant/AssistantMessage.tsx | 6 +- .../assistant/AssistantThreadList.tsx | 4 +- .../assistant/AssistantThreadView.tsx | 10 +- .../solid/stores/AssistantStore.tsx | 7 +- .../assistant/AssistantConfigPanel.test.tsx | 83 +++++++++ .../tests/assistant/AssistantMessage.test.tsx | 79 ++++++++ .../assistant/AssistantStore.helpers.test.ts | 45 +++++ .../assistant/AssistantThreadList.test.tsx | 49 +++++ .../assistant/AssistantThreadView.test.tsx | 70 ++++++++ .../tests/assistant/mockStore.ts | 170 ++++++++++++++++++ packages/app-framework/vitest.config.ts | 46 ++++- pnpm-lock.yaml | 26 +++ 14 files changed, 591 insertions(+), 9 deletions(-) create mode 100644 packages/app-framework/tests/assistant/AssistantConfigPanel.test.tsx create mode 100644 packages/app-framework/tests/assistant/AssistantMessage.test.tsx create mode 100644 packages/app-framework/tests/assistant/AssistantStore.helpers.test.ts create mode 100644 packages/app-framework/tests/assistant/AssistantThreadList.test.tsx create mode 100644 packages/app-framework/tests/assistant/AssistantThreadView.test.tsx create mode 100644 packages/app-framework/tests/assistant/mockStore.ts diff --git a/packages/app-framework/package.json b/packages/app-framework/package.json index e07bd96d..329076af 100644 --- a/packages/app-framework/package.json +++ b/packages/app-framework/package.json @@ -56,11 +56,14 @@ "zod": "^4.1.11" }, "devDependencies": { + "@solidjs/testing-library": "^0.8.10", "@types/node": "^22.10.2", "@types/three": "^0.176.0", "@vitest/coverage-v8": "^4.0.15", "@we/cli": "workspace:*", + "happy-dom": "^20.10.6", "tsup": "^8.5.1", + "vite-plugin-solid": "^2.11.12", "vitest": "^4.0.15" } } diff --git a/packages/app-framework/src/frameworks/solid/components/assistant/AssistantConfigPanel.tsx b/packages/app-framework/src/frameworks/solid/components/assistant/AssistantConfigPanel.tsx index 663e0daa..6ca427fa 100644 --- a/packages/app-framework/src/frameworks/solid/components/assistant/AssistantConfigPanel.tsx +++ b/packages/app-framework/src/frameworks/solid/components/assistant/AssistantConfigPanel.tsx @@ -25,6 +25,7 @@ export function AssistantConfigPanel() { return ( {(t) => ( - + Arguments diff --git a/packages/app-framework/src/frameworks/solid/components/assistant/AssistantThreadList.tsx b/packages/app-framework/src/frameworks/solid/components/assistant/AssistantThreadList.tsx index fc92b013..fb0c6167 100644 --- a/packages/app-framework/src/frameworks/solid/components/assistant/AssistantThreadList.tsx +++ b/packages/app-framework/src/frameworks/solid/components/assistant/AssistantThreadList.tsx @@ -18,6 +18,7 @@ export function AssistantThreadList() { return ( - + @@ -64,6 +65,7 @@ export function AssistantThreadList() { const active = () => thread.id === store.activeThreadId(); return ( { void store.messages().length; void store.messages().find((m) => m.status === 'streaming')?.content; - requestAnimationFrame(() => endRef?.scrollIntoView({ behavior: 'smooth' })); + // Optional call — scrollIntoView is unavailable in some environments (e.g. jsdom under test). + requestAnimationFrame(() => endRef?.scrollIntoView?.({ behavior: 'smooth' })); }); function handleSend() { @@ -39,7 +40,7 @@ export function AssistantThreadView() { + No conversation selected @@ -51,7 +52,7 @@ export function AssistantThreadView() { } > {(thread) => ( - + {/* Header */} - + diff --git a/packages/app-framework/src/frameworks/solid/stores/AssistantStore.tsx b/packages/app-framework/src/frameworks/solid/stores/AssistantStore.tsx index 16890a11..dd5f7257 100644 --- a/packages/app-framework/src/frameworks/solid/stores/AssistantStore.tsx +++ b/packages/app-framework/src/frameworks/solid/stores/AssistantStore.tsx @@ -136,7 +136,12 @@ export function parseToolCalls(json: string | undefined): ToolCall[] { } } -const AssistantContext = createContext(); +/** + * Exported so tests and standalone harnesses can render assistant components with a mock + * store injected directly (``), without the full + * AD4M provider chain. + */ +export const AssistantContext = createContext(); export function AssistantStoreProvider(props: ParentProps) { const adamStore = useAdamStore(); diff --git a/packages/app-framework/tests/assistant/AssistantConfigPanel.test.tsx b/packages/app-framework/tests/assistant/AssistantConfigPanel.test.tsx new file mode 100644 index 00000000..ced39740 --- /dev/null +++ b/packages/app-framework/tests/assistant/AssistantConfigPanel.test.tsx @@ -0,0 +1,83 @@ +// @vitest-environment jsdom +import { AssistantContext } from '@solid/stores/AssistantStore'; +import { AssistantConfigPanel } from '@solid/components/assistant/AssistantConfigPanel'; +import { cleanup, render, screen } from '@solidjs/testing-library'; +import type { JSX } from 'solid-js'; +import { afterEach, describe, expect, it } from 'vitest'; + +import { makeMockStore } from './mockStore'; + +afterEach(cleanup); + +function renderPanel(store = makeMockStore()) { + return render(() => ( + + {() as JSX.Element} + + )); +} + +describe('AssistantConfigPanel', () => { + it('renders the four config tabs', () => { + renderPanel(); + for (const id of ['assistants', 'personalities', 'skills', 'mcp']) { + expect(screen.getByTestId(`config-tab-${id}`)).toBeTruthy(); + } + }); + + it('shows the assistant editor with model + grant groups on the default tab', () => { + const { container } = renderPanel(); + // Assistant picker lists both assistants. + const options = Array.from(container.querySelectorAll('select option')).map((o) => o.textContent); + expect(options).toContain('Research Assistant'); + expect(options).toContain('Coding Assistant'); + // All three grant groups render, each listing its grantable items by name. + expect(screen.getByText('MCP servers')).toBeTruthy(); // unique heading (tab label is "MCP") + expect(screen.getByText('Friendly')).toBeTruthy(); // personality grant row + expect(screen.getByText('web-search')).toBeTruthy(); // skill grant row + expect(screen.getByText('filesystem')).toBeTruthy(); // mcp server grant row + }); + + it('toggles a personality grant on the active assistant', () => { + const store = makeMockStore(); + renderPanel(store); + // The Friendly personality appears as a grantable row in the assistant editor. + (screen.getByText('Friendly') as HTMLElement).click(); + expect(store.toggleGrant).toHaveBeenCalledWith('a1', 'personalityIds', 'p1'); + }); + + it('switches to the Personalities tab and lists personalities', () => { + renderPanel(); + (screen.getByTestId('config-tab-personalities') as HTMLElement).click(); + expect(screen.getByText('Terse')).toBeTruthy(); + // Body preview text from the fixture. + expect(screen.getByText('Minimal words. No filler.')).toBeTruthy(); + }); + + it('switches to the Skills tab and lists skills', () => { + renderPanel(); + (screen.getByTestId('config-tab-skills') as HTMLElement).click(); + expect(screen.getByText('web-search')).toBeTruthy(); + expect(screen.getByText('calculator')).toBeTruthy(); + }); + + it('switches to the MCP tab and lists servers with a transport control', () => { + const { container } = renderPanel(); + (screen.getByTestId('config-tab-mcp') as HTMLElement).click(); + expect(screen.getByText('filesystem')).toBeTruthy(); + // Transport is present in the header. + expect(container.querySelector('select')).toBeTruthy(); + }); + + it('lists the discovered models in the per-thread override selector', () => { + const { container } = renderView(); + const options = Array.from(container.querySelectorAll('select option')).map((o) => o.textContent); + expect(options.some((t) => t?.includes('llama-3.1-8b'))).toBe(true); + expect(options.some((t) => t?.includes('qwen2.5-coder'))).toBe(true); + }); + + it('writes a user message when the composer is submitted', () => { + const store = makeMockStore(); + renderView(store); + const input = screen.getByTestId('composer-input'); + input.dispatchEvent(new CustomEvent('input', { detail: 'What is the forecast?', bubbles: true })); + (screen.getByTestId('composer-send') as HTMLElement).click(); + expect(store.sendMessage).toHaveBeenCalledWith('What is the forecast?'); + }); + + it('shows a placeholder when no thread is selected', () => { + const store = makeMockStore({ activeThread: () => null, activeThreadId: () => null }); + renderView(store); + expect(screen.getByTestId('thread-view-empty')).toBeTruthy(); + expect(screen.getByText('No conversation selected')).toBeTruthy(); + }); + + it('renders a streaming assistant message with a live indicator', () => { + const streaming = [ + sampleMessages[0], + { ...sampleMessages[3], id: 'sm', content: 'Working on it', status: 'streaming' }, + ]; + const store = makeMockStore({ + messages: () => streaming as typeof sampleMessages, + streamingMessageId: () => 'sm', + }); + renderView(store); + expect(screen.getByText('streaming…')).toBeTruthy(); + }); +}); diff --git a/packages/app-framework/tests/assistant/mockStore.ts b/packages/app-framework/tests/assistant/mockStore.ts new file mode 100644 index 00000000..78a41c77 --- /dev/null +++ b/packages/app-framework/tests/assistant/mockStore.ts @@ -0,0 +1,170 @@ +/** + * Shared mock AssistantStore + representative fixtures for the assistant-component tests + * and the screenshot harness. Plain objects cast to the model types — the components only + * read fields, so no real AD4M perspective/instances are needed. + */ +import type { AssistantStore } from '@solid/stores/AssistantStore'; +import { parseIdList } from '@solid/stores/AssistantStore'; +import type { Assistant, McpServer, Message, Personality, Skill, Thread } from '@we/models'; +import { vi } from 'vitest'; + +function model(o: Record): T { + return o as unknown as T; +} + +export const sampleThreads: Thread[] = [ + model({ + id: 't1', + title: 'Weather in Melbourne', + assistantId: 'a1', + modelId: '', + createdAt: '2026-07-28T01:00:00.000Z', + updatedAt: '2026-07-28T02:00:00.000Z', + }), + model({ + id: 't2', + title: 'Refactor ideas', + assistantId: 'a2', + modelId: 'qwen2.5-coder', + createdAt: '2026-07-27T01:00:00.000Z', + updatedAt: '2026-07-27T05:00:00.000Z', + }), +]; + +export const toolCallsJson = JSON.stringify([ + { + id: 'call_1', + name: 'get_weather', + input: { city: 'Melbourne', units: 'metric' }, + result: { tempC: 14, sky: 'cloudy', wind: '12 km/h' }, + status: 'complete', + }, +]); + +export const sampleMessages: Message[] = [ + model({ + id: 'm1', + threadId: 't1', + role: 'user', + content: 'What is the weather in Melbourne right now?', + toolCalls: '', + ts: '2026-07-28T02:00:01.000Z', + status: 'complete', + }), + model({ + id: 'm2', + threadId: 't1', + role: 'assistant', + content: 'Let me check the current conditions for you.', + toolCalls: toolCallsJson, + ts: '2026-07-28T02:00:02.000Z', + status: 'complete', + }), + model({ + id: 'm3', + threadId: 't1', + role: 'tool', + content: '{\n "tempC": 14,\n "sky": "cloudy",\n "wind": "12 km/h"\n}', + toolCalls: '', + ts: '2026-07-28T02:00:03.000Z', + status: 'complete', + }), + model({ + id: 'm4', + threadId: 't1', + role: 'assistant', + content: 'It is currently **14°C and cloudy** in Melbourne, with wind around 12 km/h.', + toolCalls: '', + ts: '2026-07-28T02:00:04.000Z', + status: 'complete', + }), +]; + +export const sampleAssistants: Assistant[] = [ + model({ + id: 'a1', + name: 'Research Assistant', + modelId: 'llama-3.1-8b', + systemPrompt: 'Answer concisely and cite sources.', + personalityIds: JSON.stringify(['p1']), + skillIds: JSON.stringify(['s1']), + mcpServerIds: JSON.stringify(['mcp1']), + }), + model({ + id: 'a2', + name: 'Coding Assistant', + modelId: 'qwen2.5-coder', + systemPrompt: '', + personalityIds: '[]', + skillIds: '[]', + mcpServerIds: '[]', + }), +]; + +export const samplePersonalities: Personality[] = [ + model({ id: 'p1', name: 'Friendly', body: 'Warm, encouraging, plain language.' }), + model({ id: 'p2', name: 'Terse', body: 'Minimal words. No filler.' }), +]; + +export const sampleSkills: Skill[] = [ + model({ id: 's1', name: 'web-search', description: 'Search the web for current info', body: '...' }), + model({ id: 's2', name: 'calculator', description: 'Evaluate arithmetic', body: '...' }), +]; + +export const sampleMcpServers: McpServer[] = [ + model({ + id: 'mcp1', + name: 'filesystem', + transport: 'stdio', + url: '', + command: 'npx -y @modelcontextprotocol/server-filesystem', + auth: '', + }), +]; + +export const sampleModels = ['llama-3.1-8b', 'qwen2.5-coder', 'gpt-oss-20b']; + +/** Build a mock AssistantStore. All accessors return fixtures; all actions are spies. */ +export function makeMockStore(overrides: Partial = {}): AssistantStore { + const base: AssistantStore = { + threads: () => sampleThreads, + activeThreadId: () => 't1', + activeThread: () => sampleThreads[0], + selectThread: vi.fn(), + createThread: vi.fn(async () => 't-new'), + deleteThread: vi.fn(async () => {}), + renameThread: vi.fn(async () => {}), + setThreadModel: vi.fn(async () => {}), + + messages: () => sampleMessages, + streamingMessageId: () => null, + sendMessage: vi.fn(async () => {}), + + assistants: () => sampleAssistants, + activeAssistant: () => sampleAssistants[0], + createAssistant: vi.fn(async () => 'a-new'), + updateAssistant: vi.fn(async () => {}), + deleteAssistant: vi.fn(async () => {}), + toggleGrant: vi.fn(async () => {}), + assistantHasGrant: (assistant, field, itemId) => parseIdList(assistant[field]).includes(itemId), + + personalities: () => samplePersonalities, + createPersonality: vi.fn(async () => {}), + updatePersonality: vi.fn(async () => {}), + deletePersonality: vi.fn(async () => {}), + + skills: () => sampleSkills, + createSkill: vi.fn(async () => {}), + updateSkill: vi.fn(async () => {}), + deleteSkill: vi.fn(async () => {}), + + mcpServers: () => sampleMcpServers, + createMcpServer: vi.fn(async () => {}), + updateMcpServer: vi.fn(async () => {}), + deleteMcpServer: vi.fn(async () => {}), + + models: () => sampleModels, + refreshModels: vi.fn(async () => {}), + }; + return { ...base, ...overrides }; +} diff --git a/packages/app-framework/vitest.config.ts b/packages/app-framework/vitest.config.ts index 71ae0dc1..031bd4b8 100644 --- a/packages/app-framework/vitest.config.ts +++ b/packages/app-framework/vitest.config.ts @@ -1,9 +1,51 @@ +import { fileURLToPath } from 'node:url'; + +import solidPlugin from 'vite-plugin-solid'; import { defineConfig } from 'vitest/config'; +const r = (p: string) => fileURLToPath(new URL(p, import.meta.url)); + export default defineConfig({ test: { - globals: true, - include: ['tests/**/*.test.{ts,tsx}'], + // Two projects so the DOM/Solid setup needed to render components (browser resolve + // conditions, jsdom, the solid-js transform) is scoped to the assistant component tests + // and never touches the existing node/logic tests — whose seed code imports Node built-ins + // that the `browser` condition would otherwise externalize. + projects: [ + { + // Existing logic/seed tests — node resolution, no DOM. + test: { + name: 'node', + globals: true, + include: ['tests/**/*.test.{ts,tsx}'], + exclude: ['tests/assistant/**', '**/node_modules/**'], + }, + }, + { + // Assistant component tests — real Solid rendering in jsdom. + plugins: [solidPlugin()], + resolve: { + conditions: ['development', 'browser'], + // A single solid-js instance across the test-transformed source and the prebuilt + // design-system dist — otherwise Solid event delegation and reactive context break. + dedupe: ['solid-js', 'solid-js/web', 'solid-js/store'], + alias: { + '@shared': r('./src/shared'), + '@solid': r('./src/frameworks/solid'), + }, + }, + test: { + name: 'dom', + globals: true, + environment: 'jsdom', + include: ['tests/assistant/**/*.test.{ts,tsx}'], + // Transform the prebuilt @we/* + solid packages through vite (rather than loading them + // as external node deps) so they resolve the same deduped solid-js instance as the + // test-compiled source. + server: { deps: { inline: [/@we\//, /solid-js/, /@solidjs\//] } }, + }, + }, + ], coverage: { provider: 'v8', reporter: ['text', 'lcov'], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bc38554a..84b2b56f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -478,6 +478,9 @@ importers: specifier: ^4.1.11 version: 4.4.3 devDependencies: + '@solidjs/testing-library': + specifier: ^0.8.10 + version: 0.8.10(@solidjs/router@0.15.4(solid-js@1.9.14))(solid-js@1.9.14) '@types/node': specifier: ^22.10.2 version: 22.20.0 @@ -490,9 +493,15 @@ importers: '@we/cli': specifier: workspace:* version: link:../cli + happy-dom: + specifier: ^20.10.6 + version: 20.10.6 tsup: specifier: ^8.5.1 version: 8.5.1(postcss@8.5.16)(tsx@4.23.0)(typescript@5.9.3)(yaml@2.9.0) + vite-plugin-solid: + specifier: ^2.11.12 + version: 2.11.12(solid-js@1.9.14)(vite@7.3.6(@types/node@22.20.0)(sass@1.101.0)(tsx@4.23.0)(yaml@2.9.0)) vitest: specifier: ^4.0.15 version: 4.1.10(@types/node@22.20.0)(@vitest/coverage-v8@4.1.10)(happy-dom@20.10.6)(jsdom@27.4.0)(vite@7.3.6(@types/node@22.20.0)(sass@1.101.0)(tsx@4.23.0)(yaml@2.9.0)) @@ -11794,6 +11803,19 @@ snapshots: transitivePeerDependencies: - supports-color + vite-plugin-solid@2.11.12(solid-js@1.9.14)(vite@7.3.6(@types/node@22.20.0)(sass@1.101.0)(tsx@4.23.0)(yaml@2.9.0)): + dependencies: + '@babel/core': 7.29.7 + '@types/babel__core': 7.20.5 + babel-preset-solid: 1.9.12(@babel/core@7.29.7)(solid-js@1.9.14) + merge-anything: 5.1.7 + solid-js: 1.9.14 + solid-refresh: 0.6.3(solid-js@1.9.14) + vite: 7.3.6(@types/node@22.20.0)(sass@1.101.0)(tsx@4.23.0)(yaml@2.9.0) + vitefu: 1.1.3(vite@7.3.6(@types/node@22.20.0)(sass@1.101.0)(tsx@4.23.0)(yaml@2.9.0)) + transitivePeerDependencies: + - supports-color + vite-plugin-solid@2.11.12(solid-js@1.9.14)(vite@7.3.6(@types/node@24.13.2)(sass@1.101.0)(tsx@4.23.0)(yaml@2.9.0)): dependencies: '@babel/core': 7.29.7 @@ -11883,6 +11905,10 @@ snapshots: optionalDependencies: vite: 6.4.3(@types/node@24.13.2)(sass@1.101.0)(tsx@4.23.0)(yaml@2.9.0) + vitefu@1.1.3(vite@7.3.6(@types/node@22.20.0)(sass@1.101.0)(tsx@4.23.0)(yaml@2.9.0)): + optionalDependencies: + vite: 7.3.6(@types/node@22.20.0)(sass@1.101.0)(tsx@4.23.0)(yaml@2.9.0) + vitefu@1.1.3(vite@7.3.6(@types/node@24.13.2)(sass@1.101.0)(tsx@4.23.0)(yaml@2.9.0)): optionalDependencies: vite: 7.3.6(@types/node@24.13.2)(sass@1.101.0)(tsx@4.23.0)(yaml@2.9.0) From cbfcc91f89ffc095715dc32fee95e96b745da21d Mon Sep 17 00:00:00 2001 From: Josh Field <10372036+HexaField@users.noreply.github.com> Date: Tue, 28 Jul 2026 22:28:18 +1000 Subject: [PATCH 3/3] docs(assistant): UI screenshots for the PR Headless-Electron renders of the assistant surface: full three-pane view, expanded tool-call block, and config panel tabs. Co-Authored-By: Claude Opus 4.8 --- docs/assistant-ui/config-mcp.png | Bin 0 -> 102436 bytes docs/assistant-ui/config-skills.png | Bin 0 -> 99913 bytes docs/assistant-ui/surface.png | Bin 0 -> 92780 bytes docs/assistant-ui/thread-tool-open.png | Bin 0 -> 103296 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/assistant-ui/config-mcp.png create mode 100644 docs/assistant-ui/config-skills.png create mode 100644 docs/assistant-ui/surface.png create mode 100644 docs/assistant-ui/thread-tool-open.png diff --git a/docs/assistant-ui/config-mcp.png b/docs/assistant-ui/config-mcp.png new file mode 100644 index 0000000000000000000000000000000000000000..998c45d3be219d7b3eaa32011b74aced52af71ca GIT binary patch literal 102436 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 Rb$)h5Rar}^;`y7u{|CU!DLMcE literal 0 HcmV?d00001 diff --git a/docs/assistant-ui/config-skills.png b/docs/assistant-ui/config-skills.png new file mode 100644 index 0000000000000000000000000000000000000000..4dbd73f9e1d7814203cf823da278f7e5f466241e GIT binary patch literal 99913 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 z zkX(K4{2%6h7NI9{%d9t>7ogA3dXSG+j6s7~(fK+PADdaydx|(*2!u!k4z8ZBQJVjA zL9i}qPj$`QE^jk(2Xjw<4_RaQuL*yT`zJV<3Qo(oN!6>~+p_gu8wn+Rq|m1M=CZ3P zospa!bcP3ZuC@x$E1Ph9esyKOt3|6vpx!ZUT{D9a;7`)?dW%Z$jS%lt^^dLz7&}2i z>@sUEPF}$v^7+vdgM*Wjbf)=ia&Oc56nyq4p81Yr>_nF0Hr1fe@Ia)+v+TN>UD`v> z#Bj3V7pdqdI~^~}T9e64D1Zy!R!bh7?oncSVXc?!aMWGR=)CXWM4+7-N#vGB`Osv3 zl(r&w{X22pRVI}}Zn9bhqwtiLoV%l?cgg-YGQ|Hp6f`LY+@9@_@AMXUTq#Sa=D(Xy zFy_T7<^ND?ra+g`0s>4TM_|cZV4)yB`T$>YeWbx zUjy=s*y1H-^AuzdqY$8#eFBB@Jl_?+On|NR3@tEbiw4`Eyve7hh) zbNX*;_~jN&nMSpb09@#U%3ecxfrt%+KS!@6Ff|tO_SA(IA4P}>K_=2|bAKDWlY(=) zr4oKa1rR9y^Qd^_zdKott2>*xWUjlRf)MYbK()LX=WHw#Ga+o;{}Y2*YR7!R6g18^`dc1^Q5zK+)k<$0mNru(pnJLh z5>(A%X^Cf@_|E4!^M4%ZyD-)e7b_5ij*(2mI_nAe^zmlX!Z9bjqewu|3!*Css;hGz zNAQ0m!0>*iFxIV4wH`^>GHH@^=&4}>-PXG3=WbF>$ zL1Br*kH57>AZ%FAW`kA&lGO%^9-{(XP@&YvmEpZ){w=$HM%#stbf24njAzyG{gvYkawT zWdsL19khnoDVx1P#w9QsYJ2upPR_@Hi0oJHsd|FI;I!LM_eX^0X$App3>{`h*QMnd zK8V^SRaKkO?4VtM|8mHEMnoeMoP4>tnMz9Pnp5L%tSY1FS-iy6Ei(L7 z1Gy7^EJmT-?2U+hQQVu#N9@z43K{^5A%zBu0jI=&5I)B)QiQor4OXb37%^a!`#8}5 zX$720glnkQ9*%aGjP#}KM%cf-6aWS?ldibLye*Ss;pXh63iWrn*^InnX)&Lz#FbTG z-YRjp+m7Enh2Gadw(~##3qazbw5x5|%NXJhlDJhQ=3Yny)B|pY7>>nejW($Ky(b_f z*^r9i8|!~&G##NhzKucCWBk79I)Jw21(o@Arn~_O^tKVW8{KhK+J!sLka*6VgZ-b5 z`&+|;Ubfshb%yaf8*voz{a2hX1m3Qg5P`{A_qbF{#z6}wPu zD9e_Oth1@A#41(}MoL1*ViMWJn3TM_k@1-_O_&G?RZ^z#%e@KF*bb-J&yucElxH4N zg<=N#$>oX3`@@W6^U6ti=^eO=i^gs<9^@`jLBax?S`JEdwTtgYpMZRHybp#g_oHZJ zN*u7^r#6m{(|3)+rX%za|G5<1`Z!W?3v+B0tYSfffZ>gs@U*}dk;H@vYD$RtEp|5Kiq)gux#?a+I0Q`c68qN)-~)0%=%f6mb3 z?oJgEJJhMNQK#+Ac2rSEhu+60{m8vtr|`T{UoEHoiO1zdE$%li@TXWoBsa3^vsyhM zAT4UnmUMo(i-RLGiU3h|TZJUJW>l|exYHr#7PH`aafztyoS{&3g!g#>*PzEXAkj9uOc{qP9~D+WH$EvbiIiOvEhRf?K;r}sAR}c)6;Mh| zPShoC&}d!qNgv6c;ui6Zl`dEGR0vq!@b zpr<+1q#ZP#xMx&H14byQ#zVk~{~x-(GODhniSnQ!NN{&|2p%A~d+^}F-7UD2;10pv z-Q9w_L-62mad()Ty!XCY^JDIh%i_T5(^_4PyjHEk1L z^!JZsy-IX{U*%&TN7i}wen+KNW~NC1+XWX9awx}8DJ@G6YiloM<&mpKoOweQ@_>K5 zNP#5(i6O8`iS}Z1;X5E$2Ka_r$*;Lo7E?HUdRo&y*OXt&j&S=1bPXDN&vvwT0Gu+L zo0q~l(~h^+gR5@@^S;9NQOF%n*>&#S2vN~r#Kun3$MZ=OKa1vlYE4uoiID^|W3I}U z^-=z`aWriR^kT?q1m&BVx&B+LDuamU8f0@rxz{xwD=xL=H5FowKhpxL^LLgBBTBb% z-P8E*5+!GGPk?_d;zSHXSR5q`;3nmwG?Z&#&-sm5U`~rFcDal@9vfzQbJM@g zNnT0*p&upGR18rSnhAdf!4Ma(J+9BtavPjTRH#Pii@ zXuZ$Va0EQaV{0h-7X+kM${|BO6m`(_K8ppF4re7nbT2VGSsb09CmjJ!5CEbaQvI=s zX!$KCNOfj$jz{FH+}GENXGBZ?nC#2_+68aUGMjp2_u(`|c|G?HC+Cn#j}Kar+2J@W z2H^2bOf&)Sr8~~9rqp{r`r`k{wX=PAq&TT1-t`vS2dS!VMhd)6ta%M^I9DJ8KG6&m z5K59b;^KnB$u-hth;KA$L=>%1RWPRLKVzP%Ud{7WVYUl^IkxZ0pz>g3#L85vAq|j1 zNkpKBIsFk~-qO5P^!BMrI2OFR_kQw}9e11X$hbA?a{DT=IX*G?3D*&%q@z47PLGdJ ziphduxd&r;o1tkb2mAH2=AsI2ZU544?SZ8Yo&2lC&=RrF87EmlRbAa-SD0=T3;+)U z1j@--Q_|BP0)rOwGv(YMX$OVa$lmxHEL+#rLq7rv*NG-MOAMT1Kt7!2>n!TRW#OE-xK7U*Dk$3fZ>JmakWQoF+XEOsdSST|= zW8s+ifnIp${$8BG(b6*DfY%mYXv)1sF{xz7ofk_mB)1&;le>{$^YxYadhe{)u2DJM z&s58D#PV|ftskyTnX^$zAh!>`MJVnQsEhIlg-(bIaU6OV#Mt+|0zR#t_ZPOv6cH~5 z`2%-T008g4mC&2Tr<)1~WaSl7uiqaz|30Jqvr&2Zf{4P1<2gCz1#D5ir;0K55WW-M z*CCIkC}Q`o3*W}!2wkB*ozhXz9WBNnrSazQY0+L7la{|M9MR?XIoPjsPV#QUC~mMn z9mLPI#YBDebkaK*{I}l}KCy!O3T^Kn*`l`R{rmjtqU2 z`w=4q*Digw?bi2P0D&P2*DgUpDPcEk;M;wxS@clHJMd*Ezd}#@HmcR!63^SQ`0#7t z&o2^@i%Y#+SI=t1wc&sehi|Ys{~Q)!3r}KjBp68p-Idc`WzV4F8sH)*$lXIj zAYj)mm4dtL=P}o$WKUO=#$=?ih51fdE7@R_)5qy491HDfMZ#;&CbsmsU=tW|A#vpl zE2>#UOeWv(e}{+P>uh78X4t=2j>P%nw2GW%A-*C;qJU&HPa_TR*_P9FbUHR;5wnFzXk8YM7&^gU>|H{w&Y2&kAIPxYFwMo1D^(Sqv1( zaDT}`0HQPEnb>ctV;}&tO+9#cMDEOZWk!nH@IsF=?ZzJ?X5|Oo27@P1iXq&dq{-Qq z$JI7*6VR|LNNEo{3PC{hehCqL)_vuE=Mx8*`ObfQ6ukOvyztU5+j6U(7`~$>T~(}6Luzapk$)*M>|!_QOoU7!uAMi zYWbl^lACuX6SObYn#+W-{`Cx}gtmMKTF2s@(BQPH{w>6nn%H`%rm3ufTi{wt-$=Nw z@rt{e{`3h_k_P|dYZIEsudtX7kHugCt;dopZ+O7>XEdgVL-=d`ZLht+R!3?YdJSLV z4t7RbiUYj?Cb|9b^y)!-8T@$FxrT}M*N;VvKoNf@b@;^fdG$UkTFGe<&)b>XO1R>N zMbG^x0R!a9+M-C!of@(RYn)m1H5abiEP{pwWYbFRx5#$>GL|bz8B9m5xaHHXmGI?_ zH;W!mRT5g8-?8i1roKvCUB{1ZZxPwKjD>EMW4@h%T>XfA-b|1D8WT@IxZl@Q+ig8} zU*eYr4enYz+}_PZuw0n*N*Dd@xfUepmG=QXtq5lWOYl`M0V%LeQ2^IG(}XcuS8cMR zEnfx+c)Po2Q!NOi1Jmzd&e<0T*S1)M;`)pZ0RGfdDPAgJsv z2^Y0dJ#B84g!U{tcU_mF`wjW49P9k-^fu39=AC|nticyaJOB`|Q26{@=Zl`IO>I`w z4_ad2xBC^gkw?7+}TG)LzheeEu9ln*A)N9{$%Q{bSM_bE7t7fEp~$mh0@0p!X0=l=F_y zO-8_Es!0!=!uFiUuNA3LeY=GNNI~auK5wrF8|<*G@qnOfVL5LO-$a%qXJ)gpBM$B- zcTxcEuvDnFgD9(zlphczvYp|6MhNJOMO9mXg8)5#fWZZD`dd<wnN+@D7uhD(dq*G!r=>Xx5AW7{A~-?DfnS)KhFvBuWZHgKtHOAdAzp886jZim~F% zT;4v0ZS+~3$P z6$+|9GWhE{7+d=Lw+VDfoB8B}WjUDX(rz2nJN|`aNdrGIKWM2*Po&Vt5n+LKNvkb} zKM)tcw%9-KL|@MJ6Nc%hGF+zW64p5xn+d;r_11SEjm)QqME9eF>Y6mFC81!{vL*JgcS#HQ<^P(@&h5RyOthdN9C# zhA?Rw{vM{S==JWKDsp)rt33Znc(0sHV_yOG*}W^ehl)?RRaY}T*sS&AfEzOzp0Ae(dqDRixV-ANMj+QoMl=vy90**-bf zRE#mUa!LD7WA_1;!Pt*l6ohR_T~89Qs-=t9x|d1{%sF+qP?CR8+bMR z)4KiiXfq4))97pTZ{J|N9$16|&FEdc*w`r4AQnIJ^n>ybCd#46PElfo7CN^tv_@!2#uV+Cc)ZJ@*ntfn0K4Id`jja3tQcDvlJvXTLdW8(aucB-Vv}sm3{lFXlBNO%2QP@RO zjQo?);*z#4c10w{O5~IGp*1N$u-bl10}R;D>5kYmcGS0JVh@a1FMpT;0B9Hii2=Q# z$}*@6oSVBKCYP0@mZaH>`J)#$WPoIp7Tq_e(Ydq~ytA{bn-Yg8G%2Z2=M3WhSh`}%FilNgHsVhS6-&P(F{FvsHcA&U^~0k0wAtRZ2J3qWdt!b1 zR%`|@mXrenwUF>ri0sJe67LB6Hl?U4&4*=Losh#p&+DnPla#yj7<0!n>bANy4$d-T^z#ZIDU!GnV^K-;fn!mM{lEjZ= zJs|-X+qqG^$9PPf{G~g+@V>!&-M+Xy*Do?dVORAdDg=9D1hmrSYSm=Nt*d6|>7}=B zyeab5)~4Y};#sO-O2v4((V=;XD9risSv!QB3w3+HGDH?P*Zbc|mRH53r3@OAJWppd z6Hbc|%Wk9w7JFJLGy^$8Q?)T{{vm?V1RU_MJdu-cEN6=pp&{A1koUFT{*yiPp-HmX zanX(}lbLmzOh{SnU1o)KX)Zif-E3V>0d4_?*=}KipI^KCW5o64QmehhFYSr@28OR+ zS#EBBD?`tB5+Z${w7b216~EwiVY>yCBe1aB6K*M96(J|8`WF{L_JE&{4y)i;YoTOI;yYsd3~YbT{WN z0HZacgH1z8PHaeVJtHKmQhRs!sF+4>eTK|g&QmxsI~M{Ku-M$J5n6B#mhMitA@h=$ z>$|MmhwE6QSkDKAeo9I}^Vz&pe91BPCV&@IR=b+eVx>_|*G{V45#3qbsP3#RHd|_) zEjtAh1K2SMxM#lb4cP?bLWaRU@oO%O3ZOkXqD8bCb<4h!(^l=}Me|}8Y_m!|D1BQT zOdr$fC`*0sPFsbuY6}UyD3pEfT)^hqT)RJpoJ&S-(7W<1LtU-;hVuGC9)Iw$?Y4?o zoRA-nXG=fsZUcxREE1ETFuF|5iM?pfM)krDMfTbfeFl(R9Ny=QC2LaCTr(lGVw%0oL zn}&9J`xgP*E4N8>j9vLnz6EB}l8U#t6e9o!{}of(QRgZ@tmZNW;#u|m3%{ibo(ZFr?zhm;31eyLFDLI_m2X?D7F@q_)EsS)F&Lks{g$Ztk4 zSvoAPO^#3U@M-f*pIz1IugwFWO&jX!a%RsiJW|oVcV(~-Z7-&uEjt5~c3d0U^|7Vp z@<~k6&th{zh*=h`){)7@p^!3SBWuPPl{Pa8O)C7r>>9UyYj>~lnuD@4mQG~3X|p|l zk_HBG23M9qI^M5lMwYp0#hBci#g?Vfz_88pmoTex)g6ojc-VqSe5;)rG$oH8L!Y0t zm&|ryJ-n1vDf^NNd})~nu}XQD52_ASc$6)NCQ>wkP>Qw0(k?isl85>5@k;?J4eunh9Uj5wAzk^mIE!v2^V%b&mW1k`MW;4P>gIHk zUH1$eE+%3M)rsU$l6l-~BnC56!6Ac52?Jl^8`O)rzbAsLewv!OWP3`D`mU1UF>Ab8wCNA3K6J&vx+S1FeAQ_66*KM7am zjho^MX(N+!NJ>Vn1wKF%VC_ATq7j-wI#I2x;=rUcC(aLlx$dWE#V zV2eEm6m}+S!%4%Itjf=79o~r{r&`KDLe{j#V{(OImH;j9t|0*uNsFokcX=xo4ZP^+ zc#R$oRT7Q`O5-y>{eF-q;h!$`_c6{!1zPrRQT+4M;*S}(aOD6)Y zL7XU!kWmUFpsuFlRNH1xA}h*uNlS=hN|h&8@h7uw)3fYqy4)wLY5jg<)3-(D#$SHt zti4F1N^AHb8dD9PrIJXkCj#KEiqr;TNF>I>rK>mId3X$1hf!6R)K(^3YpX#+;oS%;shJAN=`!X!e|noPPC1X2 zHuAgkqx)OnJ4n0X13g=^x;O`i5+sS;)o15>R|5wk*82L-V2o#TG9|Pmm8T@9rzdZF z#lXIEjMz>*yHdH$Sc&H(F23YMT{=}h040w$aCfOC5~f5HlhSQ7n_+OwfL_S$ZRR8qb%c_Z)7~)20%=M6 zqlX=ApUr{KxYZeNgYk2*Dw}n3z}<}X>*;02Pb#(T0_SGC1hAJ4P3Z+zl!;jrs)?QS zEyFmM@K7lMPK@Yy0<@&OGG*h(tl}Yu9p^vLO^i^4$yZ1^Y$nn=NKn`t`1!pqJQsBA zbZpE1;{tpW@rD8LJV~m7EG5l0P))CZ3c{#&{#=cG2kt_MRV}3^rpvZm!yXZ2*nqlVPS+uVYxHaw zYhLq*jD}{9%_z44>6B5O+OeX>N3Hpv`8Korf#})As&XWSWyW0VHsT883W!vTa*SaJ zPo3c=EqyP}F3bwp(|qq|xYzK}HphE2B8xHO_NA%fcJH-rJ|@E@l=qNspL6qAUph&e z+pAK}l+2bVEW=MmXm^rRJQ2J;Hrhv!`F|W3v`Je1s^&9R2wGyAiu_;?`V#&%94xyf z(wfb_Rc`YVrL-K$@DM}#KnI%TuE0w^@6NUdV<)XlHI6%V9V-~h*r(RvcV~g$6Xp!i zbcEI?oh!@b4{L-}_y&;J45O&T%R{hd5}ec02{fiq-9*eGEjOlvLaWaesgaMd(YJ9x z%HXUBgSfNM^w3ZU&n%6~MC^PU>pn_|fZeV1FrmV_aRuEoAz`M=&Fgf#qXqq?YCF>EZ`U`-V{Yj zN+1;Ts;g2#qYhjIoDu7bs03Vg%<;s!#UC1(cvkRTj}UcH1?dS7c;4Gv<1(L}VcI=S zxUQhq3|?h<{)^*;J}|QVSm$<2WmM0^t`i`SDWY?aYk%S#ouoqM>tBd%8PaF7z9oKn z@WL$VY;!mHk{E2;%aSCddw9fma|pf6Y{hkIZYrlKyGuQ;Jo`qSQbk)peK@(>E3A@7 zxE+7c^(V@LA@Ad1eiG5Y96xa)$OK`tvcVn9xmkWo3zXUOQsQ}kGKp)E(ZTSK6eY@M z5m({(2e@3*wmJ`edc3xKE$zuYgsPdthB-1vPiZhyEPVldDn2{RsQB)qg8-b84>yWB z&%PNE1(856J@J)3-1X_~5E}H8U8FozH6fJ6~8&T7@zM`>Qmlw9jX5JgbeohW3^8GUhvjZH?K0II;*H5DoJhcn=e7 ztOhr@mBw|V%X^+5w0eW^Lal0b&din0zNa8T4FI@H2Y*SQ&MtR-h}(9bM*cP1n&2c^wnh6PI@=x3O=JH zzFv=H_6?&WZ9|YazCQT2F-Pel?nc8T`;8>oDuumcxp#b}jgjajX4?jLdo$a%#R)rd z5Q3JP#7qNmL?#(BGE-Sb=e@6ZuV#+~3$LpQE>WAEW~O##llSg8-|mW+3p;DFio*ShwIZeylc;9ZaFT!CQIu^23c)GsFthE?~0r3+t{Lww#>0i>nJgb$m_J#M>P;2=>79r!h~PXaS#w>ySh^{+})XV zulR@*TB+Mq!ZJ4c$!k1v6(ITEnnovZyp7=o__8!qpavdIdGVrmcFZx=$(iv-H}E2p8%WLYfcVlu1ajtHomZop z-?c*JfSN?U!ZZv?#=To;q1h>maQ6VAkPpU{Pv?64vdjBnU;e9zW#dH_F zHGWh8TK#zy^7n|CvgU%ghxTRB#%X%371T03{E$Ty^aW8Xa;UIEkoAM{GkHokb{N;4 z0{H^__u@wQ~GlM!Du+3tzbU^`RB`>BVyrO!8 z^_(OOAuDyX;J-oo0sK?*SrCF_<;pB>Bqcs>8@efr?6nd}Jrx3wz9~(DjeQbqL0$t% z#F!fA_lR5L45%6ti$_!UgI0rl2kjp|fO&(0LOOCm&_L8Cr(30fIw>?z!zxj@Y}LIJ zbBJ{$S@tI*U@83!pgF;S#tsL-qIqIdpuj^vi$+dP($cYl=d{z&*TG3v)_@b*+_Ik^ z2`((7TKlUozF|T9ajC&uSGKqL*E?PbCS-UQfxSmCEcu$@rbL6`=N~fAe-Cez zGSD`Xx-iDWL;_Y&imoF$#`~4E>FbGgWxzB*0;C$Nt-jLxaf?$f&G1dixr^E0=KGOU*cJ zDRvJ1B@|KsV8tECAOj~azS*+{Q{o|o_q}fW%7iBF-rEW56YFp;{XR{D^ZE#Tk?z}* z^v^c`r`LiZ{<*H}%8w+5@~{5D1F4e|%uvJsM|ZFfB@~ChSrZGF9R=+zLlU^g^^cXE zd?PH5W!s1%?A2}iHgNJ0_Ftq}uxgeT?E^am=`4bj)EDzl!MyNa&vT6bTvyhP0QFR5 zsPqr@>HCz56r;`o`05zas|>tCYCcU(ho)TLy@^a@S2(zASAAb%m!nRuv>1h$5M9+ICMM2mEpjggg-Tzr5lTc2p(Pc(RvEN|bw zebQnOCgzMOYR)$n>`8i0%l7f*X)C4ZzPUc4xQw9O(C~Qc;ZDXU3QUXi=J);#E*^Y? z4md1D;T+Y6ES-vXn8^j#J4Tk)4Urx7E`~xVA2rXIVxUNIo8L`h3krODn>pqGLS4|~ z!9kO6vh(wIz%2xSgd&u{_U!%O813i;vvUUb&YTXJ;$DB{GSNKFzf|2n zu!+9Xu1;x*Cj%)dD%e32&X#2GW+Im{rt>DV@z&LOZpz*`P|-U1tU5aQKcx;a|DQ^0 zZmEa~$JB)S*TAC#baWO(0ww71Vu(~a;CP`d6_Ts(|E)dtpCd~TA(Zeb%;@)jjM)My zM(E!a2^WC={QvgH|K9We*9T4VUVb?IId>V7@6VKK;rPPu!*oq7L@WWGbF%-}QF0ZJ zPEAaAr)A=-tu|Ed5x6hrsztyH=3ok(wA(k7I=ZN(U&vsv@ewB&+y24R+{%qVc&(gY z#7=eg?R#CQ_;^lcXKj9G_m^*ZoCmK@{-uRS594vGTQA|yHjgDA10atcEwP0I6d#+2 zfc?xtL|2l(E#Bv&80Jfg&foYV_;*G1ltkr$Gdd(ItG{tCf$%M={>Teb8BAOq^XN=n zb#%#wWLImyO~#BFb{P?t_!rRNc2U|xXrjeH={d(|BUFaGHX4XFB! z_wK(JJ&QzBuw(Y6kEmxBK1*wgYinI8+_ZyW{Sim(()?=JeXH&s))zNf9)^Wq1nQAg zS`s%3w~DS`^Dr@IKjzcbUL$>WGFa}Opo6cyB%WmtSHl^YUw9D(t#Toevg3GB8v}U~ zGY1X;;KVH^P}x>iZm%wFT08gfA*cF=Rx*l>MOD!=y(!eq^ydinuXevYM5%%MW$Q|< zx55Dzm(^x|S*XCtDx-GOubqTv)y4_q_$hWOxhXv1O{Gs?d7D)dE%WEjbN|scN4$rB zh}(bdU2nxo%H@mMPnF1TbN)60r(#t{0t^I64W zEr6P&ysJ8;{cDJ`M~PUk!o!ZyY=qSdI;xaVj}ge9avb)mpI$4GSke;K7s`?E9e`8G z(>AAuCkX!6^4#~|c<07u)_lQ9wNN@eHgFSc7wGhO-T8wmcO5U*)pV4(HNJgpR2k)K z7^}EmF5=ueido;BmbMfV~U-<@shmaj?{ZJ0cMbL}wSZNp7me7RR44SX2?(PmdI1J7LBn87;M z%*CubV(I(nP5#NkBM zCiZKx*GWl7Fk!u+$Kr7l1B6)5@Uml@c29c|@s{Ij%l(9DCKLcjt-76%Atak}+Y1Cg z&j6tf>!USF!H;|L#O-dp+&)hP($XqQNcw3Bw+mYXXrR;dun$(p__>iEY3XqE8Ua3h>6o~%hRUde z-=3W?>teGbLIT9#*?G?LMNkzql$F^4GeUIEMh0=l4EsP_JnwqDG^9$-fzg}(q5im2 z0rK5wqb9!5PXwKs*8~4(+p;`A8b+k!p!(Il)9sQNi_^Ze5B1h^eT|RpvYMS;7I8Ok z%;oHFmwqbY&PeQ~1cyIcLRLy?xm8|Is|S{pg;7I^l;Wjw@Z6q^%>StWy1+$nP}tY@ zBNu|V^vSh+M_NR&w}Dap`;D&FQ{A@cj=hBUN^20#*TD#+XxHsm;hH+NlZSrM7N*Bh zg~!HV)~Jf#N*+-VURfn{#Pv6k#U-A-D)H*d%I2#X3CYL+Z1B=COy7MmB{&gGeWR_a zoCA)PTCn+n1p=~BQ@gQ|V4D5I09%k|mhlPDo-6Zu z++y`D-V~EvuH#`E_Z2R^nritHN`lHzePKXidS!NXc?B5&^f(U9#&Z-egs%LuQdB)g zk5=2N!f`_D8NOY2Sm8M$zOx@5qJ6qjz5%-~9=D-CLNBC;;Q>45!uK1MsemAfq<2Z_ zTi~qhw@U@eKH`q)9H#3@BKLdMWjd4vtX-3BH3UITF};aTaw)$?#Jjf!qIa{R?=2yhEi{l7y__lCz>gBv2Yk9z;5^NYbclsU;ez^IZy{uI1=IhF0b4!34?iV(jSUcBcDti6CgpGlYPka7FS7A z725u#4G{VQs*ZE2lL?5-L z8@e{@EzjNc81(X98JKy4)Kh;#L5c;#M$|9ZP^OG&a<`t(^{Aeie)t<&Stc|5xOK@Z zKovhLXsJ~2uzTzeD|OAhH9r3>;(By^~dI};pJN}hsmfC~D?Iwla9 z#BLWgOQxrlfUbF?^baq*seEbyd?tu8L$lhIBd8JFZI1?@I0+|a)n;`ET8X+Prss5cp<5RQFCXht&+a$m@p-V}*^Ah@$t2FB{lq8h_#8uV%Pb zG8**a45QjK#p1)D=aKJw3r-4C8G-kO`v%d}aO#*%F&_XJ7?G6Z?CsgonHFv;tAAHI zCadxhsHY^}I)%?!nJROLiE;A~hSm-*-&FC>MOR2|CAcJ(kA1+$a1UCaIncEdj?aK(-iB78y-}kIZNh}vus&fz{ zo%2;%<#EB1gBF*3I;Z~lg3Gi@ac^lO*-s`X-mH$_E(ebOB^guHf+}+}xk4hk;)-m* zU{NG4(q`T$8L#DrMz&gd*)P2SvN{?jTziH zs>oMSyS>veA0rh2H>>)_-f|D0)ztqTA@DuZtaJ$YSX|+?WA+CWA-zhRVzjd6pwJ?g zN&eO1RUutYFZcXNL_9mn?`7P6#E+sOzc$_g%PQCRnpbe1inDcuHSvC+857056X|P? z9*^tIY%Ttl!Pg4BXcwffn`@?> zxGf~~K~Ia?m2IE4)aIc<=l*yQ^wd2v*?eS)>8W#l zULK9%H#c?j1)Nv|uV`q>T*eCw0Gfrqnr&XpYjjZLuoSX4gGL}zSWE(4nKoKP{ zo47KL?s!G(uGh+})Sm26n71#lDQ}_KR#09UrKo`4dey4$-Qd)>A6V*oiGZMVaiPSt z+VFY*Bddk~QM;&-mOFjV;z0$Tu>w?yhz0 zT1Vv%aF62bO*T&yUw0bQQ#o11J~(-I6%tN-Z*h4=s9~*))#hGM4dUqWDZFB)&h@?!xPZ<}xGsOi{LP(RNKv+;@;djFrA*zaqxGf+ zPrHy~g#HG$!TG1*;^Q0XR|i&5VFa~iQg23m-+IQ3JMu`wrAtTS>tLfyfP|I}U(I}7 z`Po#_B+`b0kfxs@4}I562HUSits?Q#n}^!SCl?n5!SCM(jZ(+g&g6_geevE~n=_4i za&fTKP5?i~A78tPsD1Yq_&g4F9D*|tmo7}n-*am>B3&xar&(D34vw(fo?Xmh8~_QX z6q{_c+EgEWX*tb`vAR*834=dfAERrse~#?vZjw^whw=^Vv@tP#W>Zs5er!h7a13_KX8D+`$qVTV&S8yRMnD9kMcCCxhD$lZ8NKl)hAX5gIRif;zMW8 z$>G-r%8Pg1PHPLLKh7AqPJARzO;(ESrtb5sT@T}JjLnCPg+nuXe6S8Cvkp!UwhB)^ z9@omnuD+A__vn5#FUijF_8Tv3;2MI_#bmAdwE~`eX88G)1B5Sn_S7Yx>7-E})* zFA+T>@Km} zvV!<@|DqnSk~E%%$|hui{Af_=V5#El8(a<02kYy$mCZJfz9oWdB34#lr`T;yaGp~= z3AEDB&SC0%=PeDs-{2MzpAT0^f7f~K*;H0;AgF<0lbX-^=;LSUf$>92KGmY}-^RNt zF^k%~u9g~re?^axPXA>nZ}NgNf`tG}%9j2h)yMG-&CN8*dMDUE};u(AJwz<9WS2;XK^u>9a3Ma;u=h~_2n zd3h8jM*m@+NYH-^u>^nr9YbR7qdzfYhJQtwf1jD*{Hu5U^U?({og6hRv$3x34}Ou& zB`z%N|A#FrZSeaWI5*J0m0K&`H8~H%{t+p(FETSdJ-xy}#3Ai3Nnln3^XAR;xq(vrNh`?6zZP78cpx?>=F zLjGR{nNOWnnTW!~ArRib{@|ccW#^*@2#`XC#4u*;2hEoRu%Ge4z%Oeu`wHn_geefvW;g^F3 z<_?D@5erpZ(0dcLUqC=}^O|o7h=`+3V9WF*_2c-3PqGLPRyHd1KREQCZLeeMrsb@t z1f-~{s(<9(SF3CDc=3%lN64ZD%Vi_PO8MykK}4FSSYD@XX+XOE7V^IO&4dXj5?|YB z(eGc=q{NYvso*#fVu+~c!T$mbToF0DcjZY!CRR^_!zApK-}HhtT3;>g=shJhaJhTj zI*2ldu3I`U)b=Z?%Cf1Ahbx{=9}&nIr-JxJ!A)k+KDq!mnV%n1UvJS9_XppKKH{qL zt2q`wHneS3{~J_AfwM+m$;ep=wJ6O)g*>O=R>pD-}XBWDlxLbo~Nw#a*=EK4F zQsiLXQ2m=2?ZDfTWFt&MFA*p&H;2QSB*WZd9DJPp;>k5{5@aRQ?_+{!6=0P&7!_b_n2m?o9b;Mmn3ER~U(-#*zU$>m=LvZq640B{lf# zQDL{wwukIY?HEjapdI`0ng;{#x!loD12yF~T9x&blypAJm=#SQ*tz$b$c;`MlL-+| zvdxWEgND{Mb}BPkJIX&RJJ{Lf4@@);6RpB?PCT4;3cEi9XzO^Y)Rg76a*J8tSOxgx zcw3&v#=3dV-KtiYUJ|PszgQ)9j#JmwHAbZCS`+qNf7MuWHK|d)#Z*(}yBiZhC2`Cg z_-QoPwOu2j+USCxS8-v1TuMvN(B@#jpHMnftiBMJ+cuwB3B^%~fXsAfHqs)YqWXWh z`pT%bny}kYffg-p1&TWqcMopG-QA13v=j(l+@ZL;JCs6j*W&JOMFRJ<@As{B@12z& zStpq}qmS&_Gmiir-wD_=t&&94mmImIt_JZE;5G@I5cDYfh>?ea_}jMT)k#iI+Zq zONW)oH88TyEG#xGl)!;{t(%iXG;P(lt$UK};SVdmLFv78*? zq6O?~D{>uXL+sDCiwO-v@2;DwRiewirQ^yL?%yEj(2IjUrSEK35P7Ye>u6%>WIZ>a z1}eK;RcW{1{}x&^eWEg;{iZ*(<~7JYl3X{vTT1-Q!@bZ}{{fxA@s;Q9*F^tqLo>nd zpOYirk}moJAmKYJht08BY6!v8RfeH0d-q`0?S;|qBg2t9SmH#}@YK-E-h{8`wCg%7 zbr^DescXwvs3ose#min^kXu)^Wj)?fd0eQ4x1hP;T`9C|ror`dqiJo%pjk6Tv8u{N zYmFr4cX@gdHOtGx0i?&?X<(C>X@v4*-NgaVQu`yW9-?O=S zK6dPqCffjW3u)d z#_S%kCISI;wVm6!6utDVKM z;L*U^L-Vv~mMWLUNnVBG#-Cwf@nz2=oKr+xQ3Ceq1O9PA@~(D5L$q?e4O=pLR$BQv z*=`nS7~*2|&h@i}SZXipZ$@fNS@}IL2KTZC=c`PQ7f^%CLwG$j6M};3-E=2zBDoJs zJ&qrOc7EFqX+2q7rg<&S7ei;;zvUFs@ORF1|1x~~2K`ZtMmnh3LSt~%K15WDWNO3@JQMzzxUFZYb|>c6yuCK2oDG_kM} zlx%3|e!Nh^AB_ERWKP;Cg!i?kbj?G6#E&>@YsGoYGb=4`tHXJ;nb*h9L`c)NK{a?l z=1jNyiZY;(`LHS)s$tb<-y!sT?rqtnJaisp0rbx?42E+7ygO*e zNG(t3VUn*;nP(2z$uDqj7OT|t3m=q_E4r{gZahIMl{Qp+|NML%aS_`uo7(@}V3$Iu z-e~>)l1Q^qBD2PO=1Xj&(AD+oI+LZ5>>^x$FG7O^f%i#xXmk|MR(I%fi;sJ18F{5E zVPQ4D=i=nHcg-tVA2ecE&vR`kR;%B_1^GfG9QE-^ie>A?Zta94HOyRT%R1|xA&`Nx z%VfWTqTR~omIN7PX~R6d!A{IHu1=1RS%h5cevBB&jmojWK@iL9YTQd>blVOo@l@Ku zXR2<=EazxVO~)i<>hT!@;jf!iciP*$j)~4U^HA~0eOZ7X)5Y(`)82dkHu?Jxb2P_Fe1Gwc2DUaWp| zdI17?pldPQdFaMG-$0bf$X<37e+kdp^Rl*v3042O(Z_YOQZP>$x6_cajs2tkjXJ2w z0rI^;yNPB`?AEYB(W6GwM~C6bCXT4o%K3U9siG_1AU@@R##bp7pL%fLk~5cvmAiwX zcdWVc)4T@FkdA#x!658S`l`V?!l+hhELi zFMt|8VCs0~!7mWyh9o&8{qdnTX!bWa&*D%JDx*JuzX@BA5+K_^PTu7F8k@tU{!VGI za+UgxAd04tcU}t1SijTJPlvh4*!MhG5Az9yM;o`^%!JJ&s**M6Kc7ii9J2W{<~lrEL=fPb;N zKUsEEQE*b_mfO$TY_jkCeY0_AgMCtHFP^)B5Ld3h+o_`E9@3QC{_kS*_hgd|pPk(| zO!cIO$#Y^=y!}TSuC7*j+#~8!?m%g@^uAot6JBK0Q}(u$g>I)~4L3KdJic2X@=ds# zTK9Wj>kP~`z5>#oNtvX5zc1iX77}Bt91H%n<1rstM+UQL{bU`nVl;HK>bFCwvcnB7 z-%fO6J?Ex?dQt-{_U`Kuc_$S|M9BS<$CvVl_p%GUr|t%vZkN~2{)>}K{Y#^sc3p$$ z*wp^qE5AYXAW*SQVKmW z%10wdS8Zkn%2)KuQg+p9lJ4#zTLswb*9Z@-e3ftPJvYYVoPGwX96iQ5 z_cr#rK07(Q9;1mwj*5#_-Qt>Cps%vGGb)alx8*F|j*PBb;+q5_9WPA>mrt^iZ5&iV zilnwWX^UWsboj{!QfzE&EVl4o+PkxWKYU}RH&j$Kyvp0-c$jPF1Z;8oy^Yatm1IkK zL4O%c&Cf_2Cq4T!c$YyS6K7jP_1ysLB;wYFfOFre)udFu?so&x=_>+0dY*dlN8@h` zxs1O#?GNpU1?uY>?HDTUOoy}c!eq$IC1j%bJG*+;_i|%vWO$fWL~9-?ShPm)C-Sf_ zi&tz&#FadJX5gFe(mxsO;;^#X?YU4)*ZE0HXv0CxUE;F5G-s#gW+TfjshNA&YYB&K zT*J#UK*{ZlBM}6*XIFJaIXN$ToK0!VGbOY{W0T8vB5Z4hoN^*3zJx!UPV~cpf3Y{< z2x@;%vdELfy`+cGP}7Rp?>xE1P5s2@nUFYaYJz=E9grUUuG6x}RSdPdw`9KcphZh*a_|D7C9mF6(5tp);t#@G%iv$zq;me8LZ`{llPf1>g2 zn3%Ee6~G_ra+|&R&isA>Y%la`S*O~{Tqujx7&yB2y4=weQ;9xE&ld)!_c^*6gg9`R zM2OIx0_$L-i)I+(V8E*;%ga*kyoAdYf3R%H@4xj5Q&r5rEWYI6f`0$ z&J8!PtQe!?I*c^?#afkty~Y(TJH64@*UkEv=nZwf(IVL3SazwL=HWgK7=rqxvHF^$ zt}vOT{2u+iwMmBPKrPoj9Ie-*!F|Scmh>3YGE}|EjLsRv5=+qOgdd#^lJxE?|<{MS2xJEx2?XdE4P%2b@M5ey* zdg_m^P5sc0imzf6t(3I90yZV|M7M+5alGyzD%u2L>!knk_vvzd!c?Z&hbGj_Z=7VFkKgdrD6%jGN>mdu zTI_}n=#R99jhL`zdl6yQn;0yD94i1g7yJmYn3c`KdI7b{YEuHcZ{gty5qTv zBudhKD9m^R3?>Ma`8TB36Jbi5=qwic&{H59g2j<;{koKsguY1P-k$X-3h9DedyBzd zePjgBMa2B2mM3NGb8Kq0{@Fx-EJ>UCYiiS-U9&>)onM=^KjO8YPs5v`C$TZEi$Jb2 zK_3?K(hv08kC|#Zeo~~hH|97gisz}q)EeFhzY0uuE%JL$w6D)+!zsPmL;F3#=CIns z7u(##Lu)QCYvQ8H4B9ygL>0&LtP;1^6J45J-e% zRL%EZpLPybN}&5FoziZzBZ6zSNfFP^QMX~VN1_qiA1LcB}l1ZKD zQs^dYN<=0qBCojqy9OUs%{UZw`dlK|akZU|3n zwKT0?uZCBWtISp7mt(fitLNx)#r$eVNNg(q8&y71zLz{Aa6&%YmtuaD z`)?)X&QY!!cHf~p_LW`g)w<4oQ5*96e%%~fe zEsF-evw*Q2Tc9RO<~gSwXnhSrxDgy(^q)H?G+O_gG`%~b5IM7%+@Le*@NIr%5yB{o3uEN9pV6OllpKS8DT)?%j zX=4Lnu5$UP`EMy$uc5d4KUk0olCNAo0IedL?LK4&c}%#T^+fHg)ds-E|>A5E5@8u|S5uRvPs-0Q!}4?(lRMl@^u_7Wrz+WkpG%}$6pFot#c z_#}gjIC@cAA{cUY)x`T-yZ4sYqelKfED&If(`Hag_c>n&a|M}p+T7c*Uh+hX;LK63^SG03kUQJ${)Xt(UN4LV1)ux3W zVA%j^Pmqr8moW>mV3``7P1PQA*AQ4-TwG7DJkZ4S-~;W{a+9vY&2d}9kQBx3!%ff6 zgnzl18P(LVsW6jFK$X051_$=Q+iy>k)Z#T7)PGb7Uz{10SHJD_-UR%#zbU{zC{NB^ zMNLgjMMH%~J2QhKZUA#5He>;1|EB4`zkq(|kOD6Q1|k{xdc})(dmDS(Y()LC-M{n5 zQd75H)8v@_hl0=sIRg*aGmz*~_(n6<@(*8{i;?_0lXFNL;Xy)LGX>J3BGHmI%P zX1musGH5i@L&XJU(#jbh+24kplol0zgLwf59_bS}e)DR>Kd#7#%R8RK1_uuu6>ch1 z$jAX!9SC$*QzE6PARD*x{Y);gt$5k=GP1}-qc*`>dHoGN4Ar0jdsU$&esOhaqN3gg zg1{r4G}*i~w|X$-g;@QvYbqFM?IAOJ!qApPA3wRtOENl|?@P?I2?JaA@GY?Wv>MIf zOw@P(8lG97dW7`6RE>X0kb6>mF}mPiv)C+YBRf6gD2{L@+9TQ2dVSDKV9wQaUR+(> zQC;m9Edj(B1JZKEm4w{I8Kr|Y2D;i3M7qMm_PO(Q<0R`PMZy8U^Ll{DeR}Y5SlG`i zAgrLQ^iaP`fLC~k<=Hpj6v@@ejJyC`K!unxKp+Cr4{t}$U}fo>AX#_YzP7$1LaH8i zc2jH|bxib_i_yDPv@E9BS!{(z>b|q9Rx}!XA87&0jq#qZ^oz%Vh_#D4rZ!q^!72PnOVO&4Wi%P%+F( z;L+(b)f_meP!?j**}pI#n#;<@ax_=!eu%-|>>r}{y$Fd&Uq_s|9Xe zElV~jy*cA)aN50={A(^J+0c35zD-<=+_8dXGfT@D{s%83#hZ5^UXT#-3l}}t`nrN0 zBR~|5$%N+BH8dm^MjLfjzRIsDXwfby4qdnfdPt8OCpW}Ert>?FYYK$RwyvIva{4re zE&+UC>(bVi3kIl(N z-z$$0^37cyuYmJtq#~uif3~~-7~kk!6$l!yQ1A3wdD>UWI{Ql9m^S>#YFPc_j`O@5 z%{}vYv%_XtNAVQF%yDhf&MK~BiDT$bvD(7kNtTTeECa{4*$%_r`;}hdCzthtpfj@d z{ln2zw(~}Vr}Rx;{7o}`bYN={B;0slw$9EGonf|TIAYzfV4Zw?w-g=S+1S^8kTpK-?{{C(^lZbhpOKyxo7yK9oH-`X>uY+N(c#N|(MsEhl;D%( z$Ut|JT>&Qyt-GJ8tvpQXuEhd_-Te)kcS=T*(spl1$&6V!vS@~mZDxd`$Gn}O&N5T; zOEp40!nuW;0l0+018s;`C|+Yerx^yQlA~#-5pBbzpe!3e2Aki{niS{=RVPeX#6n%{ zO*h2PkLhJNDq_a>i6o&N2jGL37NeP^gx*X%%*U+No>Vtqr%(V%{9lX!avDaK#*^>v z0tKJRG2?!1P~;QLNpU+~;PL5+D#New6p|$j{-$-}n?9V%%aepsweGijkxqG%pTWyg9-JY&Vufd$x zmlj#Ty$pR6HHDs-*kFh>SJ3GT)C%nxM#=x2%_K2DMh#q>MO)vDkZCEzK$0^ zVGD5#En@9+2d=xyVln{-JtnwT%5{JAGD&RRRn1mUYlXyiq@NRcJ~x?T)s7g0#ihT% zWjhwX&j0m6e3?v(*Q66!(`e>y3LeDFV1gNlUkiP9;&wXmvGCmj?qmSc8twjX#%k;o z($!!Ml(bf-N~Za(UI+ZJb-qM5GVF_+FtVMPgmV`r?eY|(WZ6s;@#&y zJBiGSbhhJ`{$8C?E$wwewSPQu=xb8E{qtPsUcQ^g`>Xz${fu7G)D)yIU0+{MCqVR1 z9f8{9S`y<)J+o45+A@yHU-{N)*C^D0_C$FrY-i3dtop0`um z4%ZW8WacCfud~M3M(-&fH%#8X=jpMYMX*scaHGvdSmgqsgv{fy3|_N>jxJ>n7E4Um4nTC`3udoOrW!k zp|MtXb_V#Vr2qPJ|KPU(6&`#dOsA85qN)m=b3oS;6`$%yAXiQQ{(u;A8T^gaMZA#h zkM8cyN&7fh0F_StH?jMrN6)!kgH@(dWf}<91zk{g;KBVTyuQTfk~Jq+X?->Ig&n4H zDDRXui=GIH{J=KbT;UZ_o~#-^%kz>M;tqk!5i(rYP)^kk?#IR{%{|3F*zQ3df0DqzU;SB%NDw1!@zu zPWDxxVws?(^3CkQ0vB;eEIvw!z|Wpm=ozl6L*drU0wa+By@H=lPj0YII>wPSe{!XP z)K}>}Zc@)jcXo$jODiYcU|mbCEXh>w3_pUS}6$lT$h$>h2bkD^i-X`<4uDQ>0l4v>*n0xuk0>5sYS0r%q-I9fw@K#r_BnYKve6$DKp3-Cf#VX8>)wuX`seAnnVEG0yu}EDUCaFFCFCyp93aTT zPWs#X`*v^M|4bDR9)Z9-WHD&>VunAd%W3LYZ>Qid+f_jZqZzC}dR5_b$9_GJRJ(jAcr>wgsLI7@h11IY#pl8KdQ`%nUOZ~Hf<<;uL-G9CgNP7Du zHcl5z6?l@L-khv*^`qoM}G7$y9vQQO+|=h(m?J#*!w$962>{$?`D8N2`mFdg<^QNjmimxPI% zf_@M?)qz0e_Z(ZM%qTaaxBKQhzQpl~BWb5gQ|N%_(G~u;cuPcSd{96l_G+tvy81e+ z*>HPK?53oN`B;jnsqH5%EuuPRexXx+MM;EzZDQsJ>^G2hVv@VV_}UX#Rr3S7c4}Hm zTD+8u|8IZQ>`zPWD&tcVe;pg31!zdH7oa*hrcwi^q48u~XWsQ`Y1e9Q_t@G^c}Imx z{dO;2-hah1 zxr9b54q;5eb0_ASIF4w=Z_4O#E5FtFQkzCO2IGKj|Cp;iSLbaW+4flpPh5dwCcE#2 zcj*m9Jp17bkP8UdfB`Ym_)OC>X_Ii_!01yRlYJofemgrc8X zMCq+(MvE@&A@A4nClmH%i#6Edz*dMsu@F3DSDjW;^-3N7z}?#8H?J^I3lCRSir03q11as$2ngFR*JWOJKGf|X zrgUe|E5vgD9H)y~x<~;HrWhiDcWH46l#Tl9jV2{ZLy{cib7_0^J+^K6oap<5e@wF92Vj?~ul zz5>vqxaa1~RI*I&g_zRPk*QOFft=@F7tg?x%IiJ>&emY9c)BZxuW-_2poRV z3_)cz@fz_{tB+}FkC3W8S;=C5>GywZs4nLd_TwRSXnC&Ab@VT*lly&lT^(EKB>~c> z%fO?(99r)W3oB`XhWHCkxXeX+`;(KQN;=qJ{f`o4e21cW!WOSQMc@+(A3%GBW zQaW*&Qu?Omj`#n1sB3CwjdT|g5xrz&iFXiEFOk<6WU^#bZ>b~LfhX0%(K1vK6Xax3 z&FGam!lI@NgG!41OKh$SUu-7{tFIQZIm<@-I1NW}Ykm0(nvd2$1ua=7p2{4y&?Wz* ztqu7Mf!y9;EoKNx8>g1svX8#*k}blNPVv0V@LzgZ1p2(b=@#1FNeVcp%qKFn zi{DDVU8<}YfM_M10Rmo+6^-_t64$F#k(yTE{8X-x?~uQAzJ&R^kK3 zDYXa_CAE(Juo+TB(<%GupB!Vh35`cegSEX-E`M-)z4vqriYS`GCkfDaX&;ILI_nSk z;@cCQPL(tCtef@GGrns$uaF$@+XFPTCr{M8feU0vQtd~{WEMCUO2t&ZX!D10Im+%y z@t~utgiBJ=Dh-(Ot)xok*|AUhwrHJIN_*-j9{b$lUrc0=Q#z3uJ9*Un`VpRv{va`1 zPHQ6I_x1c~J|2Thhb&e@b-K_9a4fmsqXNXz^8JnFq@VtLu=$sufTV!pE|0;wYT#ED z3vQHZj2jnjU{ue-;?z|8wfMiVgi9s*KKAz_rnKe2TICy^u)=#b_s>1N`0a3F_&57! zXZUh2&A_TLj{K~FLEJ%01y~7la@T^A{>gjtxk?0G@|n2%xQl^Dg}rs1O@P{w)gkfT*q^tscnJ!1Q7QU ztanU1&3Nq=dwKC^FIv!BSd`s+?T_`fa_jLN0IN~bEW+G>U8jn}aJ{JMnf8E6*uJkAHQ8f@TcG1g=)7c44{4R2oPvIm6wf)d!FfSZT zO41Oh)dc;3TH4s$xV!;6Fei3k>o{@$$Xx;C(d_DYj{&seUwXs^Orwt}5r5nGUlNA8 zve4Fg>|g!gj{q$PVvnVGtlFjTB-g0Y1|pS#x@ynQjO-LcfUU8Z(PiI({`oav^4B*F z<)J;(2E78pfG2HZYuGqNHVJg5Te@25YbC&sfgA0KjZ^-})D$(X9)^c{3337@1tfiv zmyay5#y$Ol1Y*t_h3&2_7w2YaQGhDLCY`-~{MslrAFnl-+K5ppff#2NF}-2}e!9Ek z6mNSBH!}ZKd#tYqIMEM)V`^&q`@*2L=79H%UH)X9Nq#3+t3ZUM!=y=Bjt3NsgO8!N zHxCs(uElipce%tp4%(VWEBVfCLyH z8-BE)PYBZZ09ew3Q{#5H?<3xGIjN%|4mPDouk7c)9ZBlmpSk9H5+uRLKW^|ExvDu# zimlYZL|5A_47&)GL1u%jdJ&XIp2%Q_!*MKcO1T2a) zXQc?!{p(S+F#xEC8EbQDYHApu6-vUw5G6)HZ7tv9;r423zV%e!Ax4VWlQ0t6fj7tv zjw8k_G(C@R>KFxT=(yXpb62-+^{93BR4txiQ_+$Y2&V$9F0FGb%eiQ_cNgj4k9II^ z3t|?ICOa-;LyqY`QVM?e*Zei(inwNU5C~QyMkTETYLad<73l^Fv30z=OHVhw88Tal z*(o2|hVoNB`NP*Z#rq&+l(X?a$A-q$q9$jyr?;!@1xsGGmBCK#Moq>k4P zdpbH7C9n9R;GXXHca`93$;-?CU2g(tz*sZU(^n|J!$%?F=>jKN76pDM%rYqXARn2Y z>yL|Rg||mj(M!@Q0sb{J_ha&fl4!-Ek4j|A7ZzQj3VX>|+yXa;v#4!c-DY)8EulLZ z4l6uDmJ6f`J((mVN{tIhlREh@(&*hb9ps7we`9{in2Zd?SDubZUj7|@K|6~bI-5XR zNo9Hz)`0Zr^ar{j9Ndq3Wy!kmfe<_bUA+vdTvv7phV##UVu6qq&$0D98djlGbwPZ} zUk$UbA}PqoVD9{hol~bN=~n+%Z$J_{VEpNso8H2oYWmstr!sD2^A9TECSZsG2wm;H zmm>$dngz9_1s9)i_NO{+twV-joqcd$7<0bJTVo8OZ2)8MKGyhb>79@}(Z z1O>HhC?u@1SHi%?%d$QvtlMl$BI}9oxjJ#%4*Zji%}NtpLPatTf`!N<9j0TK^AyvO zqJ-=9pFw>#2tYDFhVW9U_)%h2lU6V?TE%~jlN_|!-tocb_0Lj}5!89K-uB-g1-I4x zXi8;|ly9Ak8aJSoJJo zLT7XoX_2M#p7dkya-s%_+3m+T~Drg@=FQi*&hdAAC-+Y z=aFYkksAoRe$+fZS{q*h+>H;c^@L?&@o66SIQxGKVGmP0)vh(EHLw*-z}CQwiCU1N zXM0JUWS=2tnHpm>9l5$MOk>CX&*RAW6oYZMT(Rk&{}K}v##u4@Q6u|k{{yH6O=1w_f;~5_85mYt{73s};2vK9IitIFuEG~;8&P`L%!p8# zv2t|YSRE>%rZ1B6)#a#wCk+#QA1RW(=!1|G)MCyuXo0i)HSUG!vTc>F@ONoy^ej6U+9%b>Q+aWB zn&l1ix;~x-T@}@;zbqthD~W|vM(eXUX}5bAR$Aa%p?xZNx;N2OU%fk|M)c;z3OLDb zuwTB_$ZDo8JYZ4%nb}L|Mub%@q*rzpdb*+_>?t=*FjK>k4jW#p#MF|ow>6q)sEL? zqYe&Rqo!1TC4Juz+5sjqbOi9 z$ZY`^jLyx`wY+~;3@r(*CN8Z=XP_r#dUDE_5bEfIrElfM$J=;f&;}0883Qp<@tyC? z)q}3G%aoNpYRfcM1+}dy=ttXP(&HUrvoG@tDg-4nAaty83eZ*WBBcah7Dme4CS|?w zLfPAj)g}+xO+fjpXc&ad@HcD>?o=H6oR$xw^P|7jvqr{oE?WDbST~ zq1;WmKFOyUYjGo|rLDE9ZXq}+y=lqHj7|3{WHR)$H^1n$v5I~{-{EtloT@9^dgOM| z8*!+GmM5p+Kva;L^9d^^*+o`azr4ur>;soGI;7F5IpM9#|0q2Ph_mN+Ra=5ovB*c z*tq=wI#n3Sl+_bKCgJ%SwqC^di-W{c$hiMqwqOXLf@2;ZD$e*%ikhDtz6zo%IZm$V z`AZK=KA&bFgxne=u*>aD5OA;etn;jr$W_`FDJ=Wc-IDdx1wwOcN(dWRMySS;g_I32 zJpVlWLICGg^cu<1(dSJ##$HbmfLC+Xz zw<44KozPwP5Gnw2wn$C+1h9~E?8>Y;jZIO(6R4_v&(H&mvfL2&3o5YFfU8nXQ?H&m zOg9uTC4dF&5o+1F&6#~Q=Pa#dr38Fzm!Eo8ol?dX=d9fNFib>m zDC=zO7uM#%%V{<4Z4M}SGmiD1W}Nge!VtIKr83n+A?K$Tgvb7slD@bMf=QZxf-g6x z3gQofF@@4E5@T96M0QBN6i!C;Ei>JXa{FckiQ2y; z`C^^nOMB!=0#f6qL;vuI1GG>T(;>M%s70MJ+Ls4#u*PMwrAbQPl8mC`IYOT7wDo32 zR6}FAZOvACYXLv_Jqlg?QX4rNIhpZIWA)lQ^bm)>{4|W7Z1vyZ>7k`>k{d@GPOtF= zIq}48);{WxyOJ62X>+4IQy;tNYbQFn=&6}VB2Q~ji<@gFrXz>QzqjfqB_l5l&9%?V zVvxffI;w*}nsCI1z0s8%*vL^@RHpnrgiz7wm3?Ws#+Qmz2>Eu=(INRGCBGTZelFu`V2V)Ry}%g^V%q~R3(@(1g)NRD6Pqn zAu7y?yh{1X1s^EP))D|5`ETt(!dyl);SL1_h4il*aB$ioknTzAHmc1x$K@Cf`W;y6 zpTx9Z9+k6)o`j=j$;2Y+;*6w?ep(4dMv)tCj?J&bh~-6}*%f9-zD`l?uhHZ6k1gg! z$1c=uO3q(d)r~`J!7#Ei-^p-CHZXao53#w ztFxwq>G0fqan;Y;(I!ED?812b7}((uX7 z@vj@FkZk6EavjS{r~a<{mJQ>cqF--DUxmdoZN*UB?hx@T`g{{J$Qed$%!&WyrBzdQ(ccEc|Dbfw=fsJPncau^7V!PZ7>0l;~t;a@Mq7S zPwju)l#R9TU#dT&$KfhsPe&t7;HEl;&KKNpwueHbVD;|i!$d}dexLbhm2{=rve_~+ zb8hGAHXva2*+N|j~3rM(JtYAi;!K3bv`2msD zVCMPe&+7`r_Aj%BBldoCdk=dqN9g%pI^B;TFw~+e5QmrXCI~C}%UeDWU;{J6Y@q37 z$OvrQ%8;2%ndD=)BS=vzIn|Bj&do}r6?FEZo3R@1!1X3^etTPOi~$F<$I?UzU;r*! zQ2Wqj9DuG+5xCFp({ej4DDcsjn$7E>+ogy0M0Uj|(H{jnC4@6$keJ)(+6PHa=|z_m z5Pls<0lOkI2}m0<8w=5Up%HQ~^J{`;{If*pm&f09A%Or_30LEM;itpw?z7Wd|H;2O z^k2NzU^btrLO`vZIUS&Bq1RImJgovHcf305N8m)ulbdI7*%|KXNj2To*ei zuc!=SXAt%V2%aEN%TXr){s(BFFin8;y)IeX!%c;H`>1DZlO7B}W zo?GeMtb!>lJGQ&dPz(Bsm7?qwhQ+tMZm^jHDjL{(orimVfz73hU!@n;$}|2Mo9yZ; zoxL$E39J(f7o}WSGkHu^n{5IOxJg@~PqCL8d5AeRvat?`Y6IVEKQ}iBDyi9T8x+#@ z2BArZ^H_cz)d|GQAf)+^t^#^SFJOk7J{-KF+*a#sT}}T)Lu{v3tG}>&87fCcCz$pe zfQ7$(E#8h`g|1ZDNL?lB zAhqv$(zcFF#+p(j(Eq%er>oVG-UJ5!!W($_EW<2MHhFN}5bZaa|C2&VeA2h#2TS7N zcBnWw^XW>mkJ%HeFNz*E8Cd~AVFMXm6XsC3BCFYR4H%aV#Ks)J@-Y& zlza}${)~t&&_;K#Z@!=7`iph zeJQ;fe@>&7(|hC~CEbX%5Hy_}UreW}j;WNuzYo4-slCvCjh?$u5E9GB0S1ddXYx$g zO1e^Z`~yB+kb*?-&PY4F;o5A08e${nmy{p|PE430{Y4@23v$I(ud3=Uj5fhtB}*mg z4|ztvWyNHJASL1P(aHcxWAYx3AwykTlbpI_?6e>I?lx3PP32GtPGY&e!eH*f%eTh~ z&q>^GU2M`A5fYZBR-lcWW|%o}kaDd?N4MR3Yl9zrG#c`6yEua)iTJi$8W4^D9{ zg4zotZn0zO$U1f=#Z%=D9!nk(d$UL^vUW?Y`fVuCtV5?I@2+q#LJ5&9t(bLHt4W3L zcb{u83{>XIRCk1mDD_5C*u2qW6#NrW2ZnOO1e=QsCOU7a1=~EypJ9U87mJ>a5%M!z zz+}O;YFqK1{Y+u?*P_p?P9<2gN@HH~R>H}gX|DEA9{lV5;DcqR)3c-1QzQXd z&{u8;2hT`C<@atItLZw3lV+NVN9~_e8lF^m7(vYJ*x1N;zy^o~(k8$uK__~wDwWEw zu^>V2LJGLHR9ZnTu1KUy;22{_=QVyVLs=jELjPc&Jnt8U4Y2lHT{%!t$|?Z)p+^x{ zFGQwIrBbH@57I|vP=6R2G;DbxjO+S&xu8%qibNIEBJS>2@eh^x3!;(%d0nqh@H=t< zqv;2s%Vr1=WEaq=e~&T5j4BwE=gqXwMI@SCR@{Az0;kXa|Ir448MJ&xgtgZBbNl_@;sG%Z2OMJh?<;5z?k^GS zZ{p9&b1X&J-gLC;d|tji=m@o(&y^hv!(x~ zMXohdL?XRqo;2D9!$YOLc@uXbQC)-fO$nb03pe+0M)>IE-(DhhsQ#W3=~nsnKQ?XG zWfA+%XXIwv-z*&r7oYiSSRAh6VCh|X=TA{jja}VngWlntB4yA!D*5@%a} zpPG8(np{nqBh8neBYcYQ@K*jBSq>pm=R#i29*NmGgpcr;cDiOUo=#TVtUNd0#kOJu7u=Wo1-hk^m! z(sYo8K`ZZIp{|YOa$`6M)-R|4pK<%R(A5Zhh#& zOw0(8kn{UPIVo_hG<|b-) z+FKaDnka)v3X41z16_KPd{ZhU17FGCEFF_1$%@x6{k4)+UE$@@hvK2AvtOzc3m`7H zrU#0#KGRS3$}6v%#hbagzb{}7@p)QH{f`XIBZ&ZqdBsp0G`FFgiq zf42hjlx;xZ&v`^3yLrN4fn4jcg?Mo&sUZBh;3ek_BhHkY!GY%3ts~vTGIQCUlHDqN zKI-j-i%*$9Pj|SUV5jMU=SPY7_as~S&O3oA@)%s_iyD3N$6?a#8EL>(DMU9;x0SM{ zQsRWV=^DLfcbcqEsBxI%qU3;!Xj6jWEYwyZt%KNu>B$2-ZxIw>iV%dd$JsnC@q zzCUb8-Aulla8>$t+En8JL@dXhaks0e_5NnNbMi*XNp9Q;={$)oL*tjLsh{fQZ6N!0 zS_)I?hHD}`m?C@w?LN7{)+q(|`@*Qr#KF)lUAM2#f6^h7k7vF6oR=vk%9hN@iEzvb z<*D7WgRj%5arpnx^_2l}G|jri13`iZ4<6hhIDy68-Q9z`BtaH;cXtTxkl^m_?(VwW z+2nn{bM86!_OIF5o|?AmDS4{ezUzt(_Z9?l&tpkN^yfvwj2L&Oq-r3aEJsmOJ*n@| zZed#>im3xxyulQn%{4&|aUzkG;Bxa@PSi*{VG`_Lyv;dfNN^|DHqQj?=Iyft-MA`N zk^sGHf(J&+aaH!u1i40nWV$m9)uCBlmMw1v>DOv)DfH0K*#Y z_9l2b$~dFm=-7Yk1aCRe(nHW~`+T2r?lLNLMcu{2)bBWhy4u`Z5Y^R`$Vm0n2ec2dw>EiZrus&QhDLj5 zJ7*)LK^ku`=NX^k(QLDKJ`}7YZlBhF!6DWQTrk!O6xCzDQ9%`DT9-FSNMQ1Xgk^@u z^x8Ap1^9qEDr|q6-I~>Z5{)j>-(E0qhn*kN_t&Iq#5JDX#g!7HA>!mgF86W72;rOs z8jyn#gIq4ZF5hESFCUfc(>ajRm}-*9s~=)~Lqt&YX7%5W z8b_wJUS--<+e@b;XGrf8TrCNnHq=<2ziG@q#7Sn$*}{ks+b@j7W~M%9W2~-mwSTLv z!^a?K2#Tful1R90lD0HWx&n-Kw4$@UvcWjs znGD)ksBEW!zR1bC8a9Ud`Ef2g# zN7^Z9;WYo#ql21>t8BVLk-7>JsD z*}3&p@`Y}>eH|!Ay5{Dks_^~QO$A}`lv6FQ+4ucA_Ok}%ToIB6G=kmZmdAb@H+`gm z3DYdPL0AoL&4;Fk_MqZf&)?U{j*V)(vqGjm+a$vZ-FTdy*v6g4s4>2Djx!Tgb9qt1 zJ9FTd$!+tZDHao8(o*aNCM9&Ax=dnL>9DL|LO~2 z$Bk5&kctAit8RI%--uKc`s&awt={;7}#7CCTL{U9$qhjRb5Q(m=$Q)#3q6)j8MyR_d4xiYVYEN^h zP&xzD_iF*7>bR(j*_G_bILa2mJ*G@OQ(7&`PzCBw8AdhL5OI!3xwjRD5I-lUa|%jc z7MQCy*u+8Ww0;^fcZmN)PEO9m@rf~t`amK8+@qJA^*h1(I(Lqp^J@T@x+`ovV8-oZ z_f$Q^v;X-tOKH_||7Fr!Ss|&doVTr=rD^`X@Er6Ozg=(1j7`DQdaYpb1a@``2FOur z5ro(68Xr?0^7QOMbBmc}QbCNRAm9E=oMJ;diF&Mxhx(zF`!tJrfTrQ1$70KjX56vf zv>x4@X7Pb_rAfK$Myw>I!Vdp+qW!3c*%rK~SG13qoaE-E`;C6`Is10guxX-^*7>db zkm{asp@_lLZNq8x7f6e_bVs&Pjs|CiQQ*^;)9g!#q`ioXP%Fh#N{%DZ$+CHm^9 z=C)n9jFpUv65MB(5$39@stn|@!#9kwA@d52#sy*8Ej^SrgV_noDRr@tiC=eXH=`bh zrwXed4FbUSce^rb&K=do_t*Vq>RyRvfvV)wH^cYZAbuq!rM7@&T0^QtRU8xw*O#SV zdm*-G1Ba#a=qy~mLUAU?|?N8eZc$J456{ zqfdt=_jDmkX#4lVh+0u}Vj(lXmJwextj?*$mvc4_#hxO)bG;YuP4$H=}%I1>$;vdyfp6pd^cZ$P;#`(>JSW<8g`3a^9_K@c7I2S+I ze)8G5#(^0v9@F6~GR_Gu>CwA$VqsR!I0E=&<^`8F@-Nrq2N27gN%LfCQ1H{0Z6IJbY_;)}=d9&d@2Bk@1C zVNU$SW*#+tu3Du-y=)*D-b3E2;xL!=?tkcOz3~IAclsY%{;@RzFmBx&6h2NW51EK4 z;_U7T;l^6NvasU*f8Ie0mjTb$7$HXBm(rjhPdqg_**8d$UtA1vKDxKHwRJETkD^VL z_Oz)=|25hzcZ`lGm*jamHYoS|EuHw`Rnb4nCI5e;tN6$Et@u%1^;xZR4hzg~O5fmJ>)8sws>2F}C% z+s7T-_kA!`VQ)w`W6&qHmX10FbBx<)!@QiLYeIAL8^|u4H}Xdj8yeL7va=3Lj(a2khgZ{<|z|4O6^kReu4lYn~@V>vlA02~-o|ToJeuBnB#^zy16>(fV zUOT&}X!0RN1pN*-VS5` z+=mh7P=GpiL?4KIPFaeh>q-d=?v)s}bDL*iB9@jdzfH2NM9TEKeN+j|Kk|}|h`WPN zq3?F`rj(Vmy+LXvd7I;4zSb_aCmqk$TW`Ic3}n-X7W>bDSv%e1VmB)yHB|tlriQ)V z6}AD4r)$_0+sI(w!1R96_<~Z-lTV5WvT4)hkg++2l?szfF>Kx^)`PNaH9aP&ht!W7 zZ#9gEmwsBVR$%?OpV&&h;coe9Ck^-a9UO?jTsg{UX*obNB)qcjJgHy%HPkr%n3%jZ zCWbH^(8&PF{*4;@rTFC&t0$rqFJO-xePRV+eb(x6z}dQH8t72Rp2D`!!A zJAU`Fupur%YfgNHeIYob2+vjQZy!cfq03tHuKD20k2e5$Dr)zycgOwf%MKnf0GEKP z@Qeo6Q$M3SQSHV?x9>B}EX|wW=7Fgwcli3!(a=1dT|0bhw)da zn*bOKCZw7yI^sC`pRNJOaICj~gUNu03}7<;+6n+!82;mb3{m0F0LJ;JFnR-I{}#U2 zz_9#Ndj9>A0l%^MfY3B zSW)`wPvxc0KttxFC_Pk^)Ce)e4K&|Yjb;glnVEM~v*^h>gfzTPYu_c^5ByVk1>rle zeOfBtrQ-%j41dHB7bA%7Z-D#rpK~S9bQ5CW5l~xS1DpvP3M^G&X@tWc|2xddYv}eO zl$ofe8V7R-&kLM14wM}U=*z(|B8HmJtC$`n{!C9g6Csq)f_cIA?_mH)0u&C^f4|1sV|}81y+6;ur0)YGGLm7NCAEkwq2Br{mVE!8;ZHaJeM0Ju z*cqroD#=3f&mf<00mF?aCf4zuc%SlL3eZM>Q_&TYV%JV5+y5Jd0ucV43{>?AS#I3A zkH@A7yCwd2N`Ac?k$;{3gTBVDb)kAFq~3k2L1e1>FEzgDA2P4gUoiOnfRBGO+gVZi z&vZ55Lth-&PEXwrjN9M3JFWmld+G(3Ki?@Bm_#4oQGwIy2{Sk!^a|R4p5*9l^G&O% zAO#jAV$SZ$W>4xIMjh)$YO(k~>pZmP>uTPz*OLboPXFXoAZH!E_tCe0MdzF=m-=hY zVvO*FmOG9LT4?PCs&bXHF;`vm8L3g*S^0^vqxcP zX9p$`1}}#&!t{}j^Iu^~YODy8=lin@i4fET-*>#0n{=F7$S@5)2jK|&{I;_l>Awc! z`qF4iKew{$Oiwzt)AEp_&)w;26CYCgjmXpOg(q?VSH7JgbAjBDaHN&-VT~a3Ozb~(--(C_a1UMJdI#ndT$l3cABG^gp|st zanSp|+&#?jTu{4=y_0&OirQ)%@-icd7Fk_x;K|^T8Z~!iqATT1DfTOlv&wNhEL5a+ zOe%W&RNxis3`gTP-@E!}6W6|@pj4kW&1{UwM5w37pb$YNZtpJI6pB{Y46ei2{Hp9` zSK4cL>_pu0-(14VEYsz{N!_o~J%CMQ2gTWswFU$dLR6xu>2Gn>GTEy(3C9p1`D$DH z7D1Bww2E}i)a>j=OifJfH3t_B9*b-$7z`e*vSri-i#YYXhZMxaPua+XfHwAWYdiK>Vwf(<0Ox|2|z>aO~V>I{~jkMC2y`>W~o#OKj-< z=JIg&;M=`ko(YG{AO=sYXU>tQqPwxWPo}k>xDyLy+mo%ia$0iI@{-5!Z(y*MR?%EN zkMTM_sw(F5lLjc$I}9(liG~cX&q^-tnU6Z_o~CTopvNe@H=W|vadyX#$f)PRNsX2K z!9hrgoV$UcvCMw`5cOoODnox6lwpj5Mzr zS-@x}prm!9Z7+Bw_J80Am1)FsWz0$ji;zf!iql%@+SQQoFyAYr1+uq3 zn}K)EzJm`R%{oVTqkjwaQcz3Zw;JDS0)GS?m{_4op5 zzbz~kcjA^bm=Zhi-9DaAa&oNL-rcyQF=!lT22+S>*u+d&mx|F%L5GaF=xgv-8uc z!#TlE32W5af>@fkUsKU>(e!jk(qmVz4w~e?fTCNNPw1CjdP9vH&$)!7-5%YUvD{pn z?7M-+z;KI9ElOdFK*)Y|`rz}G)+kZ$W5YDOq`jWpg6;2bUe>Ly3cG0*hp=k3m<1bA z%{ex7y!hs3PG+65{wvCXba=0*jCdafAe7#S5=2U8xz0pXE^p={?*poKPlER@MQo3Q z;d@;n&*);6s!0P4wF1hH1XS5z)Y++YjVd<(a|gdTdngiLSbyhEF@U&=tZIaIb``l+@ZQtUcw+Ma*e1U)oQ)No1>Xk)th+ z`cUKd$?Uu@URM1DUV>vG6s8TcLW+;etN+s!Ryai(G*%Iqtf-FM$43tRK9U;vTfEJ5 z58IOa7YmS3G%!rfZP;Ly5Ttg0P)+2%USp9qi9g*6r)N}ZE)d$@Wtm2>eYcn$ImlV* z0h#BY)7zC#*_-Bwe^(G{?WCr#||!t}=8m z&!5<_Mehl`jF9nde3m+Zxvm^S0 z!Lo+Ig9_xX`3dN&qbDfFbr+Hy_y8iwA+EXluYJcF2*|11diIi%pRsQhG z-CSlbD&<1Rha_cC=ltwqwm;ZwZee2%xX?=MnTTNWTGr{6K|~I~pU?>VG+Ul!wCAqr zzf>ka-+nMtfg&(SI9FDQy0i8-`3D!|B$ia1C!x~dcckV0y5MjL`XXnGX>X1EHK=20 z0p}+nNuwt_4gp%-Ro%}{Zt^!?^?Un0vGY|5Dr-P)24#0fa-H9iDTD#Tm{Te??jnm6 z)QirabL*^Btxoz_?vE$ArRFhDHVYa!`mEnrYgOtDMdl<)lU6zypY?4+1-22?{Ct%J zZV4{ANV&6kngYc8v=a+5Ql|c)ogqdv0>mOCZFA`{^KB~qK>TWT!x8k1 zJb1pi^i6sjqD!NR1u{2E?s{qaxzop5md7c&>b3Gstl429g3JS^#;e?f;md30Rb&Kg zU5A^m5~X1oJjh8OqH?!ZC_WO&Ra~4gV$iEK1)%OGglj2y0tZR0ZF&*ML)LRot3R~- z>hG`1(9WT^onCtRqP4Tpf~DZbQLnygcCerB)nQ{6r_-ez)ll#WqCWwc79tRM;X?4zpaB6e~y}+Rnl8@@3Z+jQk_RBT$GNsWSZ;TIb zstXgr3enx3rN>Nxc^N19%+=J+npd;M-N8kpEz$(O$=h|oauYJUf~tnCrTr}=Bt&`x z%#X@%lLtP$Ds6fm0iu?CB6R63izIs|Uo(NIl3_mIiYZDGAZ+V+Q0Sa7hZxuB=?|In z?n0Ui*5Az*@h_B9F%6!9bUg*l)@NrWM#aD7CN)5=X)OF;StCSxy(2_RrbDk+c zE>Ly(JQ1^e;KJfk56mQtE1c+L+5WlRAbcykWxZX}Dv2`bX2T|2-}uw?G9|Bd`MiU6 zTCzRW4{!E92}RWo^a||uGV^v7Qw~$5M-QRGgE_Cs=bh0{r1zn94AzRUOtT~_+`h(0 z#K!eK_LCnt8uwz4M|?V;il&|>n15Ac0%4RmtwlNRYe!AUY+D|hIlOsK_MGgQTA@@D zxz}Y&+?!q5PI3a2lMmCT*Cm`LPfONC7?x-CEN*(XKUEgJd~-RFBgUeu@45mK&V@9t zQ=+jn2fE6n)y|6Q658tYl`kfx#nM>U?y98wqsg(PYNPfSf}}tsy~sS*>4)(=8Y~4> zb+J2NW}WUSdsU6k$+E1suQ3cT58sw}{JB1Z@HRj@iv)y@~zCJpU)yZs%4Y*USmDW>BwdQ;RgGTzrT`FU@Z@@p-_`T#KTI6 ziwkmAYgR|~1^1bQyUUR5CT_TLGwbRzq%0&~^-mXC_hE9udUKpNL1&^Nbg%AypNwok zlRCIe0k?KYZ}@s{3l4Pg=~QMb^eJXb6pSA0ml|QBUSKk^e#6^O(q3($2o@PK``*wN zv$jJS+K+a*hpO5NA=cfsQPo&I(l#$ynshd@LU{$Lb7BwRHSp^aRdtPbB6Ql%Q#IbN z1Pf1Y`|_qDE03?YF})g12#z2XAW?QC^y-dtIc@7!P_$#MYnqdoPPk#ssu5%PgW@<%a!fl`fblPVe=VWzmd1{_Py}(Q zp8NBVZUSl;7@WmvWR`B+yHxFuq`{)LqB1SpY41aG?=fK+b;bLPa{pIL{k zX>epcT>TWbDWX)7n;4CrPBUonYK!u)-6XjUel4rpE~`+F4L5c%;E(VQE~@Wc0YqT! zabS+zdLKVlOyo;7X2gc4XjuT&>%rq;T`+hpDa$kwN`dqag1XXgrw zMi8UGU0kPFWg&1Hg&w9_kh!y)w6%r9bA5$ zo~FrBQ1r4sxF#pDC7Y5b1`O6}8jt!u z*PV1xC7tbYC90U<^FcYwLz}tji={2?++5I;h`UkzQNo3YoN5wUGGyJ?e-I-#UB~L` z^PQKI0BMKG882kX0CG_n8+iQTOe}Di+oaNedflv7V>~{BPH8vCV9IUXK4!aR%pIk_ z$DDP1rG8Fr8omJ!Uic%iqb~ze4ilKnSz6*5GMSb;mwLESuyyUJReRMh zd2d&Z?G)e=bFLSJnwhy~tJXjOwfFETcc;K*kl}hU2o|Ba71EQR*+TBp>z}f};nS<9y~UQieRX z=pzGLpCadIcX+2F+ryKu=pRX!uiP3p%MR*5F-WSg43Eq_sq(x*l6KMlSfz=-Nj%-0 zHV5X<-6Pp1rI{8qbj9?i6HD%r%S!khJa|b^uomp|pKABh+(s}CekA7e`hK}aBMVVn zMaJSN!pi0S{GJK}S=LbU<~pGtg2v)WyyX5v%UzK2Q}MAHWbBden&iLCk3}PaO46H~ zOUFOe=5p5_wh$PImFOI-9JdyacF~8ZI1So?gs_r>OY6IvcYFI)4p76H^LRifogM*!t>L8F|{Nctcepp z7ZK6WjCJwWe1PYLC~Qd@rqGbd_ut)2%mc5^6evWwA}ZaK1y|3zWxs0Z&>MaaY$@*mZLFR5Dp)A);g=?_1R z{S3yV4@h7m0>2;T8)q<;tI4bnD}56iA&kLW)W_%c!mskCN@uR&yha3NlU~$lAC8@Smn*m48=U8yv07{6)|-0D zxHrcBae!HpBWvH?9krFSk%!drn1b4xhHdA$BcAO%gKC|yvxGQPz8e(*U%r*Vk=?|m zY7xV8ZmZB0zFn>}(q>G;Ytq#ev3g`=C4QKyoy+}_n=v8Co0Hhrh&=2d-KE^Ccv;YVvR*Vf?dW;{5Qk2Ce@{wTo#HRmk)x>`%@ z&su$D$awQB>O;CXN~-Gh<%{K#77PUO3IV0V9O;%5-Jyd8&q6+uNW@$FqU9*UDyULz zbQs*vH111ku!{b9S`=#B1A_E%9m@QS*G!fIGsH7*UL^6Wlo?jy&b_~;zeBXTQ=q+T zJmp7?>m_ptyTQ+r2=g~Ui(2fzzXn?!FFV(Dw0nJwH=JmYD01-3-_mzgk>0E-E(z9YwQEP~bbl7Qn`pOq7j>=D}t}Y=c z^lHRpQuaHGeW(Lct-~L%O`EGyKG8UzuYQ-c!>HS31a+Ko$CjMPiq{QE%vBAPKDd8B zF&$qxIeBg;otFoTl9V8oTGTS%(3gO~i?7TJ4&3FnN=zbbue~_KCN(iEhfXryCf@N> zi^uo4Ho*J>1FYAEm#G;cG{_MV0v_9OEf{{J)0L`WXX`~*VtH1VInmF*)ytl*+kXbU zZ+`H|m$mOFlIbvz4WY^gb%i`J5f####kyppuuFsb^EQv65{g)4m04uug2}_}%^A0D zB#q5`>Pk1!<(M?5)acMqh-AEskvlfW!X8|hUx9&W3s55ECxWtya5{fD>arD zl1JhC-E%O!e|(|lAQhP$F%h5)0dd-eMNl5(%f%Hsv&2=f&a50TuXI}F4Bh}-A>Pxz zses`Xb$BM3PGWdaYDnMtI_d~L`<=^cKbpr$-RM+DoKj6f_dI z-~h%e@1s0x-p=-I8eUDy75d1sjDYfYWqblr>-3RNyJkOrApc;gwyAux1ABr3GoqLf zj|~^r{lT@QLa)@{XJH(h>2eZsbU~m;2p7_O$v9!`W5dAjYO0MjI+^Z3C|CA0fHgX0 z#X?PG7@!iH(@;v2Ie*VaP;eSw`AaFlP}R?67M32@k6HM}rL&m(J(oefb|ts@%!YiN zYIj0Sd@nS0Ujq$bLN3*xGz84|Js*Jnmj+HRdn*%HFe|Pz#Hz8(`aMp9!DHW*Ujv!M zOY#k_OGWfPocH!`bFgAbomh}dOU~Y(H&o-|OACt^p|`ut^hKi7lw^7SPh%pYc2q}C z{`WUyFSG}_`9L7CnrF*{6|S?PB7>%}(hCib{;0f6W)0sy9UX%p`A^K17(nBo-i7d@ z67>Ft*WR@M-2-D1aIz7nKE}=FVK$D8X9#@a?SE+j!@Uv$c-IUxfjnePI}`xgJxCBgXh>7&=@J+&9F5tt9hS$N{mbNsY><;$^o2I6f?y9_B4I8?7) zJRjKAqn$}hrh0~!!l|+-pSebtp7tZbjHq#;ZZrHfIHnI$My*Fhngsx0g9{nToE;_x zjHsnFi}_baIx>mqI8nu=R!qgxS|Ae*vOERzm78zy<;5yu8l-?1Rx*g)kxbJp-Hc&c zOmXV+`320sj!llZ-#=g3`J25j&vD|v5+X@!iZo)Gs@h+W6q&R*AUV|xJ%#ZD+e%w- zx(ckcxOef95_Q?nw04<@gbalDz*N11y2St|TkR?zk?HImZ9Hp!NiEZ#PiAWH=!ee} zJ9@TyHbz(pR~gu=&Dj%8Ym}+61?4%a);V{Cg0IvN9n}O)d)b+FHq?cZGdWL96Aa}- zm6mIZCGS2>9`E(m;L;Gw2YvBS2mp6r$tp)?`w4{L8!b_MB5rA^E{Nf)_x#b9$q5U6 z4E+nQc#$XeFo=JxBD0UNvu`eQ4NN7Ppa>FlY752uYX2q_kA#*Aby_JP00`W$5ERne z)64)*IM5V_ASmqf=qPQIWRq?yh$u3@RzYH({FNu=ZL~W50_rLBe5$4iTc{%8>NOsD zJKzoNAB<%FC)%j@m$J%e+sTmgmCm)fhE8P&JMW0cmGBD|u}VGtND9J&nk&MH*vt?! zi<5%viUuJzI_;`t}<^7$^oow=JKeA8?aS`mrBLD4``IR)9x2_+%z zVDY;Vr;2Jus^G`XJTKdQwmK}EskN+E__-m44LE6NMLl?w`BH(sMMRkuO*jlLxWpy0 zT`_EWk!Gs$VPD)Sn^7O+LAC-6##PC=t!zUo?vHUR`lgq5_`+%8wyF0m{xAew&l3HX z5xhgQr_`f#1&N4&=>*D1Iy3j0a}JTHxvxtvd-ms%vCNA-Y0Mz@T-r)r_kM4An{DTv z)qTu%lwfiy6y!4=an#jGz>poMVuk!S5%@vmuAuY97 zlAg7v769 zTnD(?DBRp39_e!r77lerBb(Y#M$&1Ck`ejk@#iGezUzqvi!9EKcE(GCCWM89qO{)I zo#kb=+zG`Jyo$d(Zl~c$(UgFTwQhtzXeV4t48^j-B5);UY4%*VltQ&l7Fyq@lq!;l+9q2b|W~3C?lw4IOc|h(iAe4#zPp^ft zUa`wj0CCf#f_dDk9lM=`6yhLIASK-8yLy^0tcs#GK;Y`0+3(Gs75SDmwZemniV*g3Jc62zg z=4Ah>%qs-O70MQPg&+465_R_Oa;y?7pn+4sqM;?FYOJL-=uW-Wmkup&DI{SdZ00Lu zTD7D_=N^~P{8hveg>l-S_R0ubPS+9ratzbtljPTSq>{Ub_Sn+& z8|V*4MXh6}mD4S=5xtd_n1+?7wkB*>g_q7PWLupgq27zRmp?5qQZF(xsO}MO!9(aI zV3dGu-mN&sPa)oOUFus^SV80R{V{g!$*ZQ)d*LkVS4i(l$vblu^XJueYA+0%A^E2m z4as90@!2yzay6rH2;BipWU701fsy)=k%6Bd{oRI6#*7u-+(|fQI)Ca=`n0d*o6lQ`;M{t?PLH>qphzj((@N zRxp1!21thV3qXuqau`Wr?HJMLLD4={SX;okS<1cup60(%{pXVJHBgBUr?otr*uW(u4id<>cNd<_55_XN;*R*;9`!YR5A=>4wq3Z{9LjW}bt?hjz zrg3iqR7HAFb6W=kZ+e=#+(V>=Yv8z;d}Bf^NJ^`GI%zfYQZpfwNLe<3>L0KS01W~L z<#1v`0gB~80x%*D4iC(Kyq@XuP*mkS1AJatOQ?u~y1YCUa%KE=?R*4~8E}PBOe~Nq zHM7|KPhD>|DB^CqbA6QXo42<933L~i!Z>T20_+_f$o>VQagAW(oVY{u3!Bv;xJ-^QXm;|5| ztH>?CwRJ5D$z7e!Nsklo<{~tPINaG9YNFW-{woE+%q2)^ANg^22_!2_9W%D&lbRqN z{R=o9fxNt1P<&#FbU+`;0US7g-~K;PV1U`~?|o-YIE{Ms>7pm=<;Oo0srHR(`nTX0 zW&eM{VJi+H*wgn10dHzcm1`@w{fV!y8k;$R;|upT%*+AA(X({%6Q~rklItG z49_~?vA-oNCT0?pU0BG~K78+c>1zXI%_zbS!RF>$pLEi4p*ymTO^oV?LCEzeg!(zX z9lxpTz4%qM*3$s!!Ruw~5w;-IrUj!L7wr(Kk3_=c`s8ps+a5oMB8F-3?#8J}7{nqK$=y;Y0!+NdPGXG+!VQlaB%8rbwLdn-=o ziTAV7*&xGM0@(4pJ*a3_##X54(`BPvm5Vxvv3-q;RtJ_X8BT@1I@ z{7=s}V`FZ;Y*9g!qN>BTKOJ}ta}#`Hknkrk#Hdt>5&ZIVPo}CjF2?+EEnhU&zBaKt z%L?o6HssA#)16r5>WHWN7YlGQFZNuRPMkY4v8|CU$~KTP=05(SwtPZ~s8Av_KxEI5 zNv@HRowzajE?#9u#f++4()thJ;85aQUgp_ZvEXmLwZ6*~IV6~#w*X%|p6rZfRYea_ z$S-?5+}ND_jw06d@9XVF9{u%&EOT$J;f({0d8BpDRHV*@%Jst&=ht;Bjo2hzUZTu4 zyQk|xij1mKSp$iM>;gN#0+wo-dgk4&N%gt!432(djs7h>sWNJ{9FR8lefDqP=gTSB z<%kMJLL@&5mM7%p$Q?u+hfZ7$5;oXV=$&w$8>>xalW2y}He*ZT3bs%x#%VP;>h8Fu zNfvtA*l`d1N%%NIQAor({B}yc9`toLueEgRDyh~hLcDKj*W5Six&#Qg0x87cmLE_5 zyg}2&D!8o1X1!fU(!4;&X4QCLKy}WXL$gyh8VGDb>F;;O`D)1Qv zM1QBd5wg$}&l#^(!E*;rj5(HznO@$r**^O7oaI4+2`eVL=fBtu0mw*XCX)_+pD{D^=d4A2JDYO>e77^9Cj;&E`eMZR!ByuA+ z=I4Fk2e)1do0AMVE=x8L?!B)~Zt^%ag3t#gNmAo3{iM6n8atHRTW7pwqC3ot@^1-f za$xT?oKkk(1`9{at2kGiva(y+%lHk3MD(f5v-5J&F=paPDxYXPDwu@S%aFEHPtw*K-yy(DS{Tu? zuuUnEpm3{aC8kV&nta&n!%>Emx~m9kWbTcAfJNGSoibf6AVE&Oy<}_$C-r9g!!?5*>cBtRUZoLdTes?{ zS~IN;LBl=m<^lra!cuHxnVELKM~lb5k8rDvL&MK4i)S&J_|-8KWiI69&O& z8J8~q6w=iEK{C0iNYX2U#<;bP%aUr9qsuuEEUKgZ+57us<1w~27mBN$tv3SclLLw7 zKHgIX<)M8W%m^-Yg|O}ZVA#F3wIW@51n}!QF}pyx1jrsh{LASje#`h}S{G6t@Fi;t z$*K!3AfJ`<){IBi1CB_l*|D}OT-5Y5NUn^NaQ#ggPkxZ&%I^qTEK zbddM@o`CJMBY{VqOp;k-JLG!2B#F&u2}Am>;U@@Q*70G}qI_-TG;O#_CTC9ljTg^X zfr|%IuB>UMB&amP_eMrWX?#@1+6+NpFceddIhQDcoFdy}*>S%3-wf*!iMiKZ6vr)m4aIa0@DY;CXJj z8}v>w?aFv`M81?O2IXq~nE!mq!cz$Sl5u2TGP^iqH0aEZ$P-C=lHL}7O8Cboa!yED zIBqWUxsh0Z06cf=?aec6x_Ri<0K=ihD{eOz7vJfOP;}f()Z1XcLk577Obgh8z9+XoZ9aByrn+U0SWtEpSL6i z7N|Z&Zv;nkVi|2cCW#n;&-CR3!RAKG+Pk}qmYnxIB!l&d9e6DB{SNf4XIlIU_EI4= zy*^k+TN1~)7(9zAy?O`5NN;fDMhAC%=6yBv^UCFg3XyGIhdAL(Y-gMZ@hcoGjxDhs zKh4j@pRYLDx0Uc4;^aZ-_J7j8Pc7p>ROI7RjNGfrnjmEu=1)0xr% zHQ@ed6(hG7?G^(!{$q`N6v9Ol52SDZ)^{!|&x57mC}XrPL1;Zyeb8EObtU1M_9XAd z&TLqU{?h{wmSvJ@zeOs<3*4Pdh%f!LFJJprXB!_h zxC6cwCPm=C;U^th5#Dk;mMWKN0iha}d4bR|N#{fkBCViZWf4VbRj=T&nTc&~iI;wz zZU^mPW5P|@=wB2%OnQk}R#-B+>g!-Zq8B5ke|05*fXvECNgw0U#9T zU*7=`OQ5VsPCfcV(=ZAAagIT6{ohdn{~tkiC3fadT^N`$s#7DggKCo4n3@Xi_OE_( z>T0v`4qr7#asVmpZyjggU@nyEYPWZHX0;W~^kpY%5=8t7Y`FghCU{Si#_*tBOxECV z)WsaGgU`-`IG}>}e|qpgq6b;hli&UPJN;HiQ>C zpv(@(t=HD)#>$)ihc{#rB2xsViH1dDptXUXWzVpIbchuJ#LeF8D9UJUExYGukPStf zSo!zD)PhA5BsOzND^!0oau>{+BQC|v?fTEZ6pLb#(1g7zH%(d!?~RMNFXqa^`|=-? zAR_V(=jxl2t&dl5Ff;+&b?f&7v#7?s4N&=Rryd&SFzD0jv9ecBT7XW|DT~vj*<~4u z?!>Q{LVA3{>~>rNTeAG|l8x8;+KXlx1I31evEb&m8BeqF^m;r3Q(D+CAOOthb^hc$ zI;8LAi+|60vVQCJHUON@xT@oQT^FWo!TlZu+ve_~AUw^fH2yC2dMpYH&qCe3g|{v<7Hdy`W(YdPidj>WyM01wAq z#ktrV$IxYax&%=n7ygP#E61K<=rZ>PUdrJCLnFlWHZxCopO$x!*rzspPigT(rU9j_)I#Z1Yw1zZ*CiAknHTQAoMy;23qos zZkutr7$kyP1&mI1W3DCSm7g8kZwOgw;w~=O$NSQpC*+X2UC6ap9d;>J2|V#>&qHgP z@1@#TOatnpzsp zMsRa*B!6b-+5yh_N)feysO4fOd1)KM;h*= zvXIls^I9$R$fJ{lr&))OH^cg^M|a1q#R{Zt<2aayrj#HPOgK2r4gW6ESH8*%nS;X( z1L2Dq!@_iHGwF{uk;+So!yV`Sbm`NS(NyJ%~xY(~c@-kJR zZ}%6XaZb!5UQU5a6NgWj?#{JOBWqbfM#myMBiWp{YcXq{Swe5M%*ogGGa?k>;9lj0 zb=T(3INk=--q@C88XIy>G-+@1WKswLmd4bd1 zy4rYcD5JpH*J`_RPd{9)6>I51b$mC;u3Y$;ecn*N*Uk;1-_BO92C(INa58Z z3kAdJuQM2%OdsaUmxXIPC7fkSvd2!WPZyIrcRJlYCJEKC9rI5LMm^v1U2ufByf&$r zGKnA@anahMg%~x*Qn=P7f}rTLZolSfv<03sCCSg|338%^kA7izyi*N?)F|7+f<7rh z(lOz=_2ZlZ1v#IxiCE6;J7QkylA5Z8oVXhotI7)`cic`BwGpi|QHf6WOdaA~XL!_u zK)u4#2O+U4UUi+e_kM)P_~Ph9Xc={6w)5Gqm} zpYo@>$1)!n^ZQUr!gVqGmeldLSxU^7T80y&A_3!TzH63lVO_M<9;=3XE{A8R)~B0l z4xnFK$YpLm$|O<G zT7P14yy0*?lp-V|vJtu=%&jp!urvVou{oOSJ(K5935Sgi&Q%1Dn^U7 z#T4pIc)T;q`Que5wP70EY$UQCWoNTrU`M}*{~z|=JE+O_TN_1v1r-qy0i`M^NS7`k z#6l4eklsN-danUOh>8M&fQadP#^gb<8Geoa$zuB<<8|>^YFCuPma9rEM$t<@AF4&(UkNFq;u8iWw z)g!`EJe7=EYkPRGG%_cHt(_kwX!aivcxcs%kK5o*ZS9rWy|VM6Q3U-hw9LeC|4ie4 zfF+f>TmGd~XEY3FoEf9RWW0&r2rQH1KXfr*Ou13zQ#I<%fXr;>m+{Q|#N|iZ)ZdwG z!sHKWUe$$}0;#UjRv*EMckEirsTJW;6Cm$XN2i6fqQ@i9 z?rjVKa#IW67V0X^-n(@T_j7W3ywP%Ma~UGKPIZ@FVOw9^F)1h$Q4ktS%vr4FNtD)b zwHk}DWDECVF<)F4cEaoh97^X+LP#t?F*YCgBSA`9QjH7F)G1Nt1URA~6Yq`oNqioa z%3Rv7o~4!mN544?8d?hGP_If zdJ=Jrf!CFV8@#%(doGngPwbT=&U`w-(SwGXs=BqbcjGBN#m^m#rvdu(H-{ep9ao%R z?d#Q`W}&!%il9e)0Kq(|Er3IC_ruuienHdhj{yY$=GA!{l7V_4-MiYmA{zdhS=GZS%s(_1Di$!GIlT9_E0(@jVqIU<$k z&(PxBlb#hoqeO&u+TGBI1iVe^R>9Vj@P~& z51I9*TmrzSb9bwg>DhXi1th@_Gv@i4G$^iF#t}}HD8AAUQyFWP8P%MCIig#5wYPE| z0seaf%TY-54s=CJNkNw`GN*Q#(#+64A;QIz$m^yA^--cV zdV4V=f1gN18otT-DD-vrL!|7(!iRD1K4*R8{mekQ9_Rx#4B=cTY0`Cte2)HMZ^yL4 z)#sc6Ztf^(s(WE8rmt~j@Q1?7pMSa5j$Ob0l<#NUuPQWKTE=;EZi?zwd<&b~3b@Co zd!9LP{{ZiwilmUt&sQrlNcF`FTEfqjY#*)0ni1WJ_WoXOyMx2h!g71n0%nnJ8k;9- z5i_OM=p3p@j^w7P12a@kr9|VXrLFCqDCB$I-ajdy-1z^G#=y%6oZ3 z4ia;M{fQX1u>;K1Ij@z0EcsBUT2+{md_%@E8$(=?Oo}OEHMn;Ms?v(pHQ|>Nx%a3| zDeE;66tpp`Dn9_HP?lR}y5V4Bn`pJT9^G2UAq)>Lu>>`^6?jQ|cPaP~BkoNbuDA)Jmz5 z2$-t$DmEL2hmO1z_u13U=1V}_lm8IoI0kt=IKjZ|uG?#rr0?o@szMLWNiKiwXngbp z8dok6L|!6l*TOe_gV-M<-)pBN9IS$*S3BA3r4Qoo-3k6;Q!7jTpxgKaFPcMNK|6(aB^jELMyola^g)$oZj;NZm9o_OaT zBfldr?96ieWd(cUW$8OD4OfM;`)b z)ryXt$-0@EdD@K9(nTX`gPM%4Wm!{&{ctAVG1OE_5*r@i=+8;dNV`E-9p> zJD2RTz1g=KECL9Saw^yT9OtfPqC%DQp@FN$R&EH^Z{a7#-fZpGL8*B|ExuXmj<8+N zbs%D97}StaZB;8;3m)vpbJMZ2ip=PXPH8!pV43S(44NvQa>(c~FyX&kxk0NIpY8s$ z{Kwb3#W2?53(qs?$@N2zwV!E*_CNQr`%q@64PI^KyW~5iRD!)?cvGzPbOHnfi@$xR zERf@%B0wLx$%1AP37u|3y;oHo9SrUOwKVjrG18!xq$Jv#4_}t!FD~J*XHLu<;*zQe-Gs#B$@L(E6~yNsFERw$Vsdo0dlZz9Q)M zfm+IQP6Q28q4UX$1hEUxXM@9&9{1^tHnzKa9PMA|ZoR>D{!zua)N6yGq$h0Z5}+{c zdqp$)bGPfgmgC+#VWcEdFY{)a?eR@jN!5x~*Q=&F=TrhmQv1}x{dxUra%Ys#$4g0Z zKQ4O#Wep;^?eXi{ImXRWsLq2n zjT1F?b2OW9OCGKwt6<(BdiQnC1n~k{mE9n+Qjhxvm2!d9 zAxX;xve9qrwn{db;+n}zL=Qm$gORkWtd@rv>QNH)G$0*ii@9I?} zro&2}`xwNCI>3)2*Ia%8#&R*xz+O*n59=`i_qixfa#5?r%|M5G#++niBwVNuQmlrGe2Y;OFJ zFK>6I%PRK3-I}$)KxLzzOZQSvu-rQIe1`YkCXAFjT8S_{~d4Y~=F0 zth8*OmIc=w?AO&(Ac8`Zmu93QmE~QPpux$%4tE*l=#?;E?;qbrA(YH~gce)Q-G-0aID8 zzP*itxb9)r=4#gbnRA4&0p=pJchz?7qq+IdHc9jEeVCft^R!qz$hLLga&AlQQuMFR z#TFyDmD=>T81*C0nWLXvGBM~!G5j+tLzz0J`xn3+z!uKiyqq=_n!-ik+=F^mOFdK_ z$P7X&rI^f9v=Ebtr^IAyO8Sa2{>+5Zy6fmf2Xk{3$Su-6EbVXZUu-99Tu+3rlG28J zyeFNFkgpMCr5PO#H-r+qta{gZXrRH$%j;mg2fye_9MxUfFn>nO1-ywVL;~?dVS4-W zZg-Ni4oXsI8hpW|B(=zH^xgaES(Uo(6({Y;8k>HB+qGU!BGbEF*_SEl6Ax(@GZm)2 zd8S`Q=L9Kad)E0!kB{4C!`9cmg)J7iqk(TTUn*$x0B1L5Cs7_e?mke1tYhAiJ3@Cy zdjJ{ry%`gr??|he*3b88b1J=7UL$ft3suxQu#^J@s;k#HEkg$XYTbZ~9C@3;uSkt= zh?+YzlctY{8`i7C*Sde`z9ikURYh=IK^M$DXA(j#=K9fje}3S+tSup~DB30*$*Sech1VSGd0q7{hB&~A4axo>V zB)orbI&!&o)D)i`OAr)ASjl)Fve9k#tyJ(XrMsE#u-#k7HdY9 zKE`-Q2djmbn0gq?(C zuU}AHKk;gf`r>U#hHgd>wQ49+SIG}E#5|~Ce5mxIme25Tt4V>hy&Q>+)uHNkNItG@ z+W!Fk3Z$AkB|YD*b(zFx>nx=2E=4_+;B*DPAN zir9_OD=MS4ZN3AagjqUEBrjLXbTcKx_)~VO2TqQd%)foPD7kE_Gb2(rjL~_%Nvd%b zYdd+@L5$n)@m@61eOZe*!_h0sHCvg zJtMO zD;`}df!a&?bdR4zSnsP_GFF7MOz-Wj>!W{k_fwe=w|C;qc=0Xhmn+g&3drVSH~P|_ zx7U_07CD)@6&F4ax`wU1R|z2oM&aU_Ju%GcGEM^D2o8~Ocv66xi^S8XWAqXtg!nA88o zF9DPZRK=qCR%i=W_*Lq}gBGX_Ch1#QOY-Td0kceAwxsgr^fd5RFga}8UQ9<3m{Y~h zL%&Bz|o!X&r)gElg$H+)zf{0%Y}@Vy}Y%Zzne)C>7N>5bx^p9y8V$xZ7m z7uP;~z>8@n`{X}qvh^#4xC3*MAFSHGpaQ>jF>j>tY~X0FXlbhiuz)e+X}L0RNGr(Qrl}fxB;KRAF$hnDL4uU)MK8DEZ?d~h@Z~2 zM9zJz#wn5cMkvUwZe(`9^cNJGUfLR+c$ov;o~W-R2cG61ocs!;>M>#a z>>jXC_+_Doa90aIo#bICU6kJ!*FP2Mc_9A7O_PzRuM(cKlz-KfoTlGKbmd#p28ZaC zFY(#cg4*ciH+sH&W&JOUb3~LBjmpdsY&{N%bg)O6XeOhWi&c-F3^=`Lns|ZjT7DC1 zgrD3Zznywp6+uCb6O-8ET2&^vf>`XK;rDBYC9ZmFUDZ3RUYM2N?= zrwsLC(fZ=b5DM$&E!u>=u1b-G!_BGr6kia@4cGGIshGEc9^BSO$8h*f+IRD*GH6Ga ziL7*kKN%uoi68SQEyTO92=7g=2}`QM_|$rqUs+XM2QbJba|6pemSxHC=hH$H}VyX4Ir0a__@{9ZlJO zBAbtvpes}{Ey7cIJ$_h3k#nM;lai9h(EWJ{>mv!jo&M%jRwEe{wNa8s{@%jC`pU?L zkkx$QQeJ^Nf&rKN7nh>6dwcwXUH<`?aFGpqQ*`F_J6BiDj=i$yi%FY|SE{Iky$P<+ zww*f>VFkiSV`1|lkgtx9nr&uZv!`#<;O93Wk=aB^zI3?S*|7F@znh$r#JcdUTxztC z@gcawQGo)dskX?$alch|Zr8{^%`SD-Y)!^<`9t#!+3`_Rog_@p-mOeo;k6NhC`nB~ z#<@(=p$-W2-2LoWU;!BZ;s>gW3SRs0ETD>CpN8HtMY{jFk;&Kc+C ze^&3C&4&5vv8|LuEo3r{X2luFq`$J@Pu^)(T%_%s=9=0YdyOcGa5{{k)&`puA-RA| zD+TeGryufX?M+q9MvLk&iEgc@cH!1L%*22azPQ{JHu0H?3U0s_V%R7ovF`d7^I<|L z_oVEVzLT|=);IJ@L_$18f<^>hZ#Oyq5~^TmSBW}Z&l);%>dLC6vaFcHn|xPieq7vb?$C~x<5v5x>#jp>D=bL<}f@*tJO2I zY`=%67l6IlV-!k$@gfgHay+Lq`<*N9{#vA>kR6MaZLOf&PfK*u`jWj8a$*02I?9uD zGPvoH;=dS>GE~j}9x+|AL2ejOfbby}JK6@4DRLh^l5=4wC-#h8s?7pJ=4$U;Jo9XijwHp5LF!BsO-+E72JJ)OLe-pS`uxiAU4OOw z(D=(`_TdR7;*Kccyb~#}UGdvQ!?B;BuZb6IQpsh;o%^Ej-;2*m zokj(Iv5wvrmC3=u{&pTiw@ehex^lTxO*~$SEkhNwe$J#!i10aC#A)@!_&`{tIXw(M zT!rvDY1k7?hsZz5pf$>6y*GDgLNyb7kIF_et97MLdl@|^FPpDZ_8+(mY%qaQh4OMk z7%4hkX5C4Oj2T}~PyEKWiUtpe^ZyaAQO|(U_O69e+^XtO@ z>PltmODHFmjIEX<-cPGWz+h=}8HQ*H8M_$gK}9{sO9o7AbdSd}EAk#;U)FXE0~cni z<Yfm1__;XcbzhBP#%?Lt(iJUtTjV6J+pS~T=f^a6v! z%nhNLNewN}vNU6ldfHfpYjDZDlV1+>Wz-3bF1;)Kui#Xvk0%iA-5a@b&GMMyF__Kz zpamEIn1*ZwWqU6wwG4>lAp%vt6|7b$f&1CD?ajb2x9ppq~;i zEzw^(7)5EZ>dVmD?eDu8R~i-{5riDU-Q=>XF0J9GnOT;O`Aa?VW}SmxbZ-NH|6M0L z8XD+n(pcM*Lu+2E$0D43D{-=$Vb@znaGV3`!Qmjs8s^Y=mb05P+M}Wrm-B|2H|J+X zhXMp1>RE3eZ45#fWe?UzKP;_SD`+x3%b2-TI6+_a+M2TWsdGcTdW5M5i7XRa{&5;k?Qv5`kAcC85s4E;{iJZNf6VRS z9)(YJa+@?8rFv{Fk6f{yskIqsQ_|AQL9GZR79&qGZRSOOXnYQfa0z7-FdgJj$PX7_ zmEKd=(wlwUUFENQ5Lk<#91)BYb=%Ck2)e%mt+tvLx2dB1@)-mQNp?M~Q&Lw?L`a!P z-bXe zCCs0f$b=Pt>deZY`_dmb+^}gvMi$(50SbLwNqwD0qX5zlX^f^761MpheE=g{OKo#;-`9g;eURQ#Sys7kaEji zB))SYW3{)KghS+V9GB1&N4C*p(Cz-kn&|ep7_>~zvX9aZQ+6tB(LS5@HjRdX{m`%^ zcU}uFB%dw6Bb1V|TrlL<^#15Q;hg+ET&0DiRd+H~1&O_ez3$#YRzvAl`xk)qDP_M%SE7my4_Qt>{|`Luha6b#1S1Reh{-EM9RalOP1QVtVFuFiL0 z<1jmlSx!!yhnEf#b{;A7TWR`TRfeX)Xs#fS3Qd`|fq@aP$qlmQ-w6Rvq+j{CVFP78 zqdr-RnP*~|h55Y=kpk?R$;^jSUeg8pTMgFAMX>+5lg z;!p3Ym{M;S+;E?Os{kH&B_li>r#4EyKpxp28o7=ajgeXl`kl6tR+`at#1ZqJmm?sF zBq;55V73y|ZBoN~Sl4@rHxdR5ztFI%>JFb^$|;}X6YueDb(+qa3|@`(kTJ2ar`Ld% zMmj0iOOkc7|K>wk#_x-$tam80bFtV}Zn`DwwBM)UrBP8)6kOfdC!4&MaLfCF?{s0Q z+;erkfZX0vt~ywr;moDZ#eF!;OfMJ- z=aou~_7NB1cO5R2+1@vU43}6?GM(#_75bea@jxXTTN;~DVW}%#Rdr|hxRfo z=OEbdC*&5{!;Pv?Xt{8z>K8nqAPUJZ1xbG(a`+;0OlnOVSVcp&b^bTo?1}9Nc%?X@ z8q}E54N>6}G4k@nFjpTm-;vOXa%53ZEc^;wtWpdrspr$h1U?lMh+px}C3T+l@hc;H zO&EEa$*Y3n8d65bPeE(p_-KK1Kf!_jCkK*>jY9(D>Ojm7Tm#%6m;R26oduFP2z^9!T$MOq@T zEYc?2Zu4Egz}#j_@i+6Be@=kUOUK9t$1~ZI(@Wc9mpya-9sJYp#FUAb z{kcj$v8~RFzLOIdClp=SD!f+p`Ae|A7b*wZ#*4RuOnqX#=8NT?FIF>&J7K8lCGqmkTAFw=STO)w5qH&Tw+7A3dbaqk zjTw}DL_F^9K2f&RRY1w`vHXf1Y5yu|As}k+#P};3N0ODMx|S>ExaMYB7F?wY#Hl zv|4H<+ddVRl$Q(sNIs!v0+eQ7r+6ZL@Whe7@!C0(e`A>Kai+Rl6A}N?DqDrjCH0@g ztpB~qNZN(ymCu9;NK+k*UOd{PmPjG)?m-O43F+a;)BP__>Z$`Xi?F_8ng3WBbd=8+ zt?y3b+TZHJ{(4}$*QX@|k{N=R=J`5wSBu6#(e-pz7j+cI-eu*SNET#t|k#S zQ4rI*UNVHQTM|6`M5lQ&{O}d8$;}ClKXlveawnOg&JjuMVVUVkRf>j+%{5X5+%sFx zZC3za3F6EU13GE{veCaixj(~^%%4B{k#V3nI1{z^c z92;||=At+lKld6E0FB!Z-ml+(g$9?3sAk5`Mc}|zmG-cLs0;*P0gez=s*hG1< zVwa8K6jv5e74V%If3$-VnT-JmuYCHNmw9R%DjPQIpFj8-nNl4V`EHhsRNRDQnkPoC z+pCsF-%@;(KH!*e)Fn>TSQy|%~RPP6PTwv zv#7N9SDpFDN=hoRAy4M(vd#%+Yys{J_WSKyiE2P9!<}_+XX_w=YfkDP1^fuNskwRJ zRi`Pvd{H43|KN}H&3w2VQtN;_41`(O9!T|L) zGVmK?2gCZucF`Ee?ESv_Ds~_1eS3k}=8pg-5LnE8+Vc5$Hc4Rba7XAzF>+~hG`DqI zuso!xwa8^K={{(0gK?`z6R>p{w=3m(ElFyq#;SQU{=~F6(A3ml{pwyRO=L$>LpiLW zrdCA4%q+V&r>B1NTW~-qym7o+sD$Ku)#nteW%U?qjY9X_8ol^g5J@HU8Xi(eg^lH0 zcslWC@7K9ZqZ!iQcmeuR@C^ zcl??}San8jQkqnBu=t&bcI}(nvK{#@)i_BM+SpohxTQBcN{1VrSfw2Y%JUQmu(O*l z($;s_8@|!CaQoRMa4pex0sh_Bht zYhR^bGHfDvJ2 zQ9(D5U4t+XN=}a1cU@=s_}H_mN}S3}%$geAStEYy2cHOkuEzOqvA%mr(V6go;9#g@ ztkbm9Q8|>JChu{|b!>gvz({|m^H}9h+x^~&SeE03FTq9WxsIxD)UvywV5J#`%eJ4a zNS3cy&C=_uy zZ2)7}d$T~rtkCcVq?8GeYwmVNh>#c8;c9ERW}CztjzYG_~5z7Y|@(=LZBwL>SZ` zYbNL0_nsSMxBk-iIk-mE?|z}xba6F@*JvIL!z{cnUjpX6kuYA@7#tk^`}f_n@Em2W z0-tZac_lW;_)~{^Xe8l#@i`lYAv@W#N-H~^@h`i3^Uss1{<$l%f7`YH3&GF7yE&z= zU}ttABijbWbM@Xr_T(492Rbk@G4wMLaL|D(;>>~i*G7MGQqWawB0Y&+o9MvYU+t(T z@I<{@kqG}Cyu35p=!j0;1bJ+&PQ#LgWUj9ig!WkBm=O%5|Ei6zLIS}Eq_@1KJeHno(Thk=ei8I@tY~td7 z_IBU=zja$%lgH`}tvzAgx*n8d+ayJ@vo6024%UVw)@+16t{AW+L*D+=Q<7G*`Xu33 zy5FkjqgN$lV5%amo8Bo;wR@(*a~ zjzg^$!YnUD&vH6UM8$bwNbU=1M9+=Sy#gdF-*ax93hqi5vj4!$IAQX_+m_&jZ&0l; zaWY1>BZim_g+Z#m$-#v_R(p(*_3lLUY@oqs;}^4ZNPN^6T!&P2k;N>HMQ%8HkW`L! zK(EL6{@qT5nltI=t6AU}bfW|MIQ;@)^3SR=$$j$HvMG>qyEl*z>#D7jsybC^iQ=6t z(WiBI)qbp=!69MHcpbCA7a^c&HO0K&GcXn;@ex~lHztoDj>(QrojmE*zqR0G1l;z1 zX595{w7Z1ps2{6K-#2AS-W{>43<9pKcWR9y9Soeac#FJ6dn^YgXhzjr>MYYPTJ;P{uf2Ht&g>tcAmn%nqnZmRM;xzvlOTPM%O+#} zURnwo@wb?>iVJ#&K1GmY21y0`n1pyAIIds>%d;Z%u2G6~|HB2yq)Gx*F1v)SsuVo; zBLVj?N!+qd0srM#0c{og=kZopbH~hbsJ1~!bXZssG&uMzr0!Uy^W7*%j?WJ{Ihd-U zImic7unVt9z2sRit6!2w8L+{7Zs#o5ope1h;+9G_%RJm0G%+)uww~IQJtTVUc#9GP zj*gkGbPAXh)6(oOOZgnNTsG~p9#CnzzBK%R!u1wCGbcN{Wf5;W9mw`oyn9twer!bR zVTu$_g#Wf~kei#p=ftpJ{dLgoGgF)uY9d_|x`QI9k*p%)avtR9mr~?47jOOSZynG3 z_hoI$Et3tFM)Itj9Cb-0Qb>)eZt-+V>(l-0_9m4aCta0vL8iV1dk2*b8!9~N+u=Ug zSCPRtb5@PFg=~yp0Z1U4gM;IJK*dqap-!pZ5*UxxW9C?7hP;>5&4?w4rYMpZk`@S=> zajLdLXY!y!+{y45gKxD19VF@+k_^r92G>_x7l(eYXkfN$x{6^&6IaR(~{d0YMc7zTv5o zM?phTy8ad?lkJE6q9lN)%(JwleGF-_+B2ORbNd7NI;+RQhV#+a`)8 zT~rg8i?Z0`hv)9$n)zKo4C{CmK$5rz9R&bfx@_O}eSdGlSI~1C*#W!9!pA39jPsCJ z<0MunzP9P3#Y|0|!?G0{{oS$!fG&%b*waaj4D1ostC#kxo9lq;*{f}i#U>G>Ml5zx z17T8QFAjmZv_Q6Y*;2r9BsYhgTvH2hvrc1LzF0e1$p@n4<)&GD>W&aqMlg{fZ~htG zwJNz$gQx0jukW*KdP+$m)=yOKw*tDwjMgaBva?t9M1-;F!0e2+CCrkUMv%L@ ze4@pyGLGeg%F3O~Ew5HuDRT$iDFsZ*`Y_&I`&g6WaOablUYl!hm|Sb!hF#~y9n zWAg2q6CN}!ZrHfj|5H!*uaICId?!#9f7F<5NMjE@q@pB3_qQ$>P|@}#;T{j;Yh56S zY!p08#z?EveuIJSbYal6@mcOcc@dwee>DGX11J>mdCUiEwZ6E9+<pwObM;E{(HI9kAZaG{I)q(JsPQAFjO&-k(;d_oc>m2#!{pPY2nFNGv5RM{+fo?f5@L z&z*#g&oawM_|+}S08)N}L;tMWhCn3238ge1RDZ%=QaTsX;b?>0);ZlUD=%HUv!}Hc z9iv;q-z^do@*;@Bu`=S~@kQ|z5&foe6^SBwQSn^n(7F38tb1CEg7~kM=-O@wYr~jy&uE0X?tIh$+XO; zY2+Ef#wv@F z@oBKoD-M3)eDX(o|&#-SGp37DU3znBFwLC6L?$IX^y2#`q`0{o>f^A*oOWH(YmFyfPK>VtII( zy0!*xK$PAn_|B1HK_T|C&AbDU^zCTaGAJ_QbN5!Y@!og};x-FwqNtZH!|`s{uWAWP zYs>G~+^e8pJ16c&S;>qW$gL|2M@7U;dQ0k?w!>`?1yT^q1fP4-+{eE(%TVZfb8f&y zwcRvKBoED%TyguBsQdS5?c|voQGS?7k>zvKTj-Iy7YG}_{epKlSlw8}Po@Hnr-^fU z^{&V03yN^Mtu{4NB)7_JCLB5xlPY~WZAs~v`je2HwS-}+Dnskzd#9GL*zd3jQ|@CR z)WfB;8r+sSYmthdJnBu}sCW13iwhOrQ!ep19ef2fuCW9gF*xJP5XZ|<^V1;0w0u_d zhT#OzXJ??j5X?5ba#&icX{gOhAK_6}Z@Eua{KtNl9=iu@i{njh-IKCYa%Jfdw@L?H{O z;$3A5CQ$6pNJ7M*eL2H6XQK~rR+>j zE{4N*pH7oGkx=X+B^2X3uct-2(2TRvi+!R|?S&*jds_sl^(QELH_QG9M*S~tT>lnt zoIa|@HHNK1>Ts#LRgfQxXu{*nNv)_#Y>hyr{lA5D(F12d%$%&%-)CIP36Br7drhei zx9x{JFu7_&Niz7ws^q1ici=wvxQ{IH3&k1LMtMtkr z5r+SVW3itydb$oN`!9RS8fSS;E=|yIp8Opm&CN(bdMb~aajB4)6a=d#jJ}fNPtD*t zRvum<5)y4D7gOTCZC9cRW3J@*6OT-(Dn=nw_g|_Rl-1sij8Eob?;QEoHfQy(e+wYk zPImWtL(RIRqfINky=Hm=o%YTf@bwpOT}1u?sdI`k`O9S|yq*BTW0kW{lZ@)Z?{+`X{pnk|i0t_Df zk;R*MF|oHwAXp~1jko1qGcjA2#p99G6^K0B<@RYN%)K0jnBm~C8TYozIa@qTw9f6Z z|6$-zq5EuTG~&%#jigBGS_}i5xWw>IbzCjJ_^_6HMrL(b?s?P1c*MxmgsED+r0w#m z7<;(|MoU_bV68AU8vql753Vo$SgisuOPOBV>UgB*V{isyi@Z&W77`E;Dp+$%&K?0D zWEm`;PT}aurmm5Q5~S-1)9&Sn&nXyyxyV{{xBcvF9R}ZRZ^k&(zc=FbzvKgOuxrM{ z?3&XVQ&%k(%*|I$mDZ&pvpRe|?-%O?*v6xEeLOF$EMC4WAFdt-Aywc7p+qE{w!Wns z_5+}9`x96RMRG5D*Iaf@uea{`0v?{56d-fcy_&Bz3&Z0O6)4yWm2*Tz1kTe&!)HvR z{qnZLId*1Aa*t;{o(O@4MQ3+tYU@^!PUFvB;`yAy@xR#yC357)kAP)cD{EpWg6@iK zv2e}a&=;1jmdTcS)hXAeNhgz(zP6}3rEL~@2l6m%MYqz6wu0H8pBg6z*Zoo$2a0Mj z8Rb=FvoQX%XvGB~&pyZM<-O3>Gf%^oHE z)(?3U&Bm6pVpEF`WsI1+vwAX|U=N{?E~2L?`_7a~V>vFzz(xlALlNjJ{&B#H(exli zwr_%?ii#`^3>PAk(DGS(-p{5^Ta=9y1(9zC8#rPg+naeUg^G~y-YwdjeTSRdaX>F? zFI=N{>WMAT$Y%B=`FxGypL2Gw>!l>o7n*wfp8?-Y{OTV_Y~j~NC2sK+vC`8R6`%)c zXAGe8p-CB(tNUu4Innx3k1#g+y+Ui_{wrNygjavMvQkYO8rsYb|5E4>uJ5XUWnf_8 zZV0P4lkDIAML~2bOXsH$%w&g!ytb|@B z(qP27aYh-SZgj=luL^einJ=Fx^(e=lPdj4=osCr@9nYW_8*G!{aOd+?7vyg|?H!Ta z=k!LoL#lU6ZabIh1)B)cr$tHJBGMQ9!@Nk#EQz7ABv2ULi@+M*lss$Nw~S z_DIRd{wu_o|L<(|jyO7l2grk0FS9~Oih5LG4<)_?(<>3XNlGS`-3*DJpSzX;fjyEs63A#@9F5BMUzh0k@E;M_5 z++4~;M^~2~#QrY30j07tmy?r2cbmk#(dLUG{b`|ouJmKD@XkAWHG>eDi)25eva}Nt zllfax&cDvPZaH`E`0+Wi9WuY*^EFSuzo%GwNct+p-1D11sWPrUzJoP9Pv%V~D|c?{ z&fi|0+<)oqCx@8p<|q+6ZAL&X4JA`Y2NDmQ(S$)z>a~`*jd^ZAd^;S?dh0<;ip8(! zC^T^oLG8Z;vXdi zby!_$dj{p$URFsV%_D*!X;Z}AA$_$inu~WIAyZ8sH_+E#uktw`d7U~Y12vzb)!N(B z#A-n^+`D~vL6sv1A?Ix3h+-?jhrHQ#I)26Z=bSG{!iBWixT__+*2%U-&$ z*62|GaYxSbXHZcP?zsMW&}ooDuGRD9a))AfprXoF1IMSxl(P>ja#^oB)j3z;ts#R6 z*FN=^fWkde*;rFAx38b%P)U1Ly)AH>jtW&I_JXX7KV4Ul^{OubJz8tPP0`-LUhk;=K%g#TbtR6JzOMhEa!f%0&yTC}I$wSuR$wGyr80ZnHcSzWL`MKh?&GA zNMn5XXccnL+`jna|0?df|C-9SeS{f}B1KS95txh!5}G$ufyli&nD;-tpU(d5eLlOa_1&xO zv(8>%k%gq{;6zNo_5UpFe{cKj%gbr}(fS9y!C;gbO*e0hvSYsBMY}sBN9n#{Z*Vf# zS|aM&R~abq2dVA-nSUm~m?uo?VYVH=W%ia{uu6xrs`|@jdxnb54I`tp+kA%DY;OxLrp7$L z3NA{hJi0c!*^o`Fp}kbJhNSl6P?9rtNaIniOUg$q_HeEaHo3JlIKZwfHi5>cz^gJ+ zmQs4r;K$EF7Y6ONiK)~beFKWq`#?vaXwLUDGd&$rkb8NH<^LaH88QZ$NF%_<= zE#JG~VtPV8!-Z~2pwVk2XPQZR5uvo|N>mANe5{0|Yzn`93{t#o1}mQU@grw2yI;S) zeqvS!8&@?b`XS9pn!Tkt*)%USMthCF@o^3cvJBo>Pjdo8ES~APmbtT-z=+0}2|-?g zsS>msJ{A!x3SVlFO6v>j$-;8Shu_hSoRQqxx~hv;#w^z7vKVUa5$yWNc>4;U?R2l; zcgan1h#M}fR|*+VZ(OW&o?n=bvq=Q3B75}1o`8hyvHCXheJ0zn;A&!EYf^W~tpCOj zs6ORSfphe?UDchtQ|zGUfpfXv@*oE9+E=<*WaSNJhsw}cP+jQllA)Op1xV`pue=OG zCC@7H$37ivVBri+y9FIg?+b&Z$}PABAw*NXTG>hk8rBMrb}y9D4D$d=qtEFLc<)Yg z_Y=5w%jiPsygCTSD*VRi%sEV0enr0vV|sY>zcZgvYb>qI1MH`C3GE)B)B)?xWNN7WpOG7y)liPc7n;Ewyj@&5iBi@o?{ zp=EumEXl&QM>O_qta(LOgsFr9*HerDNi6(bRFEd^qAGIJ&}wI6TaW4 zL=w)gUGv3E<>6(#I?5gG`gswC;mXP?K&086E8KQQ>F9L`whE_T@Qho?;RrCqYj5ol zmwfYGLq|ijtNK}aN{!_*&M0w&apf2gqKH3v?QDElh%p9@-4R)CrZX5H+3m9$3#_qp zg_n7~`RTlU=hNv9>)Ef6e-&vx#wG%rk6nTusl990UnVWw-`YzVDX<=L&*9+UhA@+> z?%W2yk;1h8_fJH4hxDh?fD+qtpdXgE+n=A~3w?B-*QPu@Ug&06 z{3356y-H`Ig@03%!`d7shN0~ChHpTa@7A{ZrthGaH!=sq8@+jP_x;t-1gxLU$buXK ztUs4-HHT17m0Np+L(NsP(IErOvAMBEfUMtHlR;KpgLS zvf_;NcD@womYi!FGJ{@3fR}y)E)FsO#qqET+24;H+LB*zt`HVy?$Q|L+@CRYbq_a_ z!`GRZUi_4?wA)r!Wsv|$y+$_}Ygu+`ADtjp%H&z@zAP=PH#(7<^+sdCot3Yu{QWJ2 z*9!t2eR1>Jzg$dF+>)x|^IIXwL!;z~RD-Jq=7t5TI~#3(+L{vV-I+kvdwqRPJ2W*j z$h2{+Ejg0gQ~DC_uKZE&yxF+^^ZBs0euv*GZ0W6+VJ7z|^s6{QK)_O$;pm!`C`MIsI3j5=e%jaj)5NkErtP(myFuzJ$P zQU_bi7OZlTwqgRdmvo4w7q%T(vF$YwUXTt56nO-Faw@8#H~g;_wy)wC&RD7o#>oG@0Hqet5G*$;Nm0pxFiX-j@htj=uNkyY^;{ zsHW}lb_eQyWEXdmg=?b{>Xq&EXh8$1Vd`*->QuJ zWtEpUSB&-RN<%y?`%6$t3kYyl71#gIxz9CHM5Zz}4#*W;7bIUXLJ~chwY!ub3gq?A zJsk|&P~_ai5Po-wYav^S-i@d>vdzIidHzv~vc56?DU#_=ecohZ3WJ$>9uvE;k>$1X z^X%nE5*D^x;n)-4chN2Qs{CB)p6p(n!&-Ku$VkHyTxtTpyWV-Erz?ltQB$*}XQ2d| z^6_kVGkdimacyA0r26azh9j?(bXlIzdo6fp{f`wwXc`fbbl3OZUG>qbJ}3;(3jZ*1 zI!wcE;h!HZjoh0qeYtD-(s?AUdCfltWr<-kbehfVH2{PC)p9tPdf zlnVfzHo=Kg0e+DHD*oRe4*@$Hm<8wSJ?`k8{dG!K+RiA)4?A)%X0w9X`!RoXOPY!2 z+oh;B0fZ%v>v!hfawY88v(asd{AYs_pcMmT!<)dG$LboHM=aW5<}UHA3X?A&1)S!f zgt8xI`x4kd_1W>xyifB$N?oT@&9batRF*B+C;s(YaWM##^vgBC7QJ)RB*r&nx+`o^ z69M*_?pmZOIM(6J{EM$86g*D%a{Wekpodm18^fXGX+U`EqNdEzk>4g^5%jehZ3&h}}GgTo?NN-Sm63 zD}?aZP%Wu6VskWi;COK#c{{Mo!)tx|Ch# zWJ@b%6O}aBddt6k%XclFCA9Rr%X2EwJsDU=YW+!DC+A=sHMA;uVY%O;qd74;sI0j@ zam99T{8>g#|A#cI#`e}Q0Up+dwogi$+VX+TFRT$JrWGI4{)cpKO7~!aN1e49$xIxd z_sv=9uL|^r<81kUfUr4b-p@+C1V#3~1be){9{w=ctKb;qIQ^{A+x6do9owlu^(eO3 z`%vFrLX}2_cz=JrxylW&1UH@{${}c13}dS91-v^G;q;&-+D?p=qi)&^)#bvSK@0RE zulY3MjJbZa;N_`P0n*JCDI=Tlk`menP%Mf6@O5WyyQf@0$>G-u~zF#=foZL z$UT^D@GWSX!X&F!x|b>4tCZCoL+u*iqzTeqzdXbti7$sTznIw3>h>QZd(C(Dqcx4X zuw$$*5IFWoc%=T_ocUq%vtD%-&d9Z+0+#v|K_@QXuDX7>F{ zgp$a=3}|#9*6z7@0>Fd0XhV)*ZBbmUF)|VjaD?WK1kQiRa8mMH#RQLT5XbWR;-RUV zgd5Klvnb=hCF15j@)_6tdNK)wxg$X;z{PN@6Tdg75Vib15a*kZVAD=%X{q+9fkgki z*ClDKz6+NIt&k?aS&j;dDpki?1_sll=A>l3{8g4NgR)Kl0TEXhH7Hab5Cow3T+X(_ zXr0b{eYPt;?nO&zm_3}Gn*;xOWnCd)>OIBD=BuS75K;M+v?rxXZs6Z`Q`t7NzJ7h; z2P^-&io}M`rJ|A~6OHh$JX!^G^NvF?Nr%BWZ9{3^Oo&7N1ZqM7YyQ>I+tbt0Goi!% zo%y7(;kX5E9{8e3I5nq=a|dAPTA7!vLlr8ito%+P61%!pj>Y$7z#=CltpK>l1w1%1 zB^E;<+4lnj_ZCk)(6C(;7y`Qrl=KwP0YE&ZDJCZ7gUX?ec2hI6jyWwre*letYk{c~ zTl|P*CG1bXl%aRNDrUje#CzWynt41DuY2L3EDw~sQ7uozh*(+Cgms25EyBdov9nvm zFkAjz<&eki&p6Q}+f59L2UduJLzt$zPh#YQ@K1FmwcY#?;DC`4eLU`rM`lGuZjF@~ zkT91akw{#@se}1~O3(9P@i*Jy}45C023hrD|L literal 0 HcmV?d00001 diff --git a/docs/assistant-ui/thread-tool-open.png b/docs/assistant-ui/thread-tool-open.png new file mode 100644 index 0000000000000000000000000000000000000000..ce241b4c47e13f0768f90cb2606af693c4bdee23 GIT binary patch literal 103296 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 z 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

X?Rt!DuJG8`i5EL4C`pojEUvm8RIU1f3&$+R& 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

fpw=^P@1ebX(0y}u6s!ee4Kcl(1bBc*=fv%!wA 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 literal 0 HcmV?d00001