stitchkit 0.107.0 → 0.108.1

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 (102) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/README.md +2 -0
  3. package/darwin-native.cjs +1 -0
  4. package/dist/agent-runtime/sandbox-process-owner.d.ts +3 -3
  5. package/dist/agent-runtime/sandbox-process-owner.d.ts.map +1 -1
  6. package/dist/agent-runtime/sandbox-process.d.ts +2 -2
  7. package/dist/agent-runtime/sandbox-process.d.ts.map +1 -1
  8. package/dist/agent-runtime/store-conformance-support.d.ts +5 -5
  9. package/dist/browser/stream.d.ts +38 -12
  10. package/dist/browser/stream.d.ts.map +1 -1
  11. package/dist/entrypoints/agent-runtime/coding-tools.js +2 -2
  12. package/dist/entrypoints/agent-runtime/sandbox.js +2 -2
  13. package/dist/entrypoints/application/diagnostic-journal.js +2 -2
  14. package/dist/entrypoints/application/directory-inbox.js +4 -4
  15. package/dist/entrypoints/bin/upgrade-cli.d.ts +32 -0
  16. package/dist/entrypoints/bin/upgrade-cli.d.ts.map +1 -1
  17. package/dist/entrypoints/bin/upgrade-cli.js +451 -8
  18. package/dist/entrypoints/cli/publish.js +3 -3
  19. package/dist/entrypoints/files/packaging.d.ts +3 -1
  20. package/dist/entrypoints/files/packaging.d.ts.map +1 -1
  21. package/dist/entrypoints/files/packaging.js +105 -41
  22. package/dist/entrypoints/files.js +3 -3
  23. package/dist/entrypoints/index.d.ts +1 -1
  24. package/dist/entrypoints/index.d.ts.map +1 -1
  25. package/dist/entrypoints/index.js +7 -1
  26. package/dist/entrypoints/process.js +2 -2
  27. package/dist/entrypoints/remote.js +1 -1
  28. package/dist/entrypoints/server.js +4 -4
  29. package/dist/entrypoints/telegram/screens.js +1 -1
  30. package/dist/entrypoints/telegram.d.ts +2 -0
  31. package/dist/entrypoints/telegram.d.ts.map +1 -1
  32. package/dist/entrypoints/telegram.js +337 -3
  33. package/dist/entrypoints/testing.d.ts +1 -0
  34. package/dist/entrypoints/testing.d.ts.map +1 -1
  35. package/dist/entrypoints/testing.js +131 -1
  36. package/dist/files/native-artifact.d.ts +14 -0
  37. package/dist/files/native-artifact.d.ts.map +1 -0
  38. package/dist/files/native-packaging-layout.d.ts +5 -0
  39. package/dist/files/native-packaging-layout.d.ts.map +1 -1
  40. package/dist/files/native-packaging-plugin.d.ts +53 -0
  41. package/dist/files/native-packaging-plugin.d.ts.map +1 -0
  42. package/dist/files/native-packaging.d.ts +1 -35
  43. package/dist/files/native-packaging.d.ts.map +1 -1
  44. package/dist/index-a5qr2rj6.js +26 -0
  45. package/dist/{index-7r74re56.js → index-bh2ht9y5.js} +12 -6
  46. package/dist/{index-dwf0gymy.js → index-e35py42g.js} +1 -1
  47. package/dist/{index-4q9jvqg7.js → index-epg514ys.js} +182 -13
  48. package/dist/{index-mbf4h8kp.js → index-nx49x0tw.js} +1 -1
  49. package/dist/{index-zsqt5q98.js → index-p5kx5vqd.js} +209 -54
  50. package/dist/{index-bnf8s6v3.js → index-t2bsd0hm.js} +1 -1
  51. package/dist/{index-4f37d3bg.js → index-w9mqgnz9.js} +1 -1
  52. package/dist/{index-e05cjgtf.js → index-xvj9h8yh.js} +28 -1
  53. package/dist/internal/bounded-lines.d.ts +46 -2
  54. package/dist/internal/bounded-lines.d.ts.map +1 -1
  55. package/dist/internal/process-identity.d.ts.map +1 -1
  56. package/dist/internal/until-aborted.d.ts +9 -0
  57. package/dist/internal/until-aborted.d.ts.map +1 -0
  58. package/dist/internal/upgrade-affects.d.ts +58 -0
  59. package/dist/internal/upgrade-affects.d.ts.map +1 -0
  60. package/dist/internal/upgrade-plan.d.ts +20 -0
  61. package/dist/internal/upgrade-plan.d.ts.map +1 -1
  62. package/dist/internal/upgrade-usage.d.ts +61 -0
  63. package/dist/internal/upgrade-usage.d.ts.map +1 -0
  64. package/dist/process/bun-child.d.ts +38 -0
  65. package/dist/process/bun-child.d.ts.map +1 -0
  66. package/dist/process/command-owner.d.ts +2 -2
  67. package/dist/process/command-owner.d.ts.map +1 -1
  68. package/dist/process/launch.d.ts +2 -2
  69. package/dist/process/launch.d.ts.map +1 -1
  70. package/dist/process/owned-child.d.ts +2 -1
  71. package/dist/process/owned-child.d.ts.map +1 -1
  72. package/dist/telegram/bot-api.d.ts +10 -4
  73. package/dist/telegram/bot-api.d.ts.map +1 -1
  74. package/dist/telegram/broadcast.d.ts +2 -1
  75. package/dist/telegram/broadcast.d.ts.map +1 -1
  76. package/dist/telegram/not-dispatched.d.ts +26 -0
  77. package/dist/telegram/not-dispatched.d.ts.map +1 -0
  78. package/dist/telegram/operator-channel.d.ts +2 -1
  79. package/dist/telegram/operator-channel.d.ts.map +1 -1
  80. package/dist/telegram/send-failure.d.ts +4 -3
  81. package/dist/telegram/send-failure.d.ts.map +1 -1
  82. package/dist/telegram/transport-connect.d.ts +38 -0
  83. package/dist/telegram/transport-connect.d.ts.map +1 -0
  84. package/dist/telegram/transport.d.ts +43 -0
  85. package/dist/telegram/transport.d.ts.map +1 -0
  86. package/dist/telegram/webhook.d.ts +2 -1
  87. package/dist/telegram/webhook.d.ts.map +1 -1
  88. package/dist/testing/manual-clock.d.ts +82 -0
  89. package/dist/testing/manual-clock.d.ts.map +1 -0
  90. package/llms/files-packaging.txt +4 -1
  91. package/llms/process.txt +19 -5
  92. package/llms/stitchkit.2.txt +211 -628
  93. package/llms/stitchkit.txt +635 -10
  94. package/llms/telegram.txt +36 -3
  95. package/llms/testing.txt +47 -0
  96. package/llms/{upgrading-0.98.0-0.107.0.txt → upgrading-0.100.0-0.108.0.txt} +59 -64
  97. package/llms/{upgrading-0.72.0-0.97.0.txt → upgrading-0.72.0-0.99.0.txt} +64 -3
  98. package/llms/upgrading.txt +34 -2
  99. package/llms-full.txt +246 -17
  100. package/llms.txt +8 -8
  101. package/package.json +1 -1
  102. package/llms/stitchkit.3.txt +0 -177
