@relaycast/engine 8.16.0 → 9.1.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 (154) hide show
  1. package/dist/adapters/node/event-queue.d.ts +7 -2
  2. package/dist/adapters/node/event-queue.d.ts.map +1 -1
  3. package/dist/adapters/node/event-queue.js +19 -4
  4. package/dist/adapters/node/event-queue.js.map +1 -1
  5. package/dist/adapters/node/index.d.ts.map +1 -1
  6. package/dist/adapters/node/index.js +18 -2
  7. package/dist/adapters/node/index.js.map +1 -1
  8. package/dist/adapters/node/ssrf-fetch.d.ts +12 -0
  9. package/dist/adapters/node/ssrf-fetch.d.ts.map +1 -0
  10. package/dist/adapters/node/ssrf-fetch.js +81 -0
  11. package/dist/adapters/node/ssrf-fetch.js.map +1 -0
  12. package/dist/auth/index.d.ts +1 -0
  13. package/dist/auth/index.d.ts.map +1 -1
  14. package/dist/auth/index.js +16 -4
  15. package/dist/auth/index.js.map +1 -1
  16. package/dist/auth/workspaceExpiry.d.ts +28 -0
  17. package/dist/auth/workspaceExpiry.d.ts.map +1 -0
  18. package/dist/auth/workspaceExpiry.js +39 -0
  19. package/dist/auth/workspaceExpiry.js.map +1 -0
  20. package/dist/db/migrations/0062_direct_dm_idempotency.sql +20 -0
  21. package/dist/db/migrations/0063_node_rotation_recovery.sql +13 -0
  22. package/dist/db/migrations/0064_action_invocations_status_dispatched_index.sql +9 -0
  23. package/dist/db/migrations/0065_action_invocations_task_deadline_any_status.sql +10 -0
  24. package/dist/db/migrations/0066_action_invocations_status_sweep_ranges.sql +15 -0
  25. package/dist/db/migrations/0067_webhook_delivery_reliability.sql +37 -0
  26. package/dist/db/schema.d.ts +425 -0
  27. package/dist/db/schema.d.ts.map +1 -1
  28. package/dist/db/schema.js +68 -1
  29. package/dist/db/schema.js.map +1 -1
  30. package/dist/engine/a2aEgress.d.ts +10 -0
  31. package/dist/engine/a2aEgress.d.ts.map +1 -1
  32. package/dist/engine/a2aEgress.js +35 -3
  33. package/dist/engine/a2aEgress.js.map +1 -1
  34. package/dist/engine/attachments.d.ts.map +1 -1
  35. package/dist/engine/attachments.js +5 -3
  36. package/dist/engine/attachments.js.map +1 -1
  37. package/dist/engine/dm.d.ts +5 -1
  38. package/dist/engine/dm.d.ts.map +1 -1
  39. package/dist/engine/dm.js +139 -20
  40. package/dist/engine/dm.js.map +1 -1
  41. package/dist/engine/dmAll.d.ts +6 -0
  42. package/dist/engine/dmAll.d.ts.map +1 -1
  43. package/dist/engine/dmAll.js +51 -2
  44. package/dist/engine/dmAll.js.map +1 -1
  45. package/dist/engine/eventDelivery.d.ts +50 -1
  46. package/dist/engine/eventDelivery.d.ts.map +1 -1
  47. package/dist/engine/eventDelivery.js +435 -75
  48. package/dist/engine/eventDelivery.js.map +1 -1
  49. package/dist/engine/eventDispatch.d.ts.map +1 -1
  50. package/dist/engine/eventDispatch.js +2 -0
  51. package/dist/engine/eventDispatch.js.map +1 -1
  52. package/dist/engine/eventQueue.d.ts +3 -2
  53. package/dist/engine/eventQueue.d.ts.map +1 -1
  54. package/dist/engine/eventQueue.js +9 -4
  55. package/dist/engine/eventQueue.js.map +1 -1
  56. package/dist/engine/eventSubscription.d.ts +5 -0
  57. package/dist/engine/eventSubscription.d.ts.map +1 -1
  58. package/dist/engine/eventSubscription.js +4 -0
  59. package/dist/engine/eventSubscription.js.map +1 -1
  60. package/dist/engine/httpPushDispatch.d.ts +1 -0
  61. package/dist/engine/httpPushDispatch.d.ts.map +1 -1
  62. package/dist/engine/httpPushDispatch.js +21 -8
  63. package/dist/engine/httpPushDispatch.js.map +1 -1
  64. package/dist/engine/inboundWebhook.d.ts +4 -0
  65. package/dist/engine/inboundWebhook.d.ts.map +1 -1
  66. package/dist/engine/inboundWebhook.js +5 -0
  67. package/dist/engine/inboundWebhook.js.map +1 -1
  68. package/dist/engine/invocationCompletion.d.ts.map +1 -1
  69. package/dist/engine/invocationCompletion.js +2 -0
  70. package/dist/engine/invocationCompletion.js.map +1 -1
  71. package/dist/engine/messageMetadata.d.ts +4 -0
  72. package/dist/engine/messageMetadata.d.ts.map +1 -1
  73. package/dist/engine/messageMetadata.js +7 -1
  74. package/dist/engine/messageMetadata.js.map +1 -1
  75. package/dist/engine/node.d.ts +37 -7
  76. package/dist/engine/node.d.ts.map +1 -1
  77. package/dist/engine/node.js +107 -19
  78. package/dist/engine/node.js.map +1 -1
  79. package/dist/engine/nodeContext.d.ts +1 -0
  80. package/dist/engine/nodeContext.d.ts.map +1 -1
  81. package/dist/engine/nodeContext.js +1 -0
  82. package/dist/engine/nodeContext.js.map +1 -1
  83. package/dist/engine/nodeDeliver.d.ts +1 -0
  84. package/dist/engine/nodeDeliver.d.ts.map +1 -1
  85. package/dist/engine/nodeDeliver.js +1 -0
  86. package/dist/engine/nodeDeliver.js.map +1 -1
  87. package/dist/engine/sessionEvent.d.ts.map +1 -1
  88. package/dist/engine/sessionEvent.js +2 -0
  89. package/dist/engine/sessionEvent.js.map +1 -1
  90. package/dist/engine/workspace.d.ts +7 -0
  91. package/dist/engine/workspace.d.ts.map +1 -1
  92. package/dist/engine/workspace.js +11 -0
  93. package/dist/engine/workspace.js.map +1 -1
  94. package/dist/engine/wsAuth.d.ts +2 -1
  95. package/dist/engine/wsAuth.d.ts.map +1 -1
  96. package/dist/engine/wsAuth.js +27 -2
  97. package/dist/engine/wsAuth.js.map +1 -1
  98. package/dist/index.d.ts +4 -2
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +7 -2
  101. package/dist/index.js.map +1 -1
  102. package/dist/lib/serverTelemetry.d.ts +13 -2
  103. package/dist/lib/serverTelemetry.d.ts.map +1 -1
  104. package/dist/lib/serverTelemetry.js +4 -0
  105. package/dist/lib/serverTelemetry.js.map +1 -1
  106. package/dist/lib/ssrf.d.ts +16 -17
  107. package/dist/lib/ssrf.d.ts.map +1 -1
  108. package/dist/lib/ssrf.js +160 -46
  109. package/dist/lib/ssrf.js.map +1 -1
  110. package/dist/lib/standardWebhook.d.ts +15 -0
  111. package/dist/lib/standardWebhook.d.ts.map +1 -0
  112. package/dist/lib/standardWebhook.js +89 -0
  113. package/dist/lib/standardWebhook.js.map +1 -0
  114. package/dist/middleware/auth.d.ts.map +1 -1
  115. package/dist/middleware/auth.js +3 -2
  116. package/dist/middleware/auth.js.map +1 -1
  117. package/dist/middleware/idempotency.d.ts +15 -9
  118. package/dist/middleware/idempotency.d.ts.map +1 -1
  119. package/dist/middleware/idempotency.js +104 -58
  120. package/dist/middleware/idempotency.js.map +1 -1
  121. package/dist/ports/index.d.ts +6 -0
  122. package/dist/ports/index.d.ts.map +1 -1
  123. package/dist/routes/a2a.d.ts.map +1 -1
  124. package/dist/routes/a2a.js +15 -2
  125. package/dist/routes/a2a.js.map +1 -1
  126. package/dist/routes/action.js +1 -0
  127. package/dist/routes/action.js.map +1 -1
  128. package/dist/routes/agent.d.ts.map +1 -1
  129. package/dist/routes/agent.js +13 -2
  130. package/dist/routes/agent.js.map +1 -1
  131. package/dist/routes/deliveryRouting.d.ts.map +1 -1
  132. package/dist/routes/deliveryRouting.js +3 -2
  133. package/dist/routes/deliveryRouting.js.map +1 -1
  134. package/dist/routes/dm.d.ts.map +1 -1
  135. package/dist/routes/dm.js +70 -42
  136. package/dist/routes/dm.js.map +1 -1
  137. package/dist/routes/eventSubscription.d.ts.map +1 -1
  138. package/dist/routes/eventSubscription.js +64 -3
  139. package/dist/routes/eventSubscription.js.map +1 -1
  140. package/dist/routes/node.d.ts.map +1 -1
  141. package/dist/routes/node.js +53 -4
  142. package/dist/routes/node.js.map +1 -1
  143. package/dist/routes/reaction.js +2 -0
  144. package/dist/routes/reaction.js.map +1 -1
  145. package/dist/routes/receipt.js +1 -0
  146. package/dist/routes/receipt.js.map +1 -1
  147. package/dist/routes/webhookOutbox.d.ts +1 -0
  148. package/dist/routes/webhookOutbox.d.ts.map +1 -1
  149. package/dist/routes/webhookOutbox.js +9 -5
  150. package/dist/routes/webhookOutbox.js.map +1 -1
  151. package/dist/routes/workspace.d.ts.map +1 -1
  152. package/dist/routes/workspace.js +41 -7
  153. package/dist/routes/workspace.js.map +1 -1
  154. package/package.json +4 -4
