@plurnk/plurnk-a2a 1.9.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.
Files changed (53) hide show
  1. package/.env.defaults +30 -0
  2. package/README.md +69 -0
  3. package/SPEC.md +199 -0
  4. package/dist/A2a.d.ts +12 -0
  5. package/dist/A2a.d.ts.map +1 -0
  6. package/dist/A2a.js +397 -0
  7. package/dist/A2a.js.map +1 -0
  8. package/dist/A2aMessage.d.ts +10 -0
  9. package/dist/A2aMessage.d.ts.map +1 -0
  10. package/dist/A2aMessage.js +28 -0
  11. package/dist/A2aMessage.js.map +1 -0
  12. package/dist/A2aProjection.d.ts +25 -0
  13. package/dist/A2aProjection.d.ts.map +1 -0
  14. package/dist/A2aProjection.js +183 -0
  15. package/dist/A2aProjection.js.map +1 -0
  16. package/dist/Functionality.d.ts +77 -0
  17. package/dist/Functionality.d.ts.map +1 -0
  18. package/dist/Functionality.js +247 -0
  19. package/dist/Functionality.js.map +1 -0
  20. package/dist/HttpJsonClient.d.ts +21 -0
  21. package/dist/HttpJsonClient.d.ts.map +1 -0
  22. package/dist/HttpJsonClient.js +41 -0
  23. package/dist/HttpJsonClient.js.map +1 -0
  24. package/dist/Module.d.ts +32 -0
  25. package/dist/Module.d.ts.map +1 -0
  26. package/dist/Module.js +91 -0
  27. package/dist/Module.js.map +1 -0
  28. package/dist/OutboundModule.d.ts +14 -0
  29. package/dist/OutboundModule.d.ts.map +1 -0
  30. package/dist/OutboundModule.js +24 -0
  31. package/dist/OutboundModule.js.map +1 -0
  32. package/dist/PlurnkAgentExecutor.d.ts +11 -0
  33. package/dist/PlurnkAgentExecutor.d.ts.map +1 -0
  34. package/dist/PlurnkAgentExecutor.js +282 -0
  35. package/dist/PlurnkAgentExecutor.js.map +1 -0
  36. package/dist/PlurnkTaskStore.d.ts +19 -0
  37. package/dist/PlurnkTaskStore.d.ts.map +1 -0
  38. package/dist/PlurnkTaskStore.js +271 -0
  39. package/dist/PlurnkTaskStore.js.map +1 -0
  40. package/dist/WorkspaceBinding.d.ts +13 -0
  41. package/dist/WorkspaceBinding.d.ts.map +1 -0
  42. package/dist/WorkspaceBinding.js +40 -0
  43. package/dist/WorkspaceBinding.js.map +1 -0
  44. package/dist/config.d.ts +22 -0
  45. package/dist/config.d.ts.map +1 -0
  46. package/dist/config.js +332 -0
  47. package/dist/config.js.map +1 -0
  48. package/dist/index.d.ts +10 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +9 -0
  51. package/dist/index.js.map +1 -0
  52. package/docs/a2a.md +23 -0
  53. package/package.json +66 -0
