@pingroom/sdk 0.8.0 → 0.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 (179) hide show
  1. package/README.md +153 -41
  2. package/dist/client.d.ts +14 -348
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +15 -1300
  5. package/dist/client.js.map +1 -1
  6. package/dist/errors.d.ts +32 -3
  7. package/dist/errors.d.ts.map +1 -1
  8. package/dist/errors.js +47 -1
  9. package/dist/errors.js.map +1 -1
  10. package/dist/http.d.ts.map +1 -1
  11. package/dist/http.js +7 -1
  12. package/dist/http.js.map +1 -1
  13. package/dist/index.d.ts +3 -5
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +1 -2
  16. package/dist/index.js.map +1 -1
  17. package/dist/internal/guards.d.ts +7 -0
  18. package/dist/internal/guards.d.ts.map +1 -1
  19. package/dist/internal/guards.js +1 -1
  20. package/dist/internal/guards.js.map +1 -1
  21. package/dist/internal/request.d.ts +41 -0
  22. package/dist/internal/request.d.ts.map +1 -0
  23. package/dist/internal/request.js +78 -0
  24. package/dist/internal/request.js.map +1 -0
  25. package/dist/internal/retry.d.ts +9 -2
  26. package/dist/internal/retry.d.ts.map +1 -1
  27. package/dist/internal/retry.js +24 -6
  28. package/dist/internal/retry.js.map +1 -1
  29. package/dist/internal/validate.d.ts +13 -0
  30. package/dist/internal/validate.d.ts.map +1 -0
  31. package/dist/internal/validate.js +36 -0
  32. package/dist/internal/validate.js.map +1 -0
  33. package/dist/liveStatus.d.ts +106 -11
  34. package/dist/liveStatus.d.ts.map +1 -1
  35. package/dist/liveStatus.js +20 -3
  36. package/dist/liveStatus.js.map +1 -1
  37. package/dist/mcp.d.ts.map +1 -1
  38. package/dist/mcp.js +30 -8
  39. package/dist/mcp.js.map +1 -1
  40. package/dist/namespaces/actions.d.ts +50 -0
  41. package/dist/namespaces/actions.d.ts.map +1 -0
  42. package/dist/namespaces/actions.js +219 -0
  43. package/dist/namespaces/actions.js.map +1 -0
  44. package/dist/namespaces/approvals.d.ts +23 -0
  45. package/dist/namespaces/approvals.d.ts.map +1 -0
  46. package/dist/namespaces/approvals.js +78 -0
  47. package/dist/namespaces/approvals.js.map +1 -0
  48. package/dist/namespaces/attachments.d.ts +37 -0
  49. package/dist/namespaces/attachments.d.ts.map +1 -0
  50. package/dist/namespaces/attachments.js +91 -0
  51. package/dist/namespaces/attachments.js.map +1 -0
  52. package/dist/namespaces/auth.d.ts +58 -0
  53. package/dist/namespaces/auth.d.ts.map +1 -0
  54. package/dist/namespaces/auth.js +242 -0
  55. package/dist/namespaces/auth.js.map +1 -0
  56. package/dist/namespaces/directory.d.ts +10 -0
  57. package/dist/namespaces/directory.d.ts.map +1 -0
  58. package/dist/namespaces/directory.js +19 -0
  59. package/dist/namespaces/directory.js.map +1 -0
  60. package/dist/namespaces/handoffs.d.ts +47 -0
  61. package/dist/namespaces/handoffs.d.ts.map +1 -0
  62. package/dist/namespaces/handoffs.js +126 -0
  63. package/dist/namespaces/handoffs.js.map +1 -0
  64. package/dist/namespaces/inbox.d.ts +17 -0
  65. package/dist/namespaces/inbox.d.ts.map +1 -0
  66. package/dist/namespaces/inbox.js +192 -0
  67. package/dist/namespaces/inbox.js.map +1 -0
  68. package/dist/namespaces/live.d.ts +57 -0
  69. package/dist/namespaces/live.d.ts.map +1 -0
  70. package/dist/namespaces/live.js +116 -0
  71. package/dist/namespaces/live.js.map +1 -0
  72. package/dist/namespaces/notifications.d.ts +25 -0
  73. package/dist/namespaces/notifications.d.ts.map +1 -0
  74. package/dist/namespaces/notifications.js +128 -0
  75. package/dist/namespaces/notifications.js.map +1 -0
  76. package/dist/namespaces/profile.d.ts +19 -0
  77. package/dist/namespaces/profile.d.ts.map +1 -0
  78. package/dist/namespaces/profile.js +22 -0
  79. package/dist/namespaces/profile.js.map +1 -0
  80. package/dist/namespaces/questions.d.ts +41 -0
  81. package/dist/namespaces/questions.d.ts.map +1 -0
  82. package/dist/namespaces/questions.js +107 -0
  83. package/dist/namespaces/questions.js.map +1 -0
  84. package/dist/namespaces/rooms.d.ts +13 -0
  85. package/dist/namespaces/rooms.d.ts.map +1 -0
  86. package/dist/namespaces/rooms.js +41 -0
  87. package/dist/namespaces/rooms.js.map +1 -0
  88. package/dist/namespaces/webhooks.d.ts +11 -0
  89. package/dist/namespaces/webhooks.d.ts.map +1 -0
  90. package/dist/namespaces/webhooks.js +32 -0
  91. package/dist/namespaces/webhooks.js.map +1 -0
  92. package/dist/types/approvals.d.ts +62 -0
  93. package/dist/types/approvals.d.ts.map +1 -0
  94. package/dist/types/approvals.js +2 -0
  95. package/dist/types/approvals.js.map +1 -0
  96. package/dist/types/auth.d.ts +185 -0
  97. package/dist/types/auth.d.ts.map +1 -0
  98. package/dist/types/auth.js +2 -0
  99. package/dist/types/auth.js.map +1 -0
  100. package/dist/types/common.d.ts +43 -0
  101. package/dist/types/common.d.ts.map +1 -0
  102. package/dist/types/common.js +2 -0
  103. package/dist/types/common.js.map +1 -0
  104. package/dist/types/handoffs.d.ts +121 -0
  105. package/dist/types/handoffs.d.ts.map +1 -0
  106. package/dist/types/handoffs.js +2 -0
  107. package/dist/types/handoffs.js.map +1 -0
  108. package/dist/types/inbox.d.ts +51 -0
  109. package/dist/types/inbox.d.ts.map +1 -0
  110. package/dist/types/inbox.js +2 -0
  111. package/dist/types/inbox.js.map +1 -0
  112. package/dist/types/notifications.d.ts +376 -0
  113. package/dist/types/notifications.d.ts.map +1 -0
  114. package/dist/types/notifications.js +2 -0
  115. package/dist/types/notifications.js.map +1 -0
  116. package/dist/types/profile.d.ts +30 -0
  117. package/dist/types/profile.d.ts.map +1 -0
  118. package/dist/types/profile.js +3 -0
  119. package/dist/types/profile.js.map +1 -0
  120. package/dist/types/questions.d.ts +210 -0
  121. package/dist/types/questions.d.ts.map +1 -0
  122. package/dist/types/questions.js +2 -0
  123. package/dist/types/questions.js.map +1 -0
  124. package/dist/types/rooms.d.ts +163 -0
  125. package/dist/types/rooms.d.ts.map +1 -0
  126. package/dist/types/rooms.js +3 -0
  127. package/dist/types/rooms.js.map +1 -0
  128. package/dist/types.d.ts +9 -1199
  129. package/dist/types.d.ts.map +1 -1
  130. package/dist/version.d.ts +1 -1
  131. package/dist/version.js +1 -1
  132. package/dist/webhooks.d.ts +14 -4
  133. package/dist/webhooks.d.ts.map +1 -1
  134. package/dist/webhooks.js +30 -5
  135. package/dist/webhooks.js.map +1 -1
  136. package/package.json +4 -2
  137. package/src/client.ts +115 -0
  138. package/src/errors.ts +291 -0
  139. package/src/http.ts +225 -0
  140. package/src/index.ts +97 -0
  141. package/src/internal/async.ts +54 -0
  142. package/src/internal/guards.ts +129 -0
  143. package/src/internal/request.ts +97 -0
  144. package/src/internal/retry.ts +157 -0
  145. package/src/internal/url.ts +78 -0
  146. package/src/internal/validate.ts +42 -0
  147. package/src/linkPing.ts +56 -0
  148. package/src/liveStatus.ts +337 -0
  149. package/src/locationPing.ts +101 -0
  150. package/src/mcp.ts +161 -0
  151. package/src/namespaces/actions.ts +234 -0
  152. package/src/namespaces/approvals.ts +104 -0
  153. package/src/namespaces/attachments.ts +106 -0
  154. package/src/namespaces/auth.ts +284 -0
  155. package/src/namespaces/directory.ts +21 -0
  156. package/src/namespaces/handoffs.ts +160 -0
  157. package/src/namespaces/inbox.ts +253 -0
  158. package/src/namespaces/live.ts +134 -0
  159. package/src/namespaces/notifications.ts +152 -0
  160. package/src/namespaces/profile.ts +24 -0
  161. package/src/namespaces/questions.ts +133 -0
  162. package/src/namespaces/rooms.ts +53 -0
  163. package/src/namespaces/webhooks.ts +38 -0
  164. package/src/types/approvals.ts +67 -0
  165. package/src/types/auth.ts +202 -0
  166. package/src/types/common.ts +74 -0
  167. package/src/types/handoffs.ts +148 -0
  168. package/src/types/inbox.ts +64 -0
  169. package/src/types/notifications.ts +393 -0
  170. package/src/types/profile.ts +37 -0
  171. package/src/types/questions.ts +226 -0
  172. package/src/types/rooms.ts +169 -0
  173. package/src/types.ts +17 -0
  174. package/src/version.ts +2 -0
  175. package/src/webhooks.ts +373 -0
  176. package/dist/liveActivity.d.ts +0 -101
  177. package/dist/liveActivity.d.ts.map +0 -1
  178. package/dist/liveActivity.js +0 -83
  179. package/dist/liveActivity.js.map +0 -1