package/dist/lib/ssrf.js CHANGED
@@ -1,57 +1,171 @@
1
- /**
2
- * Guard for outbound fetches to operator/tenant-supplied URLs (A2A external
3
- * agent URLs, agent-card URLs). Always rejects non-http(s) schemes; in `strict`
4
- * mode additionally rejects loopback/link-local/private hosts.
5
- *
6
- * The strict host check is literal (no DNS resolution), so it does not defend
7
- * against DNS-rebinding; a hardened deployment should also validate the resolved
8
- * address at connect time.
9
- */
10
- export function isSafeExternalUrl(rawUrl, options = {}) {
1
+ function parseIpv4(host) {
2
+ const match = host.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
3
+ if (!match)
4
+ return null;
5
+ const octets = match.slice(1).map(Number);
6
+ if (octets.some((octet) => octet > 255))
7
+ return null;
8
+ return (((octets[0] * 256 + octets[1]) * 256 + octets[2]) * 256 + octets[3]) >>> 0;
9
+ }
10
+ function v4InCidr(value, base, prefix) {
11
+ const baseValue = parseIpv4(base);
12
+ if (baseValue === null)
13
+ return false;
14
+ const shift = 32 - prefix;
15
+ return (value >>> shift) === (baseValue >>> shift);
16
+ }
17
+ function parseIpv6(input) {
18
+ let host = input.toLowerCase();
19
+ if (host.includes('%'))
20
+ host = host.slice(0, host.indexOf('%'));
21
+ const ipv4Tail = host.match(/(?:^|:)(\d{1,3}(?:\.\d{1,3}){3})$/)?.[1];
22
+ if (ipv4Tail) {
23
+ const ipv4 = parseIpv4(ipv4Tail);
24
+ if (ipv4 === null)
25
+ return null;
26
+ host = `${host.slice(0, -ipv4Tail.length)}${((ipv4 >>> 16) & 0xffff).toString(16)}:${(ipv4 & 0xffff).toString(16)}`;
27
+ }
28
+ const halves = host.split('::');
29
+ if (halves.length > 2)
30
+ return null;
31
+ const left = halves[0] ? halves[0].split(':') : [];
32
+ const right = halves.length === 2 && halves[1] ? halves[1].split(':') : [];
33
+ if (halves.length === 1 && left.length !== 8)
34
+ return null;
35
+ const missing = 8 - left.length - right.length;
36
+ if (missing < (halves.length === 2 ? 1 : 0))
37
+ return null;
38
+ const groups = [...left, ...Array.from({ length: missing }, () => '0'), ...right];
39
+ if (groups.length !== 8 || groups.some((group) => !/^[0-9a-f]{1,4}$/.test(group)))
40
+ return null;
41
+ let value = 0n;
42
+ for (const group of groups)
43
+ value = (value << 16n) | BigInt(`0x${group}`);
44
+ return value;
45
+ }
46
+ function ipv6Base(value) {
47
+ const parsed = parseIpv6(value);
48
+ if (parsed === null)
49
+ throw new Error(`Invalid IPv6 CIDR base: ${value}`);
50
+ return parsed;
51
+ }
52
+ function v6InCidr(value, base, prefix) {
53
+ const shift = 128n - BigInt(prefix);
54
+ return (value >> shift) === (ipv6Base(base) >> shift);
55
+ }
56
+ function ipv4FromInteger(value) {
57
+ const embedded = Number(value & 0xffffffffn) >>> 0;
58
+ return [
59
+ embedded >>> 24,
60
+ (embedded >>> 16) & 0xff,
61
+ (embedded >>> 8) & 0xff,
62
+ embedded & 0xff,
63
+ ].join('.');
64
+ }
65
+ /** IANA special-purpose address filtering used both before and during connection. */
66
+ export function isGlobalIpAddress(address) {
67
+ const normalized = address.toLowerCase().replace(/^\[|\]$/g, '');
68
+ const ipv4 = parseIpv4(normalized);
69
+ if (ipv4 !== null) {
70
+ // The two PCP/TURN anycast addresses are the globally reachable exceptions
71
+ // inside 192.0.0.0/24.
72
+ const protocolAssignmentException = normalized === '192.0.0.9' || normalized === '192.0.0.10';
73
+ return !(v4InCidr(ipv4, '0.0.0.0', 8)
74
+ || v4InCidr(ipv4, '10.0.0.0', 8)
75
+ || v4InCidr(ipv4, '100.64.0.0', 10)
76
+ || v4InCidr(ipv4, '127.0.0.0', 8)
77
+ || v4InCidr(ipv4, '169.254.0.0', 16)
78
+ || v4InCidr(ipv4, '172.16.0.0', 12)
79
+ || (v4InCidr(ipv4, '192.0.0.0', 24) && !protocolAssignmentException)
80
+ || v4InCidr(ipv4, '192.0.2.0', 24)
81
+ || v4InCidr(ipv4, '192.88.99.0', 24)
82
+ || v4InCidr(ipv4, '192.168.0.0', 16)
83
+ || v4InCidr(ipv4, '198.18.0.0', 15)
84
+ || v4InCidr(ipv4, '198.51.100.0', 24)
85
+ || v4InCidr(ipv4, '203.0.113.0', 24)
86
+ || v4InCidr(ipv4, '224.0.0.0', 4)
87
+ || v4InCidr(ipv4, '240.0.0.0', 4));
88
+ }
89
+ const ipv6 = parseIpv6(normalized);
90
+ if (ipv6 === null)
91
+ return false;
92
+ // IPv4-mapped IPv6 must inherit the embedded address's classification.
93
+ if (v6InCidr(ipv6, '::ffff:0:0', 96)) {
94
+ return isGlobalIpAddress(ipv4FromInteger(ipv6));
95
+ }
96
+ // The well-known NAT64 prefix and 6to4 both embed an IPv4 destination.
97
+ // Do not let either representation bypass the IPv4 special-range policy.
98
+ if (v6InCidr(ipv6, '64:ff9b::', 96)) {
99
+ return isGlobalIpAddress(ipv4FromInteger(ipv6));
100
+ }
101
+ if (v6InCidr(ipv6, '2002::', 16)) {
102
+ return isGlobalIpAddress(ipv4FromInteger(ipv6 >> 80n));
103
+ }
104
+ // IANA global unicast allocation is 2000::/3. Known special-purpose
105
+ // sub-ranges within it remain blocked below.
106
+ return v6InCidr(ipv6, '2000::', 3) && !(v6InCidr(ipv6, '2001::', 23)
107
+ || v6InCidr(ipv6, '2001:db8::', 32)
108
+ || v6InCidr(ipv6, '3fff::', 20));
109
+ }
110
+ function parsedSafeUrl(rawUrl, options) {
11
111
  let url;
12
112
  try {
13
113
  url = new URL(rawUrl);
14
114
  }
15
115
  catch {
16
- return false;
116
+ return null;
117
+ }
118
+ if (options.requireHttps) {
119
+ if (url.protocol !== 'https:')
120
+ return null;
121
+ }
122
+ else if (url.protocol !== 'http:' && url.protocol !== 'https:') {
123
+ return null;
17
124
  }
18
- if (url.protocol !== 'http:' && url.protocol !== 'https:')
19
- return false;
20
125
  if (!options.strict)
21
- return true;
22
- const host = url.hostname.toLowerCase().replace(/^\[|\]$/g, ''); // strip IPv6 brackets
23
- if (host === 'localhost' ||
24
- host === '0.0.0.0' ||
25
- host === '::' ||
26
- host === '::1' ||
27
- host.endsWith('.localhost') ||
28
- host.endsWith('.local') ||
29
- host.endsWith('.internal')) {
30
- return false;
126
+ return url;
127
+ const host = url.hostname.toLowerCase().replace(/^\[|\]$/g, '');
128
+ if (host === 'localhost'
129
+ || host.endsWith('.localhost')
130
+ || host.endsWith('.local')
131
+ || host.endsWith('.internal')) {
132
+ return null;
31
133
  }
32
- // IPv4 literal → check private/loopback/link-local ranges.
33
- const v4 = host.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
34
- if (v4) {
35
- const [a, b] = [Number(v4[1]), Number(v4[2])];
36
- if (a === 10)
37
- return false; // 10.0.0.0/8
38
- if (a === 127)
39
- return false; // loopback
40
- if (a === 0)
41
- return false; // "this host"
42
- if (a === 169 && b === 254)
43
- return false; // link-local (incl. cloud metadata)
44
- if (a === 172 && b >= 16 && b <= 31)
45
- return false; // 172.16.0.0/12
46
- if (a === 192 && b === 168)
47
- return false; // 192.168.0.0/16
48
- if (a >= 224)
49
- return false; // multicast / reserved
50
- }
51
- // IPv6 unique-local (fc00::/7) and link-local (fe80::/10).
52
- if (host.includes(':') && (host.startsWith('fc') || host.startsWith('fd') || host.startsWith('fe8') || host.startsWith('fe9') || host.startsWith('fea') || host.startsWith('feb'))) {
53
- return false;
134
+ if (parseIpv4(host) !== null || parseIpv6(host) !== null) {
135
+ return isGlobalIpAddress(host) ? url : null;
136
+ }
137
+ return url;
138
+ }
139
+ /** Fast syntax/literal-IP check. Use `resolveSafeExternalUrl` before connecting. */
140
+ export function isSafeExternalUrl(rawUrl, options = {}) {
141
+ return parsedSafeUrl(rawUrl, options) !== null;
142
+ }
143
+ /**
144
+ * Resolve every address and reject the hostname if any answer is non-global.
145
+ * A production HTTP connector must run this same classification inside its DNS
146
+ * lookup callback and connect to that validated answer to close the rebinding gap.
147
+ */
148
+ export async function resolveSafeExternalUrl(rawUrl, resolver, options = {}) {
149
+ const effectiveOptions = { strict: true, ...options };
150
+ const url = parsedSafeUrl(rawUrl, effectiveOptions);
151
+ if (!url)
152
+ return null;
153
+ if (!effectiveOptions.strict)
154
+ return url;
155
+ const host = url.hostname.toLowerCase().replace(/^\[|\]$/g, '');
156
+ if (parseIpv4(host) !== null || parseIpv6(host) !== null)
157
+ return url;
158
+ let resolved;
159
+ try {
160
+ resolved = await resolver(host);
161
+ }
162
+ catch {
163
+ return null;
54
164
  }
55
- return true;
165
+ if (resolved.length === 0)
166
+ return null;
167
+ return resolved.every((entry) => isGlobalIpAddress(typeof entry === 'string' ? entry : entry.address))
168
+ ? url
169
+ : null;
56
170
  }
57
171
  //# sourceMappingURL=ssrf.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ssrf.js","sourceRoot":"","sources":["../../src/lib/ssrf.ts"],"names":[],"mappings":"AAaA;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,UAA0B,EAAE;IAC5E,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAExE,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEjC,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,sBAAsB;IAEvF,IACE,IAAI,KAAK,WAAW;QACpB,IAAI,KAAK,SAAS;QAClB,IAAI,KAAK,IAAI;QACb,IAAI,KAAK,KAAK;QACd,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC3B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACvB,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAC1B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2DAA2D;IAC3D,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;IACtE,IAAI,EAAE,EAAE,CAAC;QACP,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,KAAK,EAAE;YAAE,OAAO,KAAK,CAAC,CAAC,aAAa;QACzC,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,KAAK,CAAC,CAAC,WAAW;QACxC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,CAAC,cAAc;QACzC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,KAAK,CAAC,CAAC,oCAAoC;QAC9E,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;YAAE,OAAO,KAAK,CAAC,CAAC,gBAAgB;QACnE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,KAAK,CAAC,CAAC,iBAAiB;QAC3D,IAAI,CAAC,IAAI,GAAG;YAAE,OAAO,KAAK,CAAC,CAAC,uBAAuB;IACrD,CAAC;IAED,2DAA2D;IAC3D,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACnL,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"ssrf.js","sourceRoot":"","sources":["../../src/lib/ssrf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export declare function isValidStandardWebhookSecret(secretWhsec: string): boolean;
2
+ /**
3
+ * Sign the exact request body using the Standard Webhooks symmetric scheme.
4
+ * `tsSeconds` is the attempt timestamp, not the event creation timestamp.
5
+ */
6
+ export declare function signStandardWebhook(secretWhsec: string, msgId: string, tsSeconds: string, rawBody: string): Promise<string>;
7
+ export interface VerifyStandardWebhookOptions {
8
+ /** Unix time used for freshness checks; defaults to the current time. */
9
+ nowSeconds?: number;
10
+ /** Maximum allowed clock skew in seconds; defaults to five minutes. */
11
+ toleranceSeconds?: number;
12
+ }
13
+ /** Accept a fresh matching v1 signature from the rotation-friendly space-delimited header. */
14
+ export declare function verifyStandardWebhook(secretWhsec: string, msgId: string, tsSeconds: string, rawBody: string, signatureHeader: string, options?: VerifyStandardWebhookOptions): Promise<boolean>;
15
+ //# sourceMappingURL=standardWebhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standardWebhook.d.ts","sourceRoot":"","sources":["../../src/lib/standardWebhook.ts"],"names":[],"mappings":"AAwCA,wBAAgB,4BAA4B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAOzE;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAED,MAAM,WAAW,4BAA4B;IAC3C,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,8FAA8F;AAC9F,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,EACvB,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,OAAO,CAAC,CAsBlB"}
@@ -0,0 +1,89 @@
1
+ const encoder = new TextEncoder();
2
+ const STANDARD_WEBHOOK_SECRET_PREFIX = 'whsec_';
3
+ const MIN_SECRET_BYTES = 24;
4
+ const MAX_SECRET_BYTES = 64;
5
+ const DEFAULT_TIMESTAMP_TOLERANCE_SECONDS = 5 * 60;
6
+ function decodeBase64(value) {
7
+ const normalized = value.replace(/\s/g, '');
8
+ if (!/^[A-Za-z0-9+/]*={0,2}$/.test(normalized)) {
9
+ throw new Error('Standard Webhooks secret is not valid base64');
10
+ }
11
+ const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, '=');
12
+ let decoded;
13
+ try {
14
+ decoded = globalThis.atob(padded);
15
+ }
16
+ catch {
17
+ throw new Error('Standard Webhooks secret is not valid base64');
18
+ }
19
+ return Uint8Array.from(decoded, (character) => character.charCodeAt(0));
20
+ }
21
+ function encodeBase64(value) {
22
+ const bytes = new Uint8Array(value);
23
+ let binary = '';
24
+ for (const byte of bytes)
25
+ binary += String.fromCharCode(byte);
26
+ return globalThis.btoa(binary);
27
+ }
28
+ function decodeStandardWebhookSecret(secretWhsec) {
29
+ if (!secretWhsec.startsWith(STANDARD_WEBHOOK_SECRET_PREFIX)) {
30
+ throw new Error('Standard Webhooks secret must start with whsec_');
31
+ }
32
+ const secret = decodeBase64(secretWhsec.slice(STANDARD_WEBHOOK_SECRET_PREFIX.length));
33
+ if (secret.length < MIN_SECRET_BYTES || secret.length > MAX_SECRET_BYTES) {
34
+ throw new Error('Standard Webhooks secret must decode to 24-64 bytes');
35
+ }
36
+ return secret;
37
+ }
38
+ export function isValidStandardWebhookSecret(secretWhsec) {
39
+ try {
40
+ decodeStandardWebhookSecret(secretWhsec);
41
+ return true;
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ }
47
+ /**
48
+ * Sign the exact request body using the Standard Webhooks symmetric scheme.
49
+ * `tsSeconds` is the attempt timestamp, not the event creation timestamp.
50
+ */
51
+ export async function signStandardWebhook(secretWhsec, msgId, tsSeconds, rawBody) {
52
+ if (!msgId || !/^\d+$/.test(tsSeconds)) {
53
+ throw new Error('Standard Webhooks signing requires a message id and Unix-seconds timestamp');
54
+ }
55
+ const secret = decodeStandardWebhookSecret(secretWhsec);
56
+ const secretBytes = secret.buffer.slice(secret.byteOffset, secret.byteOffset + secret.byteLength);
57
+ const key = await globalThis.crypto.subtle.importKey('raw', secretBytes, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
58
+ const signed = `${msgId}.${tsSeconds}.${rawBody}`;
59
+ const signature = await globalThis.crypto.subtle.sign('HMAC', key, encoder.encode(signed));
60
+ return `v1,${encodeBase64(signature)}`;
61
+ }
62
+ /** Accept a fresh matching v1 signature from the rotation-friendly space-delimited header. */
63
+ export async function verifyStandardWebhook(secretWhsec, msgId, tsSeconds, rawBody, signatureHeader, options = {}) {
64
+ if (!/^\d+$/.test(tsSeconds))
65
+ return false;
66
+ const timestamp = Number(tsSeconds);
67
+ const now = options.nowSeconds ?? Math.floor(Date.now() / 1000);
68
+ const tolerance = options.toleranceSeconds ?? DEFAULT_TIMESTAMP_TOLERANCE_SECONDS;
69
+ if (!Number.isSafeInteger(timestamp)
70
+ || !Number.isSafeInteger(now)
71
+ || !Number.isSafeInteger(tolerance)
72
+ || tolerance < 0
73
+ || Math.abs(now - timestamp) > tolerance) {
74
+ return false;
75
+ }
76
+ const expected = await signStandardWebhook(secretWhsec, msgId, tsSeconds, rawBody);
77
+ for (const candidate of signatureHeader.trim().split(/\s+/)) {
78
+ if (!candidate.startsWith('v1,') || candidate.length !== expected.length)
79
+ continue;
80
+ let difference = 0;
81
+ for (let index = 0; index < expected.length; index += 1) {
82
+ difference |= expected.charCodeAt(index) ^ candidate.charCodeAt(index);
83
+ }
84
+ if (difference === 0)
85
+ return true;
86
+ }
87
+ return false;
88
+ }
89
+ //# sourceMappingURL=standardWebhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standardWebhook.js","sourceRoot":"","sources":["../../src/lib/standardWebhook.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAIxC,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,4BAA4B,CAAC;AAIpC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAyC7C,UAAU,oBAAoB;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAMD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,GAAG,aAAa,EAAE,EACvC,OAAO,GAAE,oBAAyB,kEAuDnC;AAED,gDAAgD;AAChD,eAAO,MAAM,mBAAmB,gEAAkC,CAAC;AAEnE,wDAAwD;AACxD,eAAO,MAAM,WAAW,gEAA4B,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,aAAa,gEAA+B,CAAC;AAE1D,+CAA+C;AAC/C,eAAO,MAAM,iBAAiB,gEAA8B,CAAC;AAE7D,6CAA6C;AAC7C,eAAO,MAAM,gBAAgB,gEAA6B,CAAC"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAKxC,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,4BAA4B,CAAC;AAIpC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAyC7C,UAAU,oBAAoB;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAMD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,GAAG,aAAa,EAAE,EACvC,OAAO,GAAE,oBAAyB,kEAuDnC;AAED,gDAAgD;AAChD,eAAO,MAAM,mBAAmB,gEAAkC,CAAC;AAEnE,wDAAwD;AACxD,eAAO,MAAM,WAAW,gEAA4B,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,aAAa,gEAA+B,CAAC;AAE1D,+CAA+C;AAC/C,eAAO,MAAM,iBAAiB,gEAA8B,CAAC;AAE7D,6CAA6C;AAC7C,eAAO,MAAM,gBAAgB,gEAA6B,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { createMiddleware } from 'hono/factory';
2
2
  import { touchLastSeen } from '../engine/agent.js';
3
3
  import { getAuthTokenKind } from '../auth/tokenKind.js';
4
+ import { authenticateUnexpired } from '../auth/workspaceExpiry.js';
4
5
  import { jsonError } from '../lib/httpResponse.js';
5
6
  import { hasAnyObserverScope, } from '../engine/observerToken.js';
6
7
  // Re-exported for the WS upgrade, which looks tokens up
@@ -19,7 +20,7 @@ function makeAuthMiddleware(require) {
19
20
  return jsonError(c, 'unauthorized', 'Missing or invalid Authorization header', 401);
20
21
  }
21
22
  const db = c.get('db');
22
- const result = await c.get('engine').auth.authenticate({ token, require, db });
23
+ const result = await authenticateUnexpired(c.get('engine').auth, { token, require, db });
23
24
  if (!result.ok) {
24
25
  return jsonError(c, result.code, result.message, result.status);
25
26
  }
@@ -58,7 +59,7 @@ export function requireWorkspaceRead(scopes, options = {}) {
58
59
  : allowAgent || allowNode
59
60
  ? 'any'
60
61
  : 'workspace';
61
- const result = await c.get('engine').auth.authenticate({ token, require, db });
62
+ const result = await authenticateUnexpired(c.get('engine').auth, { token, require, db });
62
63
  if (!result.ok) {
63
64
  return jsonError(c, result.code, result.message, result.status);
64
65
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,8 @@ type DeliveryInternals = {
10
10
  _delivery?: unknown;
11
11
  _deliveries?: unknown;
12
12
  _delivery_rejections?: unknown;
13
+ _idempotency_replayed?: boolean;
14
+ _idempotency_ttl_seconds?: number;
13
15
  };
14
16
  interface RunIdempotentOptions<T> {
15
17
  workspaceId: string;
@@ -18,9 +20,13 @@ interface RunIdempotentOptions<T> {
18
20
  key?: string;
19
21
  status?: number;
20
22
  fingerprint?: string;
23
+ /** Primary fingerprint persisted for rollback compatibility. */
24
+ storageFingerprint?: string;
21
25
  /** Prior fingerprint formats accepted only when replaying an existing record. */
22
26
  compatibleFingerprints?: string[];
23
27
  ttlSeconds?: number;
28
+ /** Override result retention (for example, an authoritative claim's remaining lifetime). */
29
+ ttlSecondsForResult?: (data: T) => number | undefined;
24
30
  kv?: KeyValueStore;
25
31
  requireKv?: boolean;
26
32
  /** Fail closed on an unreadable prior record, without failing a committed write on KV completion loss. */
@@ -40,28 +46,28 @@ export declare function parseIdempotencyKey(headerValue: string | undefined): {
40
46
  error?: string;
41
47
  };
42
48
  export declare function applyIdempotencyReplayHeader<T>(c: Context, result: IdempotentResult<T>): void;
43
- export declare function stripDeliveryInternals<T extends object>(data: T): Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery">;
44
- export declare function jsonIdempotentOk<T extends object>(c: Context, result: IdempotentResult<T>): Response & import("hono").TypedResponse<true | Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery"> extends bigint | readonly bigint[] ? never : { [K in keyof {
49
+ export declare function stripDeliveryInternals<T extends object>(data: T): Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery" | "_idempotency_replayed" | "_idempotency_ttl_seconds">;
50
+ export declare function jsonIdempotentOk<T extends object>(c: Context, result: IdempotentResult<T>): Response & import("hono").TypedResponse<true | Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery" | "_idempotency_replayed" | "_idempotency_ttl_seconds"> extends bigint | readonly bigint[] ? never : { [K in keyof {
45
51
  ok: true;
46
- data: Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery">;
52
+ data: Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery" | "_idempotency_replayed" | "_idempotency_ttl_seconds">;
47
53
  } as ({
48
54
  ok: true;
49
- data: Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery">;
55
+ data: Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery" | "_idempotency_replayed" | "_idempotency_ttl_seconds">;
50
56
  }[K] extends infer T_1 ? T_1 extends {
51
57
  ok: true;
52
- data: Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery">;
58
+ data: Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery" | "_idempotency_replayed" | "_idempotency_ttl_seconds">;
53
59
  }[K] ? T_1 extends import("hono/utils/types").InvalidJSONValue ? true : false : never : never) extends true ? never : K]: boolean extends ({
54
60
  ok: true;
55
- data: Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery">;
61
+ data: Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery" | "_idempotency_replayed" | "_idempotency_ttl_seconds">;
56
62
  }[K] extends infer T_2 ? T_2 extends {
57
63
  ok: true;
58
- data: Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery">;
64
+ data: Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery" | "_idempotency_replayed" | "_idempotency_ttl_seconds">;
59
65
  }[K] ? T_2 extends import("hono/utils/types").InvalidJSONValue ? true : false : never : never) ? import("hono/utils/types").JSONParsed<{
60
66
  ok: true;
61
- data: Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery">;
67
+ data: Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery" | "_idempotency_replayed" | "_idempotency_ttl_seconds">;
62
68
  }[K], bigint | readonly bigint[]> | undefined : import("hono/utils/types").JSONParsed<{
63
69
  ok: true;
64
- data: Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery">;
70
+ data: Omit<T & DeliveryInternals, "_deliveries" | "_delivery_rejections" | "_notifications_durable" | "_delivery" | "_idempotency_replayed" | "_idempotency_ttl_seconds">;
65
71
  }[K], bigint | readonly bigint[]>; }, -1 | 100 | 102 | 103 | 200 | 201 | 202 | 203 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 305 | 306 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511, "json">;
66
72
  export declare function runIdempotent<T>(options: RunIdempotentOptions<T>): Promise<IdempotentResult<T>>;
67
73
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../../src/middleware/idempotency.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAcpD,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,KAAK,iBAAiB,GAAG;IACvB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,UAAU,oBAAoB,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,EAAE,CAAC,EAAE,aAAa,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0GAA0G;IAC1G,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5B;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAgBD,wBAAsB,0BAA0B,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMlI;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAwBrG;AAED,wBAAgB,4BAA4B,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,QAItF;AAED,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,CAAC,gHAS/D;AAED,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;oZAGzF;AAED,wBAAsB,aAAa,CAAC,CAAC,EACnC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAuJ9B"}
1
+ {"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../../src/middleware/idempotency.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAmBpD,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,KAAK,iBAAiB,GAAG;IACvB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACnC,CAAC;AAEF,UAAU,oBAAoB,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iFAAiF;IACjF,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4FAA4F;IAC5F,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC;IACtD,EAAE,CAAC,EAAE,aAAa,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0GAA0G;IAC1G,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5B;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AA6BD,wBAAsB,0BAA0B,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMlI;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAwBrG;AAED,wBAAgB,4BAA4B,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,QAItF;AAED,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,CAAC,uKAW/D;AAED,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;oZAGzF;AAED,wBAAsB,aAAa,CAAC,CAAC,EACnC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CA0L9B"}