@@ -0,0 +1,271 @@
1
+ var _a;
2
+ import { Role, TaskState, } from "@a2a-js/sdk";
3
+ import {} from "@a2a-js/sdk/server";
4
+ import { RequestMalformedError } from "@a2a-js/sdk/errors";
5
+ const nonempty = (value) => typeof value === "string" && value.length > 0;
6
+ const message = (messageId, contextId, taskId, role, content, mediaType = "text/plain") => ({
7
+ messageId,
8
+ contextId,
9
+ taskId,
10
+ role,
11
+ parts: [{
12
+ content: { $case: "text", value: content },
13
+ filename: "",
14
+ mediaType,
15
+ metadata: {},
16
+ }],
17
+ metadata: {},
18
+ extensions: [],
19
+ referenceTaskIds: [],
20
+ });
21
+ const messageIdFromSource = (source, fallback) => {
22
+ if (!nonempty(source))
23
+ return fallback;
24
+ try {
25
+ const segments = new URL(source).pathname.split("/").filter(Boolean);
26
+ const marker = segments.lastIndexOf("messages");
27
+ return marker >= 0 && nonempty(segments[marker + 1])
28
+ ? decodeURIComponent(segments[marker + 1])
29
+ : fallback;
30
+ }
31
+ catch {
32
+ return fallback;
33
+ }
34
+ };
35
+ const terminalArtifact = (result) => {
36
+ if (result === null || result.status < 200 || result.status >= 400)
37
+ return [];
38
+ if (!nonempty(result.content))
39
+ return [];
40
+ return [{
41
+ artifactId: "result",
42
+ name: "Result",
43
+ description: "The terminal Plurnk SEND deliverable.",
44
+ parts: [{
45
+ content: { $case: "text", value: result.content },
46
+ filename: "",
47
+ mediaType: nonempty(result.mimetype) ? result.mimetype : "text/markdown",
48
+ metadata: {},
49
+ }],
50
+ metadata: {},
51
+ extensions: [],
52
+ }];
53
+ };
54
+ class PlurnkTaskStore {
55
+ #port;
56
+ #workspace;
57
+ constructor(port, workspace) {
58
+ this.#port = port;
59
+ this.#workspace = workspace;
60
+ }
61
+ async binding(taskId) {
62
+ const workspaceId = await this.#workspace.id();
63
+ const task = await this.#port.readWorker({
64
+ workspaceId,
65
+ identity: { name: taskId },
66
+ });
67
+ if (task === null || task.origin !== "model" || task.parentWorkerId === null)
68
+ return null;
69
+ const context = await this.#port.readWorker({
70
+ workspaceId,
71
+ identity: { id: task.parentWorkerId },
72
+ });
73
+ if (context === null || context.origin !== "model" || context.parentWorkerId !== null) {
74
+ throw new Error(`A2A Task '${taskId}' has no unique root Context worker.`);
75
+ }
76
+ const loops = await this.#port.listWorkerLoops({
77
+ workspaceId,
78
+ workerId: task.id,
79
+ });
80
+ const loop = loops
81
+ .filter(({ promptSource }) => _a.#ownsSource(promptSource, context.name, task.name))
82
+ .at(-1) ?? null;
83
+ if (loop === null)
84
+ return null;
85
+ return { context, task, loop };
86
+ }
87
+ async ownsContext(context) {
88
+ if (context.origin !== "model" || context.parentWorkerId !== null)
89
+ return false;
90
+ const children = await this.#port.listWorkers(await this.#workspace.id(), {
91
+ origin: "model",
92
+ parentWorkerId: context.id,
93
+ });
94
+ for (const child of children) {
95
+ if (await this.binding(child.name) !== null)
96
+ return true;
97
+ }
98
+ return false;
99
+ }
100
+ async load(taskId, context) {
101
+ this.#assertTenant(context);
102
+ const binding = await this.binding(taskId);
103
+ return binding === null ? undefined : await this.#project(binding);
104
+ }
105
+ async save(task, context) {
106
+ this.#assertTenant(context);
107
+ const binding = await this.binding(task.id);
108
+ if (binding === null) {
109
+ // The SDK turns an executor-side admission rejection into an
110
+ // ephemeral FAILED Task event. It is protocol evidence, not
111
+ // authority to create a second Task store or adopt a Worker.
112
+ if (task.status?.state === TaskState.TASK_STATE_FAILED)
113
+ return;
114
+ throw new Error(`A2A Task '${task.id}' has no Plurnk worker.`);
115
+ }
116
+ if (binding.context.name !== task.contextId) {
117
+ throw new Error(`A2A Task '${task.id}' belongs to Context '${binding.context.name}', not '${task.contextId}'.`);
118
+ }
119
+ // Core state is authoritative. SDK merge writes validate identity but
120
+ // never create a parallel Task lifecycle in this projection store.
121
+ if (task.status?.state === TaskState.TASK_STATE_CANCELED) {
122
+ await this.#port.cancelWorker({
123
+ workspaceId: await this.#workspace.id(),
124
+ workerId: binding.task.id,
125
+ reason: "A2A caller cancelled the Task",
126
+ });
127
+ }
128
+ }
129
+ async list(params, context) {
130
+ this.#assertTenant(context);
131
+ const workspaceId = await this.#workspace.id();
132
+ const pageSize = params.pageSize ?? 50;
133
+ const offset = params.pageToken.length === 0 ? 0 : Number(params.pageToken);
134
+ if (!Number.isSafeInteger(offset) || offset < 0) {
135
+ throw new RequestMalformedError("pageToken must be an empty string or a non-negative integer offset.");
136
+ }
137
+ let taskWorkers;
138
+ if (params.contextId.length > 0) {
139
+ const contextWorker = await this.#port.readWorker({
140
+ workspaceId,
141
+ identity: { name: params.contextId },
142
+ });
143
+ if (contextWorker === null
144
+ || contextWorker.origin !== "model"
145
+ || contextWorker.parentWorkerId !== null) {
146
+ taskWorkers = [];
147
+ }
148
+ else {
149
+ taskWorkers = await this.#port.listWorkers(workspaceId, {
150
+ origin: "model",
151
+ parentWorkerId: contextWorker.id,
152
+ });
153
+ }
154
+ }
155
+ else {
156
+ taskWorkers = (await this.#port.listWorkers(workspaceId, { origin: "model" }))
157
+ .filter(({ parentWorkerId }) => parentWorkerId !== null);
158
+ }
159
+ const projected = (await Promise.all(taskWorkers.map(({ name }) => this.load(name, context))))
160
+ .filter((task) => task !== undefined)
161
+ .filter((task) => params.status === TaskState.TASK_STATE_UNSPECIFIED
162
+ || task.status?.state === params.status)
163
+ .filter((task) => params.statusTimestampAfter === undefined
164
+ || (task.status?.timestamp !== undefined
165
+ && Date.parse(task.status.timestamp) >= Date.parse(params.statusTimestampAfter)))
166
+ .map((task) => params.includeArtifacts === true ? task : { ...task, artifacts: [] });
167
+ const tasks = projected.slice(offset, offset + pageSize);
168
+ const next = offset + tasks.length;
169
+ return {
170
+ tasks,
171
+ nextPageToken: next < projected.length ? String(next) : "",
172
+ pageSize,
173
+ totalSize: projected.length,
174
+ };
175
+ }
176
+ async #project(binding) {
177
+ const { context, task, loop } = binding;
178
+ if (loop === null) {
179
+ return {
180
+ id: task.name,
181
+ contextId: context.name,
182
+ status: {
183
+ state: TaskState.TASK_STATE_SUBMITTED,
184
+ message: undefined,
185
+ timestamp: undefined,
186
+ },
187
+ artifacts: [],
188
+ history: [],
189
+ metadata: {},
190
+ };
191
+ }
192
+ const workspaceId = await this.#workspace.id();
193
+ const [rows, interactions] = await Promise.all([
194
+ this.#port.readLog({
195
+ workspaceId,
196
+ workerId: task.id,
197
+ loopId: loop.id,
198
+ limit: 1000,
199
+ }),
200
+ this.#port.pendingClientInteractions(workspaceId),
201
+ ]);
202
+ const pending = interactions.find((candidate) => candidate.workerId === task.id && candidate.loopId === loop.id) ?? null;
203
+ const state = _a.#state(loop.status, pending);
204
+ const statusMessage = _a.#statusMessage(context.name, task.name, loop.terminalResult, pending);
205
+ const history = rows
206
+ .filter((row) => row.loop_id === loop.id && row.op === "prompt" && nonempty(row.rx))
207
+ .toSorted((left, right) => Number(left.id) - Number(right.id))
208
+ .map((row) => message(messageIdFromSource(row.source, `plurnk-log-${String(row.id)}`), context.name, task.name, Role.ROLE_USER, row.rx, nonempty(row.mimetype_rx) ? row.mimetype_rx : "text/markdown"));
209
+ return {
210
+ id: task.name,
211
+ contextId: context.name,
212
+ status: {
213
+ state,
214
+ message: statusMessage,
215
+ timestamp: loop.terminatedAt ?? undefined,
216
+ },
217
+ artifacts: terminalArtifact(loop.terminalResult),
218
+ history,
219
+ metadata: {},
220
+ };
221
+ }
222
+ #assertTenant(context) {
223
+ if ((context.tenant ?? "") !== "") {
224
+ throw new RequestMalformedError("This A2A exposure does not define tenant routing.");
225
+ }
226
+ }
227
+ static #state(status, pending) {
228
+ if (pending !== null)
229
+ return TaskState.TASK_STATE_INPUT_REQUIRED;
230
+ if (status === 100)
231
+ return TaskState.TASK_STATE_SUBMITTED;
232
+ if (status === 102 || status === 202)
233
+ return TaskState.TASK_STATE_WORKING;
234
+ if (status === 200)
235
+ return TaskState.TASK_STATE_COMPLETED;
236
+ if (status === 499)
237
+ return TaskState.TASK_STATE_CANCELED;
238
+ return TaskState.TASK_STATE_FAILED;
239
+ }
240
+ static #statusMessage(contextId, taskId, result, pending) {
241
+ if (pending !== null) {
242
+ return message(`plurnk-interaction-${pending.interactionId}`, contextId, taskId, Role.ROLE_AGENT, pending.request.message ?? `${pending.request.toolName} requires input.`);
243
+ }
244
+ const detail = result?.problem?.detail;
245
+ return nonempty(detail)
246
+ ? message(`plurnk-terminal-${taskId}`, contextId, taskId, Role.ROLE_AGENT, detail)
247
+ : undefined;
248
+ }
249
+ static #ownsSource(source, contextId, taskId) {
250
+ if (source === null)
251
+ return false;
252
+ try {
253
+ const url = new URL(source);
254
+ const segments = url.pathname.split("/").filter(Boolean).map(decodeURIComponent);
255
+ return url.protocol === "a2a:"
256
+ && segments.length === 6
257
+ && segments[0] === "contexts"
258
+ && segments[1] === contextId
259
+ && segments[2] === "tasks"
260
+ && segments[3] === taskId
261
+ && segments[4] === "messages"
262
+ && segments[5].length > 0;
263
+ }
264
+ catch {
265
+ return false;
266
+ }
267
+ }
268
+ }
269
+ _a = PlurnkTaskStore;
270
+ export default PlurnkTaskStore;
271
+ //# sourceMappingURL=PlurnkTaskStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlurnkTaskStore.js","sourceRoot":"","sources":["../src/PlurnkTaskStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { ApplicationPort } from "@plurnk/plurnk-contracts";
2
+ export interface A2aWorkspaceConfiguration {
3
+ readonly name: string;
4
+ /** Required only when creating a new workspace; null adopts an existing named workspace. */
5
+ readonly projectRoot: string | null;
6
+ }
7
+ /** Lazily resolves the workspace owned by one inbound A2A exposure. */
8
+ export default class WorkspaceBinding {
9
+ #private;
10
+ constructor(port: ApplicationPort, configuration: A2aWorkspaceConfiguration);
11
+ id(): Promise<number>;
12
+ }
13
+ //# sourceMappingURL=WorkspaceBinding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkspaceBinding.d.ts","sourceRoot":"","sources":["../src/WorkspaceBinding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE,MAAM,WAAW,yBAAyB;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4FAA4F;IAC5F,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC;AAED,uEAAuE;AACvE,MAAM,CAAC,OAAO,OAAO,gBAAgB;;IAKjC,YAAY,IAAI,EAAE,eAAe,EAAE,aAAa,EAAE,yBAAyB,EAG1E;IAED,EAAE,IAAI,OAAO,CAAC,MAAM,CAAC,CAMpB;CA4BJ"}
@@ -0,0 +1,40 @@
1
+ /** Lazily resolves the workspace owned by one inbound A2A exposure. */
2
+ export default class WorkspaceBinding {
3
+ #port;
4
+ #configuration;
5
+ #resolution = null;
6
+ constructor(port, configuration) {
7
+ this.#port = port;
8
+ this.#configuration = structuredClone(configuration);
9
+ }
10
+ id() {
11
+ this.#resolution ??= this.#resolve().catch((cause) => {
12
+ this.#resolution = null;
13
+ throw cause;
14
+ });
15
+ return this.#resolution;
16
+ }
17
+ async #resolve() {
18
+ const matches = (await this.#port.listWorkspaces())
19
+ .filter(({ name }) => name === this.#configuration.name);
20
+ if (matches.length > 1) {
21
+ throw new Error(`A2A workspace name '${this.#configuration.name}' is not unique.`);
22
+ }
23
+ const existing = matches[0];
24
+ if (existing !== undefined) {
25
+ if (this.#configuration.projectRoot !== null
26
+ && existing.project_root !== this.#configuration.projectRoot) {
27
+ throw new Error(`A2A workspace '${this.#configuration.name}' has project root `
28
+ + `${JSON.stringify(existing.project_root)}, not configured root `
29
+ + `${JSON.stringify(this.#configuration.projectRoot)}.`);
30
+ }
31
+ return existing.id;
32
+ }
33
+ const created = await this.#port.createWorkspace({
34
+ name: this.#configuration.name,
35
+ projectRoot: this.#configuration.projectRoot,
36
+ });
37
+ return created.workspaceId;
38
+ }
39
+ }
40
+ //# sourceMappingURL=WorkspaceBinding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkspaceBinding.js","sourceRoot":"","sources":["../src/WorkspaceBinding.ts"],"names":[],"mappings":"AAQA,uEAAuE;AACvE,MAAM,CAAC,OAAO,OAAO,gBAAgB;IACxB,KAAK,CAAkB;IACvB,cAAc,CAA4B;IACnD,WAAW,GAA2B,IAAI,CAAC;IAE3C,YAAY,IAAqB,EAAE,aAAwC;QACvE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,cAAc,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;IACzD,CAAC;IAED,EAAE;QACE,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACjD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,MAAM,KAAK,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,WAAW,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,QAAQ;QACV,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;aAC9C,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC7D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,CAAC,cAAc,CAAC,IAAI,kBAAkB,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACzB,IACI,IAAI,CAAC,cAAc,CAAC,WAAW,KAAK,IAAI;mBACrC,QAAQ,CAAC,YAAY,KAAK,IAAI,CAAC,cAAc,CAAC,WAAW,EAC9D,CAAC;gBACC,MAAM,IAAI,KAAK,CACX,kBAAkB,IAAI,CAAC,cAAc,CAAC,IAAI,qBAAqB;sBAC7D,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,wBAAwB;sBAChE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,GAAG,CAC1D,CAAC;YACN,CAAC;YACD,OAAO,QAAQ,CAAC,EAAE,CAAC;QACvB,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;YAC7C,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI;YAC9B,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,WAAW;SAC/C,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,WAAW,CAAC;IAC/B,CAAC;CACJ"}
@@ -0,0 +1,22 @@
1
+ import type { A2AAgentDefinition as A2aAgentDefinition } from "@plurnk/plurnk-contracts";
2
+ import { AgentCard } from "@a2a-js/sdk";
3
+ export type OutboundAgentDefinition = A2aAgentDefinition;
4
+ export interface HostedAgentConfiguration {
5
+ readonly host: string;
6
+ readonly port: number;
7
+ readonly endpointPath: string;
8
+ readonly endpointUrl?: string;
9
+ readonly workspace: {
10
+ readonly name: string;
11
+ readonly projectRoot: string | null;
12
+ };
13
+ readonly card: AgentCard;
14
+ }
15
+ export declare const outboundAgentNames: (environ?: NodeJS.ProcessEnv) => string[];
16
+ export declare const outboundAgentDefinition: (name: string, environ?: NodeJS.ProcessEnv) => OutboundAgentDefinition | null;
17
+ export declare const outboundDefinitions: (environ?: NodeJS.ProcessEnv) => OutboundAgentDefinition[];
18
+ export declare const serviceEnabledNames: (environ?: NodeJS.ProcessEnv) => string[];
19
+ export declare const hostedAgentConfiguration: (environ?: NodeJS.ProcessEnv) => HostedAgentConfiguration | null;
20
+ export declare const connectTimeoutMs: (environ?: NodeJS.ProcessEnv) => number;
21
+ export declare const requestTimeoutMs: (environ?: NodeJS.ProcessEnv) => number;
22
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,IAAI,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEzF,OAAO,EAEH,SAAS,EAEZ,MAAM,aAAa,CAAC;AA2CrB,MAAM,MAAM,uBAAuB,GAAG,kBAAkB,CAAC;AAEzD,MAAM,WAAW,wBAAwB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE;QAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;KACvC,CAAC;IACF,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CAC5B;AAqMD,eAAO,MAAM,kBAAkB,aAAa,MAAM,CAAC,UAAU,KAAiB,MAAM,EACxB,CAAC;AAE7D,eAAO,MAAM,uBAAuB,SAC1B,MAAM,YACH,MAAM,CAAC,UAAU,KAC3B,uBAAuB,GAAG,IA+B5B,CAAC;AAEF,eAAO,MAAM,mBAAmB,aACnB,MAAM,CAAC,UAAU,KAC3B,uBAAuB,EAIxB,CAAC;AAEH,eAAO,MAAM,mBAAmB,aAAa,MAAM,CAAC,UAAU,KAAiB,MAAM,EAYpF,CAAC;AAEF,eAAO,MAAM,wBAAwB,aACxB,MAAM,CAAC,UAAU,KAC3B,wBAAwB,GAAG,IAkE7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,aAAa,MAAM,CAAC,UAAU,KAAiB,MACS,CAAC;AAEtF,eAAO,MAAM,gBAAgB,aAAa,MAAM,CAAC,UAAU,KAAiB,MACS,CAAC"}