@@ -2,18 +2,23 @@ import {
2
2
  backoffDelay
3
3
  } from "../index-g6a3na27.js";
4
4
  import"../index-2kbysk9s.js";
5
- import"../index-7r74re56.js";
5
+ import"../index-bh2ht9y5.js";
6
6
  import {
7
7
  attemptExclusiveLock
8
- } from "../index-bnf8s6v3.js";
8
+ } from "../index-t2bsd0hm.js";
9
9
  import {
10
+ TelegramNotDispatchedError2,
11
+ isTelegramNotDispatchedError,
10
12
  TELEGRAM_SEND_FAILURE_REASONS2,
11
13
  classifyTelegramSendFailure2
12
- } from "../index-e05cjgtf.js";
14
+ } from "../index-xvj9h8yh.js";
13
15
  import {
14
16
  TELEGRAM_TEXT_LIMIT2,
15
17
  truncateTelegramHtml2
16
18
  } from "../index-nmaqxdx7.js";
19
+ import {
20
+ untilAborted
21
+ } from "../index-a5qr2rj6.js";
17
22
  import {
18
23
  raceAbort
19
24
  } from "../index-b0kddvzw.js";
@@ -24,6 +29,9 @@ import {
24
29
  MAX_TIMER_MS,
25
30
  sleep
26
31
  } from "../index-eemvahkc.js";
32
+ import {
33
+ assertPositiveSafeInteger
34
+ } from "../index-0s4xebbg.js";
27
35
  import {
28
36
  BOT_TOKEN_SECRET
29
37
  } from "../index-sznqf8fx.js";
@@ -72,6 +80,8 @@ async function callTelegramBotApi(call) {
72
80
  } catch (error) {
73
81
  if (call.signal?.aborted)
74
82
  throw call.signal.reason;
83
+ if (isTelegramNotDispatchedError(error))
84
+ throw error;
75
85
  const kind = error instanceof Error ? error.name : "Error";
76
86
  throw new Error(`Telegram ${call.method} request failed (${kind})`);
77
87
  }
@@ -888,6 +898,328 @@ function telegramOperatorSender(config) {
888
898
  ...config.fetch && { fetch: config.fetch }
889
899
  });
890
900
  }
