cmskite-mcp 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,7 +7,34 @@ content surface behind one agent token.
7
7
 
8
8
  Create a token in the dashboard under **Settings → Agent tokens**. Tick only
9
9
  what the assistant needs; the defaults are read and write content. The token is
10
- shown once.
10
+ shown once, and that dialogue generates the block below for whichever client you
11
+ pick — **Set up a client** on the same screen shows it again afterwards.
12
+
13
+ The first start downloads the package, which can take longer than a client
14
+ waits for a server (often 30 seconds). If yours reports a timeout, run
15
+ `npx -y cmskite-mcp@latest` once in a terminal to fill the cache, or
16
+ `npm install -g cmskite-mcp` and use `cmskite-mcp` as the command.
17
+
18
+ Every client runs the same process. They disagree only about where it is written
19
+ and under what key, and a block copied from the wrong one pastes without
20
+ complaint and then does nothing.
21
+
22
+ ### Claude Code
23
+
24
+ ```sh
25
+ claude mcp add cmskite --scope user \
26
+ --env CMSKITE_API_URL=https://api.cmskite.com \
27
+ --env CMSKITE_AGENT_TOKEN=cka_live_… \
28
+ -- npx -y cmskite-mcp
29
+ ```
30
+
31
+ `--scope user` puts it in every project. Drop it to add it to one repository.
32
+
33
+ ### Claude Desktop, Cursor, Windsurf, and most others
34
+
35
+ `~/Library/Application Support/Claude/claude_desktop_config.json` ·
36
+ `%APPDATA%\Claude\claude_desktop_config.json` · `~/.cursor/mcp.json` ·
37
+ `~/.codeium/windsurf/mcp_config.json`
11
38
 
12
39
  ```jsonc
13
40
  {
@@ -24,6 +51,65 @@ shown once.
24
51
  }
25
52
  ```
26
53
 
54
+ Claude Desktop reads that file only at start-up, so quit it completely and open
55
+ it again.
56
+
57
+ ### Codex CLI
58
+
59
+ `~/.codex/config.toml` — TOML, and the only one here that does not take the
60
+ block above.
61
+
62
+ ```toml
63
+ [mcp_servers.cmskite]
64
+ command = "npx"
65
+ args = ["-y", "cmskite-mcp"]
66
+
67
+ [mcp_servers.cmskite.env]
68
+ CMSKITE_API_URL = "https://api.cmskite.com"
69
+ CMSKITE_AGENT_TOKEN = "cka_live_…"
70
+ ```
71
+
72
+ ### VS Code
73
+
74
+ `.vscode/mcp.json` — the key is `servers`, not `mcpServers`, and the transport
75
+ is named.
76
+
77
+ ```jsonc
78
+ {
79
+ "servers": {
80
+ "cmskite": {
81
+ "type": "stdio",
82
+ "command": "npx",
83
+ "args": ["-y", "cmskite-mcp"],
84
+ "env": {
85
+ "CMSKITE_API_URL": "https://api.cmskite.com",
86
+ "CMSKITE_AGENT_TOKEN": "cka_live_…"
87
+ }
88
+ }
89
+ }
90
+ }
91
+ ```
92
+
93
+ ### Zed
94
+
95
+ Settings (`cmd-shift-p` → “open settings”) — context servers, marked custom.
96
+
97
+ ```jsonc
98
+ {
99
+ "context_servers": {
100
+ "cmskite": {
101
+ "source": "custom",
102
+ "command": "npx",
103
+ "args": ["-y", "cmskite-mcp"],
104
+ "env": {
105
+ "CMSKITE_API_URL": "https://api.cmskite.com",
106
+ "CMSKITE_AGENT_TOKEN": "cka_live_…"
107
+ }
108
+ }
109
+ }
110
+ }
111
+ ```
112
+
27
113
  | Variable | |
28
114
  |---|---|
29
115
  | `CMSKITE_AGENT_TOKEN` | Required. Starts `cka_`. A `csk_` value is a project API key: read-only, one project, and rejected here. |
@@ -32,7 +118,8 @@ shown once.
32
118
 
33
119
  ## Tools
34
120
 
35
- **Where am I** — `whoami`, `list_projects`, `get_project`, `get_project_summary`
121
+ **Where am I** — `whoami`, `list_projects`, `get_project`, `get_project_summary`,
122
+ `update_project`
36
123
 
37
124
  **Shape** — `create_workspace`, `create_project`, `list_categories`,
38
125
  `create_category`, `update_category`, `delete_category`, `list_tags`,
@@ -41,23 +128,56 @@ shown once.
41
128
  **Content** — `list_posts`, `get_post`, `search_posts`, `create_post`,
42
129
  `update_post`, `delete_post`
43
130
 
