@formthefog/stratus 2026.2.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +719 -0
- package/TROUBLESHOOTING.md +245 -0
- package/banner.png +0 -0
- package/index.ts +387 -0
- package/install.sh +215 -0
- package/openclaw.plugin.json +62 -0
- package/package.json +34 -0
- package/skills/stratus-info/SKILL.md +228 -0
- package/src/client.ts +98 -0
- package/src/config.ts +70 -0
- package/src/setup.ts +210 -0
- package/src/types.ts +56 -0
- package/verify.sh +110 -0
package/src/config.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { OpenClawPluginConfigSchema } from "openclaw/plugin-sdk";
|
|
2
|
+
import type { StratusPluginConfig } from "./types.js";
|
|
3
|
+
|
|
4
|
+
export const StratusConfigSchema: OpenClawPluginConfigSchema = {
|
|
5
|
+
parse(value: unknown): StratusPluginConfig {
|
|
6
|
+
const raw =
|
|
7
|
+
value && typeof value === "object" && !Array.isArray(value)
|
|
8
|
+
? (value as Record<string, unknown>)
|
|
9
|
+
: {};
|
|
10
|
+
|
|
11
|
+
const enabled = typeof raw.enabled === "boolean" ? raw.enabled : true;
|
|
12
|
+
const apiKey = typeof raw.apiKey === "string" ? raw.apiKey : process.env.STRATUS_API_KEY;
|
|
13
|
+
const baseUrl = typeof raw.baseUrl === "string" ? raw.baseUrl : "https://dev.api.stratus.run";
|
|
14
|
+
|
|
15
|
+
const provider =
|
|
16
|
+
raw.provider && typeof raw.provider === "object" && !Array.isArray(raw.provider)
|
|
17
|
+
? (raw.provider as Record<string, unknown>)
|
|
18
|
+
: {};
|
|
19
|
+
|
|
20
|
+
const providerEnabled = typeof provider.enabled === "boolean" ? provider.enabled : true;
|
|
21
|
+
const defaultModel =
|
|
22
|
+
typeof provider.defaultModel === "string"
|
|
23
|
+
? provider.defaultModel
|
|
24
|
+
: "stratus-x1ac-base-claude-sonnet-4-5";
|
|
25
|
+
|
|
26
|
+
const tools =
|
|
27
|
+
raw.tools && typeof raw.tools === "object" && !Array.isArray(raw.tools)
|
|
28
|
+
? (raw.tools as Record<string, unknown>)
|
|
29
|
+
: {};
|
|
30
|
+
|
|
31
|
+
const embeddings =
|
|
32
|
+
tools.embeddings && typeof tools.embeddings === "object"
|
|
33
|
+
? (tools.embeddings as Record<string, unknown>)
|
|
34
|
+
: {};
|
|
35
|
+
const rollout =
|
|
36
|
+
tools.rollout && typeof tools.rollout === "object"
|
|
37
|
+
? (tools.rollout as Record<string, unknown>)
|
|
38
|
+
: {};
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
enabled,
|
|
42
|
+
apiKey,
|
|
43
|
+
baseUrl,
|
|
44
|
+
provider: {
|
|
45
|
+
enabled: providerEnabled,
|
|
46
|
+
defaultModel,
|
|
47
|
+
},
|
|
48
|
+
tools: {
|
|
49
|
+
embeddings: {
|
|
50
|
+
enabled: typeof embeddings.enabled === "boolean" ? embeddings.enabled : true,
|
|
51
|
+
},
|
|
52
|
+
rollout: {
|
|
53
|
+
enabled: typeof rollout.enabled === "boolean" ? rollout.enabled : true,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
uiHints: {
|
|
59
|
+
enabled: { label: "Enabled" },
|
|
60
|
+
apiKey: { label: "API Key", sensitive: true },
|
|
61
|
+
baseUrl: { label: "Base URL", placeholder: "https://dev.api.stratus.run" },
|
|
62
|
+
"provider.enabled": { label: "Provider Enabled" },
|
|
63
|
+
"provider.defaultModel": {
|
|
64
|
+
label: "Default Model",
|
|
65
|
+
placeholder: "stratus-x1ac-base-claude-sonnet-4-5",
|
|
66
|
+
},
|
|
67
|
+
"tools.embeddings.enabled": { label: "Embeddings Tool Enabled" },
|
|
68
|
+
"tools.rollout.enabled": { label: "Rollout Tool Enabled" },
|
|
69
|
+
},
|
|
70
|
+
};
|
package/src/setup.ts
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import * as os from "os";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Interactive setup command for Stratus plugin
|
|
7
|
+
*
|
|
8
|
+
* @purpose Handles automated configuration of Stratus plugin including OpenClaw config, auth profiles, and environment setup
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
interface SetupResult {
|
|
12
|
+
success: boolean;
|
|
13
|
+
message: string;
|
|
14
|
+
details?: string[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function setupStratus(prompter?: any): Promise<SetupResult> {
|
|
18
|
+
const details: string[] = [];
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
// Step 1: Check for existing API key
|
|
22
|
+
const apiKey = process.env.STRATUS_API_KEY;
|
|
23
|
+
|
|
24
|
+
if (!apiKey) {
|
|
25
|
+
return {
|
|
26
|
+
success: false,
|
|
27
|
+
message: "STRATUS_API_KEY not found",
|
|
28
|
+
details: [
|
|
29
|
+
"Please set your Stratus API key as an environment variable:",
|
|
30
|
+
"",
|
|
31
|
+
" export STRATUS_API_KEY=stratus_sk_your_key_here",
|
|
32
|
+
"",
|
|
33
|
+
"Or add to your shell config (~/.zshrc or ~/.bashrc):",
|
|
34
|
+
"",
|
|
35
|
+
" echo 'export STRATUS_API_KEY=stratus_sk_your_key_here' >> ~/.zshrc",
|
|
36
|
+
" source ~/.zshrc",
|
|
37
|
+
"",
|
|
38
|
+
"Get your API key at: https://stratus.run",
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
details.push("✓ Using STRATUS_API_KEY from environment");
|
|
44
|
+
|
|
45
|
+
// Paths
|
|
46
|
+
const homeDir = os.homedir();
|
|
47
|
+
const openclawConfig = path.join(homeDir, ".openclaw", "openclaw.json");
|
|
48
|
+
const authProfiles = path.join(
|
|
49
|
+
homeDir,
|
|
50
|
+
".openclaw",
|
|
51
|
+
"agents",
|
|
52
|
+
"main",
|
|
53
|
+
"agent",
|
|
54
|
+
"auth-profiles.json"
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// Step 2: Update OpenClaw config
|
|
58
|
+
details.push("🔧 Updating OpenClaw configuration...");
|
|
59
|
+
|
|
60
|
+
if (fs.existsSync(openclawConfig)) {
|
|
61
|
+
// Backup
|
|
62
|
+
const backupPath = `${openclawConfig}.backup-${Date.now()}`;
|
|
63
|
+
fs.copyFileSync(openclawConfig, backupPath);
|
|
64
|
+
details.push(` 📦 Created backup: ${path.basename(backupPath)}`);
|
|
65
|
+
|
|
66
|
+
// Read and update config
|
|
67
|
+
const config = JSON.parse(fs.readFileSync(openclawConfig, "utf-8"));
|
|
68
|
+
|
|
69
|
+
// Add models.providers.stratus if not present
|
|
70
|
+
if (!config.models) {
|
|
71
|
+
config.models = {};
|
|
72
|
+
}
|
|
73
|
+
if (!config.models.providers) {
|
|
74
|
+
config.models.providers = {};
|
|
75
|
+
}
|
|
76
|
+
if (!config.models.providers.stratus) {
|
|
77
|
+
config.models.providers.stratus = {
|
|
78
|
+
baseUrl: "https://dev.api.stratus.run/v1",
|
|
79
|
+
api: "openai-completions",
|
|
80
|
+
models: [
|
|
81
|
+
{
|
|
82
|
+
id: "stratus-x1ac-base-claude-sonnet-4-5",
|
|
83
|
+
name: "Stratus X1AC Base (Claude 4.5 Sonnet)",
|
|
84
|
+
reasoning: true,
|
|
85
|
+
input: ["text", "image"],
|
|
86
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
87
|
+
contextWindow: 200000,
|
|
88
|
+
maxTokens: 8192,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
};
|
|
92
|
+
details.push(" ✓ Added Stratus provider configuration");
|
|
93
|
+
} else {
|
|
94
|
+
details.push(" ✓ Stratus provider already configured");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Add model alias
|
|
98
|
+
if (!config.agents?.defaults?.models) {
|
|
99
|
+
if (!config.agents) config.agents = {};
|
|
100
|
+
if (!config.agents.defaults) config.agents.defaults = {};
|
|
101
|
+
if (!config.agents.defaults.models) config.agents.defaults.models = {};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!config.agents.defaults.models["stratus/stratus-x1ac-base-claude-sonnet-4-5"]) {
|
|
105
|
+
config.agents.defaults.models["stratus/stratus-x1ac-base-claude-sonnet-4-5"] = {
|
|
106
|
+
alias: "stratus",
|
|
107
|
+
params: {},
|
|
108
|
+
};
|
|
109
|
+
details.push(" ✓ Added model alias 'stratus'");
|
|
110
|
+
} else {
|
|
111
|
+
details.push(" ✓ Model alias already configured");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Write updated config
|
|
115
|
+
fs.writeFileSync(openclawConfig, JSON.stringify(config, null, 2));
|
|
116
|
+
} else {
|
|
117
|
+
return {
|
|
118
|
+
success: false,
|
|
119
|
+
message: "OpenClaw config not found",
|
|
120
|
+
details: [
|
|
121
|
+
"Run 'openclaw setup' first to initialize OpenClaw",
|
|
122
|
+
"",
|
|
123
|
+
"Need help? Check the docs: https://docs.openclaw.ai",
|
|
124
|
+
],
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Step 3: Update auth profiles
|
|
129
|
+
details.push("🔑 Configuring authentication...");
|
|
130
|
+
|
|
131
|
+
const authDir = path.dirname(authProfiles);
|
|
132
|
+
if (!fs.existsSync(authDir)) {
|
|
133
|
+
fs.mkdirSync(authDir, { recursive: true });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
let authConfig: any;
|
|
137
|
+
if (fs.existsSync(authProfiles)) {
|
|
138
|
+
// Backup
|
|
139
|
+
const backupPath = `${authProfiles}.backup-${Date.now()}`;
|
|
140
|
+
fs.copyFileSync(authProfiles, backupPath);
|
|
141
|
+
|
|
142
|
+
// Update existing
|
|
143
|
+
authConfig = JSON.parse(fs.readFileSync(authProfiles, "utf-8"));
|
|
144
|
+
} else {
|
|
145
|
+
// Create new
|
|
146
|
+
authConfig = {
|
|
147
|
+
version: 1,
|
|
148
|
+
profiles: {},
|
|
149
|
+
lastGood: {},
|
|
150
|
+
usageStats: {},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Add Stratus profile
|
|
155
|
+
authConfig.profiles["stratus:default"] = {
|
|
156
|
+
type: "api_key",
|
|
157
|
+
provider: "stratus",
|
|
158
|
+
key: apiKey,
|
|
159
|
+
};
|
|
160
|
+
authConfig.lastGood.stratus = "stratus:default";
|
|
161
|
+
|
|
162
|
+
fs.writeFileSync(authProfiles, JSON.stringify(authConfig, null, 2));
|
|
163
|
+
details.push(" ✓ Updated auth profile");
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
success: true,
|
|
167
|
+
message: "Setup complete! 🎉",
|
|
168
|
+
details: [
|
|
169
|
+
...details,
|
|
170
|
+
"",
|
|
171
|
+
"🎯 Next steps:",
|
|
172
|
+
" 1. Restart gateway: openclaw gateway stop && openclaw gateway install",
|
|
173
|
+
" 2. Verify: openclaw models list | grep stratus",
|
|
174
|
+
" 3. Test: openclaw agent 'Hello Stratus!' --model stratus",
|
|
175
|
+
"",
|
|
176
|
+
"📚 Available tools:",
|
|
177
|
+
" • stratus_embeddings - Generate semantic embeddings",
|
|
178
|
+
" • stratus_rollout - Multi-step task planning",
|
|
179
|
+
],
|
|
180
|
+
};
|
|
181
|
+
} catch (error) {
|
|
182
|
+
return {
|
|
183
|
+
success: false,
|
|
184
|
+
message: "Setup failed",
|
|
185
|
+
details: [
|
|
186
|
+
error instanceof Error ? error.message : String(error),
|
|
187
|
+
"",
|
|
188
|
+
"Need help? Visit: https://stratus.run/docs",
|
|
189
|
+
"Report issues: https://github.com/formthefog/openclaw-stratus-x1-plugin/issues",
|
|
190
|
+
],
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function detectShellConfig(): string | null {
|
|
196
|
+
const homeDir = os.homedir();
|
|
197
|
+
const shell = process.env.SHELL || "";
|
|
198
|
+
|
|
199
|
+
if (shell.includes("zsh")) {
|
|
200
|
+
return path.join(homeDir, ".zshrc");
|
|
201
|
+
} else if (shell.includes("bash")) {
|
|
202
|
+
if (process.platform === "darwin") {
|
|
203
|
+
return path.join(homeDir, ".bash_profile");
|
|
204
|
+
} else {
|
|
205
|
+
return path.join(homeDir, ".bashrc");
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return null;
|
|
210
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export interface StratusEmbeddingsRequest {
|
|
2
|
+
input: string | string[];
|
|
3
|
+
model?: string;
|
|
4
|
+
encoding_format?: "float" | "base64";
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface StratusEmbeddingsResponse {
|
|
8
|
+
object: "list";
|
|
9
|
+
data: Array<{
|
|
10
|
+
object: "embedding";
|
|
11
|
+
index: number;
|
|
12
|
+
embedding: number[] | string;
|
|
13
|
+
}>;
|
|
14
|
+
model: string;
|
|
15
|
+
usage: {
|
|
16
|
+
prompt_tokens: number;
|
|
17
|
+
total_tokens: number;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface StratusRolloutRequest {
|
|
22
|
+
goal: string;
|
|
23
|
+
initial_state?: string;
|
|
24
|
+
max_steps?: number;
|
|
25
|
+
return_intermediate?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface StratusRolloutStep {
|
|
29
|
+
action?: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
state?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface StratusRolloutResponse {
|
|
35
|
+
goal: string;
|
|
36
|
+
steps: StratusRolloutStep[];
|
|
37
|
+
success: boolean;
|
|
38
|
+
metadata?: {
|
|
39
|
+
model: string;
|
|
40
|
+
duration_ms?: number;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface StratusPluginConfig {
|
|
45
|
+
enabled?: boolean;
|
|
46
|
+
apiKey?: string;
|
|
47
|
+
baseUrl?: string;
|
|
48
|
+
provider?: {
|
|
49
|
+
enabled?: boolean;
|
|
50
|
+
defaultModel?: string;
|
|
51
|
+
};
|
|
52
|
+
tools?: {
|
|
53
|
+
embeddings?: { enabled?: boolean };
|
|
54
|
+
rollout?: { enabled?: boolean };
|
|
55
|
+
};
|
|
56
|
+
}
|
package/verify.sh
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Stratus OpenClaw Plugin Verification
|
|
4
|
+
# Checks that everything is configured correctly
|
|
5
|
+
|
|
6
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
7
|
+
echo " 🔍 Stratus Plugin Verification"
|
|
8
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
9
|
+
echo ""
|
|
10
|
+
|
|
11
|
+
ERRORS=0
|
|
12
|
+
|
|
13
|
+
# Check 1: Environment variable
|
|
14
|
+
echo "1️⃣ Checking STRATUS_API_KEY..."
|
|
15
|
+
if [[ -n "$STRATUS_API_KEY" ]]; then
|
|
16
|
+
echo " ✓ STRATUS_API_KEY is set"
|
|
17
|
+
else
|
|
18
|
+
echo " ❌ STRATUS_API_KEY not found in environment"
|
|
19
|
+
ERRORS=$((ERRORS + 1))
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Check 2: OpenClaw config
|
|
23
|
+
echo ""
|
|
24
|
+
echo "2️⃣ Checking OpenClaw configuration..."
|
|
25
|
+
OPENCLAW_CONFIG="$HOME/.openclaw/openclaw.json"
|
|
26
|
+
if [[ -f "$OPENCLAW_CONFIG" ]]; then
|
|
27
|
+
if jq -e '.models.providers.stratus' "$OPENCLAW_CONFIG" > /dev/null 2>&1; then
|
|
28
|
+
echo " ✓ Stratus provider configured"
|
|
29
|
+
else
|
|
30
|
+
echo " ❌ Stratus provider not in config"
|
|
31
|
+
ERRORS=$((ERRORS + 1))
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
if jq -e '.agents.defaults.models["stratus/stratus-x1ac-base-claude-sonnet-4-5"]' "$OPENCLAW_CONFIG" > /dev/null 2>&1; then
|
|
35
|
+
echo " ✓ Stratus model alias configured"
|
|
36
|
+
else
|
|
37
|
+
echo " ❌ Stratus model alias not configured"
|
|
38
|
+
ERRORS=$((ERRORS + 1))
|
|
39
|
+
fi
|
|
40
|
+
else
|
|
41
|
+
echo " ❌ OpenClaw config not found"
|
|
42
|
+
ERRORS=$((ERRORS + 1))
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Check 3: Auth profile
|
|
46
|
+
echo ""
|
|
47
|
+
echo "3️⃣ Checking authentication profile..."
|
|
48
|
+
AUTH_PROFILES="$HOME/.openclaw/agents/main/agent/auth-profiles.json"
|
|
49
|
+
if [[ -f "$AUTH_PROFILES" ]]; then
|
|
50
|
+
if jq -e '.profiles["stratus:default"]' "$AUTH_PROFILES" > /dev/null 2>&1; then
|
|
51
|
+
echo " ✓ Stratus auth profile exists"
|
|
52
|
+
else
|
|
53
|
+
echo " ❌ Stratus auth profile not found"
|
|
54
|
+
ERRORS=$((ERRORS + 1))
|
|
55
|
+
fi
|
|
56
|
+
else
|
|
57
|
+
echo " ❌ Auth profiles file not found"
|
|
58
|
+
ERRORS=$((ERRORS + 1))
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Check 4: Plugin loaded
|
|
62
|
+
echo ""
|
|
63
|
+
echo "4️⃣ Checking plugin status..."
|
|
64
|
+
if command -v openclaw > /dev/null 2>&1; then
|
|
65
|
+
if openclaw plugins info stratus 2>&1 | grep -q "Status: loaded"; then
|
|
66
|
+
echo " ✓ Plugin loaded successfully"
|
|
67
|
+
else
|
|
68
|
+
echo " ⚠️ Plugin not loaded (restart gateway)"
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# Check 5: Models available
|
|
72
|
+
echo ""
|
|
73
|
+
echo "5️⃣ Checking model availability..."
|
|
74
|
+
if openclaw models list 2>&1 | grep -q "stratus"; then
|
|
75
|
+
echo " ✓ Stratus model available"
|
|
76
|
+
else
|
|
77
|
+
echo " ❌ Stratus model not in model list"
|
|
78
|
+
ERRORS=$((ERRORS + 1))
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
# Check 6: Gateway status
|
|
82
|
+
echo ""
|
|
83
|
+
echo "6️⃣ Checking gateway..."
|
|
84
|
+
if openclaw gateway status 2>&1 | grep -q "RPC probe: ok"; then
|
|
85
|
+
echo " ✓ Gateway operational"
|
|
86
|
+
else
|
|
87
|
+
echo " ⚠️ Gateway not responding"
|
|
88
|
+
fi
|
|
89
|
+
else
|
|
90
|
+
echo " ⚠️ OpenClaw CLI not found (install OpenClaw first)"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
echo ""
|
|
94
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
95
|
+
if [[ $ERRORS -eq 0 ]]; then
|
|
96
|
+
echo " ✅ All checks passed!"
|
|
97
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
98
|
+
echo ""
|
|
99
|
+
echo "🎯 Try it out:"
|
|
100
|
+
echo " openclaw agent 'Hello Stratus!' --model stratus"
|
|
101
|
+
echo ""
|
|
102
|
+
exit 0
|
|
103
|
+
else
|
|
104
|
+
echo " ❌ $ERRORS issue(s) found"
|
|
105
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
106
|
+
echo ""
|
|
107
|
+
echo "💡 Try running: ./install.sh"
|
|
108
|
+
echo ""
|
|
109
|
+
exit 1
|
|
110
|
+
fi
|