@open-everywhere/adapters 0.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 (156) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +21 -0
  3. package/README.md +43 -0
  4. package/agent/aws/cli.ts +121 -0
  5. package/agent/aws/config.ts +71 -0
  6. package/agent/aws/register.ts +65 -0
  7. package/agent/aws/sso.ts +567 -0
  8. package/agent/aws/sts.ts +191 -0
  9. package/agent/blob/hosting.ts +24 -0
  10. package/agent/browser/config.ts +62 -0
  11. package/agent/browser/register.ts +66 -0
  12. package/agent/browser/sandbox.ts +39 -0
  13. package/agent/contributions.ts +12 -0
  14. package/agent/directory/config.ts +138 -0
  15. package/agent/directory/okta.ts +226 -0
  16. package/agent/directory/register.ts +16 -0
  17. package/agent/instrumentation.ts +42 -0
  18. package/agent/model/approval-judge.ts +57 -0
  19. package/agent/model/dream-judge.ts +105 -0
  20. package/agent/model/gateway-vision.ts +162 -0
  21. package/agent/model/gateway.ts +85 -0
  22. package/agent/oe-oauth/config.ts +246 -0
  23. package/agent/oe-oauth/errors.ts +77 -0
  24. package/agent/oe-oauth/oauth-client.ts +376 -0
  25. package/agent/oe-oauth/pkce.ts +21 -0
  26. package/agent/oe-oauth/register.ts +32 -0
  27. package/agent/oe-oauth/token-vault.ts +652 -0
  28. package/agent/oe-oauth/user-auth-flow.ts +76 -0
  29. package/agent/postgres/neon.ts +108 -0
  30. package/agent/sandbox/backend-stop.ts +259 -0
  31. package/agent/sandbox/created-sandbox-registry.ts +27 -0
  32. package/agent/sandbox/extend-workspace-time.ts +77 -0
  33. package/agent/sandbox/vercel-lifecycle.ts +252 -0
  34. package/dist/agent/aws/cli.d.ts +24 -0
  35. package/dist/agent/aws/cli.d.ts.map +1 -0
  36. package/dist/agent/aws/cli.js +89 -0
  37. package/dist/agent/aws/cli.js.map +1 -0
  38. package/dist/agent/aws/config.d.ts +27 -0
  39. package/dist/agent/aws/config.d.ts.map +1 -0
  40. package/dist/agent/aws/config.js +46 -0
  41. package/dist/agent/aws/config.js.map +1 -0
  42. package/dist/agent/aws/register.d.ts +23 -0
  43. package/dist/agent/aws/register.d.ts.map +1 -0
  44. package/dist/agent/aws/register.js +39 -0
  45. package/dist/agent/aws/register.js.map +1 -0
  46. package/dist/agent/aws/sso.d.ts +109 -0
  47. package/dist/agent/aws/sso.d.ts.map +1 -0
  48. package/dist/agent/aws/sso.js +421 -0
  49. package/dist/agent/aws/sso.js.map +1 -0
  50. package/dist/agent/aws/sts.d.ts +27 -0
  51. package/dist/agent/aws/sts.d.ts.map +1 -0
  52. package/dist/agent/aws/sts.js +135 -0
  53. package/dist/agent/aws/sts.js.map +1 -0
  54. package/dist/agent/blob/hosting.d.ts +4 -0
  55. package/dist/agent/blob/hosting.d.ts.map +1 -0
  56. package/dist/agent/blob/hosting.js +20 -0
  57. package/dist/agent/blob/hosting.js.map +1 -0
  58. package/dist/agent/browser/config.d.ts +24 -0
  59. package/dist/agent/browser/config.d.ts.map +1 -0
  60. package/dist/agent/browser/config.js +50 -0
  61. package/dist/agent/browser/config.js.map +1 -0
  62. package/dist/agent/browser/register.d.ts +7 -0
  63. package/dist/agent/browser/register.d.ts.map +1 -0
  64. package/dist/agent/browser/register.js +47 -0
  65. package/dist/agent/browser/register.js.map +1 -0
  66. package/dist/agent/browser/sandbox.d.ts +23 -0
  67. package/dist/agent/browser/sandbox.d.ts.map +1 -0
  68. package/dist/agent/browser/sandbox.js +27 -0
  69. package/dist/agent/browser/sandbox.js.map +1 -0
  70. package/dist/agent/contributions.d.ts +16 -0
  71. package/dist/agent/contributions.d.ts.map +1 -0
  72. package/dist/agent/contributions.js +11 -0
  73. package/dist/agent/contributions.js.map +1 -0
  74. package/dist/agent/directory/config.d.ts +39 -0
  75. package/dist/agent/directory/config.d.ts.map +1 -0
  76. package/dist/agent/directory/config.js +101 -0
  77. package/dist/agent/directory/config.js.map +1 -0
  78. package/dist/agent/directory/okta.d.ts +19 -0
  79. package/dist/agent/directory/okta.d.ts.map +1 -0
  80. package/dist/agent/directory/okta.js +178 -0
  81. package/dist/agent/directory/okta.js.map +1 -0
  82. package/dist/agent/directory/register.d.ts +6 -0
  83. package/dist/agent/directory/register.d.ts.map +1 -0
  84. package/dist/agent/directory/register.js +16 -0
  85. package/dist/agent/directory/register.js.map +1 -0
  86. package/dist/agent/instrumentation.d.ts +5 -0
  87. package/dist/agent/instrumentation.d.ts.map +1 -0
  88. package/dist/agent/instrumentation.js +39 -0
  89. package/dist/agent/instrumentation.js.map +1 -0
  90. package/dist/agent/model/approval-judge.d.ts +15 -0
  91. package/dist/agent/model/approval-judge.d.ts.map +1 -0
  92. package/dist/agent/model/approval-judge.js +46 -0
  93. package/dist/agent/model/approval-judge.js.map +1 -0
  94. package/dist/agent/model/dream-judge.d.ts +40 -0
  95. package/dist/agent/model/dream-judge.d.ts.map +1 -0
  96. package/dist/agent/model/dream-judge.js +80 -0
  97. package/dist/agent/model/dream-judge.js.map +1 -0
  98. package/dist/agent/model/gateway-vision.d.ts +53 -0
  99. package/dist/agent/model/gateway-vision.d.ts.map +1 -0
  100. package/dist/agent/model/gateway-vision.js +129 -0
  101. package/dist/agent/model/gateway-vision.js.map +1 -0
  102. package/dist/agent/model/gateway.d.ts +30 -0
  103. package/dist/agent/model/gateway.d.ts.map +1 -0
  104. package/dist/agent/model/gateway.js +55 -0
  105. package/dist/agent/model/gateway.js.map +1 -0
  106. package/dist/agent/oe-oauth/config.d.ts +69 -0
  107. package/dist/agent/oe-oauth/config.d.ts.map +1 -0
  108. package/dist/agent/oe-oauth/config.js +182 -0
  109. package/dist/agent/oe-oauth/config.js.map +1 -0
  110. package/dist/agent/oe-oauth/errors.d.ts +63 -0
  111. package/dist/agent/oe-oauth/errors.d.ts.map +1 -0
  112. package/dist/agent/oe-oauth/errors.js +73 -0
  113. package/dist/agent/oe-oauth/errors.js.map +1 -0
  114. package/dist/agent/oe-oauth/oauth-client.d.ts +124 -0
  115. package/dist/agent/oe-oauth/oauth-client.d.ts.map +1 -0
  116. package/dist/agent/oe-oauth/oauth-client.js +262 -0
  117. package/dist/agent/oe-oauth/oauth-client.js.map +1 -0
  118. package/dist/agent/oe-oauth/pkce.d.ts +8 -0
  119. package/dist/agent/oe-oauth/pkce.d.ts.map +1 -0
  120. package/dist/agent/oe-oauth/pkce.js +18 -0
  121. package/dist/agent/oe-oauth/pkce.js.map +1 -0
  122. package/dist/agent/oe-oauth/register.d.ts +17 -0
  123. package/dist/agent/oe-oauth/register.d.ts.map +1 -0
  124. package/dist/agent/oe-oauth/register.js +24 -0
  125. package/dist/agent/oe-oauth/register.js.map +1 -0
  126. package/dist/agent/oe-oauth/token-vault.d.ts +107 -0
  127. package/dist/agent/oe-oauth/token-vault.d.ts.map +1 -0
  128. package/dist/agent/oe-oauth/token-vault.js +498 -0
  129. package/dist/agent/oe-oauth/token-vault.js.map +1 -0
  130. package/dist/agent/oe-oauth/user-auth-flow.d.ts +10 -0
  131. package/dist/agent/oe-oauth/user-auth-flow.d.ts.map +1 -0
  132. package/dist/agent/oe-oauth/user-auth-flow.js +66 -0
  133. package/dist/agent/oe-oauth/user-auth-flow.js.map +1 -0
  134. package/dist/agent/postgres/neon.d.ts +29 -0
  135. package/dist/agent/postgres/neon.d.ts.map +1 -0
  136. package/dist/agent/postgres/neon.js +76 -0
  137. package/dist/agent/postgres/neon.js.map +1 -0
  138. package/dist/agent/sandbox/backend-stop.d.ts +98 -0
  139. package/dist/agent/sandbox/backend-stop.d.ts.map +1 -0
  140. package/dist/agent/sandbox/backend-stop.js +188 -0
  141. package/dist/agent/sandbox/backend-stop.js.map +1 -0
  142. package/dist/agent/sandbox/created-sandbox-registry.d.ts +15 -0
  143. package/dist/agent/sandbox/created-sandbox-registry.d.ts.map +1 -0
  144. package/dist/agent/sandbox/created-sandbox-registry.js +26 -0
  145. package/dist/agent/sandbox/created-sandbox-registry.js.map +1 -0
  146. package/dist/agent/sandbox/extend-workspace-time.d.ts +31 -0
  147. package/dist/agent/sandbox/extend-workspace-time.d.ts.map +1 -0
  148. package/dist/agent/sandbox/extend-workspace-time.js +63 -0
  149. package/dist/agent/sandbox/extend-workspace-time.js.map +1 -0
  150. package/dist/agent/sandbox/vercel-lifecycle.d.ts +38 -0
  151. package/dist/agent/sandbox/vercel-lifecycle.d.ts.map +1 -0
  152. package/dist/agent/sandbox/vercel-lifecycle.js +244 -0
  153. package/dist/agent/sandbox/vercel-lifecycle.js.map +1 -0
  154. package/package.json +204 -0
  155. package/tsconfig.build.json +22 -0
  156. package/tsconfig.json +22 -0