901
+ // src/telegram/transport-connect.ts
902
+ import { lookup } from "node:dns/promises";
903
+ import { connect as connectTcp, isIP } from "node:net";
904
+ import { connect as connectTls } from "node:tls";
905
+ var NEXT_ADDRESS_DELAY_MS = 250;
906
+ var MAX_ROUNDS = 3;
907
+ var resolveAll = async (host) => (await lookup(host, { all: true, verbatim: true })).map((entry) => entry.address);
908
+ var openSocket = ({ address, port, tls, servername }) => tls ? connectTls({
909
+ host: address,
910
+ port,
911
+ ...servername !== undefined && { servername },
912
+ ALPNProtocols: ["http/1.1"]
913
+ }) : connectTcp({ host: address, port });
914
+ var connectedEvent = (socket) => ("encrypted" in socket) && socket.encrypted ? "secureConnect" : "connect";
915
+ function race(addresses, target, open, timeoutMs, signal) {
916
+ return new Promise((resolve) => {
917
+ const sockets = [];
918
+ const timers = [];
919
+ let failed = 0;
920
+ let started = 0;
921
+ let lastFailure;
922
+ let settled = false;
923
+ const finish = (winner) => {
924
+ if (settled)
925
+ return;
926
+ settled = true;
927
+ for (const timer of timers)
928
+ clearTimeout(timer);
929
+ signal?.removeEventListener("abort", abort);
930
+ for (const socket of sockets)
931
+ if (socket !== winner)
932
+ socket.destroy();
933
+ resolve(winner ? { socket: winner } : { failure: lastFailure });
934
+ };
935
+ const abort = () => finish(undefined);
936
+ const failOne = (cause) => {
937
+ lastFailure = cause;
938
+ if (++failed === addresses.length)
939
+ finish(undefined);
940
+ else
941
+ launchNext();
942
+ };
943
+ const launchNext = () => {
944
+ if (settled)
945
+ return;
946
+ const address = addresses[started++];
947
+ if (address === undefined)
948
+ return;
949
+ let socket;
950
+ try {
951
+ socket = open({ address, ...target });
952
+ } catch (cause) {
953
+ failOne(cause);
954
+ return;
955
+ }
956
+ sockets.push(socket);
957
+ socket.once(connectedEvent(socket), () => finish(socket));
958
+ socket.once("error", (cause) => {
959
+ socket.destroy();
960
+ failOne(cause);
961
+ });
962
+ if (started < addresses.length)
963
+ timers.push(setTimeout(launchNext, NEXT_ADDRESS_DELAY_MS));
964
+ };
965
+ timers.push(setTimeout(() => finish(undefined), timeoutMs));
966
+ signal?.addEventListener("abort", abort, { once: true });
967
+ if (signal?.aborted)
968
+ finish(undefined);
969
+ else
970
+ launchNext();
971
+ });
972
+ }
973
+ function lookupWithin(host, policy, signal) {
974
+ return new Promise((resolve, reject) => {
975
+ const settle = (act) => {
976
+ clearTimeout(timer);
977
+ signal?.removeEventListener("abort", abort);
978
+ act();
979
+ };
980
+ const abort = () => settle(() => reject(signal?.reason));
981
+ const timer = setTimeout(() => settle(() => reject(new Error(`Address lookup took longer than ${policy.budgetMs} ms`))), policy.budgetMs);
982
+ if (signal?.aborted) {
983
+ abort();
984
+ return;
985
+ }
986
+ signal?.addEventListener("abort", abort, { once: true });
987
+ Promise.resolve().then(() => policy.resolve(host)).then((found) => settle(() => resolve(found)), (error) => settle(() => reject(error)));
988
+ });
989
+ }
990
+ async function establish(host, port, tls, policy, signal) {
991
+ const literal = isIP(host) !== 0;
992
+ let addresses;
993
+ if (literal)
994
+ addresses = [host];
995
+ else {
996
+ try {
997
+ addresses = await lookupWithin(host, policy, signal);
998
+ } catch (cause) {
999
+ signal?.throwIfAborted();
1000
+ throw new TelegramNotDispatchedError2("lookup", "Telegram address lookup failed", {
1001
+ cause
1002
+ });
1003
+ }
1004
+ }
1005
+ signal?.throwIfAborted();
1006
+ if (addresses.length === 0)
1007
+ throw new TelegramNotDispatchedError2("lookup", "Telegram address lookup returned nothing");
1008
+ const target = { port, tls, servername: tls && !literal ? host : undefined };
1009
+ const deadline = performance.now() + policy.budgetMs;
1010
+ let lastFailure;
1011
+ for (let round = 0;round < MAX_ROUNDS; round++) {
1012
+ const left = deadline - performance.now();
1013
+ if (left <= 0)
1014
+ break;
1015
+ const outcome = await race(addresses, target, policy.open, Math.min(policy.attemptMs, left), signal);
1016
+ if (signal?.aborted && "socket" in outcome)
1017
+ outcome.socket.destroy();
1018
+ signal?.throwIfAborted();
1019
+ if ("socket" in outcome)
1020
+ return outcome.socket;
1021
+ lastFailure = outcome.failure ?? lastFailure;
1022
+ }
1023
+ throw new TelegramNotDispatchedError2("connect", "Telegram connection was not established", {
1024
+ cause: lastFailure
1025
+ });
1026
+ }
1027
+
1028
+ // src/telegram/transport.ts
1029
+ function chunkedBody(body) {
1030
+ const parts = [];
1031
+ let at = 0;
1032
+ for (;; ) {
1033
+ const lineEnd = body.indexOf(`\r
1034
+ `, at);
1035
+ if (lineEnd < 0)
1036
+ throw new Error("Telegram chunked answer was truncated");
1037
+ const size = Number.parseInt(body.subarray(at, lineEnd).toString("latin1"), 16);
1038
+ if (!Number.isSafeInteger(size) || size < 0)
1039
+ throw new Error("Telegram chunked answer had an invalid chunk size");
1040
+ if (size === 0)
1041
+ return Buffer.concat(parts);
1042
+ const start = lineEnd + 2;
1043
+ if (start + size > body.length)
1044
+ throw new Error("Telegram chunked answer was truncated");
1045
+ parts.push(body.subarray(start, start + size));
1046
+ at = start + size + 2;
1047
+ }
1048
+ }
1049
+ function answerHead(raw) {
1050
+ const headEnd = raw.indexOf(`\r
1051
+ \r
1052
+ `);
1053
+ if (headEnd < 0)
1054
+ return;
1055
+ const [statusLine = "", ...lines] = raw.subarray(0, headEnd).toString("latin1").split(`\r
1056
+ `);
1057
+ const status = /^HTTP\/1\.[01] (\d{3})/.exec(statusLine)?.[1];
1058
+ if (status === undefined)
1059
+ throw new Error("Telegram answer had an invalid status line");
1060
+ if (Number(status) < 200)
1061
+ throw new Error(`Telegram answer was an interim response (HTTP ${status}), not a final one`);
1062
+ const headers = new Headers;
1063
+ for (const line of lines) {
1064
+ const colon = line.indexOf(":");
1065
+ if (colon > 0)
1066
+ headers.append(line.slice(0, colon).trim(), line.slice(colon + 1).trim());
1067
+ }
1068
+ return { bodyStart: headEnd + 4, status: Number(status), headers };
1069
+ }
1070
+ var bodiless = (status) => status === 204 || status === 304;
1071
+ var isChunked = (headers) => /\bchunked\b/i.test(headers.get("transfer-encoding") ?? "");
1072
+ function declaredLength(headers) {
1073
+ const raw = headers.get("content-length");
1074
+ if (raw === null)
1075
+ return;
1076
+ const values = new Set(raw.split(",").map((value) => value.trim()));
1077
+ const [only = ""] = values;
1078
+ if (values.size !== 1 || !/^\d{1,15}$/.test(only))
1079
+ throw new Error("Telegram answer had an invalid Content-Length");
1080
+ return Number(only);
1081
+ }
1082
+ function answerComplete(raw) {
1083
+ const head = answerHead(raw);
1084
+ if (!head)
1085
+ return false;
1086
+ if (bodiless(head.status))
1087
+ return true;
1088
+ const body = raw.subarray(head.bodyStart);
1089
+ if (isChunked(head.headers)) {
1090
+ try {
1091
+ chunkedBody(body);
1092
+ return true;
1093
+ } catch {
1094
+ return false;
1095
+ }
1096
+ }
1097
+ const length = declaredLength(head.headers);
1098
+ return length !== undefined && body.length >= length;
1099
+ }
1100
+ function parseAnswer(raw) {
1101
+ const head = answerHead(raw);
1102
+ if (!head)
1103
+ throw new Error("Telegram answer ended inside its head");
1104
+ const { status, headers } = head;
1105
+ let body = raw.subarray(head.bodyStart);
1106
+ if (isChunked(headers)) {
1107
+ body = chunkedBody(body);
1108
+ headers.delete("content-length");
1109
+ } else {
1110
+ const expected = declaredLength(headers);
1111
+ if (expected !== undefined) {
1112
+ if (body.length < expected)
1113
+ throw new Error("Telegram answer body was truncated");
1114
+ body = body.subarray(0, expected);
1115
+ }
1116
+ }
1117
+ headers.delete("transfer-encoding");
1118
+ return new Response(bodiless(status) ? null : new Uint8Array(body), { status, headers });
1119
+ }
1120
+ function exchange(socket, request, limits, signal) {
1121
+ return new Promise((resolve, reject) => {
1122
+ const chunks = [];
1123
+ let bytes = 0;
1124
+ let done = false;
1125
+ const finish = (error) => {
1126
+ if (done)
1127
+ return;
1128
+ done = true;
1129
+ clearTimeout(timer);
1130
+ signal?.removeEventListener("abort", abort);
1131
+ socket.destroy();
1132
+ if (error !== undefined) {
1133
+ reject(error);
1134
+ return;
1135
+ }
1136
+ try {
1137
+ resolve(parseAnswer(Buffer.concat(chunks)));
1138
+ } catch (parseError) {
1139
+ reject(parseError);
1140
+ }
1141
+ };
1142
+ const abort = () => finish(signal?.reason);
1143
+ const timer = setTimeout(() => finish(new Error(`Telegram answer took longer than ${limits.responseTimeoutMs} ms`)), limits.responseTimeoutMs);
1144
+ socket.on("data", (chunk) => {
1145
+ bytes += chunk.byteLength;
1146
+ if (bytes > limits.maxResponseBytes) {
1147
+ finish(new Error(`Telegram answer exceeded ${limits.maxResponseBytes} bytes`));
1148
+ return;
1149
+ }
1150
+ chunks.push(chunk);
1151
+ try {
1152
+ if (answerComplete(Buffer.concat(chunks)))
1153
+ finish(undefined);
1154
+ } catch (error) {
1155
+ finish(error);
1156
+ }
1157
+ });
1158
+ socket.once("end", () => finish(undefined));
1159
+ socket.once("close", () => finish(undefined));
1160
+ socket.once("error", (error) => finish(error));
1161
+ signal?.addEventListener("abort", abort, { once: true });
1162
+ if (signal?.aborted)
1163
+ abort();
1164
+ else
1165
+ socket.write(request);
1166
+ });
1167
+ }
1168
+ async function requestBytes(url, init, signal) {
1169
+ let request;
1170
+ let headers;
1171
+ let body;
1172
+ try {
1173
+ request = new Request(url, { ...init, signal: null });
1174
+ headers = [...request.headers].filter(([name]) => !["host", "content-length", "connection", "transfer-encoding"].includes(name));
1175
+ const read = request.arrayBuffer();
1176
+ body = new Uint8Array(await (signal ? untilAborted(read, signal) : read));
1177
+ } catch (cause) {
1178
+ signal?.throwIfAborted();
1179
+ throw new TelegramNotDispatchedError2("request", "Telegram request body could not be read", {
1180
+ cause
1181
+ });
1182
+ }
1183
+ const head = [
1184
+ `${request.method} ${url.pathname}${url.search} HTTP/1.1`,
1185
+ `Host: ${url.host}`,
1186
+ ...headers.map(([name, value]) => `${name}: ${value}`),
1187
+ `Content-Length: ${body.byteLength}`,
1188
+ "Connection: close",
1189
+ "",
1190
+ ""
1191
+ ].join(`\r
1192
+ `);
1193
+ return { head, body };
1194
+ }
1195
+ function createTelegramBotTransport(options = {}) {
1196
+ const connectAttemptMs = options.connectAttemptMs ?? 2000;
1197
+ const connectBudgetMs = options.connectBudgetMs ?? 5000;
1198
+ const responseTimeoutMs = options.responseTimeoutMs ?? 30000;
1199
+ const maxResponseBytes = options.maxResponseBytes ?? 1024 * 1024;
1200
+ assertPositiveSafeInteger("connectAttemptMs", connectAttemptMs);
1201
+ assertPositiveSafeInteger("connectBudgetMs", connectBudgetMs);
1202
+ assertPositiveSafeInteger("responseTimeoutMs", responseTimeoutMs);
1203
+ assertPositiveSafeInteger("maxResponseBytes", maxResponseBytes);
1204
+ const policy = {
1205
+ resolve: options.resolve ?? resolveAll,
1206
+ open: options.open ?? openSocket,
1207
+ attemptMs: connectAttemptMs,
1208
+ budgetMs: connectBudgetMs
1209
+ };
1210
+ return async (url, init) => {
1211
+ const signal = init.signal ?? undefined;
1212
+ signal?.throwIfAborted();
1213
+ const target = new URL(url);
1214
+ const tls = target.protocol === "https:";
1215
+ if (!tls && target.protocol !== "http:")
1216
+ throw new TelegramNotDispatchedError2("request", `Telegram transport speaks http and https, not ${target.protocol}`);
1217
+ const { head, body } = await requestBytes(target, init, signal);
1218
+ signal?.throwIfAborted();
1219
+ const socket = await establish(target.hostname.replace(/^\[|\]$/g, ""), Number(target.port || (tls ? 443 : 80)), tls, policy, signal);
1220
+ return exchange(socket, Buffer.concat([Buffer.from(head, "latin1"), body]), { maxResponseBytes, responseTimeoutMs }, signal);
1221
+ };
1222
+ }
891
1223
  // src/telegram/update-intake.ts
