@suigar/mcp 0.1.0 → 0.2.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/LICENSE +201 -0
- package/README.md +79 -110
- package/dist/app/index.html +181 -0
- package/dist/bin.mjs +3 -7
- package/dist/bin.mjs.map +1 -0
- package/dist/client.d.mts +41 -11
- package/dist/client.d.mts.map +1 -0
- package/dist/client.mjs +107 -34
- package/dist/client.mjs.map +1 -0
- package/dist/dry-run.mjs +163 -0
- package/dist/dry-run.mjs.map +1 -0
- package/dist/format.mjs +24 -0
- package/dist/format.mjs.map +1 -0
- package/dist/index.d.mts +5 -9
- package/dist/index.mjs +4 -8
- package/dist/schemas.d.mts +642 -0
- package/dist/schemas.d.mts.map +1 -0
- package/dist/schemas.mjs +113 -0
- package/dist/schemas.mjs.map +1 -0
- package/dist/server.d.mts +21 -69
- package/dist/server.d.mts.map +1 -0
- package/dist/server.mjs +172 -411
- package/dist/server.mjs.map +1 -0
- package/dist/tools.d.mts +14 -155
- package/dist/tools.d.mts.map +1 -0
- package/dist/tools.mjs +297 -553
- package/dist/tools.mjs.map +1 -0
- package/dist/types.d.mts +109 -83
- package/dist/types.d.mts.map +1 -0
- package/package.json +83 -61
- package/dist/bin.cjs +0 -11
- package/dist/bin.d.cts +0 -1
- package/dist/client.cjs +0 -46
- package/dist/client.d.cts +0 -17
- package/dist/coin.cjs +0 -86
- package/dist/coin.d.cts +0 -35
- package/dist/coin.d.mts +0 -35
- package/dist/coin.mjs +0 -86
- package/dist/config.cjs +0 -183
- package/dist/config.d.cts +0 -15
- package/dist/config.d.mts +0 -15
- package/dist/config.mjs +0 -174
- package/dist/index.cjs +0 -53
- package/dist/index.d.cts +0 -10
- package/dist/mcp-support.cjs +0 -62
- package/dist/mcp-support.d.cts +0 -16
- package/dist/mcp-support.d.mts +0 -16
- package/dist/mcp-support.mjs +0 -60
- package/dist/metadata.cjs +0 -51
- package/dist/metadata.d.cts +0 -52
- package/dist/metadata.d.mts +0 -52
- package/dist/metadata.mjs +0 -47
- package/dist/server.cjs +0 -433
- package/dist/server.d.cts +0 -73
- package/dist/tools.cjs +0 -617
- package/dist/tools.d.cts +0 -158
- package/dist/transactions.cjs +0 -294
- package/dist/transactions.d.cts +0 -40
- package/dist/transactions.d.mts +0 -40
- package/dist/transactions.mjs +0 -286
- package/dist/types.d.cts +0 -111
- package/node_modules/@suigar/currency-registry/dist/index.cjs +0 -121
- package/node_modules/@suigar/currency-registry/dist/index.d.cts +0 -50
- package/node_modules/@suigar/currency-registry/dist/index.d.mts +0 -50
- package/node_modules/@suigar/currency-registry/dist/index.mjs +0 -110
- package/node_modules/@suigar/currency-registry/package.json +0 -31
- package/node_modules/@suigar/game-registry/dist/index.cjs +0 -310
- package/node_modules/@suigar/game-registry/dist/index.d.cts +0 -65
- package/node_modules/@suigar/game-registry/dist/index.d.mts +0 -65
- package/node_modules/@suigar/game-registry/dist/index.mjs +0 -292
- package/node_modules/@suigar/game-registry/package.json +0 -31
- package/node_modules/@suigar/sui-rpc-pool/dist/index.cjs +0 -45590
- package/node_modules/@suigar/sui-rpc-pool/dist/index.d.cts +0 -465
- package/node_modules/@suigar/sui-rpc-pool/dist/index.d.mts +0 -465
- package/node_modules/@suigar/sui-rpc-pool/dist/index.mjs +0 -45570
- package/node_modules/@suigar/sui-rpc-pool/package.json +0 -31
package/dist/server.mjs
CHANGED
|
@@ -1,431 +1,192 @@
|
|
|
1
|
+
import { coinflipInputSchema, configIdInputSchema, limboInputSchema, pvpCoinflipCancelInputSchema, pvpCoinflipCreateInputSchema, pvpCoinflipJoinInputSchema, rangeInputSchema, readConfigInputSchema, readGameMetadataInputSchema, toolOutputSchema } from "./schemas.mjs";
|
|
1
2
|
import { buildCoinflipTransactionTool, buildLimboTransactionTool, buildPlinkoTransactionTool, buildPvpCoinflipCancelTransactionTool, buildPvpCoinflipCreateTransactionTool, buildPvpCoinflipJoinTransactionTool, buildRangeTransactionTool, buildWheelTransactionTool, readConfigTool, readGameMetadataTool } from "./tools.mjs";
|
|
2
|
-
import {
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
|
+
import { RESOURCE_MIME_TYPE, registerAppResource, registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
6
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
7
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
-
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
5
8
|
//#region src/server.ts
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
{
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
9
|
+
const SUIGAR_MCP_APP_RESOURCE_URI = "ui://suigar/transaction-inspector.html";
|
|
10
|
+
const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
|
|
11
|
+
const errorText = (error) => {
|
|
12
|
+
if (error instanceof Error) return `${error.name}: ${error.message}`;
|
|
13
|
+
return String(error);
|
|
14
|
+
};
|
|
15
|
+
const hasErrorCode = (error, code) => error instanceof Error && "code" in error && error.code === code;
|
|
16
|
+
const withToolErrors = (handler) => async (input) => {
|
|
17
|
+
try {
|
|
18
|
+
return await handler(input);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
return {
|
|
21
|
+
isError: true,
|
|
22
|
+
content: [{
|
|
23
|
+
type: "text",
|
|
24
|
+
text: `${errorText(error)}\n\nCheck required fields, network, coin type, and SDK config overrides. The MCP server only builds unsigned transactions and never signs or executes them.`
|
|
25
|
+
}]
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const readSuigarMcpAppHtml = async () => {
|
|
30
|
+
try {
|
|
31
|
+
return await readFile(new URL("./app/index.html", import.meta.url), "utf8");
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (!hasErrorCode(error, "ENOENT")) throw error;
|
|
34
|
+
throw new Error("Unable to find bundled Suigar MCP App HTML.", { cause: error });
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const createSuigarMcpAppResourceResult = async () => ({ contents: [{
|
|
38
|
+
uri: SUIGAR_MCP_APP_RESOURCE_URI,
|
|
39
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
40
|
+
text: await readSuigarMcpAppHtml(),
|
|
41
|
+
_meta: { ui: { csp: {
|
|
42
|
+
connectDomains: [],
|
|
43
|
+
resourceDomains: []
|
|
44
|
+
} } }
|
|
45
|
+
}] });
|
|
46
|
+
const createSuigarMcpServer = () => {
|
|
47
|
+
const server = new McpServer({
|
|
48
|
+
name: "suigar",
|
|
49
|
+
version: packageJson.version
|
|
50
|
+
});
|
|
51
|
+
server.registerTool("read_config", {
|
|
52
|
+
title: "Read Suigar Config",
|
|
53
|
+
description: "Resolve Suigar SDK config for mainnet or testnet. Defaults to testnet.",
|
|
54
|
+
inputSchema: readConfigInputSchema,
|
|
55
|
+
outputSchema: toolOutputSchema,
|
|
56
|
+
annotations: {
|
|
57
|
+
readOnlyHint: true,
|
|
58
|
+
destructiveHint: false,
|
|
59
|
+
idempotentHint: true,
|
|
60
|
+
openWorldHint: false
|
|
61
|
+
}
|
|
62
|
+
}, withToolErrors(readConfigTool));
|
|
63
|
+
registerAppResource(server, "Suigar Transaction Inspector", SUIGAR_MCP_APP_RESOURCE_URI, { description: "Compact MCP App UI for inspecting Suigar config, transaction plans, summaries, dry-runs, and serialized bytes." }, createSuigarMcpAppResourceResult);
|
|
64
|
+
const appToolMeta = { ui: { resourceUri: SUIGAR_MCP_APP_RESOURCE_URI } };
|
|
65
|
+
registerAppTool(server, "read_game_metadata", {
|
|
66
|
+
title: "Read Suigar Game Metadata",
|
|
67
|
+
description: "Read SDK-backed metadata for a supported Suigar game and coin type.",
|
|
68
|
+
inputSchema: readGameMetadataInputSchema,
|
|
69
|
+
outputSchema: toolOutputSchema,
|
|
70
|
+
annotations: {
|
|
71
|
+
readOnlyHint: true,
|
|
72
|
+
destructiveHint: false,
|
|
73
|
+
idempotentHint: true,
|
|
74
|
+
openWorldHint: false
|
|
47
75
|
},
|
|
48
|
-
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
|
|
52
|
-
description: "Build, dry-run, or inspect
|
|
53
|
-
inputSchema:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"dry-run",
|
|
61
|
-
"read-only"
|
|
62
|
-
],
|
|
63
|
-
default: "build"
|
|
64
|
-
},
|
|
65
|
-
network: {
|
|
66
|
-
type: "string",
|
|
67
|
-
default: "testnet"
|
|
68
|
-
},
|
|
69
|
-
owner: { type: "string" },
|
|
70
|
-
coinType: { type: "string" },
|
|
71
|
-
stake: { type: "number" },
|
|
72
|
-
cashStake: { type: "number" },
|
|
73
|
-
betCount: { type: "number" },
|
|
74
|
-
side: {
|
|
75
|
-
type: "string",
|
|
76
|
-
enum: ["heads", "tails"]
|
|
77
|
-
},
|
|
78
|
-
coinObjectIds: {
|
|
79
|
-
type: "array",
|
|
80
|
-
items: { type: "string" }
|
|
81
|
-
},
|
|
82
|
-
partner: { type: "string" },
|
|
83
|
-
metadata: {
|
|
84
|
-
type: "object",
|
|
85
|
-
additionalProperties: true
|
|
86
|
-
},
|
|
87
|
-
config: {
|
|
88
|
-
type: "object",
|
|
89
|
-
additionalProperties: true
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
additionalProperties: true
|
|
76
|
+
_meta: appToolMeta
|
|
77
|
+
}, withToolErrors(readGameMetadataTool));
|
|
78
|
+
registerAppTool(server, "build_coinflip_transaction", {
|
|
79
|
+
title: "Build Coinflip Transaction",
|
|
80
|
+
description: "Build, dry-run, or inspect an unsigned Suigar coinflip transaction.",
|
|
81
|
+
inputSchema: coinflipInputSchema,
|
|
82
|
+
outputSchema: toolOutputSchema,
|
|
83
|
+
annotations: {
|
|
84
|
+
readOnlyHint: false,
|
|
85
|
+
destructiveHint: false,
|
|
86
|
+
idempotentHint: false,
|
|
87
|
+
openWorldHint: true
|
|
93
88
|
},
|
|
94
|
-
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
|
|
98
|
-
description: "Build, dry-run, or inspect
|
|
99
|
-
inputSchema:
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
"dry-run",
|
|
107
|
-
"read-only"
|
|
108
|
-
],
|
|
109
|
-
default: "build"
|
|
110
|
-
},
|
|
111
|
-
network: {
|
|
112
|
-
type: "string",
|
|
113
|
-
default: "testnet"
|
|
114
|
-
},
|
|
115
|
-
owner: { type: "string" },
|
|
116
|
-
coinType: { type: "string" },
|
|
117
|
-
stake: { type: "number" },
|
|
118
|
-
cashStake: { type: "number" },
|
|
119
|
-
betCount: { type: "number" },
|
|
120
|
-
targetMultiplier: { type: "number" },
|
|
121
|
-
coinObjectIds: {
|
|
122
|
-
type: "array",
|
|
123
|
-
items: { type: "string" }
|
|
124
|
-
},
|
|
125
|
-
partner: { type: "string" },
|
|
126
|
-
metadata: {
|
|
127
|
-
type: "object",
|
|
128
|
-
additionalProperties: true
|
|
129
|
-
},
|
|
130
|
-
config: {
|
|
131
|
-
type: "object",
|
|
132
|
-
additionalProperties: true
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
additionalProperties: true
|
|
89
|
+
_meta: appToolMeta
|
|
90
|
+
}, withToolErrors(buildCoinflipTransactionTool));
|
|
91
|
+
registerAppTool(server, "build_limbo_transaction", {
|
|
92
|
+
title: "Build Limbo Transaction",
|
|
93
|
+
description: "Build, dry-run, or inspect an unsigned Suigar limbo transaction.",
|
|
94
|
+
inputSchema: limboInputSchema,
|
|
95
|
+
outputSchema: toolOutputSchema,
|
|
96
|
+
annotations: {
|
|
97
|
+
readOnlyHint: false,
|
|
98
|
+
destructiveHint: false,
|
|
99
|
+
idempotentHint: false,
|
|
100
|
+
openWorldHint: true
|
|
136
101
|
},
|
|
137
|
-
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
|
|
141
|
-
description: "Build, dry-run, or inspect
|
|
142
|
-
inputSchema:
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
"dry-run",
|
|
150
|
-
"read-only"
|
|
151
|
-
],
|
|
152
|
-
default: "build"
|
|
153
|
-
},
|
|
154
|
-
network: {
|
|
155
|
-
type: "string",
|
|
156
|
-
default: "testnet"
|
|
157
|
-
},
|
|
158
|
-
owner: { type: "string" },
|
|
159
|
-
coinType: { type: "string" },
|
|
160
|
-
stake: { type: "number" },
|
|
161
|
-
cashStake: { type: "number" },
|
|
162
|
-
betCount: { type: "number" },
|
|
163
|
-
configId: { type: "number" },
|
|
164
|
-
coinObjectIds: {
|
|
165
|
-
type: "array",
|
|
166
|
-
items: { type: "string" }
|
|
167
|
-
},
|
|
168
|
-
partner: { type: "string" },
|
|
169
|
-
metadata: {
|
|
170
|
-
type: "object",
|
|
171
|
-
additionalProperties: true
|
|
172
|
-
},
|
|
173
|
-
config: {
|
|
174
|
-
type: "object",
|
|
175
|
-
additionalProperties: true
|
|
176
|
-
}
|
|
177
|
-
},
|
|
178
|
-
additionalProperties: true
|
|
102
|
+
_meta: appToolMeta
|
|
103
|
+
}, withToolErrors(buildLimboTransactionTool));
|
|
104
|
+
registerAppTool(server, "build_plinko_transaction", {
|
|
105
|
+
title: "Build Plinko Transaction",
|
|
106
|
+
description: "Build, dry-run, or inspect an unsigned Suigar plinko transaction.",
|
|
107
|
+
inputSchema: configIdInputSchema,
|
|
108
|
+
outputSchema: toolOutputSchema,
|
|
109
|
+
annotations: {
|
|
110
|
+
readOnlyHint: false,
|
|
111
|
+
destructiveHint: false,
|
|
112
|
+
idempotentHint: false,
|
|
113
|
+
openWorldHint: true
|
|
179
114
|
},
|
|
180
|
-
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
|
|
184
|
-
description: "Build, dry-run, or inspect
|
|
185
|
-
inputSchema:
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
"dry-run",
|
|
193
|
-
"read-only"
|
|
194
|
-
],
|
|
195
|
-
default: "build"
|
|
196
|
-
},
|
|
197
|
-
network: {
|
|
198
|
-
type: "string",
|
|
199
|
-
default: "testnet"
|
|
200
|
-
},
|
|
201
|
-
owner: { type: "string" },
|
|
202
|
-
coinType: { type: "string" },
|
|
203
|
-
stake: { type: "number" },
|
|
204
|
-
cashStake: { type: "number" },
|
|
205
|
-
betCount: { type: "number" },
|
|
206
|
-
configId: { type: "number" },
|
|
207
|
-
coinObjectIds: {
|
|
208
|
-
type: "array",
|
|
209
|
-
items: { type: "string" }
|
|
210
|
-
},
|
|
211
|
-
partner: { type: "string" },
|
|
212
|
-
metadata: {
|
|
213
|
-
type: "object",
|
|
214
|
-
additionalProperties: true
|
|
215
|
-
},
|
|
216
|
-
config: {
|
|
217
|
-
type: "object",
|
|
218
|
-
additionalProperties: true
|
|
219
|
-
}
|
|
220
|
-
},
|
|
221
|
-
additionalProperties: true
|
|
115
|
+
_meta: appToolMeta
|
|
116
|
+
}, withToolErrors(buildPlinkoTransactionTool));
|
|
117
|
+
registerAppTool(server, "build_wheel_transaction", {
|
|
118
|
+
title: "Build Wheel Transaction",
|
|
119
|
+
description: "Build, dry-run, or inspect an unsigned Suigar wheel transaction.",
|
|
120
|
+
inputSchema: configIdInputSchema,
|
|
121
|
+
outputSchema: toolOutputSchema,
|
|
122
|
+
annotations: {
|
|
123
|
+
readOnlyHint: false,
|
|
124
|
+
destructiveHint: false,
|
|
125
|
+
idempotentHint: false,
|
|
126
|
+
openWorldHint: true
|
|
222
127
|
},
|
|
223
|
-
|
|
224
|
-
},
|
|
225
|
-
{
|
|
226
|
-
|
|
227
|
-
description: "Build, dry-run, or inspect
|
|
228
|
-
inputSchema:
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
"dry-run",
|
|
236
|
-
"read-only"
|
|
237
|
-
],
|
|
238
|
-
default: "build"
|
|
239
|
-
},
|
|
240
|
-
network: {
|
|
241
|
-
type: "string",
|
|
242
|
-
default: "testnet"
|
|
243
|
-
},
|
|
244
|
-
owner: { type: "string" },
|
|
245
|
-
coinType: { type: "string" },
|
|
246
|
-
stake: { type: "number" },
|
|
247
|
-
cashStake: { type: "number" },
|
|
248
|
-
betCount: { type: "number" },
|
|
249
|
-
leftPoint: { type: "number" },
|
|
250
|
-
rightPoint: { type: "number" },
|
|
251
|
-
outOfRange: { type: "boolean" },
|
|
252
|
-
coinObjectIds: {
|
|
253
|
-
type: "array",
|
|
254
|
-
items: { type: "string" }
|
|
255
|
-
},
|
|
256
|
-
partner: { type: "string" },
|
|
257
|
-
metadata: {
|
|
258
|
-
type: "object",
|
|
259
|
-
additionalProperties: true
|
|
260
|
-
},
|
|
261
|
-
config: {
|
|
262
|
-
type: "object",
|
|
263
|
-
additionalProperties: true
|
|
264
|
-
}
|
|
265
|
-
},
|
|
266
|
-
additionalProperties: true
|
|
128
|
+
_meta: appToolMeta
|
|
129
|
+
}, withToolErrors(buildWheelTransactionTool));
|
|
130
|
+
registerAppTool(server, "build_range_transaction", {
|
|
131
|
+
title: "Build Range Transaction",
|
|
132
|
+
description: "Build, dry-run, or inspect an unsigned Suigar range transaction.",
|
|
133
|
+
inputSchema: rangeInputSchema,
|
|
134
|
+
outputSchema: toolOutputSchema,
|
|
135
|
+
annotations: {
|
|
136
|
+
readOnlyHint: false,
|
|
137
|
+
destructiveHint: false,
|
|
138
|
+
idempotentHint: false,
|
|
139
|
+
openWorldHint: true
|
|
267
140
|
},
|
|
268
|
-
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
|
|
272
|
-
description: "Build, dry-run, or inspect
|
|
273
|
-
inputSchema:
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
"dry-run",
|
|
281
|
-
"read-only"
|
|
282
|
-
],
|
|
283
|
-
default: "build"
|
|
284
|
-
},
|
|
285
|
-
network: {
|
|
286
|
-
type: "string",
|
|
287
|
-
default: "testnet"
|
|
288
|
-
},
|
|
289
|
-
owner: { type: "string" },
|
|
290
|
-
coinType: { type: "string" },
|
|
291
|
-
stake: { type: "number" },
|
|
292
|
-
creatorSide: {
|
|
293
|
-
type: "string",
|
|
294
|
-
enum: ["heads", "tails"]
|
|
295
|
-
},
|
|
296
|
-
isPrivate: { type: "boolean" },
|
|
297
|
-
coinObjectIds: {
|
|
298
|
-
type: "array",
|
|
299
|
-
items: { type: "string" }
|
|
300
|
-
},
|
|
301
|
-
partner: { type: "string" },
|
|
302
|
-
metadata: {
|
|
303
|
-
type: "object",
|
|
304
|
-
additionalProperties: true
|
|
305
|
-
},
|
|
306
|
-
config: {
|
|
307
|
-
type: "object",
|
|
308
|
-
additionalProperties: true
|
|
309
|
-
}
|
|
310
|
-
},
|
|
311
|
-
additionalProperties: true
|
|
141
|
+
_meta: appToolMeta
|
|
142
|
+
}, withToolErrors(buildRangeTransactionTool));
|
|
143
|
+
registerAppTool(server, "build_pvp_coinflip_create_transaction", {
|
|
144
|
+
title: "Build PvP Coinflip Create",
|
|
145
|
+
description: "Build, dry-run, or inspect an unsigned Suigar PvP coinflip lobby creation transaction.",
|
|
146
|
+
inputSchema: pvpCoinflipCreateInputSchema,
|
|
147
|
+
outputSchema: toolOutputSchema,
|
|
148
|
+
annotations: {
|
|
149
|
+
readOnlyHint: false,
|
|
150
|
+
destructiveHint: false,
|
|
151
|
+
idempotentHint: false,
|
|
152
|
+
openWorldHint: true
|
|
312
153
|
},
|
|
313
|
-
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
|
|
317
|
-
description: "Build, dry-run, or inspect
|
|
318
|
-
inputSchema:
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
"dry-run",
|
|
326
|
-
"read-only"
|
|
327
|
-
],
|
|
328
|
-
default: "build"
|
|
329
|
-
},
|
|
330
|
-
network: {
|
|
331
|
-
type: "string",
|
|
332
|
-
default: "testnet"
|
|
333
|
-
},
|
|
334
|
-
owner: { type: "string" },
|
|
335
|
-
gameId: { type: "string" },
|
|
336
|
-
coinType: { type: "string" },
|
|
337
|
-
stake: { type: "number" },
|
|
338
|
-
coinObjectIds: {
|
|
339
|
-
type: "array",
|
|
340
|
-
items: { type: "string" }
|
|
341
|
-
},
|
|
342
|
-
partner: { type: "string" },
|
|
343
|
-
metadata: {
|
|
344
|
-
type: "object",
|
|
345
|
-
additionalProperties: true
|
|
346
|
-
},
|
|
347
|
-
config: {
|
|
348
|
-
type: "object",
|
|
349
|
-
additionalProperties: true
|
|
350
|
-
}
|
|
351
|
-
},
|
|
352
|
-
additionalProperties: true
|
|
154
|
+
_meta: appToolMeta
|
|
155
|
+
}, withToolErrors(buildPvpCoinflipCreateTransactionTool));
|
|
156
|
+
registerAppTool(server, "build_pvp_coinflip_join_transaction", {
|
|
157
|
+
title: "Build PvP Coinflip Join",
|
|
158
|
+
description: "Build, dry-run, or inspect an unsigned Suigar PvP coinflip join transaction.",
|
|
159
|
+
inputSchema: pvpCoinflipJoinInputSchema,
|
|
160
|
+
outputSchema: toolOutputSchema,
|
|
161
|
+
annotations: {
|
|
162
|
+
readOnlyHint: false,
|
|
163
|
+
destructiveHint: false,
|
|
164
|
+
idempotentHint: false,
|
|
165
|
+
openWorldHint: true
|
|
353
166
|
},
|
|
354
|
-
|
|
355
|
-
},
|
|
356
|
-
{
|
|
357
|
-
|
|
358
|
-
description: "Build, dry-run, or inspect
|
|
359
|
-
inputSchema:
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
"dry-run",
|
|
367
|
-
"read-only"
|
|
368
|
-
],
|
|
369
|
-
default: "build"
|
|
370
|
-
},
|
|
371
|
-
network: {
|
|
372
|
-
type: "string",
|
|
373
|
-
default: "testnet"
|
|
374
|
-
},
|
|
375
|
-
owner: { type: "string" },
|
|
376
|
-
gameId: { type: "string" },
|
|
377
|
-
coinType: { type: "string" },
|
|
378
|
-
config: {
|
|
379
|
-
type: "object",
|
|
380
|
-
additionalProperties: true
|
|
381
|
-
}
|
|
382
|
-
},
|
|
383
|
-
additionalProperties: true
|
|
167
|
+
_meta: appToolMeta
|
|
168
|
+
}, withToolErrors(buildPvpCoinflipJoinTransactionTool));
|
|
169
|
+
registerAppTool(server, "build_pvp_coinflip_cancel_transaction", {
|
|
170
|
+
title: "Build PvP Coinflip Cancel",
|
|
171
|
+
description: "Build, dry-run, or inspect an unsigned Suigar PvP coinflip cancel transaction.",
|
|
172
|
+
inputSchema: pvpCoinflipCancelInputSchema,
|
|
173
|
+
outputSchema: toolOutputSchema,
|
|
174
|
+
annotations: {
|
|
175
|
+
readOnlyHint: false,
|
|
176
|
+
destructiveHint: false,
|
|
177
|
+
idempotentHint: false,
|
|
178
|
+
openWorldHint: true
|
|
384
179
|
},
|
|
385
|
-
|
|
386
|
-
}
|
|
387
|
-
];
|
|
388
|
-
const createSuigarMcpServer = () => {
|
|
389
|
-
const server = new Server({
|
|
390
|
-
name: "suigar",
|
|
391
|
-
version: "0.0.0"
|
|
392
|
-
}, { capabilities: { tools: {} } });
|
|
393
|
-
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOL_DEFINITIONS.map(({ name, description, inputSchema }) => ({
|
|
394
|
-
name,
|
|
395
|
-
description,
|
|
396
|
-
inputSchema
|
|
397
|
-
})) }));
|
|
398
|
-
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
399
|
-
const tool = TOOL_DEFINITIONS.find((entry) => entry.name === request.params.name);
|
|
400
|
-
if (!tool) return {
|
|
401
|
-
isError: true,
|
|
402
|
-
content: [{
|
|
403
|
-
type: "text",
|
|
404
|
-
text: `Unknown tool: ${request.params.name}`
|
|
405
|
-
}]
|
|
406
|
-
};
|
|
407
|
-
try {
|
|
408
|
-
return { content: [{
|
|
409
|
-
type: "text",
|
|
410
|
-
text: json(await tool.handler(request.params.arguments ?? {}))
|
|
411
|
-
}] };
|
|
412
|
-
} catch (error) {
|
|
413
|
-
return {
|
|
414
|
-
isError: true,
|
|
415
|
-
content: [{
|
|
416
|
-
type: "text",
|
|
417
|
-
text: error instanceof Error ? error.message : String(error ?? "Unknown error")
|
|
418
|
-
}]
|
|
419
|
-
};
|
|
420
|
-
}
|
|
421
|
-
});
|
|
180
|
+
_meta: appToolMeta
|
|
181
|
+
}, withToolErrors(buildPvpCoinflipCancelTransactionTool));
|
|
422
182
|
return server;
|
|
423
183
|
};
|
|
424
184
|
const startSuigarMcpServer = async () => {
|
|
425
185
|
const server = createSuigarMcpServer();
|
|
426
186
|
const transport = new StdioServerTransport();
|
|
427
187
|
await server.connect(transport);
|
|
428
|
-
return server;
|
|
429
188
|
};
|
|
430
189
|
//#endregion
|
|
431
|
-
export { createSuigarMcpServer, startSuigarMcpServer };
|
|
190
|
+
export { SUIGAR_MCP_APP_RESOURCE_URI, createSuigarMcpAppResourceResult, createSuigarMcpServer, readSuigarMcpAppHtml, startSuigarMcpServer };
|
|
191
|
+
|
|
192
|
+
//# sourceMappingURL=server.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.mjs","names":[],"sources":["../src/server.ts"],"sourcesContent":["// Copyright (c) Suigar\n// SPDX-License-Identifier: Apache-2.0\n\nimport { readFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport {\n\tregisterAppResource,\n\tregisterAppTool,\n\tRESOURCE_MIME_TYPE,\n} from '@modelcontextprotocol/ext-apps/server';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n\tcoinflipInputSchema,\n\tconfigIdInputSchema,\n\tlimboInputSchema,\n\tpvpCoinflipCancelInputSchema,\n\tpvpCoinflipCreateInputSchema,\n\tpvpCoinflipJoinInputSchema,\n\trangeInputSchema,\n\treadConfigInputSchema,\n\treadGameMetadataInputSchema,\n\ttoolOutputSchema,\n} from './schemas.js';\nimport {\n\tbuildCoinflipTransactionTool,\n\tbuildLimboTransactionTool,\n\tbuildPlinkoTransactionTool,\n\tbuildPvpCoinflipCancelTransactionTool,\n\tbuildPvpCoinflipCreateTransactionTool,\n\tbuildPvpCoinflipJoinTransactionTool,\n\tbuildRangeTransactionTool,\n\tbuildWheelTransactionTool,\n\treadConfigTool,\n\treadGameMetadataTool,\n} from './tools.js';\nimport type { ToolTextResult } from './types.js';\n\nexport const SUIGAR_MCP_APP_RESOURCE_URI =\n\t'ui://suigar/transaction-inspector.html';\n\nconst packageJson = JSON.parse(\n\treadFileSync(new URL('../package.json', import.meta.url), 'utf8'),\n) as { version: string };\n\nconst errorText = (error: unknown) => {\n\tif (error instanceof Error) {\n\t\treturn `${error.name}: ${error.message}`;\n\t}\n\treturn String(error);\n};\n\nconst hasErrorCode = (\n\terror: unknown,\n\tcode: string,\n): error is Error & { code: string } =>\n\terror instanceof Error &&\n\t'code' in error &&\n\t(error as { code: unknown }).code === code;\n\nconst withToolErrors =\n\t<TInput>(handler: (input: TInput) => Promise<ToolTextResult>) =>\n\tasync (\n\t\tinput: TInput,\n\t): Promise<\n\t\t| ToolTextResult\n\t\t| { isError: true; content: [{ type: 'text'; text: string }] }\n\t> => {\n\t\ttry {\n\t\t\treturn await handler(input);\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tisError: true,\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\ttext: `${errorText(error)}\\n\\nCheck required fields, network, coin type, and SDK config overrides. The MCP server only builds unsigned transactions and never signs or executes them.`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\t};\n\nexport const readSuigarMcpAppHtml = async () => {\n\ttry {\n\t\treturn await readFile(new URL('./app/index.html', import.meta.url), 'utf8');\n\t} catch (error) {\n\t\tif (!hasErrorCode(error, 'ENOENT')) {\n\t\t\tthrow error;\n\t\t}\n\t\tthrow new Error('Unable to find bundled Suigar MCP App HTML.', {\n\t\t\tcause: error,\n\t\t});\n\t}\n};\n\nexport const createSuigarMcpAppResourceResult = async () => ({\n\tcontents: [\n\t\t{\n\t\t\turi: SUIGAR_MCP_APP_RESOURCE_URI,\n\t\t\tmimeType: RESOURCE_MIME_TYPE,\n\t\t\ttext: await readSuigarMcpAppHtml(),\n\t\t\t_meta: {\n\t\t\t\tui: {\n\t\t\t\t\tcsp: {\n\t\t\t\t\t\tconnectDomains: [],\n\t\t\t\t\t\tresourceDomains: [],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t],\n});\n\nexport const createSuigarMcpServer = () => {\n\tconst server = new McpServer({\n\t\tname: 'suigar',\n\t\tversion: packageJson.version,\n\t});\n\n\tserver.registerTool(\n\t\t'read_config',\n\t\t{\n\t\t\ttitle: 'Read Suigar Config',\n\t\t\tdescription:\n\t\t\t\t'Resolve Suigar SDK config for mainnet or testnet. Defaults to testnet.',\n\t\t\tinputSchema: readConfigInputSchema,\n\t\t\toutputSchema: toolOutputSchema,\n\t\t\tannotations: {\n\t\t\t\treadOnlyHint: true,\n\t\t\t\tdestructiveHint: false,\n\t\t\t\tidempotentHint: true,\n\t\t\t\topenWorldHint: false,\n\t\t\t},\n\t\t},\n\t\twithToolErrors(readConfigTool),\n\t);\n\n\tregisterAppResource(\n\t\tserver,\n\t\t'Suigar Transaction Inspector',\n\t\tSUIGAR_MCP_APP_RESOURCE_URI,\n\t\t{\n\t\t\tdescription:\n\t\t\t\t'Compact MCP App UI for inspecting Suigar config, transaction plans, summaries, dry-runs, and serialized bytes.',\n\t\t},\n\t\tcreateSuigarMcpAppResourceResult,\n\t);\n\n\tconst appToolMeta = {\n\t\tui: {\n\t\t\tresourceUri: SUIGAR_MCP_APP_RESOURCE_URI,\n\t\t},\n\t};\n\n\tregisterAppTool(\n\t\tserver,\n\t\t'read_game_metadata',\n\t\t{\n\t\t\ttitle: 'Read Suigar Game Metadata',\n\t\t\tdescription:\n\t\t\t\t'Read SDK-backed metadata for a supported Suigar game and coin type.',\n\t\t\tinputSchema: readGameMetadataInputSchema,\n\t\t\toutputSchema: toolOutputSchema,\n\t\t\tannotations: {\n\t\t\t\treadOnlyHint: true,\n\t\t\t\tdestructiveHint: false,\n\t\t\t\tidempotentHint: true,\n\t\t\t\topenWorldHint: false,\n\t\t\t},\n\t\t\t_meta: appToolMeta,\n\t\t},\n\t\twithToolErrors(readGameMetadataTool),\n\t);\n\n\tregisterAppTool(\n\t\tserver,\n\t\t'build_coinflip_transaction',\n\t\t{\n\t\t\ttitle: 'Build Coinflip Transaction',\n\t\t\tdescription:\n\t\t\t\t'Build, dry-run, or inspect an unsigned Suigar coinflip transaction.',\n\t\t\tinputSchema: coinflipInputSchema,\n\t\t\toutputSchema: toolOutputSchema,\n\t\t\tannotations: {\n\t\t\t\treadOnlyHint: false,\n\t\t\t\tdestructiveHint: false,\n\t\t\t\tidempotentHint: false,\n\t\t\t\topenWorldHint: true,\n\t\t\t},\n\t\t\t_meta: appToolMeta,\n\t\t},\n\t\twithToolErrors(buildCoinflipTransactionTool),\n\t);\n\n\tregisterAppTool(\n\t\tserver,\n\t\t'build_limbo_transaction',\n\t\t{\n\t\t\ttitle: 'Build Limbo Transaction',\n\t\t\tdescription:\n\t\t\t\t'Build, dry-run, or inspect an unsigned Suigar limbo transaction.',\n\t\t\tinputSchema: limboInputSchema,\n\t\t\toutputSchema: toolOutputSchema,\n\t\t\tannotations: {\n\t\t\t\treadOnlyHint: false,\n\t\t\t\tdestructiveHint: false,\n\t\t\t\tidempotentHint: false,\n\t\t\t\topenWorldHint: true,\n\t\t\t},\n\t\t\t_meta: appToolMeta,\n\t\t},\n\t\twithToolErrors(buildLimboTransactionTool),\n\t);\n\n\tregisterAppTool(\n\t\tserver,\n\t\t'build_plinko_transaction',\n\t\t{\n\t\t\ttitle: 'Build Plinko Transaction',\n\t\t\tdescription:\n\t\t\t\t'Build, dry-run, or inspect an unsigned Suigar plinko transaction.',\n\t\t\tinputSchema: configIdInputSchema,\n\t\t\toutputSchema: toolOutputSchema,\n\t\t\tannotations: {\n\t\t\t\treadOnlyHint: false,\n\t\t\t\tdestructiveHint: false,\n\t\t\t\tidempotentHint: false,\n\t\t\t\topenWorldHint: true,\n\t\t\t},\n\t\t\t_meta: appToolMeta,\n\t\t},\n\t\twithToolErrors(buildPlinkoTransactionTool),\n\t);\n\n\tregisterAppTool(\n\t\tserver,\n\t\t'build_wheel_transaction',\n\t\t{\n\t\t\ttitle: 'Build Wheel Transaction',\n\t\t\tdescription:\n\t\t\t\t'Build, dry-run, or inspect an unsigned Suigar wheel transaction.',\n\t\t\tinputSchema: configIdInputSchema,\n\t\t\toutputSchema: toolOutputSchema,\n\t\t\tannotations: {\n\t\t\t\treadOnlyHint: false,\n\t\t\t\tdestructiveHint: false,\n\t\t\t\tidempotentHint: false,\n\t\t\t\topenWorldHint: true,\n\t\t\t},\n\t\t\t_meta: appToolMeta,\n\t\t},\n\t\twithToolErrors(buildWheelTransactionTool),\n\t);\n\n\tregisterAppTool(\n\t\tserver,\n\t\t'build_range_transaction',\n\t\t{\n\t\t\ttitle: 'Build Range Transaction',\n\t\t\tdescription:\n\t\t\t\t'Build, dry-run, or inspect an unsigned Suigar range transaction.',\n\t\t\tinputSchema: rangeInputSchema,\n\t\t\toutputSchema: toolOutputSchema,\n\t\t\tannotations: {\n\t\t\t\treadOnlyHint: false,\n\t\t\t\tdestructiveHint: false,\n\t\t\t\tidempotentHint: false,\n\t\t\t\topenWorldHint: true,\n\t\t\t},\n\t\t\t_meta: appToolMeta,\n\t\t},\n\t\twithToolErrors(buildRangeTransactionTool),\n\t);\n\n\tregisterAppTool(\n\t\tserver,\n\t\t'build_pvp_coinflip_create_transaction',\n\t\t{\n\t\t\ttitle: 'Build PvP Coinflip Create',\n\t\t\tdescription:\n\t\t\t\t'Build, dry-run, or inspect an unsigned Suigar PvP coinflip lobby creation transaction.',\n\t\t\tinputSchema: pvpCoinflipCreateInputSchema,\n\t\t\toutputSchema: toolOutputSchema,\n\t\t\tannotations: {\n\t\t\t\treadOnlyHint: false,\n\t\t\t\tdestructiveHint: false,\n\t\t\t\tidempotentHint: false,\n\t\t\t\topenWorldHint: true,\n\t\t\t},\n\t\t\t_meta: appToolMeta,\n\t\t},\n\t\twithToolErrors(buildPvpCoinflipCreateTransactionTool),\n\t);\n\n\tregisterAppTool(\n\t\tserver,\n\t\t'build_pvp_coinflip_join_transaction',\n\t\t{\n\t\t\ttitle: 'Build PvP Coinflip Join',\n\t\t\tdescription:\n\t\t\t\t'Build, dry-run, or inspect an unsigned Suigar PvP coinflip join transaction.',\n\t\t\tinputSchema: pvpCoinflipJoinInputSchema,\n\t\t\toutputSchema: toolOutputSchema,\n\t\t\tannotations: {\n\t\t\t\treadOnlyHint: false,\n\t\t\t\tdestructiveHint: false,\n\t\t\t\tidempotentHint: false,\n\t\t\t\topenWorldHint: true,\n\t\t\t},\n\t\t\t_meta: appToolMeta,\n\t\t},\n\t\twithToolErrors(buildPvpCoinflipJoinTransactionTool),\n\t);\n\n\tregisterAppTool(\n\t\tserver,\n\t\t'build_pvp_coinflip_cancel_transaction',\n\t\t{\n\t\t\ttitle: 'Build PvP Coinflip Cancel',\n\t\t\tdescription:\n\t\t\t\t'Build, dry-run, or inspect an unsigned Suigar PvP coinflip cancel transaction.',\n\t\t\tinputSchema: pvpCoinflipCancelInputSchema,\n\t\t\toutputSchema: toolOutputSchema,\n\t\t\tannotations: {\n\t\t\t\treadOnlyHint: false,\n\t\t\t\tdestructiveHint: false,\n\t\t\t\tidempotentHint: false,\n\t\t\t\topenWorldHint: true,\n\t\t\t},\n\t\t\t_meta: appToolMeta,\n\t\t},\n\t\twithToolErrors(buildPvpCoinflipCancelTransactionTool),\n\t);\n\n\treturn server;\n};\n\nexport const startSuigarMcpServer = async () => {\n\tconst server = createSuigarMcpServer();\n\tconst transport = new StdioServerTransport();\n\tawait server.connect(transport);\n};\n"],"mappings":";;;;;;;;AAsCA,MAAa,8BACZ;AAED,MAAM,cAAc,KAAK,MACxB,aAAa,IAAI,IAAI,mBAAmB,OAAO,KAAK,GAAG,GAAG,MAAM,CACjE;AAEA,MAAM,aAAa,UAAmB;CACrC,IAAI,iBAAiB,OACpB,OAAO,GAAG,MAAM,KAAK,IAAI,MAAM;CAEhC,OAAO,OAAO,KAAK;AACpB;AAEA,MAAM,gBACL,OACA,SAEA,iBAAiB,SACjB,UAAU,SACT,MAA4B,SAAS;AAEvC,MAAM,kBACI,YACT,OACC,UAII;CACJ,IAAI;EACH,OAAO,MAAM,QAAQ,KAAK;CAC3B,SAAS,OAAO;EACf,OAAO;GACN,SAAS;GACT,SAAS,CACR;IACC,MAAM;IACN,MAAM,GAAG,UAAU,KAAK,EAAE;GAC3B,CACD;EACD;CACD;AACD;AAED,MAAa,uBAAuB,YAAY;CAC/C,IAAI;EACH,OAAO,MAAM,SAAS,IAAI,IAAI,oBAAoB,OAAO,KAAK,GAAG,GAAG,MAAM;CAC3E,SAAS,OAAO;EACf,IAAI,CAAC,aAAa,OAAO,QAAQ,GAChC,MAAM;EAEP,MAAM,IAAI,MAAM,+CAA+C,EAC9D,OAAO,MACR,CAAC;CACF;AACD;AAEA,MAAa,mCAAmC,aAAa,EAC5D,UAAU,CACT;CACC,KAAK;CACL,UAAU;CACV,MAAM,MAAM,qBAAqB;CACjC,OAAO,EACN,IAAI,EACH,KAAK;EACJ,gBAAgB,CAAC;EACjB,iBAAiB,CAAC;CACnB,EACD,EACD;AACD,CACD,EACD;AAEA,MAAa,8BAA8B;CAC1C,MAAM,SAAS,IAAI,UAAU;EAC5B,MAAM;EACN,SAAS,YAAY;CACtB,CAAC;CAED,OAAO,aACN,eACA;EACC,OAAO;EACP,aACC;EACD,aAAa;EACb,cAAc;EACd,aAAa;GACZ,cAAc;GACd,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;EAChB;CACD,GACA,eAAe,cAAc,CAC9B;CAEA,oBACC,QACA,gCACA,6BACA,EACC,aACC,iHACF,GACA,gCACD;CAEA,MAAM,cAAc,EACnB,IAAI,EACH,aAAa,4BACd,EACD;CAEA,gBACC,QACA,sBACA;EACC,OAAO;EACP,aACC;EACD,aAAa;EACb,cAAc;EACd,aAAa;GACZ,cAAc;GACd,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;EAChB;EACA,OAAO;CACR,GACA,eAAe,oBAAoB,CACpC;CAEA,gBACC,QACA,8BACA;EACC,OAAO;EACP,aACC;EACD,aAAa;EACb,cAAc;EACd,aAAa;GACZ,cAAc;GACd,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;EAChB;EACA,OAAO;CACR,GACA,eAAe,4BAA4B,CAC5C;CAEA,gBACC,QACA,2BACA;EACC,OAAO;EACP,aACC;EACD,aAAa;EACb,cAAc;EACd,aAAa;GACZ,cAAc;GACd,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;EAChB;EACA,OAAO;CACR,GACA,eAAe,yBAAyB,CACzC;CAEA,gBACC,QACA,4BACA;EACC,OAAO;EACP,aACC;EACD,aAAa;EACb,cAAc;EACd,aAAa;GACZ,cAAc;GACd,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;EAChB;EACA,OAAO;CACR,GACA,eAAe,0BAA0B,CAC1C;CAEA,gBACC,QACA,2BACA;EACC,OAAO;EACP,aACC;EACD,aAAa;EACb,cAAc;EACd,aAAa;GACZ,cAAc;GACd,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;EAChB;EACA,OAAO;CACR,GACA,eAAe,yBAAyB,CACzC;CAEA,gBACC,QACA,2BACA;EACC,OAAO;EACP,aACC;EACD,aAAa;EACb,cAAc;EACd,aAAa;GACZ,cAAc;GACd,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;EAChB;EACA,OAAO;CACR,GACA,eAAe,yBAAyB,CACzC;CAEA,gBACC,QACA,yCACA;EACC,OAAO;EACP,aACC;EACD,aAAa;EACb,cAAc;EACd,aAAa;GACZ,cAAc;GACd,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;EAChB;EACA,OAAO;CACR,GACA,eAAe,qCAAqC,CACrD;CAEA,gBACC,QACA,uCACA;EACC,OAAO;EACP,aACC;EACD,aAAa;EACb,cAAc;EACd,aAAa;GACZ,cAAc;GACd,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;EAChB;EACA,OAAO;CACR,GACA,eAAe,mCAAmC,CACnD;CAEA,gBACC,QACA,yCACA;EACC,OAAO;EACP,aACC;EACD,aAAa;EACb,cAAc;EACd,aAAa;GACZ,cAAc;GACd,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;EAChB;EACA,OAAO;CACR,GACA,eAAe,qCAAqC,CACrD;CAEA,OAAO;AACR;AAEA,MAAa,uBAAuB,YAAY;CAC/C,MAAM,SAAS,sBAAsB;CACrC,MAAM,YAAY,IAAI,qBAAqB;CAC3C,MAAM,OAAO,QAAQ,SAAS;AAC/B"}
|