44
- Start with `whoami`, then `list_projects` for a `prj_…` id. Every content tool
131
+ **Keys** — `list_api_keys`, `create_api_key`
132
+
133
+ **Connecting a website** — `get_integration_guide`, `check_integration`,
134
+ `get_content_analytics`, `get_post_analytics`
135
+
136
+ Start with `whoami`, then `list_projects` for a `prj_…` id. `whoami` returns
137
+ `agentGrants`, the token's own list: a tool works only when that list and the
138
+ owner's role both allow it. Every content tool
45
139
  needs one unless `CMSKITE_PROJECT_ID` is set.
46
140
 
141
+ ### Connecting a website
142
+
143
+ `get_integration_guide` returns the files to write for the project in front of
144
+ you. It answers for JavaScript with the `cmskite` package, and for PHP,
145
+ WordPress, Laravel, Python or a plain HTML site with the raw HTTP calls — those
146
+ need no dependency at all.
147
+
148
+ `check_integration` is the one to finish with, and the one to start with when
149
+ somebody says their views are zero. An integration has two halves: the server
150
+ fetches content, and the reader's browser reports the view. Building only the
151
+ first produces a site that works perfectly and counts nobody, with no error
152
+ anywhere to find. Nothing else can tell those two states apart.
153
+
47
154
  Each tool needs the matching grant, and a token has only what was ticked:
48
155
 
49
156
  | Tool | Grant |
50
157
  |---|---|
51
158
  | `whoami` | `member.read` — tick it, or the first call an assistant makes is the one that fails |
52
159
  | `list_projects`, `get_project`, `get_project_summary` | `project.read` |
53
- | `create_project` | `project.write` |
160
+ | `create_project`, `update_project` (including allowed origins) | `project.write` |
54
161
  | `create_workspace` | `workspace.create` |
55
162
  | `list_*`, `get_post`, `search_posts` | `content.read` |
56
163
  | `create_*`, `update_*` | `content.write` |
164
+ | `update_post` with `status: "published"` | `content.publish`, on top of `content.write` |
57
165
  | `delete_*` | `content.delete` |
166
+ | `list_api_keys` | `apikey.read` |
167
+ | `create_api_key` | `apikey.write` |
168
+ | `check_integration` | `project.read` |
169
+ | `get_content_analytics`, `get_post_analytics` | `analytics.read` |
170
+ | `get_integration_guide` | none — it reads nothing and changes nothing |
58
171
 
59
172
  New posts are drafts. Publishing is `update_post` with `status: "published"` —
60
- a separate step, because publishing is a decision the person should make.
173
+ a separate step, because publishing is a decision the person should make, and a
174
+ separate grant, so an assistant can be allowed to draft without being allowed to
175
+ ship.
176
+
177
+ The member's own permissions are checked as well, fresh on every request. A
178
+ token ticked for `content.publish` held by somebody whose role does not include
179
+ it publishes nothing: the grant list is a ceiling on what its owner can already
180
+ do, never an addition to it.
61
181
 
62
182
  ## What it cannot do
63
183
 
@@ -65,8 +185,18 @@ This server adds no permissions. Every limit is enforced by the API on every
65
185
  request: the token's grant list, the member's current role, the one workspace
66
186
  the token is bound to, and the plan.
67
187
 
68
- No token can mint or revoke credentials, delete a project, or delete a
69
- workspace — not at any role and not with any configuration. See
188
+ No token can revoke credentials, invite or remove a member, change anybody's
189
+ permissions, delete a project, or delete a workspace — not at any role and not
190
+ with any configuration.
191
+
192
+ `create_api_key` is the one credential an agent can mint, and only with the
193
+ grant ticked. What it produces is strictly weaker than the token that made it:
194
+ one project, read-only, published content only, no ability to revoke anything.
195
+ It exists so that finishing a site does not require shipping the agent token —
196
+ which can write and delete — to production.
197
+
198
+ A token also cannot reach a project its owner was not admitted to. Project
199
+ access belongs to the person, and the token acts as them. See
70
200
  `docs/agents-and-mcp.md` in the API repository.
71
201
 
72
202
  `create_workspace` returns a **new** token for the workspace it created. The
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
2
3
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
4
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
5
  import { CmsKiteClient } from './client.js';
@@ -14,10 +15,12 @@ import { allTools, registerTools } from './tools/index.js';
14
15
  * translator, not a second authorization layer, which is the only arrangement
15
16
  * where the two cannot disagree.
16
17
  */