@@ -0,0 +1,219 @@
1
+ // `pr.actions`: a room's quick-action slots, pages and presses.
2
+ import { PingRoomError } from '../errors.js';
3
+ import { assertActionNumber, requireNonEmpty, requirePresentString } from '../internal/guards.js';
4
+ import { linkPing } from '../linkPing.js';
5
+ import { locationPing } from '../locationPing.js';
6
+ import { enc, splitIdempotencyKey, dropUndefined } from '../internal/request.js';
7
+ const MAX_TRIGGER_ATTACHMENTS = 4;
8
+ const QUICK_ACTION_PAGE_SIZE = 4;
9
+ const MAX_QUICK_ACTION_PAGES = 4;
10
+ /**
11
+ * The per-slot checks shared by `updateMany()` and `updateLayout()`: a valid,
12
+ * present, unique action_number and an icon whenever the slot has a label.
13
+ * Two entries for one slot would let the last silently win, and the caller
14
+ * would never learn which of its definitions was stored.
15
+ */
16
+ function assertActionSlots(actions) {
17
+ const seen = new Set();
18
+ for (const action of actions) {
19
+ assertActionNumber(action.action_number);
20
+ if (action.action_number === undefined || action.action_number === null) {
21
+ throw new PingRoomError('`action_number` is required for each action.', { code: 'invalid_request' });
22
+ }
23
+ if (seen.has(action.action_number)) {
24
+ throw new PingRoomError(`Duplicate action_number ${action.action_number}.`, { code: 'invalid_request' });
25
+ }
26
+ seen.add(action.action_number);
27
+ assertQuickActionIcon(action);
28
+ }
29
+ }
30
+ /**
31
+ * Mirrors the server's `icon` rule (`present`, `required_with:label`): the emoji
32
+ * is the half that must be there unless BOTH are empty, which reserves the
33
+ * slot as disabled.
34
+ */
35
+ function assertQuickActionIcon(action) {
36
+ requirePresentString(action.label, 'label');
37
+ requirePresentString(action.icon, 'icon');
38
+ if (action.icon.trim() === '' && action.label.trim() !== '') {
39
+ throw new PingRoomError('`icon` is required when `label` is set; send both empty to disable the slot.', {
40
+ code: 'invalid_request',
41
+ });
42
+ }
43
+ }
44
+ function assertTriggerInput(input) {
45
+ const data = input.data;
46
+ if (data !== undefined) {
47
+ if (data === null || typeof data !== 'object' || Array.isArray(data)) {
48
+ throw new PingRoomError('`data` must be an object with `location` and/or `url`.', { code: 'invalid_request' });
49
+ }
50
+ for (const key of Object.keys(data)) {
51
+ if (key !== 'location' && key !== 'url') {
52
+ throw new PingRoomError(`\`data.${key}\` is not accepted on a quick-action press; only location and url are.`, {
53
+ code: 'invalid_request',
54
+ });
55
+ }
56
+ }
57
+ try {
58
+ if (data.location !== undefined)
59
+ locationPing(data.location);
60
+ if (data.url !== undefined)
61
+ linkPing({ url: data.url });
62
+ }
63
+ catch (error) {
64
+ throw new PingRoomError(error.message, { code: 'invalid_request' });
65
+ }
66
+ }
67
+ if (input.attachment_ids !== undefined) {
68
+ if (!Array.isArray(input.attachment_ids) || input.attachment_ids.length > MAX_TRIGGER_ATTACHMENTS) {
69
+ throw new PingRoomError(`\`attachment_ids\` accepts at most ${MAX_TRIGGER_ATTACHMENTS} ids.`, { code: 'invalid_request' });
70
+ }
71
+ for (const id of input.attachment_ids)
72
+ requireNonEmpty(id, 'attachment_ids[]');
73
+ }
74
+ }
75
+ export class ActionsApi {
76
+ http;
77
+ constructor(http) {
78
+ this.http = http;
79
+ }
80
+ list(inviteCode) {
81
+ return this.http.request('GET', `/api/agent/rooms/${enc(inviteCode)}/actions`);
82
+ }
83
+ update(inviteCode, actionNumber, input) {
84
+ assertActionNumber(actionNumber);
85
+ // A Ping's title is optional — its emoji can be the whole name — so an
86
+ // empty `label` is a valid update. `icon` is the half that must be there,
87
+ // unless both are empty: that reserves the slot as disabled.
88
+ assertQuickActionIcon(input);
89
+ return this.http.request('PUT', `/api/agent/rooms/${enc(inviteCode)}/actions/${actionNumber}`, {
90
+ body: dropUndefined({ ...input }),
91
+ });
92
+ }
93
+ /**
94
+ * Write up to 16 action slots in one request. The server enforces the room owner's plan.
95
+ * Add new pages in complete groups of four; existing slots may be edited individually.
96
+ *
97
+ * Prefer this over looping `update()`. Each single-slot write enqueues its
98
+ * own silent rooms-refresh push, so configuring a room's four Pings one at a
99
+ * time wakes room members' devices four times inside a few seconds — four of a
100
+ * finite daily background-push budget spent on one logical operation.
101
+ *
102
+ * Partial and additive: slots absent from `actions` keep their current
103
+ * configuration, so this is also the right call for editing a single Ping.
104
+ * Nothing here deletes an action, and an empty array is rejected locally
105
+ * rather than being sent as a clear. Resolves to the room's full ordered
106
+ * action set, not just the slots written.
107
+ */
108
+ updateMany(inviteCode, actions) {
109
+ if (!Array.isArray(actions) || actions.length === 0) {
110
+ throw new PingRoomError('`actions` must contain at least one action.', { code: 'invalid_request' });
111
+ }
112
+ if (actions.length > 16) {
113
+ throw new PingRoomError('A batch may contain at most 16 action slots.', { code: 'invalid_request' });
114
+ }
115
+ assertActionSlots(actions);
116
+ return this.http.request('PUT', `/api/agent/rooms/${enc(inviteCode)}/actions`, {
117
+ body: { actions: actions.map((action) => dropUndefined({ ...action })) },
118
+ });
119
+ }
120
+ /**
121
+ * Press a slot. When the action has an `input_type`, pass the matching
122
+ * detail (`data.location`, `data.url`, or `attachment_ids`) or the server
123
+ * refuses the press with `422 quick_action_input_required` and sends nothing.
124
+ * Read `input_type` from `list()` first; pass the action's `id` as
125
+ * `quick_action_id` to be refused rather than fire the wrong Ping if the
126
+ * owner moved pages meanwhile.
127
+ */
128
+ trigger(inviteCode, actionNumber, input = {}) {
129
+ assertActionNumber(actionNumber);
130
+ assertTriggerInput(input);
131
+ const { body, headers } = splitIdempotencyKey(input);
132
+ return this.http.request('POST', `/api/agent/rooms/${enc(inviteCode)}/actions/${actionNumber}/trigger`, {
133
+ body: dropUndefined({ ...body }),
134
+ ...(headers ? { headers } : {}),
135
+ });
136
+ }
137
+ /**
138
+ * Replace the room's page layout atomically (room owner on Pro only). See
139
+ * `UpdateQuickActionLayoutInput` for the snapshot contract; a stale
140
+ * `base_action_ids` is `409 quick_action_layout_changed`, a page still used
141
+ * by a time trigger, webhook, agent binding or running live update is
142
+ * `409 quick_action_page_in_use`. Prefer `deletePage()`, which builds the
143
+ * body from a fresh read.
144
+ */
145
+ updateLayout(inviteCode, input) {
146
+ if (!Array.isArray(input.base_action_ids)) {
147
+ throw new PingRoomError('`base_action_ids` must be an array of action ids (may be empty).', { code: 'invalid_request' });
148
+ }
149
+ if (!Array.isArray(input.page_order) || input.page_order.length < 1 || input.page_order.length > MAX_QUICK_ACTION_PAGES) {
150
+ throw new PingRoomError(`\`page_order\` must list 1–${MAX_QUICK_ACTION_PAGES} pages.`, { code: 'invalid_request' });
151
+ }
152
+ for (const page of input.page_order) {
153
+ if (page !== null && (!Number.isInteger(page) || page < 1 || page > MAX_QUICK_ACTION_PAGES)) {
154
+ throw new PingRoomError('`page_order` entries must be an original page number 1–4 or null for a blank page.', {
155
+ code: 'invalid_request',
156
+ });
157
+ }
158
+ }
159
+ const expected = input.page_order.length * QUICK_ACTION_PAGE_SIZE;
160
+ if (!Array.isArray(input.actions) || input.actions.length !== expected) {
161
+ throw new PingRoomError(`\`actions\` must hold exactly ${expected} slots for ${input.page_order.length} page(s).`, {
162
+ code: 'invalid_request',
163
+ });
164
+ }
165
+ assertActionSlots(input.actions);
166
+ return this.http.request('PUT', `/api/agent/rooms/${enc(inviteCode)}/actions/layout`, {
167
+ body: {
168
+ base_action_ids: input.base_action_ids,
169
+ page_order: input.page_order,
170
+ actions: input.actions.map((action) => dropUndefined({ ...action })),
171
+ },
172
+ });
173
+ }
174
+ /**
175
+ * Delete one page (1–4) and shift the later pages left, keeping every other
176
+ * slot's configuration. Reads the current action set first so the layout
177
+ * snapshot is real, then calls `updateLayout()`. Page 1 can be deleted only
178
+ * when another page remains.
179
+ */
180
+ async deletePage(inviteCode, page) {
181
+ if (!Number.isInteger(page) || page < 1 || page > MAX_QUICK_ACTION_PAGES) {
182
+ throw new PingRoomError('`page` must be an integer 1–4.', { code: 'invalid_request' });
183
+ }
184
+ const current = await this.list(inviteCode);
185
+ const stored = [...current].sort((a, b) => a.action_number - b.action_number);
186
+ const pageCount = Math.max(1, Math.ceil((stored.at(-1)?.action_number ?? 0) / QUICK_ACTION_PAGE_SIZE));
187
+ if (page > pageCount) {
188
+ throw new PingRoomError(`The room has ${pageCount} page(s); page ${page} does not exist.`, { code: 'invalid_request' });
189
+ }
190
+ if (pageCount === 1) {
191
+ throw new PingRoomError('A room keeps at least one page; configure its slots instead of deleting it.', {
192
+ code: 'invalid_request',
193
+ });
194
+ }
195
+ const keep = Array.from({ length: pageCount }, (_, i) => i + 1).filter((p) => p !== page);
196
+ const byNumber = new Map(stored.map((a) => [a.action_number, a]));
197
+ const actions = [];
198
+ keep.forEach((originalPage, index) => {
199
+ for (let offset = 1; offset <= QUICK_ACTION_PAGE_SIZE; offset++) {
200
+ const source = byNumber.get((originalPage - 1) * QUICK_ACTION_PAGE_SIZE + offset);
201
+ actions.push({
202
+ action_number: index * QUICK_ACTION_PAGE_SIZE + offset,
203
+ label: source?.label ?? '',
204
+ icon: source?.icon ?? '',
205
+ ...(source?.sound !== undefined ? { sound: source.sound } : {}),
206
+ ...(source?.haptic_style !== undefined ? { haptic_style: source.haptic_style } : {}),
207
+ ...(source?.requires_ack !== undefined ? { requires_ack: source.requires_ack } : {}),
208
+ ...(source?.input_type !== undefined ? { input_type: source.input_type } : {}),
209
+ });
210
+ }
211
+ });
212
+ return this.updateLayout(inviteCode, {
213
+ base_action_ids: stored.map((a) => a.id).filter((id) => typeof id === 'string'),
214
+ page_order: keep,
215
+ actions,
216
+ });
217
+ }
218
+ }
219
+ //# sourceMappingURL=actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/namespaces/actions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { HttpClient } from '../http.js';
2
+ import type { Approval, ApprovalInput, WaitApprovalInput, WaitForOutcomeOptions } from '../types.js';
3
+ export declare class ApprovalsApi {
4
+ private readonly http;
5
+ constructor(http: HttpClient);
6
+ /** Ask the human you act for to decide; returns the pending approval. */
7
+ request(inviteCode: string, input: ApprovalInput): Promise<Approval>;
8
+ get(approvalId: string): Promise<Approval>;
9
+ /** One long-poll for the decision; returns the (possibly still-pending) approval. */
10
+ wait(approvalId: string, input?: WaitApprovalInput): Promise<Approval>;
11
+ /**
12
+ * Block until the human decides (or the request expires or is cancelled),
13
+ * looping wait() under the hood, with polls started at least 2.1 s apart. A
14
+ * response that is not this approval in a known status rejects with
15
+ * `invalid_response`. Network failures, 429 and 5xx are retried with backoff
16
+ * (honouring `retryAfter`), and reported to `onRetry`, until `signal` aborts
17
+ * or the outage outlasts the approval's `expires_at` by 5 minutes (15 minutes
18
+ * of failures while no `expires_at` has been read); that rejects with
19
+ * `unavailable`. See {@link WaitForOutcomeOptions}.
20
+ */
21
+ waitForDecision(approvalId: string, input?: WaitForOutcomeOptions): Promise<Approval>;
22
+ }
23
+ //# sourceMappingURL=approvals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../../src/namespaces/approvals.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,OAAO,KAAK,EACV,QAAQ,EACR,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACtB,MAAM,aAAa,CAAC;AA0CrB,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,yEAAyE;IACzE,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC;IAUpE,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAI1C,qFAAqF;IACrF,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE,iBAAsB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAQ1E;;;;;;;;;OASG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE,qBAA0B,GAAG,OAAO,CAAC,QAAQ,CAAC;CAchG"}
@@ -0,0 +1,78 @@
1
+ // `pr.approvals`: two-option human-in-the-loop decisions.
2
+ import { assertStructuredData, requireNonEmpty } from '../internal/guards.js';
3
+ import { pollUntilSettled } from '../internal/retry.js';
4
+ import { MIN_WAIT_POLL_INTERVAL_MS, enc, splitIdempotencyKey, assertOnRetry, dropUndefined, waitTimeoutMs, } from '../internal/request.js';
5
+ import { isRecord, isNonEmptyString, isNullableString, sameId, invalidWaitResponse, } from '../internal/validate.js';
6
+ const APPROVAL_STATUSES = new Set(['pending', 'decided', 'expired', 'cancelled']);
7
+ /**
8
+ * A wait response is trusted as an outcome only when it is the approval that
9
+ * was asked about, in a known status. A captive portal's HTML, `{}`, or another
10
+ * approval must not read as "decided".
11
+ */
12
+ function validateApprovalWait(value, approvalId) {
13
+ const status = isRecord(value) ? value['status'] : undefined;
14
+ if (!isRecord(value)
15
+ || !sameId(value['id'], approvalId)
16
+ || typeof status !== 'string'
17
+ || !APPROVAL_STATUSES.has(status)
18
+ || !isNullableString(value['decided_at'])
19
+ // A gate acts on `decision`; a decided approval without one, or a pending
20
+ // one already stamped decided, is not an outcome it can act on.
21
+ || (status === 'decided' && !isNonEmptyString(value['decision']))
22
+ || (status === 'pending' && value['decided_at'] !== null)) {
23
+ return invalidWaitResponse('approval', approvalId, value, 'status');
24
+ }
25
+ return value;
26
+ }
27
+ export class ApprovalsApi {
28
+ http;
29
+ constructor(http) {
30
+ this.http = http;
31
+ }
32
+ /** Ask the human you act for to decide; returns the pending approval. */
33
+ request(inviteCode, input) {
34
+ requireNonEmpty(input.question, 'question');
35
+ assertStructuredData(input.data);
36
+ const { body, headers } = splitIdempotencyKey(input);
37
+ return this.http.request('POST', `/api/agent/rooms/${enc(inviteCode)}/approvals`, {
38
+ body: dropUndefined({ ...body }),
39
+ ...(headers ? { headers } : {}),
40
+ });
41
+ }
42
+ get(approvalId) {
43
+ return this.http.request('GET', `/api/agent/approvals/${enc(approvalId)}`);
44
+ }
45
+ /** One long-poll for the decision; returns the (possibly still-pending) approval. */
46
+ wait(approvalId, input = {}) {
47
+ return this.http.request('GET', `/api/agent/approvals/${enc(approvalId)}/wait`, {
48
+ query: dropUndefined({ timeout: input.timeout }),
49
+ timeoutMs: waitTimeoutMs(input.timeout),
50
+ ...(input.signal ? { signal: input.signal } : {}),
51
+ });
52
+ }
53
+ /**
54
+ * Block until the human decides (or the request expires or is cancelled),
55
+ * looping wait() under the hood, with polls started at least 2.1 s apart. A
56
+ * response that is not this approval in a known status rejects with
57
+ * `invalid_response`. Network failures, 429 and 5xx are retried with backoff
58
+ * (honouring `retryAfter`), and reported to `onRetry`, until `signal` aborts
59
+ * or the outage outlasts the approval's `expires_at` by 5 minutes (15 minutes
60
+ * of failures while no `expires_at` has been read); that rejects with
61
+ * `unavailable`. See {@link WaitForOutcomeOptions}.
62
+ */
63
+ async waitForDecision(approvalId, input = {}) {
64
+ requireNonEmpty(approvalId, 'approvalId');
65
+ assertOnRetry(input.onRetry);
66
+ return pollUntilSettled({
67
+ poll: () => this.wait(approvalId, input.signal ? { signal: input.signal } : {}),
68
+ validate: (value) => validateApprovalWait(value, approvalId),
69
+ settled: (approval) => approval.status !== 'pending',
70
+ expiresAt: (approval) => approval.expires_at,
71
+ what: `approval ${approvalId}`,
72
+ minIntervalMs: MIN_WAIT_POLL_INTERVAL_MS,
73
+ ...(input.signal ? { signal: input.signal } : {}),
74
+ ...(input.onRetry ? { onRetry: input.onRetry } : {}),
75
+ });
76
+ }
77
+ }
78
+ //# sourceMappingURL=approvals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approvals.js","sourceRoot":"","sources":["../../src/namespaces/approvals.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAG1D,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAOxD,OAAO,EACL,yBAAyB,EACzB,GAAG,EACH,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,aAAa,GACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,MAAM,EACN,mBAAmB,GACpB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,iBAAiB,GAAwB,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;AAEvG;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,KAAc,EAAE,UAAkB;IAC9D,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7D,IACE,CAAC,QAAQ,CAAC,KAAK,CAAC;WACb,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;WAChC,OAAO,MAAM,KAAK,QAAQ;WAC1B,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC;WAC9B,CAAC,gBAAgB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACzC,0EAA0E;QAC1E,gEAAgE;WAC7D,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;WAC9D,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC,EACzD,CAAC;QACD,OAAO,mBAAmB,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,KAA4B,CAAC;AACtC,CAAC;AAED,MAAM,OAAO,YAAY;IACM;IAA7B,YAA6B,IAAgB;QAAhB,SAAI,GAAJ,IAAI,CAAY;IAAG,CAAC;IAEjD,yEAAyE;IACzE,OAAO,CAAC,UAAkB,EAAE,KAAoB;QAC9C,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC5C,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,oBAAoB,GAAG,CAAC,UAAU,CAAC,YAAY,EAAE;YAChF,IAAI,EAAE,aAAa,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC;YAChC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChC,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,UAAkB;QACpB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,wBAAwB,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,qFAAqF;IACrF,IAAI,CAAC,UAAkB,EAAE,QAA2B,EAAE;QACpD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,wBAAwB,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE;YAC9E,KAAK,EAAE,aAAa,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;YAChD,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC;YACvC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClD,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,eAAe,CAAC,UAAkB,EAAE,QAA+B,EAAE;QACzE,eAAe,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAC1C,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,OAAO,gBAAgB,CAAC;YACtB,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/E,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,oBAAoB,CAAC,KAAK,EAAE,UAAU,CAAC;YAC5D,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,KAAK,SAAS;YACpD,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU;YAC5C,IAAI,EAAE,YAAY,UAAU,EAAE;YAC9B,aAAa,EAAE,yBAAyB;YACxC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrD,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ import type { HttpClient } from '../http.js';
2
+ import type { Attachment, ZipManifest, UploadAttachmentInput } from '../types.js';
3
+ /**
4
+ * Private files that a Ping or Question can carry.
5
+ *
6
+ * Upload first, then pass the returned ids to `broadcast()` / `questions.ask()`
7
+ * as `attachment_ids`. Bytes never travel inside a JSON ping body (the MCP
8
+ * `upload_attachment` tool takes only small files, about 90 KiB, as base64). An
9
+ * upload that is never attached expires on its own after 24 hours.
10
+ * Each file must be 1 byte–5 MiB with an md/pdf/html/txt/jpg/jpeg/png/zip filename;
11
+ * a Ping or Question accepts at most four ids.
12
+ *
13
+ * Uploading requires the bound account to hold Pro (the API answers 402
14
+ * `pro_required` otherwise). Reading and deleting are not gated.
15
+ */
16
+ export declare class AttachmentsApi {
17
+ private readonly http;
18
+ constructor(http: HttpClient);
19
+ /** Upload one file and get back the id a send can claim. */
20
+ upload(input: UploadAttachmentInput): Promise<Attachment>;
21
+ /**
22
+ * Raw bytes for an attachment this credential is allowed to see. Returns the
23
+ * undecoded Response so a caller can stream it, or read text/arrayBuffer.
24
+ */
25
+ content(attachmentId: string, signal?: AbortSignal): Promise<Response>;
26
+ /**
27
+ * The listing of a `.zip`'s contents, recorded when it was uploaded.
28
+ *
29
+ * Resolves null for a non-archive, and for an archive whose central
30
+ * directory did not parse. Nothing decompresses the file to produce this, so
31
+ * the declared sizes are what the archive claims, not verified output.
32
+ */
33
+ manifest(attachmentId: string, signal?: AbortSignal): Promise<ZipManifest | null>;
34
+ /** Discard an upload that has not been attached to a ping yet. */
35
+ delete(attachmentId: string): Promise<void>;
36
+ }
37
+ //# sourceMappingURL=attachments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../src/namespaces/attachments.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAYlF;;;;;;;;;;;;GAYG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,4DAA4D;IAC5D,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC;IAqBzD;;;OAGG;IACH,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAOtE;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAWjF,kEAAkE;IAClE,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAI5C"}
@@ -0,0 +1,91 @@
1
+ // `pr.attachments`: upload, read and discard private files.
2
+ import { PingRoomError } from '../errors.js';
3
+ import { requireNonEmpty } from '../internal/guards.js';
4
+ import { enc } from '../internal/request.js';
5
+ /** Server cap per uploaded file; a larger body is a 413 the server answers before reading it. */
6
+ const ATTACHMENT_MAX_BYTES = 5 * 1024 * 1024;
7
+ function attachmentByteLength(content) {
8
+ if (content instanceof Blob)
9
+ return content.size;
10
+ if (typeof content === 'string')
11
+ return new TextEncoder().encode(content).byteLength;
12
+ return content.byteLength;
13
+ }
14
+ /**
15
+ * Private files that a Ping or Question can carry.
16
+ *
17
+ * Upload first, then pass the returned ids to `broadcast()` / `questions.ask()`
18
+ * as `attachment_ids`. Bytes never travel inside a JSON ping body (the MCP
19
+ * `upload_attachment` tool takes only small files, about 90 KiB, as base64). An
20
+ * upload that is never attached expires on its own after 24 hours.
21
+ * Each file must be 1 byte–5 MiB with an md/pdf/html/txt/jpg/jpeg/png/zip filename;
22
+ * a Ping or Question accepts at most four ids.
23
+ *
24
+ * Uploading requires the bound account to hold Pro (the API answers 402
25
+ * `pro_required` otherwise). Reading and deleting are not gated.
26
+ */
27
+ export class AttachmentsApi {
28
+ http;
29
+ constructor(http) {
30
+ this.http = http;
31
+ }
32
+ /** Upload one file and get back the id a send can claim. */
33
+ upload(input) {
34
+ requireNonEmpty(input.filename, 'filename');
35
+ // The server answers an oversized body with 413 before reading it; refuse
36
+ // locally so no bytes travel for a file that can never be accepted.
37
+ if (attachmentByteLength(input.content) > ATTACHMENT_MAX_BYTES) {
38
+ return Promise.reject(new PingRoomError('Attachments are at most 5 MiB each.', { code: 'attachment_too_large', status: 413 }));
39
+ }
40
+ const body = new FormData();
41
+ body.append('file', toAttachmentBlob(input), input.filename);
42
+ return this.http
43
+ .request('POST', '/api/agent/attachments', {
44
+ body,
45
+ ...(input.signal ? { signal: input.signal } : {}),
46
+ })
47
+ .then((res) => res.attachment);
48
+ }
49
+ /**
50
+ * Raw bytes for an attachment this credential is allowed to see. Returns the
51
+ * undecoded Response so a caller can stream it, or read text/arrayBuffer.
52
+ */
53
+ content(attachmentId, signal) {
54
+ requireNonEmpty(attachmentId, 'attachmentId');
55
+ return this.http.raw('GET', `/api/agent/attachments/${enc(attachmentId)}/content`, {
56
+ ...(signal ? { signal } : {}),
57
+ });
58
+ }
59
+ /**
60
+ * The listing of a `.zip`'s contents, recorded when it was uploaded.
61
+ *
62
+ * Resolves null for a non-archive, and for an archive whose central
63
+ * directory did not parse. Nothing decompresses the file to produce this, so
64
+ * the declared sizes are what the archive claims, not verified output.
65
+ */
66
+ manifest(attachmentId, signal) {
67
+ requireNonEmpty(attachmentId, 'attachmentId');
68
+ return this.http
69
+ .request('GET', `/api/agent/attachments/${enc(attachmentId)}/manifest`, { ...(signal ? { signal } : {}) })
70
+ .then((res) => res.manifest ?? null);
71
+ }
72
+ /** Discard an upload that has not been attached to a ping yet. */
73
+ delete(attachmentId) {
74
+ requireNonEmpty(attachmentId, 'attachmentId');
75
+ return this.http.request('DELETE', `/api/agent/attachments/${enc(attachmentId)}`);
76
+ }
77
+ }
78
+ /** Normalise the three accepted content shapes into one multipart part. */
79
+ function toAttachmentBlob(input) {
80
+ const type = input.contentType ?? '';
81
+ if (input.content instanceof Blob) {
82
+ return type ? new Blob([input.content], { type }) : input.content;
83
+ }
84
+ // Copy into a plain ArrayBuffer: a Uint8Array view may be a window onto a
85
+ // larger (or SharedArrayBuffer-backed) buffer, which Blob would not accept.
86
+ const parts = typeof input.content === 'string'
87
+ ? [input.content]
88
+ : [new Uint8Array(input.content).slice().buffer];
89
+ return new Blob(parts, type ? { type } : undefined);
90
+ }
91
+ //# sourceMappingURL=attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/namespaces/attachments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type { HttpClient } from '../http.js';
2
+ import type { AgentConnectionInfo, AgentDisconnectResult, Credential, ClaimCompleteParams, ClaimStartParams, RegisterParams, PairingStart, PairingStatus, PairedCredential, StartPairingParams, WaitForPairingOptions } from '../types.js';
3
+ /** Agent credential lifecycle (auth.md flow). */
4
+ export declare class AuthApi {
5
+ private readonly http;
6
+ private pairing;
7
+ constructor(http: HttpClient);
8
+ /** Register an agent. Anonymous or via an identity assertion (ID-JAG / verified email). Public. */
9
+ register(params: RegisterParams): Promise<Credential>;
10
+ /** Begin claiming a pre-claim credential onto a human account; emails an OTP. */
11
+ claimStart(params: ClaimStartParams): Promise<{
12
+ message: string;
13
+ expires_in: number;
14
+ }>;
15
+ /** Complete the claim with the emailed OTP; returns an active credential + handle. */
16
+ claimComplete(params: ClaimCompleteParams): Promise<Credential>;
17
+ /**
18
+ * Register a pending agent and create a short-lived link that opens the
19
+ * PingRoom app. The server owns the full grant shown to the approver; this
20
+ * client sends no scope list. The pending credential stays private inside the
21
+ * client and is replaced automatically once waitForPairing() succeeds. If the
22
+ * client already held a credential, it is put back when the pairing expires
23
+ * or the wait is aborted, so a re-pairing that never completes leaves the
24
+ * client on the working credential rather than the dead pending one.
25
+ */
26
+ startPairing(params?: StartPairingParams): Promise<PairingStart>;
27
+ /** Read the current state of an app pairing using the pending credential. */
28
+ pairingStatus(options?: Pick<WaitForPairingOptions, 'signal'>): Promise<PairingStatus>;
29
+ /**
30
+ * Wait until the person approves in PingRoom, or the short-lived link
31
+ * expires. Transient network, 429, and 5xx failures are retried inside the
32
+ * server-provided lifetime. On success the client immediately starts using
33
+ * the active credential returned by the server. When the link expires or the
34
+ * wait is aborted, the credential the client held before startPairing() is
35
+ * restored; calling waitForPairing() again after an abort resumes the same
36
+ * pairing.
37
+ */
38
+ waitForPairing(pairing: PairingStart, options?: WaitForPairingOptions): Promise<PairedCredential>;
39
+ private pollPairing;
40
+ /** Rotate to a fresh credential (same scopes/handle). */
41
+ refresh(): Promise<Credential>;
42
+ /** Revoke the current credential. */
43
+ revoke(): Promise<void>;
44
+ /**
45
+ * What this credential is connected to: the robot, the owner's public id and
46
+ * name, the home room and room memberships, and the room grant. Check
47
+ * `owner.id` and `handle` against the account and robot you approved before
48
+ * sending anything.
49
+ */
50
+ connection(): Promise<AgentConnectionInfo>;
51
+ /**
52
+ * Disconnect this agent: revokes the calling credential and its refresh
53
+ * credentials. The client keeps the now-revoked token; clear it with
54
+ * `setToken(null)` or pair again.
55
+ */
56
+ disconnect(): Promise<AgentDisconnectResult>;
57
+ }
58
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/namespaces/auth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,OAAO,KAAK,EACV,mBAAmB,EACnB,qBAAqB,EACrB,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,aAAa,CAAC;AA2CrB,iDAAiD;AACjD,qBAAa,OAAO;IAGN,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,OAAO,CAA+B;gBAEjB,IAAI,EAAE,UAAU;IAE7C,mGAAmG;IACnG,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAKrD,iFAAiF;IACjF,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAKtF,sFAAsF;IACtF,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAM/D;;;;;;;;OAQG;IACG,YAAY,CAAC,MAAM,GAAE,kBAAuB,GAAG,OAAO,CAAC,YAAY,CAAC;IA8B1E,6EAA6E;IAC7E,aAAa,CAAC,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAI1F;;;;;;;;OAQG;IACG,cAAc,CAClB,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,gBAAgB,CAAC;YAyBd,WAAW;IAwFzB,yDAAyD;IACzD,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAI9B,qCAAqC;IACrC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvB;;;;;OAKG;IACH,UAAU,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAI1C;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC,qBAAqB,CAAC;CAG7C"}