@@ -0,0 +1,178 @@
1
+ // THE OKTA DIRECTORY ADAPTER — everything it returns is a PROPOSAL, and nothing here confirms a link. The
2
+ // grade follows the field: `externalId` is attested (the SCIM write-back), `credentials.userName` asserted.
3
+ import { getSecretVia } from "@open-everywhere/core/agent/adapter-api.js";
4
+ /** Okta user statuses that mean "this person is deactivated". Everything else (ACTIVE, PROVISIONED,
5
+ * STAGED, RECOVERY, LOCKED_OUT, PASSWORD_EXPIRED) is a live human with an access problem, not a
6
+ * departed one — and treating a locked-out person as deprovisioned would suspend their identity
7
+ * every time they fat-fingered a password. */
8
+ const DEPROVISIONED_STATUSES = new Set(["DEPROVISIONED", "SUSPENDED"]);
9
+ /** Page size. Okta's `/users` and `/groups` cap at 200; `/apps/{id}/users` allows 500. Asking for
10
+ * the max is what keeps a small org to one round trip per resource. */
11
+ const PAGE_LIMIT = 200;
12
+ const APP_PAGE_LIMIT = 500;
13
+ /** A hard cap on pages followed per resource — a runaway `Link: rel="next"` loop (a proxy rewriting
14
+ * the header, a vendor bug) must not spin forever inside a scheduled tick. 200 pages ≈ 40k users. */
15
+ const MAX_PAGES = 200;
16
+ /** The display name to show a human, from whichever profile fields Okta actually filled in. DISPLAY
17
+ * ONLY — link-store.ts invariant 4 means it can never become a lookup key, here or downstream. */
18
+ function displayNameOf(user) {
19
+ const p = user.profile ?? {};
20
+ const full = [p.firstName, p.lastName].filter(Boolean).join(" ").trim();
21
+ return p.displayName?.trim() || full || p.login?.trim() || p.email?.trim() || user.id || "unknown";
22
+ }
23
+ /**
24
+ * The `rel="next"` URL from the RFC-5988 `Link` header. Okta paginates with an opaque cursor and no total
25
+ * count, so following the header is the ONLY correct way to page — an offset would truncate or duplicate.
26
+ */
27
+ export function nextLink(header) {
28
+ if (!header)
29
+ return undefined;
30
+ for (const part of header.split(",")) {
31
+ const m = /^\s*<([^>]+)>\s*;\s*(.+)$/u.exec(part);
32
+ if (m && /\brel\s*=\s*"?next"?/u.test(m[2]))
33
+ return m[1];
34
+ }
35
+ return undefined;
36
+ }
37
+ /** Build the Okta directory provider. Every edge is injected, so the whole mapping is offline-testable. */
38
+ export function makeOktaDirectoryProvider(deps) {
39
+ const { config } = deps;
40
+ const fetchImpl = deps.fetch ?? fetch;
41
+ const resolveToken = deps.resolveToken ?? ((broker, ref) => getSecretVia(broker, ref));
42
+ // The operator's OWN Okta origin — the ONLY origin the SSWS token may ever be sent to. Computed
43
+ // once; every request in getAll (the first AND every `Link: rel="next"` hop) is checked against it.
44
+ const orgOrigin = new URL(config.orgUrl).origin;
45
+ /** One authenticated GET, following `Link: rel="next"` to the end. Returns the concatenated pages. */
46
+ async function getAll(path, token) {
47
+ let url = path.startsWith("http") ? path : `${config.orgUrl}${path}`;
48
+ const out = [];
49
+ for (let page = 0; url && page < MAX_PAGES; page++) {
50
+ // 🔴 SAME-ORIGIN OR REFUSE: a `Link: rel="next"` is an absolute URL, and this request carries the SSWS token
51
+ // in its header. Any cross-origin URL, initial or paginated, is refused before the fetch.
52
+ let reqOrigin;
53
+ try {
54
+ reqOrigin = new URL(url).origin;
55
+ }
56
+ catch {
57
+ throw new Error(`Okta pagination produced an unparseable URL — refusing to send the API token to it.`);
58
+ }
59
+ if (reqOrigin !== orgOrigin) {
60
+ throw new Error(`Okta pagination tried to leave the org origin (${reqOrigin} ≠ ${orgOrigin}) — refusing to send the SSWS token off ${orgOrigin}.`);
61
+ }
62
+ let res;
63
+ try {
64
+ res = await fetchImpl(url, {
65
+ method: "GET",
66
+ // Okta paginates by the Link header, NEVER a 3xx — so a redirect is unexpected, and
67
+ // FOLLOWING one could carry the token to the redirect target. Error out instead (F6).
68
+ redirect: "error",
69
+ headers: { authorization: `SSWS ${token}`, accept: "application/json" },
70
+ });
71
+ }
72
+ catch (err) {
73
+ // The URL is safe to name (it is the operator's own org); the token is not, and never
74
+ // appears in a message raised from here.
75
+ throw new Error(`Okta request to ${url} failed: ${err instanceof Error ? err.message : String(err)}`);
76
+ }
77
+ if (!res.ok) {
78
+ let detail = "";
79
+ try {
80
+ const body = (await res.json());
81
+ detail = [body.errorCode, body.errorSummary].filter(Boolean).join(" — ");
82
+ }
83
+ catch {
84
+ /* non-JSON error body: the status alone is the whole message */
85
+ }
86
+ throw new Error(`Okta ${res.status} for ${url}${detail ? ` — ${detail}` : ""}`);
87
+ }
88
+ const body = (await res.json());
89
+ if (Array.isArray(body))
90
+ out.push(...body);
91
+ url = nextLink(res.headers.get("link"));
92
+ }
93
+ return out;
94
+ }
95
+ /**
96
+ * Okta user id → the IdP group NAMES they belong to. GROUP-FIRST: its cost is O(groups), where a per-user
97
+ * shape costs one round trip per person against Okta's org-wide rate limit.
98
+ */
99
+ async function groupsByUser(token) {
100
+ const byUser = new Map();
101
+ const groups = await getAll(`/api/v1/groups?limit=${PAGE_LIMIT}`, token);
102
+ for (const group of groups) {
103
+ const name = group.profile?.name?.trim();
104
+ if (!group.id || !name)
105
+ continue;
106
+ const members = await getAll(`/api/v1/groups/${encodeURIComponent(group.id)}/users?limit=${PAGE_LIMIT}`, token);
107
+ for (const m of members) {
108
+ if (!m.id)
109
+ continue;
110
+ const list = byUser.get(m.id) ?? [];
111
+ list.push(name);
112
+ byUser.set(m.id, list);
113
+ }
114
+ }
115
+ return byUser;
116
+ }
117
+ /** Okta user id → the platform accounts the mapped apps provision for them. */
118
+ async function accountsByUser(token) {
119
+ const byUser = new Map();
120
+ for (const app of config.apps) {
121
+ const assignments = await getAll(`/api/v1/apps/${encodeURIComponent(app.appId)}/users?limit=${APP_PAGE_LIMIT}`, token);
122
+ for (const a of assignments) {
123
+ if (!a.id)
124
+ continue;
125
+ // A deprovisioned ASSIGNMENT is not a mapping any more. (It is also not evidence that the
126
+ // person is gone — that is the user's own status — so it only ever removes this one
127
+ // proposal, and never proposes an unlink: absence is not evidence.)
128
+ if (a.status && DEPROVISIONED_STATUSES.has(a.status.toUpperCase()))
129
+ continue;
130
+ const nativeId = appSideId(a, app);
131
+ if (!nativeId)
132
+ continue;
133
+ const list = byUser.get(a.id) ?? [];
134
+ // THE GRADE IS A FUNCTION OF WHICH FIELD WAS READ, and of nothing else. The workspace comes off the APP MAP —
135
+ // the operator's own env, never anything Okta said; omitted keeps the sole-admitted-workspace meaning.
136
+ list.push({ platform: app.platform, ...(app.tenant ? { tenant: app.tenant } : {}), nativeId, grade: app.field === "userName" ? "asserted" : "attested" });
137
+ byUser.set(a.id, list);
138
+ }
139
+ }
140
+ return byUser;
141
+ }
142
+ return {
143
+ id: "okta",
144
+ name: `Okta (${config.orgUrl})`,
145
+ async listPeople() {
146
+ // Resolved ONCE per sync, through the broker, and held only for the duration of this call.
147
+ const token = await resolveToken(config.tokenBroker, config.tokenRef);
148
+ const users = await getAll(`/api/v1/users?limit=${PAGE_LIMIT}`, token);
149
+ const groups = await groupsByUser(token);
150
+ const accounts = await accountsByUser(token);
151
+ const people = [];
152
+ for (const user of users) {
153
+ if (!user.id)
154
+ continue;
155
+ const email = user.profile?.email?.trim();
156
+ people.push({
157
+ externalId: user.id,
158
+ displayName: displayNameOf(user),
159
+ ...(email ? { email } : {}),
160
+ accounts: accounts.get(user.id) ?? [],
161
+ groups: (groups.get(user.id) ?? []).slice().sort(),
162
+ deprovisioned: DEPROVISIONED_STATUSES.has((user.status ?? "").toUpperCase()),
163
+ });
164
+ }
165
+ return people;
166
+ },
167
+ };
168
+ }
169
+ /**
170
+ * The app-side identity for one assignment, per the app's configured field. Empty ⇒ no mapping, NEVER a
171
+ * fallback to another field: the grade contract rests on which field was read.
172
+ */
173
+ function appSideId(assignment, app) {
174
+ const raw = app.field === "userName" ? assignment.credentials?.userName : assignment.externalId;
175
+ const trimmed = raw?.trim();
176
+ return trimmed ? trimmed : undefined;
177
+ }
178
+ //# sourceMappingURL=okta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"okta.js","sourceRoot":"","sources":["../../../agent/directory/okta.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Arm the directory adapter if this deployment selected one; returns the registered provider id, or null.
3
+ * FAIL-LOUD on a half-configured selection — silence would look like an IdP with nothing to say.
4
+ */
5
+ export declare function registerDirectoryAdapter(): string | null;
6
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../agent/directory/register.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,GAAG,IAAI,CAIxD"}
@@ -0,0 +1,16 @@
1
+ // Boot wiring for the directory plane: register ONLY when the selector names a provider AND its config block
2
+ // loads. Selector-off ⇒ nothing registers, and the whole feature is cleanly off.
3
+ import { registerDirectoryProvider } from "@open-everywhere/core/agent/adapter-api.js";
4
+ import { loadOktaDirectoryConfig, oktaDirectoryEnabled } from "./config.js";
5
+ import { makeOktaDirectoryProvider } from "./okta.js";
6
+ /**
7
+ * Arm the directory adapter if this deployment selected one; returns the registered provider id, or null.
8
+ * FAIL-LOUD on a half-configured selection — silence would look like an IdP with nothing to say.
9
+ */
10
+ export function registerDirectoryAdapter() {
11
+ if (!oktaDirectoryEnabled())
12
+ return null;
13
+ registerDirectoryProvider(makeOktaDirectoryProvider({ config: loadOktaDirectoryConfig() }));
14
+ return "okta";
15
+ }
16
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../../agent/directory/register.ts"],"names":[],"mappings":"AAAA,6GAA6G;AAC7G,iFAAiF;AAEjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AAEtD;;;GAGG;AACH,MAAM,UAAU,wBAAwB;IACtC,IAAI,CAAC,oBAAoB,EAAE;QAAE,OAAO,IAAI,CAAC;IACzC,yBAAyB,CAAC,yBAAyB,CAAC,EAAE,MAAM,EAAE,uBAAuB,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5F,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,5 @@
1
+ declare const _default: import("eve/instrumentation").InstrumentationDeclaration<{
2
+ readonly setup: ({ agentName }: import("eve/instrumentation").ProviderSetupContext) => void;
3
+ }>;
4
+ export default _default;
5
+ //# sourceMappingURL=instrumentation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../agent/instrumentation.ts"],"names":[],"mappings":""}
@@ -0,0 +1,39 @@
1
+ // OpenTelemetry tracing through eve's instrumentation seam; the vendor SDK is why this lives in adapters.
2
+ // A provider registers only when a collector is configured, and NO model input or output reaches a span.
3
+ // eve's `defineInstrumentation` accepts `recordInputs` and `recordOutputs`; it normalises each as
4
+ // `=== true`, so an absent field reads FALSE. This adapter sets neither, so enabling model content
5
+ // takes action — suppressing it does not. A fork that sets them true still meets eve's audience
6
+ // ceiling (`applyAudienceCeiling`, eve `shared/instrumentation-content.js`), which forces both off
7
+ // for every channel whose audience is not `public` (an `unknown` audience records only inside eve's
8
+ // own dev environment).
9
+ import { defineInstrumentation } from "eve/instrumentation";
10
+ import { registerOTel } from "@vercel/otel";
11
+ import { installLogShipping, initTelemetry } from "@open-everywhere/core/agent/adapter-api.js";
12
+ /**
13
+ * A collector is configured when a standard OTLP endpoint env var is set, or when running on Vercel, where
14
+ * `registerOTel` auto-wires the built-in collector. Neither holds locally or in CI.
15
+ */
16
+ function collectorConfigured() {
17
+ return Boolean(process.env.OTEL_EXPORTER_OTLP_ENDPOINT ||
18
+ process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||
19
+ process.env.VERCEL);
20
+ }
21
+ export default defineInstrumentation({
22
+ setup({ agentName }) {
23
+ // Structured log shipping (vendor-neutral HTTP ingest; core seam). Independent of
24
+ // the OTel collector check below: it has its own env gate (OE_LOG_SHIP_URL) and is
25
+ // a full no-op — console untouched — when that is unset.
26
+ installLogShipping();
27
+ // Anonymous usage telemetry (default ON; core seam, own env gate — OE_TELEMETRY/
28
+ // DO_NOT_TRACK). Prints the boot disclosure line before anything is transmitted;
29
+ // fire-and-forget (this callback is synchronous, must never block boot).
30
+ initTelemetry();
31
+ if (!collectorConfigured())
32
+ return;
33
+ // serviceName = the agent name from `defineAgent`, per Eve's guidance. Exporter
34
+ // wiring (endpoint, headers, protocol) comes from the standard `OTEL_EXPORTER_OTLP_*`
35
+ // env vars that `@vercel/otel` reads.
36
+ registerOTel({ serviceName: agentName });
37
+ },
38
+ });
39
+ //# sourceMappingURL=instrumentation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../agent/instrumentation.ts"],"names":[],"mappings":"AAAA,0GAA0G;AAC1G,yGAAyG;AACzG,kGAAkG;AAClG,mGAAmG;AACnG,gGAAgG;AAChG,mGAAmG;AACnG,oGAAoG;AACpG,wBAAwB;AAExB,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAE/F;;;GAGG;AACH,SAAS,mBAAmB;IAC1B,OAAO,OAAO,CACZ,OAAO,CAAC,GAAG,CAAC,2BAA2B;QACrC,OAAO,CAAC,GAAG,CAAC,kCAAkC;QAC9C,OAAO,CAAC,GAAG,CAAC,MAAM,CACrB,CAAC;AACJ,CAAC;AAED,eAAe,qBAAqB,CAAC;IACnC,KAAK,CAAC,EAAE,SAAS,EAAE;QACjB,kFAAkF;QAClF,mFAAmF;QACnF,yDAAyD;QACzD,kBAAkB,EAAE,CAAC;QACrB,iFAAiF;QACjF,iFAAiF;QACjF,yEAAyE;QACzE,aAAa,EAAE,CAAC;QAChB,IAAI,CAAC,mBAAmB,EAAE;YAAE,OAAO;QACnC,gFAAgF;QAChF,sFAAsF;QACtF,sCAAsC;QACtC,YAAY,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC;IAC3C,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { type JudgePass } from "@open-everywhere/core/agent/adapter-api.js";
2
+ import { type GatewayRoutedDefaults } from "./gateway.js";
3
+ /** Map one pass onto its call settings. Pure — exported for tests (no network call needed to
4
+ * assert the pass split), mirroring dreamCallSettings. */
5
+ export declare function approvalJudgeCallSettings(pass: JudgePass, defaults: GatewayRoutedDefaults): {
6
+ id: string;
7
+ maxOutputTokens?: number;
8
+ providerOptions?: Record<string, unknown>;
9
+ };
10
+ /**
11
+ * Build and register the gateway judge transport at boot. Without it the judge answers `defer` everywhere;
12
+ * registration IS the transport opt-in, and arming is separate (approvals.judgeMode, default off).
13
+ */
14
+ export declare function registerGatewayApprovalJudge(defaults: GatewayRoutedDefaults): void;
15
+ //# sourceMappingURL=approval-judge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-judge.d.ts","sourceRoot":"","sources":["../../../agent/model/approval-judge.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,SAAS,EAEf,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAuB,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAQ/E;2DAC2D;AAC3D,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,qBAAqB,GAC9B;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAOrF;AAqBD;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI,CAElF"}
@@ -0,0 +1,46 @@
1
+ // Gateway transport for the approval judge — core owns the seam; this owns the vendor call on the fixed
2
+ // `judge` model role. NO scope routing: the judge must not inherit whatever a domain routed its seat onto.
3
+ import { gateway, generateText } from "ai";
4
+ import { registerApprovalJudgeCompletion, } from "@open-everywhere/core/agent/adapter-api.js";
5
+ import { applyGatewayOptions } from "./gateway.js";
6
+ /**
7
+ * Output budget for the scrutiny pass. A reasoning model spends reasoning tokens INSIDE the budget, so a
8
+ * tight cap truncates to empty text (live 2026-08-08: 16 produced empty completions). 512 costs ~nothing.
9
+ */
10
+ const SCRUTINY_MAX_OUTPUT_TOKENS = 512;
11
+ /** Map one pass onto its call settings. Pure — exported for tests (no network call needed to
12
+ * assert the pass split), mirroring dreamCallSettings. */
13
+ export function approvalJudgeCallSettings(pass, defaults) {
14
+ const options = applyGatewayOptions({}, {}, { id: defaults.id, defaultId: defaults.id }, defaults.gateway);
15
+ return {
16
+ id: defaults.id,
17
+ ...(pass === "scrutiny" ? { maxOutputTokens: SCRUTINY_MAX_OUTPUT_TOKENS } : {}),
18
+ ...(options.providerOptions !== undefined ? { providerOptions: options.providerOptions } : {}),
19
+ };
20
+ }
21
+ /**
22
+ * The gateway-backed judge completion. It DOES NOT touch the model stamp: the judge can run DETACHED from
23
+ * the turn, and a concurrent save and restore races the seat for the single per-session slot.
24
+ */
25
+ function gatewayApprovalJudgeCompletion(defaults) {
26
+ return async (prompt, pass) => {
27
+ const s = approvalJudgeCallSettings(pass, defaults);
28
+ const { text } = await generateText({
29
+ model: gateway(s.id),
30
+ prompt,
31
+ ...(s.maxOutputTokens !== undefined ? { maxOutputTokens: s.maxOutputTokens } : {}),
32
+ ...(s.providerOptions !== undefined
33
+ ? { providerOptions: s.providerOptions }
34
+ : {}),
35
+ });
36
+ return text;
37
+ };
38
+ }
39
+ /**
40
+ * Build and register the gateway judge transport at boot. Without it the judge answers `defer` everywhere;
41
+ * registration IS the transport opt-in, and arming is separate (approvals.judgeMode, default off).
42
+ */
43
+ export function registerGatewayApprovalJudge(defaults) {
44
+ registerApprovalJudgeCompletion(gatewayApprovalJudgeCompletion(defaults));
45
+ }
46
+ //# sourceMappingURL=approval-judge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-judge.js","sourceRoot":"","sources":["../../../agent/model/approval-judge.ts"],"names":[],"mappings":"AAAA,wGAAwG;AACxG,2GAA2G;AAE3G,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC3C,OAAO,EAGL,+BAA+B,GAChC,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAA8B,MAAM,cAAc,CAAC;AAE/E;;;GAGG;AACH,MAAM,0BAA0B,GAAG,GAAG,CAAC;AAEvC;2DAC2D;AAC3D,MAAM,UAAU,yBAAyB,CACvC,IAAe,EACf,QAA+B;IAE/B,MAAM,OAAO,GAAG,mBAAmB,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3G,OAAO;QACL,EAAE,EAAE,QAAQ,CAAC,EAAE;QACf,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,0BAA0B,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,GAAG,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/F,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,8BAA8B,CAAC,QAA+B;IACrE,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;QAC5B,MAAM,CAAC,GAAG,yBAAyB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACpD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,YAAY,CAAC;YAClC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YACpB,MAAM;YACN,GAAG,CAAC,CAAC,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClF,GAAG,CAAC,CAAC,CAAC,eAAe,KAAK,SAAS;gBACjC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,eAAwE,EAAE;gBACjG,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAAC,QAA+B;IAC1E,+BAA+B,CAAC,8BAA8B,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { type ModelRoute, type DreamJudge } from "@open-everywhere/core/agent/adapter-api.js";
2
+ import { type GatewayRoutedDefaults } from "./gateway.js";
3
+ /**
4
+ * The effective `utility` route for a dream scope (channel key | silo name | other).
5
+ * Pure given the registered config; {} (→ static defaults) when config isn't registered
6
+ * or nothing routes. Exported for tests.
7
+ */
8
+ export declare function utilityRouteForScope(scope: string): ModelRoute;
9
+ /**
10
+ * Map a resolved route onto one completion call: the gateway model id, the reasoning
11
+ * effort, and the call's `providerOptions.gateway` (via the same pin/posture rules as
12
+ * the routed turn model — applyGatewayOptions). Pure — exported for tests.
13
+ */
14
+ export declare function dreamCallSettings(route: ModelRoute, defaults: GatewayRoutedDefaults): {
15
+ id: string;
16
+ reasoning?: ModelRoute["reasoning"];
17
+ providerOptions?: Record<string, unknown>;
18
+ };
19
+ /**
20
+ * dreamCallSettings plus the model-stamp side effect, split out so a test exercises the stamp with no network.
21
+ * Whether the stamp LANDS depends on the caller: the cron-fired tidy pass has no session, so it no-ops.
22
+ */
23
+ export declare function resolvedDreamCallSettings(scope: string, defaults: GatewayRoutedDefaults): {
24
+ id: string;
25
+ reasoning?: ModelRoute["reasoning"];
26
+ providerOptions?: Record<string, unknown>;
27
+ };
28
+ /** The gateway-backed DreamJudge — core's fail-quiet skeleton over the completion above. */
29
+ export declare function gatewayDreamJudge(defaults: GatewayRoutedDefaults): DreamJudge;
30
+ /**
31
+ * Convenience for agent.ts: build + register the gateway judge at boot. Without this
32
+ * call the dream cycle runs its zero-LLM v1 heuristics — registration IS the v2 opt-in.
33
+ */
34
+ export declare function registerGatewayDreamJudge(defaults: GatewayRoutedDefaults): void;
35
+ /**
36
+ * Build and register the Mode-3 failure-facet judge at boot, on the SAME completion this module already
37
+ * builds. Without it the weekly digest falls back to static facets — registration IS the opt-in.
38
+ */
39
+ export declare function registerGatewayFailureFacetJudge(defaults: GatewayRoutedDefaults): void;
40
+ //# sourceMappingURL=dream-judge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dream-judge.d.ts","sourceRoot":"","sources":["../../../agent/model/dream-judge.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,UAAU,EAMf,KAAK,UAAU,EAMhB,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAuB,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE/E;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAc9D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,qBAAqB,GAC9B;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAIhG;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,qBAAqB,GAC9B;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAIhG;AAkBD,4FAA4F;AAC5F,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,UAAU,CAE7E;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI,CAE/E;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI,CAEtF"}
@@ -0,0 +1,80 @@
1
+ // Gateway transport for the dream judge — core owns the seam; this owns one completion on the `utility`
2
+ // role. The SCOPE locates the route: a channel key, a silo's owning domain, else `org`. It FAILS QUIET.
3
+ import { gateway, generateText } from "ai";
4
+ import { modelRouteFor, memoryRefs, domainRoster, getConfig, judgeFromCompletion, registerDreamJudge, facetJudgeFromCompletion, registerFailureFacetJudge, stampModelCall, } from "@open-everywhere/core/agent/adapter-api.js";
5
+ import { applyGatewayOptions } from "./gateway.js";
6
+ /**
7
+ * The effective `utility` route for a dream scope (channel key | silo name | other).
8
+ * Pure given the registered config; {} (→ static defaults) when config isn't registered
9
+ * or nothing routes. Exported for tests.
10
+ */
11
+ export function utilityRouteForScope(scope) {
12
+ try {
13
+ const domains = getConfig().loadDomains();
14
+ // Role presets rung in here exactly as they do on the live turn path (item 26) —
15
+ // a role that presets a `utility` route governs the dream judge for its domains too.
16
+ const roles = getConfig().loadRoles?.() ?? [];
17
+ if (domains.some((d) => domainRoster(d).includes(scope)))
18
+ return modelRouteFor("utility", scope, domains, roles);
19
+ const owner = domains.find((d) => memoryRefs(d).includes(scope) && domainRoster(d).length > 0);
20
+ // An unknown/unowned scope key matches no explicit domain, so modelRouteFor yields
21
+ // the `org` pseudo-domain layer alone — exactly the wanted fallback.
22
+ return modelRouteFor("utility", owner ? (domainRoster(owner)[0] ?? scope) : scope, domains, roles);
23
+ }
24
+ catch {
25
+ return {}; // config not registered (tests, cold paths) → static defaults, fail quiet
26
+ }
27
+ }
28
+ /**
29
+ * Map a resolved route onto one completion call: the gateway model id, the reasoning
30
+ * effort, and the call's `providerOptions.gateway` (via the same pin/posture rules as
31
+ * the routed turn model — applyGatewayOptions). Pure — exported for tests.
32
+ */
33
+ export function dreamCallSettings(route, defaults) {
34
+ const id = route.id ?? defaults.id;
35
+ const options = applyGatewayOptions(route, {}, { id, defaultId: defaults.id }, defaults.gateway);
36
+ return { id, reasoning: route.reasoning, providerOptions: options.providerOptions };
37
+ }
38
+ /**
39
+ * dreamCallSettings plus the model-stamp side effect, split out so a test exercises the stamp with no network.
40
+ * Whether the stamp LANDS depends on the caller: the cron-fired tidy pass has no session, so it no-ops.
41
+ */
42
+ export function resolvedDreamCallSettings(scope, defaults) {
43
+ const s = dreamCallSettings(utilityRouteForScope(scope), defaults);
44
+ stampModelCall(s.id);
45
+ return s;
46
+ }
47
+ /** One cheap gateway completion on the scope's utility route. */
48
+ function gatewayDreamCompletion(defaults) {
49
+ return async (scope, prompt) => {
50
+ const s = resolvedDreamCallSettings(scope, defaults);
51
+ const { text } = await generateText({
52
+ model: gateway(s.id),
53
+ prompt,
54
+ ...(s.reasoning !== undefined ? { reasoning: s.reasoning } : {}),
55
+ ...(s.providerOptions !== undefined
56
+ ? { providerOptions: s.providerOptions }
57
+ : {}),
58
+ });
59
+ return text;
60
+ };
61
+ }
62
+ /** The gateway-backed DreamJudge — core's fail-quiet skeleton over the completion above. */
63
+ export function gatewayDreamJudge(defaults) {
64
+ return judgeFromCompletion(gatewayDreamCompletion(defaults));
65
+ }
66
+ /**
67
+ * Convenience for agent.ts: build + register the gateway judge at boot. Without this
68
+ * call the dream cycle runs its zero-LLM v1 heuristics — registration IS the v2 opt-in.
69
+ */
70
+ export function registerGatewayDreamJudge(defaults) {
71
+ registerDreamJudge(gatewayDreamJudge(defaults));
72
+ }
73
+ /**
74
+ * Build and register the Mode-3 failure-facet judge at boot, on the SAME completion this module already
75
+ * builds. Without it the weekly digest falls back to static facets — registration IS the opt-in.
76
+ */
77
+ export function registerGatewayFailureFacetJudge(defaults) {
78
+ registerFailureFacetJudge(facetJudgeFromCompletion(gatewayDreamCompletion(defaults)));
79
+ }
80
+ //# sourceMappingURL=dream-judge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dream-judge.js","sourceRoot":"","sources":["../../../agent/model/dream-judge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import { type ImageDescribeResult, type ImageDescribeUsage, type ImageDescriber } from "@open-everywhere/core/agent/adapter-api.js";
2
+ /** Static config for the gateway vision transport. */
3
+ export interface GatewayVisionDefaults {
4
+ /** Gateway vision model id, e.g. "alibaba/qwen3-vl-instruct". */
5
+ readonly id: string;
6
+ /**
7
+ * providerOptions.gateway for the call, forwarded verbatim. Absent in the reference config: ZDR is the
8
+ * gateway's org policy now. A self-host wanting a per-call posture passes one here.
9
+ */
10
+ readonly gateway?: Record<string, unknown>;
11
+ }
12
+ /**
13
+ * Tolerantly parse a vision completion into `{description, ocrText}`: the strict-JSON shape, else the whole
14
+ * completion as the description. Pure — exported for tests.
15
+ */
16
+ export declare function parseVisionResult(text: string): ImageDescribeResult;
17
+ /**
18
+ * Wrap a failed vision call so the error NAMES THE MODEL ID this role asked for: a gateway refusal names only
19
+ * the provider, and the id lives in app config that neither the tool nor its audit row can see.
20
+ */
21
+ export declare function visionCallError(id: string, err: unknown): Error;
22
+ /** The `generateText` fields this transport reads for its own accounting — declared structurally
23
+ * rather than imported, because the AI SDK types them as broad optionals and the extraction below
24
+ * has to be defensive about every one of them anyway. */
25
+ interface VisionCallTelemetry {
26
+ readonly usage?: {
27
+ readonly inputTokens?: number;
28
+ readonly outputTokens?: number;
29
+ readonly inputTokenDetails?: {
30
+ readonly cacheReadTokens?: number;
31
+ readonly cacheWriteTokens?: number;
32
+ };
33
+ readonly outputTokenDetails?: {
34
+ readonly reasoningTokens?: number;
35
+ };
36
+ };
37
+ readonly providerMetadata?: Record<string, unknown>;
38
+ }
39
+ /**
40
+ * What this call cost, reduced to the seam's usage shape. 🔴 The extraction rules are EVE'S, copied
41
+ * field-for-field: these rows sit in the same two tables as turn steps and are summed by the same caps.
42
+ */
43
+ export declare function visionCallUsage(id: string, res: VisionCallTelemetry): ImageDescribeUsage;
44
+ /** Build the gateway-backed ImageDescriber. A gateway/model error — including the gateway
45
+ * refusing to route the vision model under a ZDR-only org policy — propagates as a throw, and
46
+ * the tool's fail-closed contract turns it into "couldn't describe". */
47
+ export declare function gatewayImageDescriber(defaults: GatewayVisionDefaults): ImageDescriber;
48
+ /** Convenience for agent.ts: build + register the gateway image describer at boot. Without this
49
+ * call the `describe_image` tool has no backend and fails closed on every call (the agent says
50
+ * it can't see the image) — registration IS the "agent can see images" opt-in. */
51
+ export declare function registerGatewayImageDescriber(defaults: GatewayVisionDefaults): void;
52
+ export {};
53
+ //# sourceMappingURL=gateway-vision.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-vision.d.ts","sourceRoot":"","sources":["../../../agent/model/gateway-vision.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EAEpB,MAAM,4CAA4C,CAAC;AAEpD,sDAAsD;AACtD,MAAM,WAAW,qBAAqB;IACpC,iEAAiE;IACjE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C;AAWD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAiBnE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,KAAK,CAE/D;AAED;;0DAE0D;AAC1D,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE;QACf,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,iBAAiB,CAAC,EAAE;YAAE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACvG,QAAQ,CAAC,kBAAkB,CAAC,EAAE;YAAE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KACrE,CAAC;IACF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,kBAAkB,CAuCxF;AAED;;yEAEyE;AACzE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,cAAc,CA8BrF;AAED;;mFAEmF;AACnF,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI,CAEnF"}