892
1224
  var SWEEP_BATCH = 100;
893
1225
  function defaultRetry(error, attempt) {
@@ -1524,12 +1856,14 @@ export {
1524
1856
  TelegramBotApiError,
1525
1857
  TelegramBroadcastFailureSchema,
1526
1858
  TelegramLocalFileError,
1859
+ TelegramNotDispatchedError2 as TelegramNotDispatchedError,
1527
1860
  TelegramWebhookClaimError,
1528
1861
  callTelegramBotApi,
1529
1862
  checkTelegramUpdateStore,
1530
1863
  checkTelegramWebhook,
1531
1864
  claimTelegramWebhook,
1532
1865
  classifyTelegramSendFailure2 as classifyTelegramSendFailure,
1866
+ createTelegramBotTransport,
1533
1867
  createTelegramLocalFiles,
1534
1868
  createTelegramOperatorChannel,
1535
1869
  createTelegramOperatorDedupe,
@@ -4,6 +4,7 @@
4
4
  */
5
5
  export * from '../testing/handler-clients.js';
6
6
  export { type ManagedResourceConformanceConfig, type ManagedResourceConformanceControls, ManagedResourceConformanceError, type ManagedResourceConformanceFactoryInput, type ManagedResourceConformanceFixture, type ManagedResourceConformancePhase, ManagedResourceConformancePhaseSchema, type ManagedResourceConformanceScenario, type ManagedResourceConformanceScenarioId, ManagedResourceConformanceScenarioIdSchema, ManagedResourceConformanceScenarioSchema, type ManagedResourceConformanceTraceEntry, ManagedResourceConformanceTraceEntrySchema, type ManagedResourceConformanceTraceOutcome, ManagedResourceConformanceTraceOutcomeSchema, runManagedResourceConformance, } from '../testing/managed-resource-conformance.js';
7
+ export { createManualClock, type ManualClock, ManualClockError, type ManualClockErrorCode, type ManualClockHold, type ManualClockOptions, type ManualClockTimer, type ManualClockUntilOptions, } from '../testing/manual-clock.js';
7
8
  export { type CreateRealtimeProbeDriverConfig, createRealtimeProbeDriver, type DefineRealtimeProbeConfig, defineRealtimeProbe, type RealtimeProbeAdapter, type RealtimeProbeFixture, type RealtimeProbeScenario, } from '../testing/realtime-probe.js';
8
9
  export { assertSurfaceDiscovery, type ConformanceTransport, type RealtimeDisconnectObservation, RealtimeDisconnectObservationSchema, type RealtimeRejectionObservation, RealtimeRejectionObservationSchema, type RunSurfaceProbesConfig, runSurfaceProbes, type SurfaceDiscoveryObservation, type SurfaceProbe, type SurfaceProbeDriver, type SurfaceRealtimeDiscoveryObservation, type SurfaceToolDiscoveryObservation, type TransportObservation, TransportObservationSchema, } from '../testing/surface-conformance.js';
9
10
  export { assertSurfaceManifestSnapshot, buildSurfaceManifest, type IncompatibleSchemaPolicy, type McpSchemaValidationConfig, SURFACE_MANIFEST_VERSION, type SurfaceAgentProjection, type SurfaceManifest, type SurfaceManifestConfig, type SurfaceManifestExtension, SurfaceManifestExtensionSchema, type SurfaceManifestOperation, type SurfaceManifestOperationMcp, SurfaceManifestOperationMcpSchema, SurfaceManifestOperationSchema, type SurfaceManifestOperationToolView, SurfaceManifestOperationToolViewSchema, type SurfaceManifestRealtimeEvent, SurfaceManifestRealtimeEventSchema, SurfaceManifestSchema, type SurfaceManifestTool, SurfaceManifestToolSchema, type SurfaceManifestToolSurface, SurfaceManifestToolSurfaceSchema, type SurfaceMcpPreparation, SurfaceRealtimeSchemaPairSchema, type SurfaceRuntimeToolDefinition, SurfaceSchemaDigestsSchema, type SurfaceToolDefinition, type SurfaceToolExtension, } from '../testing/surface-manifest.js';
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/entrypoints/testing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,4BAA4B,CAAC;AAC3C,OAAO,EACL,KAAK,gCAAgC,EACrC,KAAK,kCAAkC,EACvC,+BAA+B,EAC/B,KAAK,sCAAsC,EAC3C,KAAK,iCAAiC,EACtC,KAAK,+BAA+B,EACpC,qCAAqC,EACrC,KAAK,kCAAkC,EACvC,KAAK,oCAAoC,EACzC,0CAA0C,EAC1C,wCAAwC,EACxC,KAAK,oCAAoC,EACzC,0CAA0C,EAC1C,KAAK,sCAAsC,EAC3C,4CAA4C,EAC5C,6BAA6B,GAC9B,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,KAAK,+BAA+B,EACpC,yBAAyB,EACzB,KAAK,yBAAyB,EAC9B,mBAAmB,EACnB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,GAC3B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,sBAAsB,EACtB,KAAK,oBAAoB,EACzB,KAAK,6BAA6B,EAClC,mCAAmC,EACnC,KAAK,4BAA4B,EACjC,kCAAkC,EAClC,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,KAAK,2BAA2B,EAChC,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,mCAAmC,EACxC,KAAK,+BAA+B,EACpC,KAAK,oBAAoB,EACzB,0BAA0B,GAC3B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,6BAA6B,EAC7B,oBAAoB,EACpB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,wBAAwB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,8BAA8B,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,iCAAiC,EACjC,8BAA8B,EAC9B,KAAK,gCAAgC,EACrC,sCAAsC,EACtC,KAAK,4BAA4B,EACjC,kCAAkC,EAClC,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,gCAAgC,EAChC,KAAK,qBAAqB,EAC1B,+BAA+B,EAC/B,KAAK,4BAA4B,EACjC,0BAA0B,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/entrypoints/testing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,4BAA4B,CAAC;AAC3C,OAAO,EACL,KAAK,gCAAgC,EACrC,KAAK,kCAAkC,EACvC,+BAA+B,EAC/B,KAAK,sCAAsC,EAC3C,KAAK,iCAAiC,EACtC,KAAK,+BAA+B,EACpC,qCAAqC,EACrC,KAAK,kCAAkC,EACvC,KAAK,oCAAoC,EACzC,0CAA0C,EAC1C,wCAAwC,EACxC,KAAK,oCAAoC,EACzC,0CAA0C,EAC1C,KAAK,sCAAsC,EAC3C,4CAA4C,EAC5C,6BAA6B,GAC9B,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,iBAAiB,EACjB,KAAK,WAAW,EAChB,gBAAgB,EAChB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,KAAK,+BAA+B,EACpC,yBAAyB,EACzB,KAAK,yBAAyB,EAC9B,mBAAmB,EACnB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,GAC3B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,sBAAsB,EACtB,KAAK,oBAAoB,EACzB,KAAK,6BAA6B,EAClC,mCAAmC,EACnC,KAAK,4BAA4B,EACjC,kCAAkC,EAClC,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,KAAK,2BAA2B,EAChC,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,mCAAmC,EACxC,KAAK,+BAA+B,EACpC,KAAK,oBAAoB,EACzB,0BAA0B,GAC3B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,6BAA6B,EAC7B,oBAAoB,EACpB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,wBAAwB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,8BAA8B,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,iCAAiC,EACjC,8BAA8B,EAC9B,KAAK,gCAAgC,EACrC,sCAAsC,EACtC,KAAK,4BAA4B,EACjC,kCAAkC,EAClC,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,gCAAgC,EAChC,KAAK,qBAAqB,EAC1B,+BAA+B,EAC/B,KAAK,4BAA4B,EACjC,0BAA0B,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,6BAA6B,CAAC"}
@@ -35,7 +35,10 @@ import"../index-fynr93w4.js";
35
35
  import {
36
36
  createClient2,
37
37
  createClients2
38
- } from "../index-zsqt5q98.js";
38
+ } from "../index-p5kx5vqd.js";
39
+ import {
40
+ assertPositiveSafeInteger
41
+ } from "../index-0s4xebbg.js";
39
42
  import {
40
43
  compareCodeUnits,
41
44
  serializeCanonicalJson
@@ -645,6 +648,131 @@ async function runManagedResourceConformance(config) {
645
648
  await runScenario(config, scenario, watchdogTimeoutMs);
646
649
  }
647
650
  }
651
+ // src/testing/manual-clock.ts
652
+ class ManualClockError extends Error {
653
+ code;
654
+ holds;
655
+ name = "ManualClockError";
656
+ constructor(code, message, holds = []) {
657
+ super(message);
658
+ this.code = code;
659
+ this.holds = holds;
660
+ }
661
+ }
662
+ var DEFAULT_WALL_START = Date.parse("2026-01-01T00:00:00.000Z");
663
+ function createManualClock(options = {}) {
664
+ const startMs = options.startMs ?? 0;
665
+ if (!Number.isFinite(startMs))
666
+ throw new RangeError("startMs must be a finite number");
667
+ const wallStart = options.wallStart?.getTime() ?? DEFAULT_WALL_START;
668
+ if (!Number.isFinite(wallStart))
669
+ throw new RangeError("wallStart must be a valid date");
670
+ const turns = options.yieldTurns ?? 8;
671
+ assertPositiveSafeInteger("yieldTurns", turns);
672
+ const holdLimitMs = options.holdLimitMs ?? 5000;
673
+ assertPositiveSafeInteger("holdLimitMs", holdLimitMs);
674
+ let now = startMs;
675
+ let order = 0;
676
+ let moving = false;
677
+ const timers = new Map;
678
+ const holds = new Map;
679
+ const activeHolds = () => [...holds.values()].filter((hold) => !hold.parked).map((hold) => hold.reason);
680
+ const settle = async () => {
681
+ for (let turn = 0;turn < turns; turn++)
682
+ await new Promise((resolve) => setImmediate(resolve));
683
+ };
684
+ const idle = async () => {
685
+ const started = performance.now();
686
+ for (let open = activeHolds();open.length > 0; open = activeHolds()) {
687
+ if (performance.now() - started > holdLimitMs)
688
+ throw new ManualClockError("MANUAL_CLOCK_HOLD_TIMEOUT", `Manual clock waited ${holdLimitMs} ms of real time for ${open.length} open hold(s): ${open.join(", ")}`, open);
689
+ await new Promise((resolve) => setTimeout(resolve, 0));
690
+ }
691
+ await settle();
692
+ };
693
+ const nextDue = (limit) => {
694
+ let best;
695
+ for (const entry of timers) {
696
+ const [, timer] = entry;
697
+ if (timer.at > limit)
698
+ continue;
699
+ if (!best || timer.at < best[1].at || timer.at === best[1].at && timer.order < best[1].order)
700
+ best = entry;
701
+ }
702
+ return best;
703
+ };
704
+ const move = async (target) => {
705
+ await idle();
706
+ for (let due = nextDue(target);due; due = nextDue(target)) {
707
+ const [id, timer] = due;
708
+ timers.delete(id);
709
+ now = Math.max(now, timer.at);
710
+ timer.callback();
711
+ await idle();
712
+ }
713
+ now = target;
714
+ await idle();
715
+ };
716
+ const clock = {
717
+ now: () => now,
718
+ wallNow: () => new Date(wallStart + (now - startMs)),
719
+ schedule(callback, delayMs) {
720
+ if (Number.isNaN(delayMs))
721
+ throw new RangeError("Timer delay must be a number");
722
+ const id = ++order;
723
+ timers.set(id, { at: now + Math.max(0, delayMs), order: id, callback });
724
+ return { cancel: () => void timers.delete(id) };
725
+ },
726
+ async advance(ms) {
727
+ if (!Number.isFinite(ms) || ms < 0)
728
+ throw new RangeError(`Manual clock cannot advance by ${ms} ms`);
729
+ if (moving)
730
+ throw new Error("Manual clock is already advancing; await that advance first");
731
+ moving = true;
732
+ try {
733
+ await move(now + ms);
734
+ } finally {
735
+ moving = false;
736
+ }
737
+ },
738
+ async until(done, { stepMs = 100, limitMs = 600000 } = {}) {
739
+ assertPositiveSafeInteger("stepMs", stepMs);
740
+ assertPositiveSafeInteger("limitMs", limitMs);
741
+ const from = now;
742
+ await idle();
743
+ while (!done()) {
744
+ if (now - from >= limitMs)
745
+ throw new ManualClockError("MANUAL_CLOCK_LIMIT", `Condition still false after ${now - from} ms of manual time (limit ${limitMs} ms, ${timers.size} timer(s) pending)`);
746
+ const next = nextDue(Number.POSITIVE_INFINITY);
747
+ const jump = next ? Math.max(0, next[1].at - now) : stepMs;
748
+ await clock.advance(Math.min(jump, from + limitMs - now));
749
+ }
750
+ return now - from;
751
+ },
752
+ pending: () => timers.size,
753
+ hold(reason) {
754
+ const id = ++order;
755
+ holds.set(id, { reason, parked: false });
756
+ return {
757
+ release: () => void holds.delete(id),
758
+ park() {
759
+ const hold = holds.get(id);
760
+ if (!hold || hold.parked)
761
+ return () => {
762
+ return;
763
+ };
764
+ hold.parked = true;
765
+ return () => {
766
+ const current = holds.get(id);
767
+ if (current)
768
+ current.parked = false;
769
+ };
770
+ }
771
+ };
772
+ }
773
+ };
774
+ return clock;
775
+ }
648
776
  // src/testing/surface-conformance.ts
649
777
  import { z as z2 } from "zod";
650
778
  var RealtimeRejectionObservationSchema = z2.object({
@@ -1340,6 +1468,7 @@ export {
1340
1468
  ManagedResourceConformanceScenarioSchema,
1341
1469
  ManagedResourceConformanceTraceEntrySchema,
1342
1470
  ManagedResourceConformanceTraceOutcomeSchema,
1471
+ ManualClockError,
1343
1472
  RealtimeDisconnectObservationSchema,
1344
1473
  RealtimeRejectionObservationSchema,
1345
1474
  SURFACE_MANIFEST_VERSION,
@@ -1359,6 +1488,7 @@ export {
1359
1488
  buildSurfaceManifest,
1360
1489
  createHandlerTestClient,
1361
1490
  createHandlerTestClients,
1491
+ createManualClock,
1362
1492
  createRealtimeProbeDriver,
1363
1493
  defineRealtimeProbe,
1364
1494
  runManagedResourceConformance,
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Which Darwin loader an artifact carries: `packaged` (the static loader a packaging plugin
3
+ * wrote), `unpackaged` (the default loader, which refuses the addon inside a bundle) or
4
+ * `no-loader` (nothing in it loads the addon). An artifact with both reads `unpackaged`: one
5
+ * unpackaged loader is enough for its calls to refuse on macOS.
6
+ */
7
+ export type NativeArtifactLoader = 'packaged' | 'unpackaged' | 'no-loader';
8
+ /**
9
+ * Classify a built artifact (a JS bundle or a compiled executable) by the marker every generated
10
+ * loader carries, without running it. Reads the bytes only; builds made before the marker existed
11
+ * (0.107.0 and earlier) read `no-loader`.
12
+ */
13
+ export declare function inspectNativeArtifact(bytes: Uint8Array): NativeArtifactLoader;
14
+ //# sourceMappingURL=native-artifact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-artifact.d.ts","sourceRoot":"","sources":["../../src/files/native-artifact.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG,YAAY,GAAG,WAAW,CAAC;AAW3E;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,GAAG,oBAAoB,CAI7E"}
@@ -57,6 +57,11 @@ export declare function nativeAssetDigest(bytes: Uint8Array): {
57
57
  * second form into the first.
58
58
  */
59
59
  export type NativeLoaderResolution = 'static' | 'beside-loader';
60
+ /**
61
+ * The string a generated loader carries as `module.exports.stitchkitNativeLoader`: `packaged` for
62
+ * the static loader a packaging plugin writes, `unpackaged` for the default beside-loader.
63
+ */
64
+ export declare function nativeLoaderMarker(state: 'packaged' | 'unpackaged'): string;
60
65
  /** One lazy loader for package, companion and embedded delivery. */
61
66
  export declare function nativeLoaderSource(assets: Readonly<Record<string, string>>, resolution: NativeLoaderResolution): string;
62
67
  //# sourceMappingURL=native-packaging-layout.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"native-packaging-layout.d.ts","sourceRoot":"","sources":["../../src/files/native-packaging-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,wGAAwG;AACxG,eAAO,MAAM,kBAAkB,aAU5B,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;;;kBAG7B,CAAC;AAEH,kGAAkG;AAClG,eAAO,MAAM,sBAAsB;;;;kBAIjC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;kBASpC,CAAC;AAEH,wCAAwC;AACxC,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,oGAAoG;AACpG,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAErF;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,eAAe,CAAC;AAQhE,oEAAoE;AACpE,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACxC,UAAU,EAAE,sBAAsB,GACjC,MAAM,CA6CR"}
1
+ {"version":3,"file":"native-packaging-layout.d.ts","sourceRoot":"","sources":["../../src/files/native-packaging-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,wGAAwG;AACxG,eAAO,MAAM,kBAAkB,aAU5B,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;;;kBAG7B,CAAC;AAEH,kGAAkG;AAClG,eAAO,MAAM,sBAAsB;;;;kBAIjC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;kBASpC,CAAC;AAEH,wCAAwC;AACxC,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,oGAAoG;AACpG,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAErF;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,eAAe,CAAC;AAQhE;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY,GAAG,MAAM,CAE3E;AAQD,oEAAoE;AACpE,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACxC,UAAU,EAAE,sBAAsB,GACjC,MAAM,CAiDR"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Structural Bun plugin protocol: declarations need no Bun runtime or ambient types.
3
+ */
4
+ export type NativePackagingPlugin = {
5
+ name: string;
6
+ setup: (build: {
7
+ config: {
8
+ splitting?: boolean;
9
+ naming?: string | {
10
+ entry?: string;
11
+ };
12
+ entrypoints: string[];
13
+ };
14
+ onLoad: (options: {
15
+ filter: RegExp;
16
+ }, callback: (args: {
17
+ path: string;
18
+ }) => {
19
+ contents: string;
20
+ loader: 'js';
21
+ } | {
22
+ contents: Uint8Array;
23
+ loader: 'napi';
24
+ } | undefined) => unknown;
25
+ onResolve: (options: {
26
+ filter: RegExp;
27
+ }, callback: (args: {
28
+ path: string;
29
+ importer: string;
30
+ }) => {
31
+ path: string;
32
+ external: boolean;
33
+ } | undefined) => unknown;
34
+ }) => void;
35
+ };
36
+ /** The installed package a plugin belongs to: its root, its version and its loader file. */
37
+ export interface NativePackagingOwner {
38
+ readonly root: string;
39
+ readonly version: string;
40
+ /** Absolute path of the default loader, as the published manifest names it. */
41
+ readonly loaderPath: string;
42
+ /** The manifest's relative loader path, the suffix every installation's loader shares. */
43
+ readonly loaderName: string;
44
+ }
45
+ /**
46
+ * The one Bun plugin of both deliveries: it swaps its own installation's default loader for a
47
+ * static one, hands Bun the verified bytes of each embedded addon, and keeps companion addons
48
+ * external to a build whose single entry is named exactly `entryPath`. A default loader of any
49
+ * other installation fails the build: the entry imports a `stitchkit` this plugin did not package,
50
+ * and an artifact that carried that loader would refuse the addon at run time.
51
+ */
52
+ export declare function nativePlugin(owner: NativePackagingOwner, specifiers: Readonly<Record<string, string>>, embedded: ReadonlyMap<string, Uint8Array>, companionEntry: string | undefined): NativePackagingPlugin;
53
+ //# sourceMappingURL=native-packaging-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-packaging-plugin.d.ts","sourceRoot":"","sources":["../../src/files/native-packaging-plugin.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,CAAC,KAAK,EAAE;QACb,MAAM,EAAE;YACN,SAAS,CAAC,EAAE,OAAO,CAAC;YACpB,MAAM,CAAC,EAAE,MAAM,GAAG;gBAAE,KAAK,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC;YACrC,WAAW,EAAE,MAAM,EAAE,CAAC;SACvB,CAAC;QACF,MAAM,EAAE,CACN,OAAO,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,EAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE;YACf,IAAI,EAAE,MAAM,CAAC;SACd,KACG;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,IAAI,CAAA;SAAE,GAClC;YAAE,QAAQ,EAAE,UAAU,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,GACxC,SAAS,KACV,OAAO,CAAC;QACb,SAAS,EAAE,CACT,OAAO,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,EAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE;YACf,IAAI,EAAE,MAAM,CAAC;YACb,QAAQ,EAAE,MAAM,CAAC;SAClB,KAAK;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,OAAO,CAAA;SAAE,GAAG,SAAS,KAClD,OAAO,CAAC;KACd,KAAK,IAAI,CAAC;CACZ,CAAC;AAEF,4FAA4F;AAC5F,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,0FAA0F;IAC1F,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAmCD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,oBAAoB,EAC3B,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC5C,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EACzC,cAAc,EAAE,MAAM,GAAG,SAAS,GACjC,qBAAqB,CA8CvB"}