18
+ /** From package.json, so the handshake reports the version that is actually running. */
19
+ const { version } = createRequire(import.meta.url)('../package.json');
17
20
  async function main() {
18
21
  const config = readConfig();
19
22
  const client = new CmsKiteClient(config);
20
- const server = new McpServer({ name: 'cmskite', version: '0.1.0' }, {
23
+ const server = new McpServer({ name: 'cmskite', version }, {
21
24
  instructions: 'CMSKite manages blog content behind an API. A workspace holds projects; a project is ' +
22
25
  'one website and holds the posts, categories, tags and authors. Start with `whoami`, ' +
23
26
  'then `list_projects` to get a `prj_...` id — every content tool needs one unless ' +
@@ -31,7 +34,7 @@ async function main() {
31
34
  // message corrupts the stream and the client drops the connection, so every
32
35
  // diagnostic in this process goes to stderr.
33
36
  await server.connect(new StdioServerTransport());
34
- process.stderr.write(`cmskite-mcp ready: ${allTools.length} tools against ${config.apiUrl}\n`);
37
+ process.stderr.write(`cmskite-mcp ${version} ready: ${allTools.length} tools against ${config.apiUrl}\n`);
35
38
  }
36
39
  main().catch((err) => {
37
40
  process.stderr.write(`cmskite-mcp failed to start: ${err instanceof Error ? err.message : String(err)}\n`);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAE1D;;;;;;;;;GASG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAA;IAExC,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,EACrC;QACE,YAAY,EACV,uFAAuF;YACvF,sFAAsF;YACtF,mFAAmF;YACnF,mFAAmF;YACnF,8EAA8E;YAC9E,sFAAsF;YACtF,4DAA4D;KAC/D,CACF,CAAA;IAED,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;IAEvC,gFAAgF;IAChF,4EAA4E;IAC5E,6CAA6C;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAA;IAChD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,QAAQ,CAAC,MAAM,kBAAkB,MAAM,CAAC,MAAM,IAAI,CAAC,CAAA;AAChG,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC1G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAE1D;;;;;;;;;GASG;AACH,wFAAwF;AACxF,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAwB,CAAA;AAE5F,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAC3B,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAA;IAExC,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,EAC5B;QACE,YAAY,EACV,uFAAuF;YACvF,sFAAsF;YACtF,mFAAmF;YACnF,mFAAmF;YACnF,8EAA8E;YAC9E,sFAAsF;YACtF,4DAA4D;KAC/D,CACF,CAAA;IAED,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;IAEvC,gFAAgF;IAChF,4EAA4E;IAC5E,6CAA6C;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAA;IAChD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,OAAO,WAAW,QAAQ,CAAC,MAAM,kBAAkB,MAAM,CAAC,MAAM,IAAI,CAAC,CAAA;AAC3G,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC1G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
@@ -0,0 +1,96 @@
1
+ import { z } from 'zod';
2
+ import { segment } from '../client.js';
3
+ import { defineTool } from './register.js';
4
+ /**
5
+ * Whether the work actually worked.
6
+ *
7
+ * Every other tool here changes something and reports that it changed it. None
8
+ * of them could tell anybody whether the result was a working website, and the
9
+ * failure this product has is specifically one that reports success: an
10
+ * assistant creates a project, writes eight posts, mints a key and wires up the
11
+ * content fetching, and every one of those steps succeeds. The tracker is a
12
+ * separate snippet, nothing asked for it, and so nobody added it. The site
13
+ * works. Every post reads zero views. There is no error anywhere to find.
14
+ *
15
+ * So `check_integration` exists to make that state something a tool can say out
16
+ * loud. It is the last call of any integration, and the first call of "why are
17
+ * my views zero".
18
+ */
19
+ export const diagnosticTools = [
20
+ defineTool({
21
+ name: 'check_integration',
22
+ title: 'Is this project actually working?',
23
+ description: 'Checks whether a project is really connected to a website: does it have a key, has a ' +
24
+ 'site ever used it, and are views arriving from the pages that render the content. ' +
25
+ 'Each check comes back with the one action that fixes it. ' +
26
+ 'ALWAYS call this after wiring up an integration, and always when somebody says views or ' +
27
+ 'analytics are zero — a site can fetch content perfectly and report nothing, and this is ' +
28
+ 'the only thing that tells the difference. Requires the project.read grant.',
29
+ input: { projectId: z.string().describe('The project id, as `prj_...`.') },
30
+ readOnly: true,
31
+ run: (client, args) => client.request(`/v1/projects/${segment(args.projectId)}/integration-health`),
32
+ }),
33
+ defineTool({
34
+ name: 'get_content_analytics',
35
+ title: 'Views, uniques and clicks',
36
+ description: 'What readers did with a project’s posts over a date range: totals, a daily series, and ' +
37
+ 'the posts that were actually read. Read from rollups, so the answer is the same size ' +
38
+ 'whatever the traffic was. If everything is zero, call check_integration — that is a ' +
39
+ 'tracking problem far more often than it is a traffic problem. Requires the ' +
40
+ 'analytics.read grant.',
41
+ input: {
42
+ projectId: z.string().describe('The project id, as `prj_...`.'),
43
+ from: z
44
+ .string()
45
+ .regex(/^\d{4}-\d{2}-\d{2}$/)
46
+ .optional()
47
+ .describe('Inclusive UTC day. Defaults to 30 days ago.'),
48
+ to: z
49
+ .string()
50
+ .regex(/^\d{4}-\d{2}-\d{2}$/)
51
+ .optional()
52
+ .describe('Inclusive UTC day. Defaults to today.'),
53
+ topPosts: z
54
+ .number()
55
+ .int()
56
+ .min(1)
57
+ .max(50)
58
+ .optional()
59
+ .describe('How many of the best-read posts to include. Defaults to 10.'),
60
+ },
61
+ readOnly: true,
62
+ run: async (client, args) => {
63
+ const query = { projectId: args.projectId, from: args.from, to: args.to };
64
+ // Two calls rather than one, because the summary and the leaderboard are
65
+ // different shapes and an assistant asking "how is the blog doing" wants
66
+ // both. They are independent reads and nothing here mutates, so they go
67
+ // together.
68
+ const [summary, top] = await Promise.all([
69
+ client.request('/v1/analytics/content/summary', { query }),
70
+ client.request('/v1/analytics/content/top-posts', {
71
+ query: { ...query, limit: args.topPosts ?? 10 },
72
+ }),
73
+ ]);
74
+ return { summary, topPosts: top };
75
+ },
76
+ }),
77
+ defineTool({
78
+ name: 'get_post_analytics',
79
+ title: 'One post, day by day',
80
+ description: 'Views, unique readers and clicks for one post, per day. The way to check that a specific ' +
81
+ 'post\'s view landed after wiring up tracking: open the post in a real browser (headless ' +
82
+ 'browsers are not counted), wait about a minute for the rollup, then call this. A reader ' +
83
+ 'counts once per post per day. Requires the analytics.read grant.',
84
+ input: {
85
+ projectId: z.string().describe('The project id, as `prj_...`.'),
86
+ postId: z.string().describe('The post id, as `post_...`. Not the slug.'),
87
+ from: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe('Inclusive UTC day. Defaults to 30 days ago.'),
88
+ to: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe('Inclusive UTC day. Defaults to today.'),
89
+ },
90
+ readOnly: true,
91
+ run: (client, args) => client.request(`/v1/analytics/content/posts/${segment(args.postId)}`, {
92
+ query: { projectId: args.projectId, from: args.from, to: args.to },
93
+ }),
94
+ }),
95
+ ];
96
+ //# sourceMappingURL=diagnose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnose.js","sourceRoot":"","sources":["../../src/tools/diagnose.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,6 @@
1
+ import { diagnosticTools } from './diagnose.js';
2
+ import { integrationTools } from './integrate.js';
3
+ import { keyTools } from './keys.js';
1
4
  import { postTools } from './posts.js';
2
5
  import { taxonomyTools } from './taxonomy.js';
3
6
  import { workspaceTools } from './workspace.js';
@@ -5,6 +8,16 @@ import { workspaceTools } from './workspace.js';
5
8
  * Every tool, in the order an assistant meeting a workspace for the first time
6
9
  * would want them: find out where you are, then what is here, then change it.
7
10
  *
11
+ * Integration is last and used first, which is the one exception: an assistant
12
+ * asked to "add a blog to this site" should call `get_integration_guide` before
13
+ * it writes a line, because the alternative is a hand-rolled fetch wrapper that
14
+ * works and counts no readers -- a customer gets a working site with no
15
+ * analytics and nothing indicating that anything is missing.
16
+ *
17
+ * Diagnostics come after integration for the same reason integration comes
18
+ * last: `check_integration` is what an assistant calls once it thinks it has
19
+ * finished, and what it calls first when somebody says the numbers are zero.
20
+ *
8
21
  * Media is deliberately absent. Uploading goes to object storage through a
9
22
  * presigned URL, so it is two calls and a byte stream, and an assistant that
10
23
  * cannot see the file has nothing useful to send. When it is added it belongs
@@ -14,6 +27,9 @@ export const allTools = [
14
27
  ...workspaceTools,
15
28
  ...taxonomyTools,
16
29
  ...postTools,
30
+ ...keyTools,
31
+ ...integrationTools,
32
+ ...diagnosticTools,
17
33
  ];
18
34
  export { registerTools } from './register.js';
19
35
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAG/C;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,GAAG,cAAc;IACjB,GAAG,aAAa;IAChB,GAAG,SAAS;CACS,CAAA;AAEvB,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAG/C;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,GAAG,cAAc;IACjB,GAAG,aAAa;IAChB,GAAG,SAAS;IACZ,GAAG,QAAQ;IACX,GAAG,gBAAgB;IACnB,GAAG,eAAe;CACG,CAAA;AAEvB,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA"}