@nemphi/sdk 0.1.0 → 0.2.4556
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 +61 -59
- package/dist/block-kit-state.d.ts +55 -0
- package/dist/block-kit-state.d.ts.map +1 -0
- package/dist/block-kit-state.js +218 -0
- package/dist/block-kit-state.js.map +1 -0
- package/dist/block-kit.d.ts +889 -0
- package/dist/block-kit.d.ts.map +1 -0
- package/dist/block-kit.js +336 -0
- package/dist/block-kit.js.map +1 -0
- package/dist/index.d.ts +9431 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1348 -15
- package/dist/index.js.map +1 -0
- package/dist/reactions.d.ts +33 -0
- package/dist/reactions.d.ts.map +1 -0
- package/dist/reactions.js +70 -0
- package/dist/reactions.js.map +1 -0
- package/package.json +37 -15
- package/dist/client.d.ts +0 -12
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -69
- package/dist/errors.d.ts +0 -6
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -8
- package/dist/resources/crm.d.ts +0 -17
- package/dist/resources/crm.d.ts.map +0 -1
- package/dist/resources/crm.js +0 -59
- package/dist/resources/organization.d.ts +0 -23
- package/dist/resources/organization.d.ts.map +0 -1
- package/dist/resources/organization.js +0 -45
- package/dist/resources/usage.d.ts +0 -27
- package/dist/resources/usage.d.ts.map +0 -1
- package/dist/resources/usage.js +0 -35
- package/dist/types.d.ts +0 -27
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nemphi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,89 +1,91 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `@nemphi/sdk`
|
|
2
2
|
|
|
3
|
-
TypeScript
|
|
3
|
+
Typed TypeScript client for the [Nemphi](https://nemphi.com) API. Zero runtime
|
|
4
|
+
dependencies. It uses the platform `fetch`. Business tool invocations use the
|
|
5
|
+
same tenant scoping, policy, idempotency, and action ledger as the product UI.
|
|
4
6
|
|
|
5
7
|
## Install
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
10
|
npm install @nemphi/sdk
|
|
11
|
+
# or: pnpm add @nemphi/sdk / yarn add @nemphi/sdk
|
|
9
12
|
```
|
|
10
13
|
|
|
14
|
+
Requires Node 20+ (or any runtime with global `fetch`).
|
|
15
|
+
|
|
11
16
|
## Quick start
|
|
12
17
|
|
|
13
18
|
```ts
|
|
14
|
-
import {
|
|
19
|
+
import { createClient } from "@nemphi/sdk";
|
|
20
|
+
|
|
21
|
+
const nemphi = createClient({
|
|
22
|
+
baseUrl: "https://api.nemphi.com",
|
|
23
|
+
// API key (nk_…) is tenant-bound. Session tokens (nse_…) also need tenantId.
|
|
24
|
+
token: process.env.NEMPHI_API_KEY!,
|
|
25
|
+
});
|
|
15
26
|
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
token: process.env.NEMPHI_TOKEN,
|
|
19
|
-
organizationId: "org_123",
|
|
27
|
+
const { invoice, journal_entry } = await nemphi.postInvoice(invoiceId, {
|
|
28
|
+
idempotencyKey: `post-${invoiceId}`,
|
|
20
29
|
});
|
|
21
30
|
|
|
22
|
-
|
|
23
|
-
console.log(usage);
|
|
31
|
+
console.log(invoice.status, journal_entry.entry_number);
|
|
24
32
|
```
|
|
25
33
|
|
|
26
34
|
## Configuration
|
|
27
35
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
- `listEvents(query)`
|
|
42
|
-
- `trackEvent({ eventType, count, metadata })`
|
|
43
|
-
- `getMonthlyReport(month)`
|
|
44
|
-
- `sdk.organization`
|
|
45
|
-
- `create({ name })`
|
|
46
|
-
- `getMembers()`
|
|
47
|
-
- `listMemberships()`
|
|
48
|
-
- `listInvitations()`
|
|
49
|
-
- `inviteMember(input)`
|
|
50
|
-
- `removeMember(memberId)`
|
|
51
|
-
- `updateMemberRole(memberId, role)`
|
|
52
|
-
- `getStats()`
|
|
53
|
-
- `getActivity(query)`
|
|
54
|
-
- `sdk.crm`
|
|
55
|
-
- `listContacts(query)` / `getContact(contactId)`
|
|
56
|
-
- `createContact(body)` / `updateContact(contactId, body)`
|
|
57
|
-
- `listDeals(query)` / `createDeal(body)` / `updateDeal(dealId, body)`
|
|
58
|
-
- `listTasks(query)` / `createTask(body)`
|
|
59
|
-
- `createNote(body)`
|
|
60
|
-
|
|
61
|
-
## Error handling
|
|
36
|
+
| Option | Description |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| `baseUrl` | API origin, e.g. `https://api.nemphi.com` |
|
|
39
|
+
| `token` | Bearer credential: API key (`nk_…`) or session token (`nse_…`) |
|
|
40
|
+
| `tenantId` | Required for tenant-scoped calls when using a user session |
|
|
41
|
+
| `headers` | Extra headers on every request |
|
|
42
|
+
| `fetch` | Custom `fetch` (defaults to the global) |
|
|
43
|
+
|
|
44
|
+
## Auth
|
|
45
|
+
|
|
46
|
+
- **API keys** are created in the workspace settings and are already bound to one
|
|
47
|
+
tenant — pass them as `token`, no `tenantId` needed.
|
|
48
|
+
- **User sessions** need both `token` and `tenantId` (`X-Tenant-Id`).
|
|
62
49
|
|
|
63
50
|
```ts
|
|
64
|
-
|
|
51
|
+
const session = createClient({
|
|
52
|
+
baseUrl: "https://api.nemphi.com",
|
|
53
|
+
token: sessionToken,
|
|
54
|
+
tenantId: workspaceId,
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Errors
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { ApiError } from "@nemphi/sdk";
|
|
65
62
|
|
|
66
63
|
try {
|
|
67
|
-
await
|
|
68
|
-
} catch (
|
|
69
|
-
if (
|
|
70
|
-
|
|
64
|
+
await nemphi.postInvoice(id);
|
|
65
|
+
} catch (err) {
|
|
66
|
+
if (err instanceof ApiError) {
|
|
67
|
+
// status, code (e.g. "approval_required"), message, body
|
|
68
|
+
console.error(err.status, err.code, err.message);
|
|
71
69
|
}
|
|
70
|
+
throw err;
|
|
72
71
|
}
|
|
73
72
|
```
|
|
74
73
|
|
|
75
|
-
##
|
|
74
|
+
## What it covers
|
|
75
|
+
|
|
76
|
+
The client mirrors the HTTP surface used by the Nemphi web app: auth, workspaces,
|
|
77
|
+
tools (`invoke` / typed helpers), actions, runs, dashboards, mail, CRM, and more.
|
|
78
|
+
Types live next to the client in the same module.
|
|
76
79
|
|
|
77
|
-
|
|
80
|
+
For the design contract, see `docs/backbone.md` in the monorepo (§3 pillars, §9
|
|
81
|
+
API contracts).
|
|
78
82
|
|
|
79
|
-
|
|
80
|
-
2. Ensure `packages/sdk/package.json` version is bumped.
|
|
81
|
-
3. Push a matching tag in the format `sdk-v<version>` (example: `sdk-v0.1.0`).
|
|
82
|
-
4. The workflow will typecheck, build `dist/`, verify the tag-version match, and run `npm publish --access public`.
|
|
83
|
+
## Maintainer workflow
|
|
83
84
|
|
|
84
|
-
|
|
85
|
+
The web and mobile apps use `workspace:*`. Rebuild their SDK with
|
|
86
|
+
`pnpm build:sdk` after source changes. Merging an SDK change to `master`
|
|
87
|
+
publishes it to npm; [PUBLISHING.md](PUBLISHING.md) covers versioning, package
|
|
88
|
+
checks, and releases.
|
|
85
89
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
- `package.json` should include a `repository.url` that exactly matches the GitHub repo URL configured in npm Trusted Publisher settings.
|
|
89
|
-
- npm can automatically generate provenance for public packages published from public GitHub repositories via Trusted Publishing.
|
|
90
|
+
The private `@nemphi/admin-sdk` owns `/v1/admin/*`; those methods do not belong
|
|
91
|
+
in this public package.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { BlockAction, BlockElement, BlockState, BlockValue, MessageBlock, OptionObject } from "./block-kit.js";
|
|
2
|
+
/** A block's id, or its position when the author left it out. */
|
|
3
|
+
export declare const blockIdOf: (block: {
|
|
4
|
+
block_id?: string;
|
|
5
|
+
}, index: number) => string;
|
|
6
|
+
/** An element's action id, or its position in the block. */
|
|
7
|
+
export declare const actionIdOf: (element: {
|
|
8
|
+
action_id?: string;
|
|
9
|
+
}, index: number) => string;
|
|
10
|
+
/** What a select or a choice group offers, groups flattened. */
|
|
11
|
+
export declare function optionsOf(element: BlockElement): OptionObject[];
|
|
12
|
+
/** The value an element starts with, from its `initial_*` field. */
|
|
13
|
+
export declare function elementInitialValue(element: BlockElement): BlockValue;
|
|
14
|
+
/** Elements that hold a value, with the block and label they belong to. */
|
|
15
|
+
export interface ValuedElement {
|
|
16
|
+
blockId: string;
|
|
17
|
+
actionId: string;
|
|
18
|
+
element: BlockElement;
|
|
19
|
+
/** The input block's label, or the placeholder, or the action id. */
|
|
20
|
+
label: string;
|
|
21
|
+
}
|
|
22
|
+
/** Every element of a message that holds state, input blocks and controls alike. */
|
|
23
|
+
export declare function valuedElements(blocks: ReadonlyArray<MessageBlock>): ValuedElement[];
|
|
24
|
+
/** The state a message starts in: every valued element at its initial value. */
|
|
25
|
+
export declare function initialBlockState(blocks: ReadonlyArray<MessageBlock>): BlockState;
|
|
26
|
+
/** The state with one element's value replaced. */
|
|
27
|
+
export declare function withBlockValue(state: BlockState, blockId: string, actionId: string, value: BlockValue): BlockState;
|
|
28
|
+
/** One element's current value, when the state knows it. */
|
|
29
|
+
export declare const blockValueOf: (state: BlockState, blockId: string, actionId: string) => BlockValue | undefined;
|
|
30
|
+
/** Whether a value is worth reporting: a choice made, a field filled. */
|
|
31
|
+
export declare function valueIsSet(value: BlockValue): boolean;
|
|
32
|
+
/** The words for one value: the option text, the date, the text typed. */
|
|
33
|
+
export declare function valueText(value: BlockValue): string;
|
|
34
|
+
/** `Label: value` for every set field of the message, in message order. */
|
|
35
|
+
export declare function stateSummary(blocks: ReadonlyArray<MessageBlock>, state: BlockState): string[];
|
|
36
|
+
export interface ActionWords {
|
|
37
|
+
/** "Pulsaste «{label}»" */
|
|
38
|
+
clicked: string;
|
|
39
|
+
/** "Elegiste {value}" */
|
|
40
|
+
chose: string;
|
|
41
|
+
/** "Enviaste el formulario" */
|
|
42
|
+
submitted: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The line the person sees as their own turn after interacting: what they
|
|
46
|
+
* clicked or chose, then every field they had filled in.
|
|
47
|
+
*/
|
|
48
|
+
export declare function blockActionSummary(action: BlockAction, blocks: ReadonlyArray<MessageBlock>, words: ActionWords): string;
|
|
49
|
+
/**
|
|
50
|
+
* The machine-facing marker folded into the model's copy of the turn:
|
|
51
|
+
* which element fired, in which block, with which value. The state is in
|
|
52
|
+
* the visible summary already, so it stays out of the marker.
|
|
53
|
+
*/
|
|
54
|
+
export declare function blockActionContext(action: BlockAction): string;
|
|
55
|
+
//# sourceMappingURL=block-kit-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-kit-state.d.ts","sourceRoot":"","sources":["../src/block-kit-state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,UAAU,EACV,UAAU,EACV,YAAY,EACZ,YAAY,EAGb,MAAM,gBAAgB,CAAC;AAGxB,iEAAiE;AACjE,eAAO,MAAM,SAAS,UAAW;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,SAAS,MAAM,KAAG,MACpC,CAAC;AAErC,4DAA4D;AAC5D,eAAO,MAAM,UAAU,YAAa;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,SAAS,MAAM,KAAG,MACpC,CAAC;AAEzC,gEAAgE;AAChE,wBAAgB,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY,EAAE,CAY/D;AAED,oEAAoE;AACpE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,UAAU,CA2CrE;AAED,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,YAAY,CAAC;IACtB,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;CACf;AAsBD,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,aAAa,EAAE,CAmDnF;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,UAAU,CAQjF;AAED,mDAAmD;AACnD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,UAAU,GAChB,UAAU,CAOZ;AAED,4DAA4D;AAC5D,eAAO,MAAM,YAAY,UAChB,UAAU,WACR,MAAM,YACL,MAAM,KACf,UAAU,GAAG,SAA8C,CAAC;AAE/D,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAsBrD;AAED,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEnD;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,CAW7F;AAED,MAAM,WAAW,WAAW;IAC1B,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,aAAa,CAAC,YAAY,CAAC,EACnC,KAAK,EAAE,WAAW,GACjB,MAAM,CAiBR;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAM9D"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// The values a message's elements hold, and the words an interaction
|
|
2
|
+
// becomes. Pure functions over the Block Kit types, shared by the web
|
|
3
|
+
// renderer, the chat surfaces and the mobile app, so every client reasons
|
|
4
|
+
// about a message the same way without React.
|
|
5
|
+
import { blockActionText, richTextText } from "./block-kit.js";
|
|
6
|
+
/** A block's id, or its position when the author left it out. */
|
|
7
|
+
export const blockIdOf = (block, index) => block.block_id ?? `block_${index}`;
|
|
8
|
+
/** An element's action id, or its position in the block. */
|
|
9
|
+
export const actionIdOf = (element, index) => element.action_id ?? `action_${index}`;
|
|
10
|
+
/** What a select or a choice group offers, groups flattened. */
|
|
11
|
+
export function optionsOf(element) {
|
|
12
|
+
switch (element.type) {
|
|
13
|
+
case "checkboxes":
|
|
14
|
+
case "radio_buttons":
|
|
15
|
+
case "overflow":
|
|
16
|
+
return element.options;
|
|
17
|
+
case "static_select":
|
|
18
|
+
case "multi_static_select":
|
|
19
|
+
return element.options ?? element.option_groups?.flatMap((g) => g.options) ?? [];
|
|
20
|
+
default:
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** The value an element starts with, from its `initial_*` field. */
|
|
25
|
+
export function elementInitialValue(element) {
|
|
26
|
+
switch (element.type) {
|
|
27
|
+
case "checkboxes":
|
|
28
|
+
return { type: element.type, selected_options: element.initial_options ?? [] };
|
|
29
|
+
case "radio_buttons":
|
|
30
|
+
case "static_select":
|
|
31
|
+
case "external_select":
|
|
32
|
+
return { type: element.type, selected_option: element.initial_option ?? null };
|
|
33
|
+
case "multi_static_select":
|
|
34
|
+
case "multi_external_select":
|
|
35
|
+
return { type: element.type, selected_options: element.initial_options ?? [] };
|
|
36
|
+
case "users_select":
|
|
37
|
+
return { type: element.type, selected_user: element.initial_user ?? null };
|
|
38
|
+
case "multi_users_select":
|
|
39
|
+
return { type: element.type, selected_users: element.initial_users ?? [] };
|
|
40
|
+
case "conversations_select":
|
|
41
|
+
return { type: element.type, selected_conversation: element.initial_conversation ?? null };
|
|
42
|
+
case "multi_conversations_select":
|
|
43
|
+
return { type: element.type, selected_conversations: element.initial_conversations ?? [] };
|
|
44
|
+
case "channels_select":
|
|
45
|
+
return { type: element.type, selected_channel: element.initial_channel ?? null };
|
|
46
|
+
case "multi_channels_select":
|
|
47
|
+
return { type: element.type, selected_channels: element.initial_channels ?? [] };
|
|
48
|
+
case "datepicker":
|
|
49
|
+
return { type: element.type, selected_date: element.initial_date ?? null };
|
|
50
|
+
case "timepicker":
|
|
51
|
+
return { type: element.type, selected_time: element.initial_time ?? null };
|
|
52
|
+
case "datetimepicker":
|
|
53
|
+
return { type: element.type, selected_date_time: element.initial_date_time ?? null };
|
|
54
|
+
case "plain_text_input":
|
|
55
|
+
case "email_text_input":
|
|
56
|
+
case "url_text_input":
|
|
57
|
+
case "number_input":
|
|
58
|
+
return { type: element.type, value: element.initial_value ?? "" };
|
|
59
|
+
case "rich_text_input":
|
|
60
|
+
return element.initial_value
|
|
61
|
+
? { type: element.type, rich_text_value: element.initial_value }
|
|
62
|
+
: { type: element.type };
|
|
63
|
+
case "file_input":
|
|
64
|
+
return { type: element.type, files: [] };
|
|
65
|
+
default:
|
|
66
|
+
return { type: element.type };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const textOf = (t) => (t ? t.text : "");
|
|
70
|
+
/** Whether an element's `text` carries a composition object rather than a bare string. */
|
|
71
|
+
const isPlainTextObject = (text) => typeof text === "object";
|
|
72
|
+
const elementLabel = (element, actionId) => {
|
|
73
|
+
if ("placeholder" in element && element.placeholder)
|
|
74
|
+
return element.placeholder.text;
|
|
75
|
+
if ("text" in element &&
|
|
76
|
+
element.text &&
|
|
77
|
+
isPlainTextObject(element.text) &&
|
|
78
|
+
"text" in element.text)
|
|
79
|
+
return element.text.text;
|
|
80
|
+
return actionId;
|
|
81
|
+
};
|
|
82
|
+
/** Every element of a message that holds state, input blocks and controls alike. */
|
|
83
|
+
export function valuedElements(blocks) {
|
|
84
|
+
const out = [];
|
|
85
|
+
const visit = (block, index) => {
|
|
86
|
+
const blockId = blockIdOf(block, index);
|
|
87
|
+
switch (block.type) {
|
|
88
|
+
case "input":
|
|
89
|
+
out.push({
|
|
90
|
+
blockId,
|
|
91
|
+
actionId: actionIdOf(block.element, 0),
|
|
92
|
+
element: block.element,
|
|
93
|
+
label: block.label.text,
|
|
94
|
+
});
|
|
95
|
+
break;
|
|
96
|
+
case "actions":
|
|
97
|
+
block.elements.forEach((element, i) => {
|
|
98
|
+
if (element.type === "button" || element.type === "workflow_button")
|
|
99
|
+
return;
|
|
100
|
+
const actionId = actionIdOf(element, i);
|
|
101
|
+
out.push({ blockId, actionId, element, label: elementLabel(element, actionId) });
|
|
102
|
+
});
|
|
103
|
+
break;
|
|
104
|
+
case "section":
|
|
105
|
+
if (block.accessory &&
|
|
106
|
+
block.accessory.type !== "button" &&
|
|
107
|
+
block.accessory.type !== "workflow_button" &&
|
|
108
|
+
block.accessory.type !== "image" &&
|
|
109
|
+
block.accessory.type !== "overflow") {
|
|
110
|
+
const actionId = actionIdOf(block.accessory, 0);
|
|
111
|
+
out.push({
|
|
112
|
+
blockId,
|
|
113
|
+
actionId,
|
|
114
|
+
element: block.accessory,
|
|
115
|
+
label: textOf(block.text) || elementLabel(block.accessory, actionId),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
break;
|
|
119
|
+
case "container":
|
|
120
|
+
block.child_blocks.forEach((child, i) => visit(child, i));
|
|
121
|
+
break;
|
|
122
|
+
default:
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
blocks.forEach(visit);
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
129
|
+
/** The state a message starts in: every valued element at its initial value. */
|
|
130
|
+
export function initialBlockState(blocks) {
|
|
131
|
+
const values = {};
|
|
132
|
+
for (const { blockId, actionId, element } of valuedElements(blocks)) {
|
|
133
|
+
(values[blockId] ??= {})[actionId] = elementInitialValue(element);
|
|
134
|
+
}
|
|
135
|
+
return { values };
|
|
136
|
+
}
|
|
137
|
+
/** The state with one element's value replaced. */
|
|
138
|
+
export function withBlockValue(state, blockId, actionId, value) {
|
|
139
|
+
return {
|
|
140
|
+
values: {
|
|
141
|
+
...state.values,
|
|
142
|
+
[blockId]: { ...state.values[blockId], [actionId]: value },
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/** One element's current value, when the state knows it. */
|
|
147
|
+
export const blockValueOf = (state, blockId, actionId) => state.values[blockId]?.[actionId];
|
|
148
|
+
/** Whether a value is worth reporting: a choice made, a field filled. */
|
|
149
|
+
export function valueIsSet(value) {
|
|
150
|
+
if (value.value !== undefined && value.value !== "")
|
|
151
|
+
return true;
|
|
152
|
+
if (value.selected_option)
|
|
153
|
+
return true;
|
|
154
|
+
if (value.selected_options?.length)
|
|
155
|
+
return true;
|
|
156
|
+
if (value.selected_date || value.selected_time)
|
|
157
|
+
return true;
|
|
158
|
+
if (value.selected_date_time !== undefined && value.selected_date_time !== null)
|
|
159
|
+
return true;
|
|
160
|
+
if (value.selected_user || value.selected_conversation || value.selected_channel)
|
|
161
|
+
return true;
|
|
162
|
+
if (value.selected_users?.length || value.selected_conversations?.length)
|
|
163
|
+
return true;
|
|
164
|
+
if (value.selected_channels?.length)
|
|
165
|
+
return true;
|
|
166
|
+
if (value.rich_text_value)
|
|
167
|
+
return richTextText(value.rich_text_value).trim() !== "";
|
|
168
|
+
if (value.files?.length)
|
|
169
|
+
return true;
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
/** The words for one value: the option text, the date, the text typed. */
|
|
173
|
+
export function valueText(value) {
|
|
174
|
+
return blockActionText({ ...value, block_id: "", action_id: "" });
|
|
175
|
+
}
|
|
176
|
+
/** `Label: value` for every set field of the message, in message order. */
|
|
177
|
+
export function stateSummary(blocks, state) {
|
|
178
|
+
const lines = [];
|
|
179
|
+
for (const { blockId, actionId, label } of valuedElements(blocks)) {
|
|
180
|
+
const value = state.values[blockId]?.[actionId];
|
|
181
|
+
if (value === undefined || !valueIsSet(value))
|
|
182
|
+
continue;
|
|
183
|
+
lines.push(`${label}: ${valueText(value)}`);
|
|
184
|
+
}
|
|
185
|
+
return lines;
|
|
186
|
+
}
|
|
187
|
+
const fill = (template, vars) => template.replace(/\{(\w+)\}/g, (_, k) => vars[k] ?? "");
|
|
188
|
+
/**
|
|
189
|
+
* The line the person sees as their own turn after interacting: what they
|
|
190
|
+
* clicked or chose, then every field they had filled in.
|
|
191
|
+
*/
|
|
192
|
+
export function blockActionSummary(action, blocks, words) {
|
|
193
|
+
const fields = action.state ? stateSummary(blocks, action.state) : [];
|
|
194
|
+
const isButton = action.type === "button" ||
|
|
195
|
+
action.type === "workflow_button" ||
|
|
196
|
+
action.type === "icon_button" ||
|
|
197
|
+
action.type === "feedback_buttons";
|
|
198
|
+
const label = blockActionText(action);
|
|
199
|
+
let head;
|
|
200
|
+
if (isButton)
|
|
201
|
+
head = fields.length > 0 && !label ? words.submitted : fill(words.clicked, { label });
|
|
202
|
+
else
|
|
203
|
+
head = fill(words.chose, { value: label });
|
|
204
|
+
return fields.length > 0 ? `${head}\n${fields.join("\n")}` : head;
|
|
205
|
+
}
|
|
206
|
+
const ContextMax = 480;
|
|
207
|
+
/**
|
|
208
|
+
* The machine-facing marker folded into the model's copy of the turn:
|
|
209
|
+
* which element fired, in which block, with which value. The state is in
|
|
210
|
+
* the visible summary already, so it stays out of the marker.
|
|
211
|
+
*/
|
|
212
|
+
export function blockActionContext(action) {
|
|
213
|
+
const { state: _state, label: _label, ...rest } = action;
|
|
214
|
+
const compact = JSON.stringify(rest);
|
|
215
|
+
const marker = `Block action: ${compact}`;
|
|
216
|
+
return marker.length <= ContextMax ? marker : `${marker.slice(0, ContextMax - 1)}…`;
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=block-kit-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-kit-state.js","sourceRoot":"","sources":["../src/block-kit-state.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sEAAsE;AACtE,0EAA0E;AAC1E,8CAA8C;AAY9C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE/D,iEAAiE;AACjE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAA4B,EAAE,KAAa,EAAU,EAAE,CAC/E,KAAK,CAAC,QAAQ,IAAI,SAAS,KAAK,EAAE,CAAC;AAErC,4DAA4D;AAC5D,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAA+B,EAAE,KAAa,EAAU,EAAE,CACnF,OAAO,CAAC,SAAS,IAAI,UAAU,KAAK,EAAE,CAAC;AAEzC,gEAAgE;AAChE,MAAM,UAAU,SAAS,CAAC,OAAqB;IAC7C,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,YAAY,CAAC;QAClB,KAAK,eAAe,CAAC;QACrB,KAAK,UAAU;YACb,OAAO,OAAO,CAAC,OAAO,CAAC;QACzB,KAAK,eAAe,CAAC;QACrB,KAAK,qBAAqB;YACxB,OAAO,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACnF;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,mBAAmB,CAAC,OAAqB;IACvD,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,YAAY;YACf,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,eAAe,IAAI,EAAE,EAAE,CAAC;QACjF,KAAK,eAAe,CAAC;QACrB,KAAK,eAAe,CAAC;QACrB,KAAK,iBAAiB;YACpB,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,cAAc,IAAI,IAAI,EAAE,CAAC;QACjF,KAAK,qBAAqB,CAAC;QAC3B,KAAK,uBAAuB;YAC1B,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,eAAe,IAAI,EAAE,EAAE,CAAC;QACjF,KAAK,cAAc;YACjB,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC;QAC7E,KAAK,oBAAoB;YACvB,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC;QAC7E,KAAK,sBAAsB;YACzB,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,qBAAqB,EAAE,OAAO,CAAC,oBAAoB,IAAI,IAAI,EAAE,CAAC;QAC7F,KAAK,4BAA4B;YAC/B,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,sBAAsB,EAAE,OAAO,CAAC,qBAAqB,IAAI,EAAE,EAAE,CAAC;QAC7F,KAAK,iBAAiB;YACpB,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,eAAe,IAAI,IAAI,EAAE,CAAC;QACnF,KAAK,uBAAuB;YAC1B,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,iBAAiB,EAAE,OAAO,CAAC,gBAAgB,IAAI,EAAE,EAAE,CAAC;QACnF,KAAK,YAAY;YACf,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC;QAC7E,KAAK,YAAY;YACf,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC;QAC7E,KAAK,gBAAgB;YACnB,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,kBAAkB,EAAE,OAAO,CAAC,iBAAiB,IAAI,IAAI,EAAE,CAAC;QACvF,KAAK,kBAAkB,CAAC;QACxB,KAAK,kBAAkB,CAAC;QACxB,KAAK,gBAAgB,CAAC;QACtB,KAAK,cAAc;YACjB,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC;QACpE,KAAK,iBAAiB;YACpB,OAAO,OAAO,CAAC,aAAa;gBAC1B,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,aAAa,EAAE;gBAChE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;QAC7B,KAAK,YAAY;YACf,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAC3C;YACE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;AACH,CAAC;AAWD,MAAM,MAAM,GAAG,CAAC,CAAyB,EAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAExE,0FAA0F;AAC1F,MAAM,iBAAiB,GAAG,CAAC,IAA8B,EAA2B,EAAE,CACpF,OAAO,IAAI,KAAK,QAAQ,CAAC;AAE3B,MAAM,YAAY,GAAG,CAAC,OAAqB,EAAE,QAAgB,EAAU,EAAE;IACvE,IAAI,aAAa,IAAI,OAAO,IAAI,OAAO,CAAC,WAAW;QAAE,OAAO,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC;IAErF,IACE,MAAM,IAAI,OAAO;QACjB,OAAO,CAAC,IAAI;QACZ,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC;QAC/B,MAAM,IAAI,OAAO,CAAC,IAAI;QAEtB,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;IAE3B,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,oFAAoF;AACpF,MAAM,UAAU,cAAc,CAAC,MAAmC;IAChE,MAAM,GAAG,GAAoB,EAAE,CAAC;IAEhC,MAAM,KAAK,GAAG,CAAC,KAAmB,EAAE,KAAa,EAAE,EAAE;QACnD,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAExC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,OAAO;gBACV,GAAG,CAAC,IAAI,CAAC;oBACP,OAAO;oBACP,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;oBACtC,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;iBACxB,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,SAAS;gBACZ,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE;oBACpC,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,KAAK,iBAAiB;wBAAE,OAAO;oBAC5E,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;oBACxC,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACnF,CAAC,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,SAAS;gBACZ,IACE,KAAK,CAAC,SAAS;oBACf,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,QAAQ;oBACjC,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,iBAAiB;oBAC1C,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,OAAO;oBAChC,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,UAAU,EACnC,CAAC;oBACD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;oBAChD,GAAG,CAAC,IAAI,CAAC;wBACP,OAAO;wBACP,QAAQ;wBACR,OAAO,EAAE,KAAK,CAAC,SAAS;wBACxB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC;qBACrE,CAAC,CAAC;gBACL,CAAC;gBAED,MAAM;YACR,KAAK,WAAW;gBACd,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC1D,MAAM;YACR;gBACE,MAAM;QACV,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAEtB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,iBAAiB,CAAC,MAAmC;IACnE,MAAM,MAAM,GAAyB,EAAE,CAAC;IAExC,KAAK,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QACpE,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,cAAc,CAC5B,KAAiB,EACjB,OAAe,EACf,QAAgB,EAChB,KAAiB;IAEjB,OAAO;QACL,MAAM,EAAE;YACN,GAAG,KAAK,CAAC,MAAM;YACf,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE;SAC3D;KACF,CAAC;AACJ,CAAC;AAED,4DAA4D;AAC5D,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,KAAiB,EACjB,OAAe,EACf,QAAgB,EACQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;AAE/D,yEAAyE;AACzE,MAAM,UAAU,UAAU,CAAC,KAAiB;IAC1C,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAEjE,IAAI,KAAK,CAAC,eAAe;QAAE,OAAO,IAAI,CAAC;IAEvC,IAAI,KAAK,CAAC,gBAAgB,EAAE,MAAM;QAAE,OAAO,IAAI,CAAC;IAEhD,IAAI,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAE5D,IAAI,KAAK,CAAC,kBAAkB,KAAK,SAAS,IAAI,KAAK,CAAC,kBAAkB,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAE7F,IAAI,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,qBAAqB,IAAI,KAAK,CAAC,gBAAgB;QAAE,OAAO,IAAI,CAAC;IAE9F,IAAI,KAAK,CAAC,cAAc,EAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,EAAE,MAAM;QAAE,OAAO,IAAI,CAAC;IAEtF,IAAI,KAAK,CAAC,iBAAiB,EAAE,MAAM;QAAE,OAAO,IAAI,CAAC;IAEjD,IAAI,KAAK,CAAC,eAAe;QAAE,OAAO,YAAY,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;IAEpF,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM;QAAE,OAAO,IAAI,CAAC;IAErC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,SAAS,CAAC,KAAiB;IACzC,OAAO,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,YAAY,CAAC,MAAmC,EAAE,KAAiB;IACjF,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QAClE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;QAEhD,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,SAAS;QACxD,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,KAAK,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAWD,MAAM,IAAI,GAAG,CAAC,QAAgB,EAAE,IAA4B,EAAU,EAAE,CACtE,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAElE;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAmB,EACnB,MAAmC,EACnC,KAAkB;IAElB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEtE,MAAM,QAAQ,GACZ,MAAM,CAAC,IAAI,KAAK,QAAQ;QACxB,MAAM,CAAC,IAAI,KAAK,iBAAiB;QACjC,MAAM,CAAC,IAAI,KAAK,aAAa;QAC7B,MAAM,CAAC,IAAI,KAAK,kBAAkB,CAAC;IAErC,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,IAAY,CAAC;IAEjB,IAAI,QAAQ;QACV,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;;QACnF,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAEhD,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,GAAG,GAAG,CAAC;AAEvB;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAmB;IACpD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;IACzD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,iBAAiB,OAAO,EAAE,CAAC;IAE1C,OAAO,MAAM,CAAC,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC;AACtF,CAAC"}
|