@morsehq-dev/sdk 0.5.0-rc.4 → 0.5.0-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -12
- package/dist/anthropic/index.cjs +11 -11
- package/dist/anthropic/index.js +4 -4
- package/dist/anthropic-agent-sdk/index.cjs +157 -102
- package/dist/anthropic-agent-sdk/index.cjs.map +1 -1
- package/dist/anthropic-agent-sdk/index.d.cts +57 -34
- package/dist/anthropic-agent-sdk/index.d.ts +57 -34
- package/dist/anthropic-agent-sdk/index.js +126 -72
- package/dist/anthropic-agent-sdk/index.js.map +1 -1
- package/dist/browser/anthropic/index.cjs +11 -11
- package/dist/browser/anthropic/index.js +4 -4
- package/dist/browser/anthropic-agent-sdk/index.cjs +157 -102
- package/dist/browser/anthropic-agent-sdk/index.cjs.map +1 -1
- package/dist/browser/anthropic-agent-sdk/index.js +126 -72
- package/dist/browser/anthropic-agent-sdk/index.js.map +1 -1
- package/dist/browser/{chunk-VOZBYSWK.cjs → chunk-26Q2QD5J.cjs} +5 -5
- package/dist/browser/{chunk-VOZBYSWK.cjs.map → chunk-26Q2QD5J.cjs.map} +1 -1
- package/dist/browser/{chunk-36QTJJT7.cjs → chunk-47GVOQB4.cjs} +12 -12
- package/dist/browser/{chunk-36QTJJT7.cjs.map → chunk-47GVOQB4.cjs.map} +1 -1
- package/dist/browser/{chunk-E2OVLWAF.js → chunk-64YI3IZS.js} +3 -3
- package/dist/browser/{chunk-E2OVLWAF.js.map → chunk-64YI3IZS.js.map} +1 -1
- package/dist/browser/{chunk-JR6JN7IZ.js → chunk-CI7M2GHD.js} +4 -4
- package/dist/browser/{chunk-JR6JN7IZ.js.map → chunk-CI7M2GHD.js.map} +1 -1
- package/dist/browser/{chunk-WIWUEI5Z.js → chunk-EH326H6U.js} +3 -3
- package/dist/browser/{chunk-WIWUEI5Z.js.map → chunk-EH326H6U.js.map} +1 -1
- package/dist/browser/{chunk-KXVSMY6L.js → chunk-GLL57K7P.js} +3 -3
- package/dist/browser/{chunk-KXVSMY6L.js.map → chunk-GLL57K7P.js.map} +1 -1
- package/dist/browser/{chunk-3H2OJLC2.cjs → chunk-IHIS62VS.cjs} +4 -4
- package/dist/browser/chunk-IHIS62VS.cjs.map +1 -0
- package/dist/browser/{chunk-PIWO5L5N.js → chunk-MIB3EOC4.js} +5 -5
- package/dist/browser/{chunk-PIWO5L5N.js.map → chunk-MIB3EOC4.js.map} +1 -1
- package/dist/browser/{chunk-3STFITZF.cjs → chunk-QAFFDJFK.cjs} +6 -6
- package/dist/browser/{chunk-3STFITZF.cjs.map → chunk-QAFFDJFK.cjs.map} +1 -1
- package/dist/{chunk-BNMTY7PE.js → browser/chunk-UL5TNXQL.js} +4 -4
- package/dist/browser/{chunk-VZA2EPY3.js.map → chunk-UL5TNXQL.js.map} +1 -1
- package/dist/browser/{chunk-XD4VWCAC.js → chunk-V7AUPQIJ.js} +4 -4
- package/dist/browser/chunk-V7AUPQIJ.js.map +1 -0
- package/dist/browser/{chunk-YD7TO4PD.cjs → chunk-WGWPCVYB.cjs} +18 -18
- package/dist/browser/{chunk-YD7TO4PD.cjs.map → chunk-WGWPCVYB.cjs.map} +1 -1
- package/dist/browser/{chunk-6J6F5LJI.cjs → chunk-WR2SQLKP.cjs} +7 -7
- package/dist/browser/{chunk-6J6F5LJI.cjs.map → chunk-WR2SQLKP.cjs.map} +1 -1
- package/dist/browser/{chunk-255AHH2W.cjs → chunk-ZVVUZRG7.cjs} +15 -15
- package/dist/browser/{chunk-255AHH2W.cjs.map → chunk-ZVVUZRG7.cjs.map} +1 -1
- package/dist/browser/index.cjs +91 -91
- package/dist/browser/index.js +8 -8
- package/dist/browser/integrations/pino.cjs +4 -4
- package/dist/browser/integrations/pino.js +3 -3
- package/dist/browser/langchain/index.cjs +17 -17
- package/dist/browser/langchain/index.js +2 -2
- package/dist/browser/langgraph/index.cjs +27 -27
- package/dist/browser/langgraph/index.js +5 -5
- package/dist/browser/openai/index.cjs +11 -11
- package/dist/browser/openai/index.js +2 -2
- package/dist/browser/openai-agents/index.cjs +34 -34
- package/dist/browser/openai-agents/index.js +4 -4
- package/dist/browser/vercel-ai/index.cjs +14 -14
- package/dist/browser/vercel-ai/index.js +3 -3
- package/dist/{chunk-MBOISGKD.js → chunk-7I4ILCLY.js} +4 -4
- package/dist/{chunk-MBOISGKD.js.map → chunk-7I4ILCLY.js.map} +1 -1
- package/dist/{chunk-7ZNGY236.cjs → chunk-DGBQ3UI6.cjs} +7 -7
- package/dist/{chunk-7ZNGY236.cjs.map → chunk-DGBQ3UI6.cjs.map} +1 -1
- package/dist/{chunk-VM3QM22Z.cjs → chunk-DPW4W7H7.cjs} +18 -18
- package/dist/{chunk-VM3QM22Z.cjs.map → chunk-DPW4W7H7.cjs.map} +1 -1
- package/dist/{chunk-HA5RY4N5.cjs → chunk-DQ4T2MJE.cjs} +4 -4
- package/dist/chunk-DQ4T2MJE.cjs.map +1 -0
- package/dist/{chunk-ELBY4SJ7.js → chunk-ELVBOJWY.js} +4 -4
- package/dist/chunk-ELVBOJWY.js.map +1 -0
- package/dist/{chunk-JFFZBCTP.js → chunk-HONYN2OI.js} +3 -3
- package/dist/{chunk-JFFZBCTP.js.map → chunk-HONYN2OI.js.map} +1 -1
- package/dist/{chunk-ULWGK6F5.cjs → chunk-I3P5CHBV.cjs} +12 -12
- package/dist/{chunk-ULWGK6F5.cjs.map → chunk-I3P5CHBV.cjs.map} +1 -1
- package/dist/{browser/chunk-VZA2EPY3.js → chunk-MNV4HASC.js} +4 -4
- package/dist/{chunk-BNMTY7PE.js.map → chunk-MNV4HASC.js.map} +1 -1
- package/dist/{chunk-2O2FFJLK.js → chunk-NR36TJMT.js} +5 -5
- package/dist/{chunk-2O2FFJLK.js.map → chunk-NR36TJMT.js.map} +1 -1
- package/dist/{chunk-YPP5DDPO.js → chunk-QZDUGEIR.js} +3 -3
- package/dist/{chunk-YPP5DDPO.js.map → chunk-QZDUGEIR.js.map} +1 -1
- package/dist/{chunk-RDFDPK2X.cjs → chunk-RRE2LX2A.cjs} +6 -6
- package/dist/{chunk-RDFDPK2X.cjs.map → chunk-RRE2LX2A.cjs.map} +1 -1
- package/dist/{chunk-WLNADB4J.cjs → chunk-SJ625SQS.cjs} +15 -15
- package/dist/{chunk-WLNADB4J.cjs.map → chunk-SJ625SQS.cjs.map} +1 -1
- package/dist/{chunk-Q6NQQ2LO.js → chunk-YKPZQPEW.js} +3 -3
- package/dist/{chunk-Q6NQQ2LO.js.map → chunk-YKPZQPEW.js.map} +1 -1
- package/dist/{chunk-HZKXILBF.cjs → chunk-Z5MFR7UE.cjs} +5 -5
- package/dist/{chunk-HZKXILBF.cjs.map → chunk-Z5MFR7UE.cjs.map} +1 -1
- package/dist/index.cjs +104 -99
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +15 -10
- package/dist/index.js.map +1 -1
- package/dist/integrations/pino.cjs +4 -4
- package/dist/integrations/pino.js +3 -3
- package/dist/langchain/index.cjs +17 -17
- package/dist/langchain/index.js +2 -2
- package/dist/langgraph/index.cjs +27 -27
- package/dist/langgraph/index.js +5 -5
- package/dist/openai/index.cjs +11 -11
- package/dist/openai/index.js +2 -2
- package/dist/openai-agents/index.cjs +34 -34
- package/dist/openai-agents/index.js +4 -4
- package/dist/vercel-ai/index.cjs +14 -14
- package/dist/vercel-ai/index.js +3 -3
- package/package.json +1 -1
- package/dist/browser/chunk-3H2OJLC2.cjs.map +0 -1
- package/dist/browser/chunk-XD4VWCAC.js.map +0 -1
- package/dist/chunk-ELBY4SJ7.js.map +0 -1
- package/dist/chunk-HA5RY4N5.cjs.map +0 -1
package/dist/vercel-ai/index.cjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('../chunk-
|
|
3
|
+
var chunkSJ625SQS_cjs = require('../chunk-SJ625SQS.cjs');
|
|
4
|
+
require('../chunk-RRE2LX2A.cjs');
|
|
5
5
|
var chunkKBWPNIH4_cjs = require('../chunk-KBWPNIH4.cjs');
|
|
6
6
|
var chunkHICEJ4LV_cjs = require('../chunk-HICEJ4LV.cjs');
|
|
7
|
-
var
|
|
7
|
+
var chunkDQ4T2MJE_cjs = require('../chunk-DQ4T2MJE.cjs');
|
|
8
8
|
|
|
9
9
|
// src/vercel-ai/index.ts
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
chunkDQ4T2MJE_cjs.init_tracing();
|
|
11
|
+
chunkDQ4T2MJE_cjs.init_propagation();
|
|
12
12
|
var ADAPTER = "vercel-ai";
|
|
13
13
|
async function createTracedVercelAI(options = {}) {
|
|
14
14
|
const aiModule = await loadAiModule(options.aiModule);
|
|
@@ -71,11 +71,11 @@ function contextSegmentsFor(args) {
|
|
|
71
71
|
function wrapStreamText(original, options) {
|
|
72
72
|
const agentName = options.defaultAgentName ?? "vercel-ai.streamText";
|
|
73
73
|
return function patchedStreamText(...args) {
|
|
74
|
-
const inTrace =
|
|
74
|
+
const inTrace = chunkDQ4T2MJE_cjs.getActiveTraceState() !== null;
|
|
75
75
|
const callArgs = args[0] ?? {};
|
|
76
76
|
const model = modelLabel(callArgs);
|
|
77
77
|
if (inTrace) {
|
|
78
|
-
const handle =
|
|
78
|
+
const handle = chunkSJ625SQS_cjs.emitLlmSpan({
|
|
79
79
|
adapter: ADAPTER,
|
|
80
80
|
model: model ?? "unknown",
|
|
81
81
|
attributes: { max_steps: callArgs.maxSteps ?? 1 }
|
|
@@ -94,9 +94,9 @@ function wrapStreamText(original, options) {
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
let result;
|
|
97
|
-
void
|
|
97
|
+
void chunkDQ4T2MJE_cjs.runAsync({ agentName }, async (runHandle) => {
|
|
98
98
|
runHandle.setOutcome(true);
|
|
99
|
-
const handle =
|
|
99
|
+
const handle = chunkSJ625SQS_cjs.emitLlmSpan({
|
|
100
100
|
adapter: ADAPTER,
|
|
101
101
|
model: model ?? "unknown",
|
|
102
102
|
attributes: { max_steps: callArgs.maxSteps ?? 1 }
|
|
@@ -177,9 +177,9 @@ function wrapGenerate(original, spanName, options) {
|
|
|
177
177
|
return function patched(...args) {
|
|
178
178
|
const callArgs = args[0] ?? {};
|
|
179
179
|
const model = modelLabel(callArgs);
|
|
180
|
-
const inTrace =
|
|
180
|
+
const inTrace = chunkDQ4T2MJE_cjs.getActiveTraceState() !== null;
|
|
181
181
|
const work = async () => {
|
|
182
|
-
const handle =
|
|
182
|
+
const handle = chunkSJ625SQS_cjs.emitLlmSpan({
|
|
183
183
|
adapter: ADAPTER,
|
|
184
184
|
model: model ?? "unknown",
|
|
185
185
|
attributes: { max_steps: callArgs.maxSteps ?? 1 }
|
|
@@ -204,7 +204,7 @@ function wrapGenerate(original, spanName, options) {
|
|
|
204
204
|
if (inTrace) {
|
|
205
205
|
return work();
|
|
206
206
|
}
|
|
207
|
-
return
|
|
207
|
+
return chunkDQ4T2MJE_cjs.runAsync({ agentName }, async (runHandle) => {
|
|
208
208
|
runHandle.setOutcome(true);
|
|
209
209
|
return work();
|
|
210
210
|
});
|
|
@@ -212,13 +212,13 @@ function wrapGenerate(original, spanName, options) {
|
|
|
212
212
|
}
|
|
213
213
|
function wrapFetch(original) {
|
|
214
214
|
const patched = function patched2(input, init) {
|
|
215
|
-
const state =
|
|
215
|
+
const state = chunkDQ4T2MJE_cjs.getActiveTraceState();
|
|
216
216
|
if (state === null) {
|
|
217
217
|
return original(input, init);
|
|
218
218
|
}
|
|
219
219
|
try {
|
|
220
220
|
const merged = new Headers(init?.headers ?? {});
|
|
221
|
-
|
|
221
|
+
chunkDQ4T2MJE_cjs.injectTraceparent(merged);
|
|
222
222
|
const next = { ...init ?? {}, headers: merged };
|
|
223
223
|
return original(input, next);
|
|
224
224
|
} catch {
|
package/dist/vercel-ai/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { emitLlmSpan } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
import { emitLlmSpan } from '../chunk-MNV4HASC.js';
|
|
2
|
+
import '../chunk-YKPZQPEW.js';
|
|
3
3
|
import { calculateCost } from '../chunk-XTKMUJWI.js';
|
|
4
4
|
import { decomposeOpenAiMessages } from '../chunk-4JPZV2VZ.js';
|
|
5
|
-
import { init_tracing, init_propagation, getActiveTraceState, runAsync, injectTraceparent } from '../chunk-
|
|
5
|
+
import { init_tracing, init_propagation, getActiveTraceState, runAsync, injectTraceparent } from '../chunk-ELVBOJWY.js';
|
|
6
6
|
|
|
7
7
|
// src/vercel-ai/index.ts
|
|
8
8
|
init_tracing();
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/_internal/env.ts","../../src/_internal/redaction.ts","../../src/_internal/diagnostics.ts","../../src/_internal/otel-provider.browser.ts","../../src/_internal/spans.ts","../../src/_internal/tracing.ts","../../src/propagation.ts"],"names":["DEFAULT_ENDPOINT","REASON_QUEUE_FULL","REASON_RETRY_EXHAUSTED","REASON_QUOTA_REJECTED","REASON_SHUTDOWN_DROP","SpanType","setRedactionConfig","out","extractTraceparent","_resetForTesting","W3C_TRACEPARENT_HEADER"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DA,SAAS,QAAQ,GAAA,EAAiC;AAEhD,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,EAAK;AACjD,IAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AACzB,IAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,CAAA;AAAA,EACpC;AAGA,EAAA,MAAM,aAAc,UAAA,CAAmB,IAAA;AAGvC,EAAA,IAAI,UAAA,EAAY,KAAK,GAAA,EAAK;AACxB,IAAA,IAAI;AACF,MAAA,MAAM,CAAA,GAAI,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA;AAChC,MAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,CAAA;AAAA,IACpC,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,OAAO,KAAA,EAAoC;AAClD,EAAA,IAAI,CAAC,OAAO,OAAO,KAAA;AACnB,EAAA,OAAO,CAAC,GAAA,EAAK,MAAA,EAAQ,KAAA,EAAO,IAAI,CAAA,CAAE,QAAA,CAAS,KAAA,CAAM,IAAA,EAAK,CAAE,WAAA,EAAa,CAAA;AACvE;AAEO,SAAS,SAAA,GAAgC;AAC9C,EAAA,MAAM,GAAA,GAAM,QAAQ,eAAe,CAAA;AACnC,EAAA,IAAI,CAAC,KAAK,OAAO,MAAA;AACjB,EAAA,MAAM,OAAA,GAAU,IAAI,IAAA,EAAK;AACzB,EAAA,OAAO,OAAA,IAAW,MAAA;AACpB;AAEO,SAAS,WAAA,GAAkC;AAChD,EAAA,MAAM,GAAA,GAAM,QAAQ,gBAAgB,CAAA;AACpC,EAAA,IAAI,CAAC,KAAK,OAAO,MAAA;AACjB,EAAA,MAAM,OAAA,GAAU,IAAI,IAAA,EAAK;AACzB,EAAA,OAAO,OAAA,IAAW,MAAA;AACpB;AAEO,SAAS,uBAAA,CAAwB,iBAAiB,CAAA,EAAa;AACpE,EAAA,MAAM,GAAA,GAAM,QAAQ,8BAA8B,CAAA;AAClD,EAAA,IAAI,CAAC,KAAK,OAAO,cAAA;AACjB,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA;AAC3C,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,IAAK,MAAA,IAAU,GAAG,OAAO,cAAA;AACpD,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,UAAA,GAAsB;AACpC,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,gBAAgB,CAAC,CAAA;AACzC;AAEO,SAAS,OAAA,GAAmB;AACjC,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,iBAAiB,CAAC,CAAA;AAC1C;AAEO,SAAS,mBAAA,GAA+B;AAC7C,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,6BAA6B,CAAC,CAAA;AACtD;AAsBO,SAAS,iBAAA,GAAwC;AACtD,EAAA,MAAM,GAAA,GAAM,QAAQ,uBAAuB,CAAA;AAC3C,EAAA,IAAI,CAAC,KAAK,OAAO,MAAA;AACjB,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,IAAA,EAAK,CAAE,WAAA,EAAY;AACvC,EAAA,IAAI,CAAC,SAAS,OAAO,MAAA;AACrB,EAAA,OAAO,sBAAA,CAAuB,GAAA,CAAI,OAAO,CAAA,GAAI,OAAA,GAAU,MAAA;AACzD;AAEO,SAAS,sBAAsB,KAAA,EAA2C;AAC/E,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,sBAAA,CAAuB,IAAI,KAAK,CAAA;AACtE;AAOO,SAAS,aAAA,CAAc,cAAc,CAAA,EAAa;AACvD,EAAA,MAAM,GAAA,GAAM,QAAQ,mBAAmB,CAAA;AACvC,EAAA,IAAI,CAAC,KAAK,OAAO,WAAA;AACjB,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA;AAC3C,EAAA,IAAI,CAAC,OAAO,QAAA,CAAS,MAAM,KAAK,MAAA,GAAS,CAAA,IAAO,MAAA,GAAS,CAAA,EAAK,OAAO,WAAA;AACrE,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,gBAAA,CAAiB,eAAe,KAAA,EAAe;AAC7D,EAAA,MAAM,GAAA,GAAM,QAAQ,uBAAuB,CAAA;AAC3C,EAAA,IAAI,CAAC,KAAK,OAAO,YAAA;AACjB,EAAA,MAAM,SAAS,MAAA,CAAO,QAAA,CAAS,GAAA,CAAI,IAAA,IAAQ,EAAE,CAAA;AAC7C,EAAA,OAAO,OAAO,QAAA,CAAS,MAAM,CAAA,IAAK,MAAA,GAAS,IAAI,MAAA,GAAS,YAAA;AAC1D;AAGO,SAAS,eAAA,CAAgB,cAAc,IAAA,EAAc;AAC1D,EAAA,MAAM,GAAA,GAAM,QAAQ,sBAAsB,CAAA;AAC1C,EAAA,IAAI,CAAC,KAAK,OAAO,WAAA;AACjB,EAAA,MAAM,SAAS,MAAA,CAAO,QAAA,CAAS,GAAA,CAAI,IAAA,IAAQ,EAAE,CAAA;AAC7C,EAAA,OAAO,OAAO,QAAA,CAAS,MAAM,CAAA,IAAK,MAAA,GAAS,IAAI,MAAA,GAAS,WAAA;AAC1D;AAGO,SAAS,eAAA,CAAgB,cAAc,GAAA,EAAa;AACzD,EAAA,MAAM,GAAA,GAAM,QAAQ,sBAAsB,CAAA;AAC1C,EAAA,IAAI,CAAC,KAAK,OAAO,WAAA;AACjB,EAAA,MAAM,SAAS,MAAA,CAAO,QAAA,CAAS,GAAA,CAAI,IAAA,IAAQ,EAAE,CAAA;AAC7C,EAAA,OAAO,OAAO,QAAA,CAAS,MAAM,CAAA,IAAK,MAAA,GAAS,IAAI,MAAA,GAAS,WAAA;AAC1D;AAOO,SAAS,iBAAA,GAA6B;AAC3C,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,wBAAwB,CAAC,CAAA;AACjD;AApJaA,iCAAA,CAAA,KA0FP;AA9IN,IAAA,QAAA,GAAA,KAAA,CAAA;AAAA,EAAA,sBAAA,GAAA;AAoDO,IAAMA,wBAAA,GAAmB,6CAAA;AA0FhC,IAAM,sBAAA,uBAA6B,GAAA,CAAI,CAAC,WAAW,cAAA,EAAgB,UAAA,EAAY,QAAQ,CAAC,CAAA;AAAA,EAAA;AAAA,CAAA;;;AC0BjF,SAAS,qBAAqB,OAAA,EAA6C;AAChF,EAAA,MAAM,IAAA,GAAO,WAAW,EAAC;AACzB,EAAA,MAAM,OAAA,GAAU,KAAK,OAAA,KAAY,KAAA;AAEjC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,eAAA,sBAAqB,GAAA,EAAY;AAAA,MACjC,eAAe;AAAC,KAClB;AAAA,EACF;AAGA,EAAA,MAAM,WAAW,IAAI,GAAA,CAAI,IAAA,CAAK,gBAAA,IAAoB,EAAE,CAAA;AACpD,EAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,IAAA,IAAI,kBAAA,CAAmB,GAAA,CAAI,GAAG,CAAA,EAAG;AAC/B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,GAAG,CAAA,4CAAA,CAA8C,CAAA;AAAA,IACzF;AAAA,EACF;AAGA,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAY;AAC/B,EAAA,KAAA,MAAW,OAAO,aAAA,EAAe;AAC/B,IAAA,IAAI,oBAAA,CAAqB,GAAA,CAAI,GAAG,CAAA,EAAG;AACnC,IAAA,IAAI,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA,EAAG;AACvB,IAAA,MAAA,CAAO,IAAI,GAAG,CAAA;AAAA,EAChB;AAQA,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,aAAA,IAAiB,EAAC;AAC1C,EAAA,IAAI,UAAA,CAAW,SAAS,iBAAA,EAAmB;AACzC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,mCAAA,EAAsC,UAAA,CAAW,MAAM,CAAA,MAAA,EAAS,iBAAiB,CAAA,CAAA;AAAA,KACnF;AAAA,EACF;AACA,EAAA,MAAM,gBAA0B,EAAC;AACjC,EAAA,KAAA,MAAW,OAAO,UAAA,EAAY;AAC5B,IAAA,IAAI,OAAO,QAAQ,QAAA,EAAU;AAC3B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,8CAAA,EAAiD,OAAO,GAAG,CAAA,CAAE,CAAA;AAAA,IAC/E;AACA,IAAA,IAAI,GAAA,CAAI,SAAS,sBAAA,EAAwB;AACvC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gCAAA,EAAmC,sBAAsB,CAAA,MAAA,CAAQ,CAAA;AAAA,IACnF;AACA,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,IAAI,MAAA,CAAO,GAAA,EAAK,GAAG,CAAA;AAAA,IAChC,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,MAAM,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC3D,MAAA,MAAM,IAAI,MAAM,CAAA,2CAAA,EAA8C,IAAA,CAAK,UAAU,GAAG,CAAC,CAAA,QAAA,EAAM,GAAG,CAAA,CAAE,CAAA;AAAA,IAC9F;AACA,IAAA,aAAA,CAAc,KAAK,QAAQ,CAAA;AAAA,EAC7B;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,IAAA;AAAA,IACT,eAAA,EAAiB,MAAA;AAAA,IACjB;AAAA,GACF;AACF;AAOA,SAAS,UAAU,CAAA,EAAoB;AACrC,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,IAAI,GAAA,GAAM,KAAA;AACV,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,KAAA,IAAS,IAAI,CAAA,CAAE,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AACtC,IAAA,MAAM,EAAA,GAAK,CAAA,CAAE,UAAA,CAAW,CAAC,CAAA;AACzB,IAAA,IAAI,EAAA,GAAK,EAAA,IAAM,EAAA,GAAK,EAAA,EAAI;AACxB,IAAA,IAAI,IAAI,EAAA,GAAK,EAAA;AACb,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,CAAA,IAAK,CAAA;AACL,MAAA,IAAI,CAAA,GAAI,GAAG,CAAA,IAAK,CAAA;AAAA,IAClB;AACA,IAAA,GAAA,IAAO,CAAA;AACP,IAAA,GAAA,GAAM,CAAC,GAAA;AACP,IAAA,MAAA,EAAA;AAAA,EACF;AACA,EAAA,IAAI,MAAA,GAAS,EAAA,IAAM,MAAA,GAAS,EAAA,EAAI,OAAO,KAAA;AACvC,EAAA,OAAO,MAAM,EAAA,KAAO,CAAA;AACtB;AAUA,SAAS,cAAA,CACP,QACA,QAAA,EACqB;AAErB,EAAA,OAAO,MAAA,CAAO,eAAA;AAChB;AAWO,SAAS,YAAA,CACd,CAAA,EACA,MAAA,EACA,eAAA,EACQ;AACR,EAAA,IAAI,CAAC,MAAA,CAAO,OAAA,IAAW,eAAA,KAAoB,MAAA,EAAW;AACpD,IAAA,OAAO,CAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAA,CAAE,MAAA,KAAW,CAAA,EAAG,OAAO,CAAA;AAE3B,EAAA,MAAM,OAAA,GAAU,cAAA,CAAe,MAAuB,CAAA;AACtD,EAAA,IAAI,GAAA,GAAM,CAAA;AAEV,EAAA,KAAA,MAAW,OAAO,aAAA,EAAe;AAC/B,IAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA,EAAG;AACvB,IAAA,MAAM,EAAA,GAAK,SAAS,GAAG,CAAA;AACvB,IAAA,IAAI,OAAO,MAAA,EAAW;AAEtB,IAAA,EAAA,CAAG,SAAA,GAAY,CAAA;AACf,IAAA,MAAM,WAAA,GAAc,CAAA,UAAA,EAAa,UAAA,CAAW,GAAG,CAAC,CAAA,CAAA,CAAA;AAChD,IAAA,IAAI,QAAQ,aAAA,EAAe;AACzB,MAAA,GAAA,GAAM,GAAA,CAAI,QAAQ,EAAA,EAAI,CAAC,MAAO,SAAA,CAAU,CAAC,CAAA,GAAI,WAAA,GAAc,CAAE,CAAA;AAAA,IAC/D,CAAA,MAAO;AACL,MAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,EAAA,EAAI,WAAW,CAAA;AAAA,IACnC;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,EAAA,IAAM,OAAO,aAAA,EAAe;AACrC,IAAA,EAAA,CAAG,SAAA,GAAY,CAAA;AACf,IAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,EAAA,EAAI,mBAAmB,CAAA;AAAA,EAC3C;AAEA,EAAA,OAAO,GAAA;AACT;AAkBO,SAAS,WAAA,CAAY,KAAA,EAAgB,MAAA,EAAyB,KAAA,GAAQ,CAAA,EAAY;AACvF,EAAA,IAAI,CAAC,MAAA,CAAO,OAAA,EAAS,OAAO,KAAA;AAC5B,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW,OAAO,KAAA;AAClD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,YAAA,CAAa,OAAO,MAAM,CAAA;AAChE,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,OAAO,KAAA,KAAU,WAAW,OAAO,KAAA;AACpE,EAAA,IAAI,KAAA,IAAS,WAAW,OAAO,KAAA;AAE/B,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,IAAA,OAAO,KAAA,CAAM,IAAI,CAAC,IAAA,KAAS,YAAY,IAAA,EAAM,MAAA,EAAQ,KAAA,GAAQ,CAAC,CAAC,CAAA;AAAA,EACjE;AAGA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,cAAA,CAAe,KAAK,CAAA;AACzC,IAAA,IAAI,KAAA,KAAU,MAAA,CAAO,SAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AAChD,MAAA,MAAM,MAA+B,EAAC;AACtC,MAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAgC,CAAA,EAAG;AACrE,QAAA,GAAA,CAAI,CAAC,CAAA,GAAI,WAAA,CAAY,CAAA,EAAG,MAAA,EAAQ,QAAQ,CAAC,CAAA;AAAA,MAC3C;AACA,MAAA,OAAO,GAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT;AAvWA,IAqCa,eAYA,kBAAA,EAQA,oBAAA,EAMP,UAAA,EAoBA,QAAA,EAyEA,mBACA,sBAAA,EAsKA,SAAA;AAnUN,IAAA,cAAA,GAAA,KAAA,CAAA;AAAA,EAAA,4BAAA,GAAA;AAqCO,IAAM,aAAA,GAAmC;AAAA,MAC9C,kBAAA;AAAA,MACA,KAAA;AAAA,MACA,aAAA;AAAA,MACA,OAAA;AAAA,MACA,UAAA;AAAA,MACA,YAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF;AAGO,IAAM,kBAAA,uBAA8C,GAAA,CAAI;AAAA,MAC7D,kBAAA;AAAA,MACA,KAAA;AAAA,MACA,aAAA;AAAA,MACA;AAAA,KACD,CAAA;AAGM,IAAM,oBAAA,mBAA4C,IAAI,GAAA,CAAI,CAAC,YAAY,CAAC,CAAA;AAM/E,IAAM,UAAA,GAAqC;AAAA,MACzC,gBAAA,EAAkB,SAAA;AAAA,MAClB,GAAA,EAAK,KAAA;AAAA,MACL,WAAA,EAAa,aAAA;AAAA,MACb,KAAA,EAAO,OAAA;AAAA,MACP,QAAA,EAAU,OAAA;AAAA,MACV,UAAA,EAAY,OAAA;AAAA,MACZ,MAAA,EAAQ,KAAA;AAAA,MACR,UAAA,EAAY;AAAA,KACd;AAWA,IAAM,QAAA,GAAmC;AAAA,MACvC,kBAAkB,IAAI,MAAA;AAAA,QACpB,4SAAA;AAAA,QAaA;AAAA,OACF;AAAA,MACA,KAAK,IAAI,MAAA;AAAA,QACP,6EAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,WAAA,EAAa,IAAI,MAAA,CAAO,8BAAA,EAAgC,GAAG,CAAA;AAAA,MAC3D,KAAA,EAAO,IAAI,MAAA,CAAO,uDAAA,EAAyD,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQ/E,UAAU,IAAI,MAAA;AAAA,QACZ,iFAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,UAAA,EAAY,IAAI,MAAA,CAAO,gDAAA,EAAkD,GAAG,CAAA;AAAA,MAC5E,QAAQ,IAAI,MAAA;AAAA,QACV,yEAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,YAAY,IAAI,MAAA;AAAA,QACd,yIAAA;AAAA,QAKA;AAAA;AACF,KACF;AA0BA,IAAM,iBAAA,GAAoB,EAAA;AAC1B,IAAM,sBAAA,GAAyB,GAAA;AAsK/B,IAAM,SAAA,GAAY,EAAA;AAAA,EAAA;AAAA,CAAA;;;AClMX,SAAS,mBAAmB,MAAA,EAAsC;AACvE,EAAA,qBAAA,GAAwB,MAAA;AAC1B;AASO,SAAS,SAAS,GAAA,EAAsC;AAC7D,EAAA,IAAI,CAAC,GAAA,EAAK;AACV,EAAA,MAAM,QAAQ,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,GAAO,WAAA,EAAY;AAG7C,EAAA,IAAI,CAAC,YAAA,CAAa,GAAA,CAAI,KAAK,CAAA,EAAG;AAC9B,EAAA,KAAA,GAAQ,KAAA;AACV;AAWO,SAAS,mBAAA,GAA+B;AAC7C,EAAA,IAAI,mBAAA,EAAoB,IAAK,UAAA,EAAW,EAAG,OAAO,KAAA;AAClD,EAAA,OAAO,KAAA,KAAU,SAAA;AACnB;AAEA,SAAS,WAAA,CACP,OAAA,EACA,GAAA,EACA,KAAA,EACA,QAAA,EACS;AACT,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,GAAG,KAAK,EAAC;AACpC,EAAA,MAAM,SAAS,GAAA,GAAM,QAAA;AACrB,EAAA,OAAO,MAAA,CAAO,SAAS,CAAA,IAAM,MAAA,CAAO,CAAC,CAAA,GAAe,MAAA,SAAe,KAAA,EAAM;AACzE,EAAA,IAAI,MAAA,CAAO,UAAU,KAAA,EAAO;AAC1B,IAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,MAAM,CAAA;AACvB,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,MAAA,CAAO,KAAK,GAAG,CAAA;AACf,EAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,MAAM,CAAA;AACvB,EAAA,OAAO,IAAA;AACT;AAEO,SAAS,eAAe,WAAA,EAA8B;AAC3D,EAAA,MAAM,KAAA,GAAQ,KAAA,KAAU,WAAA,GAAc,2BAAA,GAA8B,qBAAA;AACpE,EAAA,OAAO,WAAA,CAAY,WAAA,EAAa,WAAA,EAAa,KAAA,EAAO,cAAc,CAAA;AACpE;AAcA,SAAS,aAAa,IAAA,EAAuB;AAC3C,EAAA,OAAO,mBAAmB,IAAA,CAAK,CAAC,WAAW,IAAA,CAAK,QAAA,CAAS,MAAM,CAAC,CAAA;AAClE;AAGA,SAAS,WAAW,IAAA,EAA+D;AACjF,EAAA,MAAM,UAAA,GAAa,4CAAA,CAA6C,IAAA,CAAK,IAAI,CAAA;AACzE,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,WAAW,CAAC,CAAA;AAAA,MAChB,IAAA,EAAM,WAAW,CAAC,CAAA;AAAA,MAClB,MAAA,EAAQ,MAAA,CAAO,UAAA,CAAW,CAAC,CAAC;AAAA,KAC9B;AAAA,EACF;AACA,EAAA,MAAM,IAAA,GAAO,gCAAA,CAAiC,IAAA,CAAK,IAAI,CAAA;AACvD,EAAA,IAAI,IAAA,EAAM,OAAO,EAAE,IAAA,EAAM,IAAA,CAAK,CAAC,CAAA,EAAG,MAAA,EAAQ,MAAA,CAAO,IAAA,CAAK,CAAC,CAAC,CAAA,EAAE;AAC1D,EAAA,OAAO,EAAC;AACV;AAEO,SAAS,iBAAiB,KAAA,EAAgD;AAC/E,EAAA,MAAM,SAAyC,EAAC;AAChD,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,KAAA,YAAiB,KAAA,GAAS,KAAA,CAAM,SAAS,EAAA,GAAM,EAAA;AAC7D,IAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,IAAA,IAAI,MAAA,GAAS,CAAA;AACb,IAAA,KAAA,MAAW,GAAA,IAAO,KAAA,CAAM,KAAA,CAAM,IAAI,CAAA,EAAG;AACnC,MAAA,IAAI,CAAC,GAAA,CAAI,IAAA,EAAK,CAAE,UAAA,CAAW,KAAK,CAAA,EAAG;AACnC,MAAA,IAAI,YAAA,CAAa,GAAG,CAAA,EAAG;AACrB,QAAA,IAAI,SAAS,CAAA,EAAG;AACd,UAAA,MAAA,CAAO,IAAA,CAAK,EAAE,MAAA,EAAQ,CAAA;AACtB,UAAA,MAAA,GAAS,CAAA;AAAA,QACX;AACA,QAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,EAAA,EAAG,GAAI,WAAW,GAAG,CAAA;AAC3C,QAAA,MAAM,QAAiC,EAAC;AAGxC,QAAA,IAAI,IAAA,EAAM,KAAA,CAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA,CAAE,KAAA,CAAM,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAC7D,QAAA,IAAI,OAAO,WAAW,QAAA,IAAY,CAAC,OAAO,KAAA,CAAM,MAAM,CAAA,EAAG,KAAA,CAAM,IAAA,GAAO,MAAA;AACtE,QAAA,IAAI,IAAI,KAAA,CAAM,QAAA,GAAW,EAAA,CAAG,KAAA,CAAM,GAAG,GAAG,CAAA;AACxC,QAAA,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,MACnB,CAAA,MAAO;AACL,QAAA,MAAA,IAAU,CAAA;AAAA,MACZ;AAAA,IACF;AACA,IAAA,IAAI,SAAS,CAAA,EAAG,MAAA,CAAO,IAAA,CAAK,EAAE,QAAQ,CAAA;AAAA,EACxC,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,OAAO,MAAA,GAAS,iBAAA,GAAoB,OAAO,KAAA,CAAM,CAAC,iBAAiB,CAAA,GAAI,MAAA;AAChF;AAUA,SAAS,gBAAgB,KAAA,EAAwB;AAC/C,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAAA,EAC7D,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAA;AAAA,EACT;AACA,EAAA,IAAI;AACF,IAAA,IAAI,qBAAA,EAAuB;AACzB,MAAA,MAAM,GAAA,GAAM,WAAA,CAAY,GAAA,EAAK,qBAAqB,CAAA;AAClD,MAAA,GAAA,GAAM,OAAO,GAAA,KAAQ,QAAA,GAAW,GAAA,GAAM,OAAO,GAAG,CAAA;AAAA,IAClD;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,yBAAA;AAAA,EACT;AACA,EAAA,OAAO,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,iBAAiB,CAAA;AACvC;AAEO,SAAS,WAAW,KAAA,EAAoE;AAC7F,EAAA,MAAM,MAA8B,EAAC;AACrC,EAAA,IAAI,CAAC,OAAO,OAAO,GAAA;AACnB,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAChD,IAAA,IAAI,kBAAA,CAAmB,GAAA,CAAI,GAAG,CAAA,IAAK,SAAS,IAAA,EAAM;AAChD,MAAA,GAAA,CAAI,GAAG,CAAA,GAAI,MAAA,CAAO,KAAK,CAAA,CAAE,KAAA,CAAM,GAAG,GAAG,CAAA;AAAA,IACvC;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAQO,SAAS,UAAA,CAAW,MAAA,EAAgB,QAAA,EAAkB,QAAA,GAAW,CAAA,EAAS;AAC/E,EAAA,IAAI;AACF,IAAA,IAAI,YAAY,CAAA,EAAG;AACnB,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA;AACjC,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AACjC,IAAA,IAAI,QAAA,WAAmB,QAAA,IAAY,QAAA;AAAA,kBACrB,GAAA,CAAI,GAAA,EAAK,EAAE,MAAA,EAAQ,QAAA,EAAU,UAAU,CAAA;AAErD,IAAA,IACE,YAAY,eAAA,EAAiB,CAAA,KAAA,EAAQ,GAAG,CAAA,CAAA,EAAI,0BAAA,EAA4B,mBAAmB,CAAA,EAC3F;AACA,MAAA,OAAA,CAAQ,KAAK,CAAA,eAAA,EAAkB,QAAQ,IAAI,QAAQ,CAAA,EAAA,EAAK,MAAM,CAAA,gCAAA,CAA6B,CAAA;AAAA,IAC7F;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAEO,SAAS,aAAA,GAAgC;AAC9C,EAAA,IAAI,QAAA,CAAS,IAAA,KAAS,CAAA,EAAG,OAAO,EAAC;AACjC,EAAA,MAAM,OAAA,GAAU,CAAC,GAAG,QAAA,CAAS,QAAQ,CAAA;AACrC,EAAA,QAAA,CAAS,KAAA,EAAM;AACf,EAAA,OAAO,OAAA;AACT;AAaO,SAAS,MAAA,CAAO,OAAgB,OAAA,EAA8B;AACnE,EAAA,IAAI,SAAA,EAAW;AACf,EAAA,SAAA,GAAY,IAAA;AACZ,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,IAAA,GAAO,OAAA;AACvD,IAAA,MAAM,aAAa,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAIxE,IAAA,IACE,WAAA;AAAA,MACE,eAAA;AAAA,MACA,OAAA,CAAQ,WAAA;AAAA,MACR,0BAAA;AAAA,MACA;AAAA,KACF,EACA;AACA,MAAA,MAAM,OAAO,CAAA,sBAAA,EAAyB,OAAA,CAAQ,WAAW,CAAA,GAAA,EAAM,QAAQ,KAAK,UAAU,CAAA,CAAA;AACtF,MAAA,IAAI,OAAA,EAAQ,EAAG,OAAA,CAAQ,KAAA,CAAM,MAAM,KAAK,CAAA;AAAA,WACnC,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IACxB;AAEA,IAAA,IAAI,CAAC,qBAAoB,EAAG;AAC5B,IAAA,IAAI,CAAC,cAAA,CAAe,OAAA,CAAQ,WAAW,CAAA,EAAG;AAE1C,IAAA,OAAA,CAAQ;AAAA,MACN,IAAA,EAAM,OAAA;AAAA,MACN,WAAA,EAAa,OAAA,CAAQ,WAAA,CAAY,KAAA,CAAM,GAAG,GAAG,CAAA;AAAA,MAC7C,UAAA,EAAY,QAAA,CAAS,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA;AAAA,MACjC,OAAA,EAAS,gBAAgB,KAAK,CAAA;AAAA,MAC9B,KAAA,EAAO,iBAAiB,KAAK,CAAA;AAAA,MAC7B,YAAA,EAAc,YAAA;AAAA,MACd,aAAa,UAAA,EAAW;AAAA,MACxB,iBAAiB,cAAA,EAAe;AAAA,MAChC,UAAU,aAAA,EAAc;AAAA,MACxB,KAAA,EAAO,UAAA,CAAW,OAAA,CAAQ,KAAK;AAAA,KAChC,CAAA;AAAA,EACH,CAAA,CAAA,MAAQ;AAAA,EAER,CAAA,SAAE;AACA,IAAA,SAAA,GAAY,KAAA;AAAA,EACd;AACF;AAEA,SAAS,UAAA,GAAqB;AAC5B,EAAA,OAAO,WAAA;AACT;AAEA,SAAS,cAAA,GAAyB;AAChC,EAAA,IAAI;AAEF,IAAA,MAAM,OAAQ,UAAA,CAAmB,OAAA;AACjC,IAAA,OAAO,IAAA,EAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA,GAAI,EAAA;AAAA,EAChD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAA;AAAA,EACT;AACF;AAEA,SAAS,aAAA,GAAwB;AAC/B,EAAA,IAAI;AAEF,IAAA,MAAM,OAAQ,UAAA,CAAmB,OAAA;AACjC,IAAA,IAAI,IAAA,EAAM,QAAA,EAAU,OAAO,CAAA,EAAG,IAAA,CAAK,QAAQ,CAAA,CAAA,EAAI,IAAA,CAAK,IAAA,IAAQ,EAAE,CAAA,CAAA,CAAG,KAAA,CAAM,GAAG,GAAG,CAAA;AAC7E,IAAA,OAAO,SAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAA;AAAA,EACT;AACF;AAEA,SAAS,QAAQ,KAAA,EAA8B;AAG7C,EAAA,OAAA,CAAQ,KAAK,KAAK,CAAA;AAClB,EAAA,OAAO,OAAA,CAAQ,MAAA,GAAS,WAAA,EAAa,OAAA,CAAQ,KAAA,EAAM;AACnD,EAAA,WAAA,EAAY;AACd;AAUA,SAAS,WAAA,GAAoB;AAC3B,EAAA,IAAI,UAAU,IAAA,EAAM;AACpB,EAAA,IAAI;AACF,IAAA,KAAA,GAAQ,YAAY,MAAM;AACxB,MAAA,KAAK,SAAA,EAAU;AAAA,IACjB,GAAG,iBAAiB,CAAA;AAEpB,IAAC,OAAe,KAAA,IAAQ;AAAA,EAC1B,CAAA,CAAA,MAAQ;AACN,IAAA,KAAA,GAAQ,IAAA;AAAA,EACV;AACF;AAEA,SAAS,aAAA,GAAyB;AAChC,EAAA,OAAO,gBAAA,GAAmB,CAAA,IAAK,IAAA,CAAK,GAAA,EAAI,GAAI,gBAAA;AAC9C;AAEA,SAAS,aAAa,EAAA,EAAmB;AACvC,EAAA,IAAI,EAAA,EAAI;AACN,IAAA,mBAAA,GAAsB,CAAA;AACtB,IAAA,gBAAA,GAAmB,CAAA;AACnB,IAAA;AAAA,EACF;AACA,EAAA,mBAAA,IAAuB,CAAA;AACvB,EAAA,IAAI,uBAAuB,iBAAA,EAAmB;AAG5C,IAAA,gBAAA,GAAmB,IAAA,CAAK,KAAI,GAAI,mBAAA;AAAA,EAClC;AACF;AAEA,eAAsB,SAAA,GAA2B;AAC/C,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,MAAA,CAAO,CAAA,EAAG,gBAAgB,CAAA;AAChD,IAAA,MAAM,UAAU,aAAA,EAAc;AAC9B,IAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,IAAA,EAAM,UAAA;AAAA,QACN,WAAA,EAAa,0BAAA;AAAA,QACb,QAAA,EAAU,OAAA;AAAA,QACV,YAAA,EAAc,YAAA;AAAA,QACd,aAAa,UAAA;AAAW,OACzB,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACxB,IAAA,IAAI,aAAA,EAAc,IAAK,CAAC,mBAAA,EAAoB,EAAG;AAE/C,IAAA,MAAM,SAAS,aAAA,EAAc;AAC7B,IAAA,IAAI,WAAW,IAAA,EAAM;AAErB,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,KAAA,CAAM,MAAA,CAAO,GAAA,EAAK;AAAA,QACjC,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,aAAA,EAAe,CAAA,OAAA,EAAU,MAAA,CAAO,MAAM,CAAA,CAAA;AAAA,UACtC,cAAA,EAAgB;AAAA,SAClB;AAAA,QACA,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,MAAA,EAAQ,OAAO;AAAA,OACvC,CAAA;AAAA,IACH,CAAA,CAAA,MAAQ;AAGN,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA;AAAA,IACF;AACA,IAAA,QAAA,CAAS,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,qBAAqB,CAAC,CAAA;AACpD,IAAA,YAAA,CAAa,SAAS,EAAE,CAAA;AAAA,EAC1B,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAeO,SAAS,2BACd,MAAA,EACM;AACN,EAAA,YAAA,GAAe,MAAA;AACjB;AAEA,SAAS,aAAA,GAAwD;AAC/D,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,YAAA,EAAc,MAAA,IAAU,SAAA,EAAU;AACjD,IAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,IAAA,MAAM,GAAA,GAAM,qBAAqB,MAAA,CAAO,YAAA,EAAc,YAAY,WAAA,EAAY,IAAK,EAAE,CAAC,CAAA;AACtF,IAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,IAAA,OAAO,EAAE,MAAA,EAAQ,MAAA,CAAO,MAAM,GAAG,GAAA,EAAI;AAAA,EACvC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEO,SAAS,qBAAqB,cAAA,EAAuC;AAC1E,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,cAAc,CAAA;AACrC,IAAA,OAAO,GAAG,MAAA,CAAO,QAAQ,KAAK,MAAA,CAAO,IAAI,GAAG,gBAAgB,CAAA,CAAA;AAAA,EAC9D,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAOO,SAAS,gBAAA,GAAyB;AACvC,EAAA,YAAA,GAAe,IAAA;AACf,EAAA,WAAA,CAAY,KAAA,EAAM;AAClB,EAAA,eAAA,CAAgB,KAAA,EAAM;AACtB,EAAA,QAAA,CAAS,KAAA,EAAM;AACf,EAAA,OAAA,GAAU,EAAC;AACX,EAAA,IAAI,UAAU,IAAA,EAAM;AAClB,IAAA,aAAA,CAAc,KAAK,CAAA;AACnB,IAAA,KAAA,GAAQ,IAAA;AAAA,EACV;AACA,EAAA,mBAAA,GAAsB,CAAA;AACtB,EAAA,gBAAA,GAAmB,CAAA;AACnB,EAAA,SAAA,GAAY,KAAA;AACZ,EAAA,KAAA,GAAQ,WAAA;AACR,EAAA,qBAAA,GAAwB,IAAA;AAC1B;AApiBA,IAyCM,WAAA,CAAA,CAEO,SAAA,CAAA,CACA,WAAA,CAAA,CACA,WAAA,CAAA,CACP,cAOF,KAAA,CAAA,CAEE,cAAA,CAAA,CACA,qBAAA,CAAA,CAEA,2BAAA,CAAA,CACA,WAAA,CAAA,CAMA,mBAAA,CAAA,CACO,0BAAA,CAAA,CACP,eAAA,CAAA,CAGO,mBACA,iBAAA,CAAA,CACA,gBAAA,CAAA,CACP,kBAAA,CAAA,CAQA,gBAAA,CAAA,CACA,WAAA,CAAA,CACA,iBAAA,CAAA,CACA,iBAAA,CAAA,CACA,mBAAA,CAAA,CAIOC,oCACAC,uCAAA,CAAA,CACAC,sCAAA,CAAA,CAGAC,qCAAA,CAAA,KAQP,QAAA,CAAA,CAyBF,uBAMA,OAAA,CAAA,CACA,KAAA,CAAA,CACA,mBAAA,CAAA,CACA,gBAAA,CAAA,CAEA,WA2DE,kBAAA,CAAA,CA8SF;AAnfJ,IAAA,gBAAA,GAAA,KAAA,CAAA;AAAA,EAAA,8BAAA,GAAA;AAkCA,IAAA,QAAA,EAAA;AACA,IAAA,cAAA,EAAA;AAMA,IAAM,WAAA,GAAoD,YAAA,CAAkB;AAErE,IAAM,SAAA,GAAY,KAAA;AAClB,IAAM,WAAA,GAAc,OAAA;AACpB,IAAM,WAAA,GAAc,OAAA;AAC3B,IAAM,+BAAoC,IAAI,GAAA,CAAI,CAAC,SAAA,EAAW,WAAA,EAAa,WAAW,CAAC,CAAA;AAOvF,IAAI,KAAA,GAAgB,WAAA;AAEpB,IAAM,cAAA,GAAiB,GAAA;AACvB,IAAM,qBAAA,GAAwB,GAAA;AAE9B,IAAM,2BAAA,GAA8B,GAAA;AACpC,IAAM,WAAA,uBAAyC,GAAA,EAAI;AAMnD,IAAM,mBAAA,GAAsB,GAAA;AACrB,IAAM,0BAAA,GAA6B,EAAA;AAC1C,IAAM,eAAA,uBAA6C,GAAA,EAAI;AAGhD,IAAM,iBAAA,GAAoB,EAAA;AAC1B,IAAM,iBAAA,GAAoB,IAAA;AAC1B,IAAM,gBAAA,GAAmB,EAAA;AAChC,IAAM,kBAAA,uBAA8C,GAAA,CAAI;AAAA,MACtD,SAAA;AAAA,MACA,QAAA;AAAA,MACA,UAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAM,gBAAA,GAAmB,yBAAA;AACzB,IAAM,WAAA,GAAc,GAAA;AACpB,IAAM,iBAAA,GAAoB,GAAA;AAC1B,IAAM,iBAAA,GAAoB,CAAA;AAC1B,IAAM,mBAAA,GAAsB,GAAA;AAIrB,IAAMH,yBAAA,GAAoB,YAAA;AAC1B,IAAMC,8BAAA,GAAyB,iBAAA;AAC/B,IAAMC,6BAAA,GAAwB,gBAAA;AAG9B,IAAMC,4BAAA,GAAuB,eAAA;AAQpC,IAAM,QAAA,uBAA0C,GAAA,EAAI;AAyBpD,IAAI,qBAAA,GAAgD,IAAA;AAMpD,IAAI,UAA6B,EAAC;AAClC,IAAI,KAAA,GAA+C,IAAA;AACnD,IAAI,mBAAA,GAAsB,CAAA;AAC1B,IAAI,gBAAA,GAAmB,CAAA;AAEvB,IAAI,SAAA,GAAY,KAAA;AA2DhB,IAAM,kBAAA,GAAqB,CAAC,cAAA,EAAgB,WAAA,EAAa,WAAW,UAAU,CAAA;AA8S9E,IAAI,YAAA,GAA8D,IAAA;AAAA,EAAA;AAAA,CAAA;;;ACzblE,SAAS,kBAAA,GAA2B;AAClC,EAAA,IAAI,MAAA,EAAQ;AACZ,EAAA,MAAA,GAAS,IAAA;AACT,EAAA,IAAI;AACF,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KAKF;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAyCO,SAAS,SAAA,GAAwB;AACtC,EAAA,OAAO,MAAA;AACT;AAwBO,SAAS,mBAAA,CAAuB,UAAA,EAAoB,SAAA,EAAmB,EAAA,EAAgB;AAG5F,EAAA,OAAO,EAAA,EAAG;AACZ;AA/IA,IA+CI,QA+BS,UAAA,EAiCP,MAAA;AA/GN,IAAA,0BAAA,GAAA,KAAA,CAAA;AAAA,EAAA,wCAAA,GAAA;AA+CA,IAAI,MAAA,GAAS,KAAA;AA+BN,IAAM,aAAN,MAAiB;AAAA;AAAA;AAAA;AAAA;AAAA,MAKtB,UAAU,IAAA,EAAwC;AAEhD,QAAA,kBAAA,EAAmB;AAAA,MACrB;AAAA,MAEA,QAAA,GAAiB;AAAA,MAAC;AAAA,MAElB,eAAA,GAAwB;AACtB,QAAA,MAAA,GAAS,KAAA;AAAA,MACX;AAAA,MAEA,MAAM,KAAA,GAAuB;AAAA,MAAC;AAAA,MAE9B,eAAe,UAAA,EAA6B;AAI1C,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,MAEA,yBAAyB,gBAAA,EAAkD;AAIzE,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,KACF;AAEA,IAAM,MAAA,GAAS,IAAI,UAAA,EAAW;AAAA,EAAA;AAAA,CAAA;;;ACVvB,SAAS,eAAA,GAA0B;AACxC,EAAA,OAAO,UAAU,EAAE,CAAA;AACrB;AAeO,SAAS,cAAA,GAAyB;AACvC,EAAA,OAAO,UAAU,EAAE,CAAA;AACrB;AAEA,SAAS,UAAU,KAAA,EAAuB;AACxC,EAAA,MAAM,QAAQ,IAAI,UAAA,CAAW,KAAK,IAAA,CAAK,KAAA,GAAQ,CAAC,CAAC,CAAA;AAGjD,EAAA,MAAM,YAAa,UAAA,CAAmB,MAAA;AACtC,EAAA,IAAI,WAAW,eAAA,EAAiB;AAC9B,IAAA,SAAA,CAAU,gBAAgB,KAAK,CAAA;AAAA,EACjC,CAAA,MAAO;AAEL,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,MAAA,KAAA,CAAM,CAAC,CAAA,GAAI,IAAA,CAAK,MAAM,IAAA,CAAK,MAAA,KAAW,GAAG,CAAA;AAAA,IAC3C;AAAA,EACF;AACA,EAAA,IAAI,GAAA,GAAM,EAAA;AACV,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,IAAA,GAAA,IAAO,EAAE,QAAA,CAAS,EAAE,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAAA,EACvC;AACA,EAAA,OAAO,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA;AAC3B;AAEO,SAAS,MAAA,GAAiB;AAC/B,EAAA,OAAA,iBAAO,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAChC;AAGO,SAAS,WAAW,IAAA,EAAyC;AAClE,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,EAAG;AACzC,IAAA,IAAI,CAAA,KAAM,MAAA,IAAa,CAAA,KAAM,IAAA,EAAM;AACjC,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,IACX;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,eAAA,CACd,QACA,KAAA,EAC0D;AAC1D,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,MAAA;AAAA,IACP,KAAA,EAAO,KAAA,CAAM,GAAA,CAAI,UAAU;AAAA,GAC7B;AACF;AA9JaC;AAPb,IAAA,UAAA,GAAA,KAAA,CAAA;AAAA,EAAA,wBAAA,GAAA;AAOO,IAAMA,gBAAA,GAAW;AAAA,MACtB,KAAA,EAAO,OAAA;AAAA,MACP,GAAA,EAAK,KAAA;AAAA,MACL,IAAA,EAAM,MAAA;AAAA,MACN,IAAA,EAAM,MAAA;AAAA,MACN,EAAA,EAAI,IAAA;AAAA,MACJ,MAAA,EAAQ,QAAA;AAAA,MACR,MAAA,EAAQ,QAAA;AAAA;AAAA;AAAA;AAAA,MAIR,SAAA,EAAW;AAAA,KACb;AAAA,EAAA;AAAA,CAAA;;;AC8EA,SAAS,UAAA,GAAyC;AAChD,EAAA,IAAI,WAAW,OAAO,GAAA;AACtB,EAAA,SAAA,GAAY,IAAA;AAEZ,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,CAAC,OAAA,CAAQ,UAAU,IAAA,EAAM;AAC7D,IAAA,GAAA,GAAM,IAAA;AACN,IAAA,OAAO,GAAA;AAAA,EACT;AAmBA,EAAA,IAAI;AAEF,IAAA,MAAM,aAAc,OAAA,EAAiB,gBAAA;AACrC,IAAA,IAAI,OAAO,eAAe,UAAA,EAAY;AAEpC,MAAA,MAAM,GAAA,GAAM,WAAW,kBAAkB,CAAA;AACzC,MAAA,IAAI,KAAK,iBAAA,EAAmB;AAC1B,QAAA,GAAA,GAAM,IAAI,IAAI,iBAAA,EAAkB;AAChC,QAAA,OAAO,GAAA;AAAA,MACT;AAAA,IACF;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,IAAI;AAIF,IAAA,MAAM,cAAA,GAAiB,QAAA,CAAS,GAAA,EAAK,mBAAmB,CAAA;AAExD,IAAA,MAAM,GAAA,GAAM,eAAe,kBAAkB,CAAA;AAC7C,IAAA,IAAI,KAAK,iBAAA,EAAmB;AAC1B,MAAA,GAAA,GAAM,IAAI,IAAI,iBAAA,EAAkB;AAChC,MAAA,OAAO,GAAA;AAAA,IACT;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAIA,EAAA,GAAA,GAAM,IAAA;AACN,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,mBAAA,GAAyC;AACvD,EAAA,MAAM,QAAQ,UAAA,EAAW;AACzB,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,OAAO,KAAA,CAAM,UAAS,IAAK,IAAA;AAAA,EAC7B;AACA,EAAA,OAAO,YAAA;AACT;AAEA,SAAS,oBAAoB,KAAA,EAAsC;AAGjE,EAAA,MAAM,QAAA,GAAW,YAAA;AACjB,EAAA,YAAA,GAAe,KAAA;AACf,EAAA,OAAO,MAAM;AACX,IAAA,YAAA,GAAe,QAAA;AAAA,EACjB,CAAA;AACF;AAYO,SAAS,aAAa,CAAA,EAA+B;AAC1D,EAAA,SAAA,GAAY,CAAA;AACd;AAEO,SAAS,YAAA,GAAqC;AACnD,EAAA,OAAO,SAAA;AACT;AAWO,SAASC,oBAAmB,MAAA,EAA+B;AAChE,EAAA,eAAA,GAAkB,MAAA;AAIlB,EAAA,kBAAA,CAA8B,MAAM,CAAA;AACtC;AAEO,SAAS,kBAAA,GAAsC;AACpD,EAAA,OAAO,eAAA;AACT;AAWO,SAAS,UAAU,KAAA,EAAwC;AAChE,EAAA,OAAA,GAAU,KAAA,IAAS,KAAA,CAAM,MAAA,GAAS,CAAA,GAAI,KAAA,GAAQ,IAAA;AAChD;AAQO,SAAS,YAAA,GAA4D;AAC1E,EAAA,OAAO,SAAA;AACT;AAMA,SAAS,YAAA,GAAuB;AAE9B,EAAA,IAAI,OAAO,WAAA,KAAgB,WAAA,IAAe,OAAO,WAAA,CAAY,QAAQ,UAAA,EAAY;AAC/E,IAAA,OAAO,YAAY,GAAA,EAAI;AAAA,EACzB;AACA,EAAA,OAAO,KAAK,GAAA,EAAI;AAClB;AAEA,SAAS,UAAU,cAAA,EAAgC;AACjD,EAAA,OAAO,IAAA,CAAK,IAAI,CAAA,EAAG,IAAA,CAAK,MAAM,YAAA,EAAa,GAAI,cAAc,CAAC,CAAA;AAChE;AAEA,SAAS,YAAA,CACP,IAAA,EACA,SAAA,EACA,MAAA,GAAqB,aACrB,YAAA,EACM;AACN,EAAA,IAAA,CAAK,WAAW,MAAA,EAAO;AACvB,EAAA,IAAA,CAAK,WAAA,GAAc,UAAU,SAAS,CAAA;AACtC,EAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,EAAA,IAAI,iBAAiB,MAAA,EAAW;AAC9B,IAAA,IAAA,CAAK,aAAA,GAAgB,YAAA;AAAA,EACvB;AACF;AAiBA,SAAS,cAAA,CACP,KACA,MAAA,EACyB;AACzB,EAAA,IAAI,CAAC,MAAA,CAAO,OAAA,EAAS,OAAO,GAAA;AAC5B,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AACxC,IAAA,IAAI,sBAAA,CAAuB,GAAA,CAAI,CAAC,CAAA,EAAG;AACjC,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,WAAA,CAAY,CAAA,EAAG,MAAM,CAAA;AAAA,IAChC,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,IACX;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,eAAA,CACP,KACA,MAAA,EACyB;AACzB,EAAA,IAAI,CAAC,MAAA,CAAO,OAAA,EAAS,OAAO,GAAA;AAC5B,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AACxC,IAAA,IAAI,uBAAA,CAAwB,GAAA,CAAI,CAAC,CAAA,EAAG;AAClC,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,WAAA,CAAY,CAAA,EAAG,MAAM,CAAA;AAAA,IAChC,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,IACX;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,cAAA,CACP,OACA,QAAA,EAIA;AACA,EAAA,MAAM,KAAA,GAAiC;AAAA,IACrC,UAAU,KAAA,CAAM,OAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAKhB,OAAO,KAAA,CAAM,SAAA;AAAA,IACb,QAAQ,QAAA,CAAS,MAAA;AAAA,IACjB,YAAY,QAAA,CAAS;AAAA,GACvB;AACA,EAAA,IAAI,QAAA,CAAS,QAAA,EAAU,KAAA,CAAM,QAAA,GAAW,QAAA,CAAS,QAAA;AACjD,EAAA,IAAI,QAAA,CAAS,WAAA,KAAgB,MAAA,EAAW,KAAA,CAAM,cAAc,QAAA,CAAS,WAAA;AACrE,EAAA,IAAI,QAAA,CAAS,aAAA,EAAe,KAAA,CAAM,aAAA,GAAgB,QAAA,CAAS,aAAA;AAC3D,EAAA,IAAI,KAAA,CAAM,OAAA,KAAY,MAAA,EAAW,KAAA,CAAM,UAAU,KAAA,CAAM,OAAA;AACvD,EAAA,IAAI,KAAA,CAAM,OAAA,KAAY,MAAA,EAAW,KAAA,CAAM,UAAU,KAAA,CAAM,OAAA;AAKvD,EAAA,IAAI,KAAA,CAAM,QAAA,KAAa,MAAA,EAAW,KAAA,CAAM,YAAY,KAAA,CAAM,QAAA;AAC1D,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,UAAU,KAAA,CAAM,MAAA;AACtD,EAAA,IAAI,KAAA,CAAM,gBAAgB,MAAA,CAAO,IAAA,CAAK,MAAM,YAAY,CAAA,CAAE,SAAS,CAAA,EAAG;AACpE,IAAA,KAAA,CAAM,gBAAgB,KAAA,CAAM,YAAA;AAAA,EAC9B;AAEA,EAAA,MAAM,QAAA,GAAW,CAAC,QAAA,EAAU,GAAG,MAAM,cAAc,CAAA;AACnD,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM;AAChC,IAAA,MAAMC,OAA+B,EAAC;AACtC,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA,EAAG;AACtC,MAAA,IAAI,CAAA,KAAM,MAAA,IAAa,CAAA,KAAM,IAAA,EAAM;AACjC,QAAAA,IAAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,MACX;AAAA,IACF;AACA,IAAA,OAAOA,IAAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,MAAM,MAAA,GAAS,eAAA;AACf,EAAA,MAAM,GAAA,GAAM;AAAA,IACV,KAAA,EAAO,eAAA,CAAgB,KAAA,EAAO,MAAM,CAAA;AAAA,IACpC,KAAA,EAAO,MAAM,GAAA,CAAI,CAAC,MAAM,cAAA,CAAe,CAAA,EAAG,MAAM,CAAC;AAAA,GACnD;AAGA,EAAA,MAAM,eAAA,GAAkB,MAAM,cAAA,IAAkB,OAAA;AAOhD,EAAA,MAAM,WAAoC,EAAC;AAC3C,EAAA,IAAI,eAAA,EAAiB;AAInB,IAAA,QAAA,CAAS,iBAAiB,CAAA,GAAI,eAAA;AAAA,EAChC;AACA,EAAA,IAAI,MAAM,SAAA,EAAW;AACnB,IAAA,QAAA,CAAS,oBAAoB,IAAI,KAAA,CAAM,SAAA;AAAA,EACzC;AACA,EAAA,IAAI,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA,CAAE,SAAS,CAAA,EAAG;AACpC,IAAC,IAAgC,QAAA,GAAW,QAAA;AAAA,EAC9C;AACA,EAAA,OAAO,GAAA;AACT;AAkBO,SAAS,UAAU,KAAA,EAGjB;AACP,EAAA,SAAA,GAAY,KAAA;AAKZ,EAAA,IAAI,iBAAA,EAAkB,IAAK,IAAiB,EAAG;AAC7C,IAAA,IAAI,cAAc,IAAA,EAAM;AACtB,MAAA,IAAI;AACF,QAAA,SAAA,CAAU,MAAM,EAAE,MAAA,EAAQ,CAAC,KAAK,GAAG,CAAA;AAAA,MACrC,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AACA,IAAA;AAAA,EACF;AAOF;AAUA,SAAS,oBAAA,CAAwB,OAAA,EAAiB,SAAA,EAAmB,EAAA,EAAgB;AACnF,EAAA,IAAI;AAIF,IAAA,OAAO,oBAAoB,OAAA,EAAS,SAAA,CAAU,MAAM,CAAA,EAAG,EAAE,GAAG,EAAE,CAAA;AAAA,EAChE,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAA,EAAG;AAAA,EACZ;AACF;AAgDA,SAAS,eAAe,KAAA,EAA8B;AACpD,EAAA,OAAO;AAAA,IACL,UAAA,CAAW,SAAS,OAAA,EAAS;AAC3B,MAAA,KAAA,CAAM,OAAA,GAAU,OAAA;AAChB,MAAA,IAAI,OAAA,KAAY,MAAA,EAAW,KAAA,CAAM,OAAA,GAAU,OAAA;AAAA,IAC7C,CAAA;AAAA,IACA,SAAS,OAAA,EAAS;AAChB,MAAA,KAAA,CAAM,YAAA,GAAe,OAAA;AACrB,MAAA,KAAA,CAAM,OAAA,GAAU,KAAA;AAAA,IAClB,CAAA;AAAA,IACA,MAAA,EAAQ;AAAA,GACV;AACF;AAEA,SAAS,WAAW,IAAA,EAIlB;AACA,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,KAAK,mBAAA,EAAqB;AAG5B,IAAA,MAAM,EAAE,kBAAA,EAAAC,mBAAAA,EAAmB,IAAI,gBAAA,EAAA,EAAA,YAAA,CAAA,mBAAA,CAAA,CAAA;AAC/B,IAAA,MAAM,GAAA,GAAMA,mBAAAA,CAAmB,IAAA,CAAK,mBAAmB,CAAA;AACvD,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,OAAA,GAAU,GAAA,CAAI,OAAA;AAAA,IAChB;AAAA,EACF;AACA,EAAA,IAAI,CAAC,OAAA,EAAS,OAAA,GAAU,eAAA,EAAgB;AAExC,EAAA,MAAM,KAAA,GAAoB;AAAA,IACxB,OAAA;AAAA,IACA,WAAW,IAAA,CAAK,SAAA;AAAA,IAChB,WAAW,EAAC;AAAA,IACZ,gBAAgB;AAAC,GACnB;AACA,EAAA,IAAI,IAAA,CAAK,QAAA,KAAa,MAAA,EAAW,KAAA,CAAM,WAAW,IAAA,CAAK,QAAA;AACvD,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,MAAA,EAAW,KAAA,CAAM,SAAS,IAAA,CAAK,MAAA;AACnD,EAAA,IAAI,KAAK,YAAA,EAAc;AACrB,IAAA,KAAA,CAAM,eAAe,MAAA,CAAO,WAAA;AAAA,MAC1B,OAAO,OAAA,CAAQ,IAAA,CAAK,YAAY,CAAA,CAAE,IAAI,CAAC,CAAC,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA,EAAG,MAAA,CAAO,CAAC,CAAC,CAAC;AAAA,KAClE;AAAA,EACF;AAGA,EAAA,IAAI,qBAAA,CAAsB,IAAA,CAAK,MAAM,CAAA,EAAG;AACtC,IAAA,KAAA,CAAM,iBAAiB,IAAA,CAAK,MAAA;AAAA,EAC9B;AACA,EAAA,MAAM,QAAA,GAAqB;AAAA,IACzB,QAAA,EAAU,OAAA;AAAA,IACV,SAAS,cAAA,EAAe;AAAA,IACxB,IAAA,EAAM,OAAA;AAAA,IACN,MAAM,IAAA,CAAK,SAAA;AAAA,IACX,YAAY,MAAA,EAAO;AAAA,IACnB,MAAA,EAAQ;AAAA,GACV;AACA,EAAA,KAAA,CAAM,SAAA,CAAU,KAAK,QAAQ,CAAA;AAC7B,EAAA,OAAO,EAAE,KAAA,EAAO,QAAA,EAAU,SAAA,EAAW,cAAa,EAAE;AACtD;AAEA,SAAS,QAAA,CACP,KAAA,EACA,QAAA,EACA,SAAA,EACA,UAAA,EACM;AACN,EAAA,KAAA,CAAM,UAAU,GAAA,EAAI;AACpB,EAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,IAAA,MAAM,GAAA,GAAM,KAAA,CAAM,YAAA,IAAgB,WAAA,CAAY,UAAU,CAAA;AACxD,IAAA,YAAA,CAAa,QAAA,EAAU,SAAA,EAAW,QAAA,EAAU,GAAG,CAAA;AAC/C,IAAA,IAAI,KAAA,CAAM,OAAA,KAAY,MAAA,EAAW,KAAA,CAAM,OAAA,GAAU,KAAA;AAAA,EACnD,CAAA,MAAA,IAAW,KAAA,CAAM,YAAA,KAAiB,MAAA,EAAW;AAC3C,IAAA,YAAA,CAAa,QAAA,EAAU,SAAA,EAAW,QAAA,EAAU,KAAA,CAAM,YAAY,CAAA;AAAA,EAEhE,CAAA,MAAO;AACL,IAAA,YAAA,CAAa,UAAU,SAAS,CAAA;AAChC,IAAA,IAAI,KAAA,CAAM,OAAA,KAAY,MAAA,EAAW,KAAA,CAAM,OAAA,GAAU,IAAA;AAAA,EACnD;AACA,EAAA,MAAM,IAAA,GAAO,cAAA,CAAe,KAAA,EAAO,QAAQ,CAAA;AAC3C,EAAA,SAAA,CAAU,IAAI,CAAA;AAChB;AAEA,SAAS,YAAY,CAAA,EAAoB;AACvC,EAAA,IAAI,CAAA,YAAa,KAAA,EAAO,OAAO,CAAA,CAAE,OAAA;AACjC,EAAA,OAAO,OAAO,CAAC,CAAA;AACjB;AAOA,SAAS,WAAW,CAAA,EAAuC;AACzD,EAAA,OACE,CAAA,KAAM,IAAA,KACL,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,CAAA,KAAM,UAAA,CAAA,IACvC,OAAQ,CAAA,CAAyB,IAAA,KAAS,UAAA;AAE9C;AAEO,SAAS,OAAA,CAAW,MAAkB,EAAA,EAA6C;AACxF,EAAA,MAAM,EAAE,KAAA,EAAO,QAAA,EAAU,SAAA,EAAU,GAAI,WAAW,IAAI,CAAA;AACtD,EAAA,MAAM,MAAA,GAAS,eAAe,KAAK,CAAA;AACnC,EAAA,MAAM,QAAQ,UAAA,EAAW;AAEzB,EAAA,MAAM,KAAA,GAAQ,MAAS,oBAAA,CAAqB,KAAA,CAAM,OAAA,EAAS,SAAS,OAAA,EAAS,MAAM,EAAA,CAAG,MAAM,CAAC,CAAA;AAY7F,EAAA,MAAM,MAAA,GAAS,CAAC,MAAA,EAAW,MAAA,KAA0B;AACnD,IAAA,IAAI,CAAC,UAAA,CAAW,MAAM,CAAA,EAAG;AACvB,MAAA,QAAA,CAAS,KAAA,EAAO,QAAA,EAAU,SAAA,EAAW,MAAS,CAAA;AAC9C,MAAA,MAAA,EAAO;AACP,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,OAAQ,MAAA,CAAgC,IAAA;AAAA,MACtC,CAAC,KAAA,KAAU;AACT,QAAA,QAAA,CAAS,KAAA,EAAO,QAAA,EAAU,SAAA,EAAW,MAAS,CAAA;AAC9C,QAAA,MAAA,EAAO;AACP,QAAA,OAAO,KAAA;AAAA,MACT,CAAA;AAAA,MACA,CAAC,GAAA,KAAQ;AACP,QAAA,QAAA,CAAS,KAAA,EAAO,QAAA,EAAU,SAAA,EAAW,GAAG,CAAA;AACxC,QAAA,MAAA,EAAO;AACP,QAAA,MAAM,GAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF,CAAA;AAEA,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,IAAI;AACF,MAAA,OAAO,OAAO,KAAA,CAAM,GAAA,CAAI,KAAA,EAAO,KAAK,GAAG,MAAM;AAAA,MAAC,CAAC,CAAA;AAAA,IACjD,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAAS,KAAA,EAAO,QAAA,EAAU,SAAA,EAAW,GAAG,CAAA;AACxC,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF,CAAA,MAAO;AAGL,IAAA,MAAM,KAAA,GAAQ,oBAAoB,KAAK,CAAA;AACvC,IAAA,IAAI;AACF,MAAA,OAAO,MAAA,CAAO,KAAA,EAAM,EAAG,KAAK,CAAA;AAAA,IAC9B,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAAS,KAAA,EAAO,QAAA,EAAU,SAAA,EAAW,GAAG,CAAA;AACxC,MAAA,KAAA,EAAM;AACN,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AACF;AAEA,eAAsB,QAAA,CACpB,MACA,EAAA,EACwB;AACxB,EAAA,MAAM,EAAE,KAAA,EAAO,QAAA,EAAU,SAAA,EAAU,GAAI,WAAW,IAAI,CAAA;AACtD,EAAA,MAAM,MAAA,GAAS,eAAe,KAAK,CAAA;AACnC,EAAA,MAAM,QAAQ,UAAA,EAAW;AAEzB,EAAA,MAAM,KAAA,GAAQ,MACZ,oBAAA,CAAqB,KAAA,CAAM,OAAA,EAAS,SAAS,OAAA,EAAS,MAAM,EAAA,CAAG,MAAM,CAAC,CAAA;AAExE,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,KAAA,CAAM,GAAA,CAAI,OAAO,KAAK,CAAA;AAC3C,MAAA,QAAA,CAAS,KAAA,EAAO,QAAA,EAAU,SAAA,EAAW,KAAA,CAAS,CAAA;AAC9C,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAAS,KAAA,EAAO,QAAA,EAAU,SAAA,EAAW,GAAG,CAAA;AACxC,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF,CAAA,MAAO;AACL,IAAA,MAAM,KAAA,GAAQ,oBAAoB,KAAK,CAAA;AACvC,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,KAAA,EAAM;AAC3B,MAAA,QAAA,CAAS,KAAA,EAAO,QAAA,EAAU,SAAA,EAAW,KAAA,CAAS,CAAA;AAC9C,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAAS,KAAA,EAAO,QAAA,EAAU,SAAA,EAAW,GAAG,CAAA;AACxC,MAAA,MAAM,GAAA;AAAA,IACR,CAAA,SAAE;AACA,MAAA,KAAA,EAAM;AAAA,IACR;AAAA,EACF;AACF;AAgBO,SAAS,WAAW,IAAA,EAAqC;AAC9D,EAAA,MAAM,QAAQ,mBAAA,EAAoB;AAClC,EAAA,IAAI,UAAU,IAAA,EAAM;AACpB,EAAA,IAAI,KAAA,CAAM,YAAA,KAAiB,MAAA,EAAW,KAAA,CAAM,eAAe,EAAC;AAC5D,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,EAAG;AACzC,IAAA,KAAA,CAAM,YAAA,CAAa,CAAC,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA;AAAA,EAClC;AACF;AA4BO,SAAS,UAAU,IAAA,EAAsC;AAC9D,EAAA,MAAM,QAAQ,mBAAA,EAAoB;AAClC,EAAA,IAAI,UAAU,IAAA,EAAM;AAalB,IAAA,IAAI,CAAC,8BAAA,EAAgC;AACnC,MAAA,8BAAA,GAAiC,IAAA;AACjC,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,CAAA,YAAA,EAAe,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAC,CAAA,iNAAA;AAAA,OAG1C;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,SAAS,KAAA,CAAM,SAAA,CAAU,KAAA,CAAM,SAAA,CAAU,SAAS,CAAC,CAAA;AACzD,EAAA,MAAM,IAAA,GAAiB;AAAA,IACrB,UAAU,KAAA,CAAM,OAAA;AAAA,IAChB,SAAS,cAAA,EAAe;AAAA,IACxB,IAAA,EAAM,KAAK,IAAA,IAAQ,QAAA;AAAA,IACnB,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,gBAAgB,MAAA,EAAQ,OAAA;AAAA,IACxB,YAAY,MAAA,EAAO;AAAA,IACnB,MAAA,EAAQ,WAAA;AAAA,IACR,UAAU,IAAA,CAAK;AAAA,GACjB;AACA,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,KAAA,CAAM,SAAA,CAAU,KAAK,IAAI,CAAA;AACzB,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,IAAI,KAAA,EAAuB;AAEzB,MAAA,IAAI,MAAM,SAAA,CAAU,KAAA,CAAM,UAAU,MAAA,GAAS,CAAC,MAAM,IAAA,EAAM;AACxD,QAAA,KAAA,CAAM,UAAU,GAAA,EAAI;AAAA,MACtB;AACA,MAAA,IAAI,UAAU,MAAA,EAAW;AACvB,QAAA,YAAA,CAAa,IAAA,EAAM,SAAA,EAAW,QAAA,EAAU,WAAA,CAAY,KAAK,CAAC,CAAA;AAAA,MAC5D,CAAA,MAAO;AACL,QAAA,YAAA,CAAa,MAAM,SAAS,CAAA;AAAA,MAC9B;AACA,MAAA,KAAA,CAAM,cAAA,CAAe,KAAK,IAAI,CAAA;AAAA,IAChC;AAAA,GACF;AACF;AAGO,SAAS,QAAA,CAAY,MAAmB,EAAA,EAAyC;AACtF,EAAA,MAAM,MAAA,GAAS,UAAU,IAAI,CAAA;AAC7B,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAA,GACX,oBAAA,CAAqB,MAAA,CAAO,KAAK,QAAA,EAAU,MAAA,CAAO,IAAA,CAAK,OAAA,EAAS,MAAM,EAAA,CAAG,MAAM,CAAC,CAAA,GAChF,GAAG,MAAM,CAAA;AACb,IAAA,MAAA,EAAQ,GAAA,EAAI;AACZ,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,GAAA,EAAK;AACZ,IAAA,MAAA,EAAQ,IAAI,GAAG,CAAA;AACf,IAAA,MAAM,GAAA;AAAA,EACR;AACF;AAGA,eAAsB,SAAA,CACpB,MACA,EAAA,EACY;AACZ,EAAA,MAAM,MAAA,GAAS,UAAU,IAAI,CAAA;AAC7B,EAAA,IAAI;AACF,IAAA,MAAM,SAAS,MAAA,GACX,MAAM,oBAAA,CAAqB,MAAA,CAAO,KAAK,QAAA,EAAU,MAAA,CAAO,IAAA,CAAK,OAAA,EAAS,MAAM,EAAA,CAAG,MAAM,CAAC,CAAA,GACtF,MAAM,GAAG,MAAM,CAAA;AACnB,IAAA,MAAA,EAAQ,GAAA,EAAI;AACZ,IAAA,OAAO,MAAA;AAAA,EACT,SAAS,GAAA,EAAK;AACZ,IAAA,MAAA,EAAQ,IAAI,GAAG,CAAA;AACf,IAAA,MAAM,GAAA;AAAA,EACR;AACF;AAMO,SAASC,iBAAAA,GAAyB;AACvC,EAAA,YAAA,GAAe,IAAA;AACf,EAAA,SAAA,GAAY,IAAA;AACZ,EAAA,eAAA,GAAkB,oBAAA,EAAqB;AAGzC;AAr0BA,IA6FI,GAAA,EACA,WACA,YAAA,EAyFA,SAAA,EAiBA,iBAqBA,OAAA,EAUA,SAAA,EAyCE,wBAQA,uBAAA,EAkcF,8BAAA;AA3tBJ,IAAA,YAAA,GAAA,KAAA,CAAA;AAAA,EAAA,0BAAA,GAAA;AA+CA,IAAA,QAAA,EAAA;AACA,IAAA,0BAAA,EAAA;AACA,IAAA,gBAAA,EAAA;AACA,IAAA,cAAA,EAAA;AAEA,IAAA,UAAA,EAAA;AAyCA,IAAI,GAAA,GAAkC,IAAA;AACtC,IAAI,SAAA,GAAY,KAAA;AAChB,IAAI,YAAA,GAAkC,IAAA;AAyFtC,IAAI,SAAA,GAAkC,IAAA;AAiBtC,IAAI,kBAAmC,oBAAA,EAAqB;AAqB5D,IAAI,OAAA,GAAyB,IAAA;AAU7B,IAAI,SAAA,GAAyD,IAAA;AAyC7D,IAAM,sBAAA,uBAAkD,GAAA,CAAI;AAAA,MAC1D,MAAA;AAAA,MACA,YAAA;AAAA,MACA,aAAA;AAAA,MACA,eAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAM,0CAA+C,IAAI,GAAA,CAAI,CAAC,OAAA,EAAS,SAAA,EAAW,eAAe,CAAC,CAAA;AAkclG,IAAI,8BAAA,GAAiC,KAAA;AAAA,EAAA;AAAA,CAAA;;;AC3tBrC,IAAA,mBAAA,GAAA,EAAA;AAAA,QAAA,CAAA,mBAAA,EAAA;AAAA,EAAA,iBAAA,EAAA,MAAA,iBAAA;AAAA,EAAA,sBAAA,EAAA,MAAAC,8BAAA;AAAA,EAAA,WAAA,EAAA,MAAA,WAAA;AAAA,EAAA,kBAAA,EAAA,MAAA,kBAAA;AAAA,EAAA,kBAAA,EAAA,MAAA,kBAAA;AAAA,EAAA,iBAAA,EAAA,MAAA,iBAAA;AAAA,EAAA,qBAAA,EAAA,MAAA,qBAAA;AAAA,EAAA,iBAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AA8BO,SAAS,iBAAA,CAAkB,SAAiB,MAAA,EAAwB;AAEzE,EAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,YAAY,EAAE,QAAA,CAAS,YAAA,EAAc,GAAG,CAAA,CAAE,WAAA,EAAY;AACnF,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,WAAW,EAAE,QAAA,CAAS,WAAA,EAAa,GAAG,CAAA,CAAE,WAAA,EAAY;AAChF,EAAA,OAAO,GAAG,WAAW,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,EAAI,GAAG,IAAI,iBAAiB,CAAA,CAAA;AAC1D;AAWO,SAAS,kBAAyC,OAAA,EAAe;AACtE,EAAA,MAAM,QAAQ,mBAAA,EAAoB;AAClC,EAAA,IAAI,KAAA,KAAU,MAAM,OAAO,OAAA;AAE3B,EAAA,MAAM,UAAU,KAAA,CAAM,OAAA;AACtB,EAAA,MAAM,OACJ,KAAA,CAAM,SAAA,CAAU,MAAA,GAAS,CAAA,GACrB,MAAM,SAAA,CAAU,KAAA,CAAM,SAAA,CAAU,MAAA,GAAS,CAAC,CAAA,GAC1C,KAAA,CAAM,eAAe,KAAA,CAAM,cAAA,CAAe,SAAS,CAAC,CAAA;AAC1D,EAAA,MAAM,SAAA,GAAY,MAAM,OAAA,IAAW,OAAA;AACnC,EAAA,MAAM,MAAA,GAAS,SAAA,CAAU,KAAA,CAAM,CAAA,EAAG,WAAW,CAAA;AAE7C,EAAA,MAAM,KAAA,GAAQ,iBAAA,CAAkB,OAAA,EAAS,MAAM,CAAA;AAC/C,EAAA,SAAA,CAAU,OAAA,EAASA,gCAAwB,KAAK,CAAA;AAChD,EAAA,OAAO,OAAA;AACT;AAiBO,SAAS,mBACd,OAAA,EACyB;AACzB,EAAA,IAAI,OAAA,KAAY,IAAA,IAAQ,OAAA,KAAY,MAAA,EAAW,OAAO,IAAA;AACtD,EAAA,MAAM,MAAM,OAAO,OAAA,KAAY,WAAW,OAAA,GAAU,SAAA,CAAU,SAASA,8BAAsB,CAAA;AAC7F,EAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA;AAC3B,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAC/B,EAAA,MAAM,CAAC,OAAA,EAAS,OAAA,EAAS,MAAM,CAAA,GAAI,KAAA;AACnC,EAAA,IAAI,OAAA,KAAY,aAAa,OAAO,IAAA;AACpC,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,YAAA,EAAc,OAAO,IAAA;AAC5C,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,WAAA,EAAa,OAAO,IAAA;AAC1C,EAAA,IAAI,CAAC,aAAA,CAAc,IAAA,CAAK,OAAO,GAAG,OAAO,IAAA;AACzC,EAAA,IAAI,CAAC,aAAA,CAAc,IAAA,CAAK,MAAM,GAAG,OAAO,IAAA;AACxC,EAAA,IAAI,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA,EAAG,OAAO,IAAA;AACjC,EAAA,IAAI,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,EAAG,OAAO,IAAA;AAChC,EAAA,OAAO,EAAE,OAAA,EAAS,YAAA,EAAc,MAAA,EAAO;AACzC;AAMO,SAAS,mBAAmB,GAAA,EAAwD;AACzF,EAAA,OAAO,kBAAA,CAAmB,IAAI,OAAO,CAAA;AACvC;AAMO,SAAS,sBAAsB,IAAA,EAAiC;AACrE,EAAA,MAAM,SAAS,IAAI,OAAA,CAAQ,IAAA,EAAM,OAAA,IAAW,EAAE,CAAA;AAC9C,EAAA,iBAAA,CAAkB,MAAM,CAAA;AACxB,EAAA,OAAO,EAAE,GAAI,IAAA,IAAQ,EAAC,EAAI,SAAS,MAAA,EAAO;AAC5C;AAYA,SAAS,SAAA,CAAU,SAAsB,IAAA,EAA6B;AACpE,EAAA,IAAI,mBAAmB,OAAA,EAAS;AAC9B,IAAA,OAAO,OAAA,CAAQ,IAAI,IAAI,CAAA;AAAA,EACzB;AAIA,EAAA,MAAM,WAAY,OAAA,CAAgB,GAAA;AAClC,EAAA,IAAI,OAAO,aAAa,UAAA,EAAY;AAClC,IAAA,MAAM,CAAA,GAAI,QAAA,CAAS,IAAA,CAAK,OAAA,EAAS,IAAI,CAAA;AACrC,IAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,CAAA;AAClC,IAAA,IAAI,CAAA,KAAM,IAAA,IAAQ,CAAA,KAAM,MAAA,EAAW,OAAO,IAAA;AAAA,EAC5C;AAEA,EAAA,MAAM,KAAA,GAAQ,KAAK,WAAA,EAAY;AAC/B,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAkC,CAAA,EAAG;AACvE,IAAA,IAAI,CAAA,CAAE,WAAA,EAAY,KAAM,KAAA,EAAO;AAC7B,MAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,CAAA;AAClC,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,EAAE,MAAA,GAAS,CAAA,IAAK,OAAO,CAAA,CAAE,CAAC,CAAA,KAAM,QAAA,EAAU,OAAO,EAAE,CAAC,CAAA;AAC5E,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,SAAA,CAAU,OAAA,EAAsB,IAAA,EAAc,KAAA,EAAqB;AAC1E,EAAA,IAAI,mBAAmB,OAAA,EAAS;AAC9B,IAAA,OAAA,CAAQ,GAAA,CAAI,MAAM,KAAK,CAAA;AACvB,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,WAAY,OAAA,CAAgB,GAAA;AAClC,EAAA,IAAI,OAAO,aAAa,UAAA,EAAY;AAClC,IAAA,QAAA,CAAS,IAAA,CAAK,OAAA,EAAS,IAAA,EAAM,KAAK,CAAA;AAClC,IAAA;AAAA,EACF;AACA,EAAC,OAAA,CAAmC,IAAI,CAAA,GAAI,KAAA;AAC9C;AAjJaA,uCAAA,CAAA,KACA,WAAA,CAAA,CACA,iBAAA,CAAA,CAEP,YAAA,CAAA,CACA;AAtBN,IAAA,gBAAA,GAAA,KAAA,CAAA;AAAA,EAAA,oBAAA,GAAA;AAeA,IAAA,YAAA,EAAA;AAEO,IAAMA,8BAAA,GAAyB,aAAA;AAC/B,IAAM,WAAA,GAAc,IAAA;AACpB,IAAM,iBAAA,GAAoB,IAAA;AAEjC,IAAM,YAAA,GAAe,EAAA;AACrB,IAAM,WAAA,GAAc,EAAA;AAAA,EAAA;AAAA,CAAA","file":"chunk-3H2OJLC2.cjs","sourcesContent":["/**\n * Environment variable resolution for SDK auto-init.\n *\n * The V2 TS SDK supports zero-setup integration: the customer sets\n * `MORSE_API_KEY` in their process environment (Node) or supplies\n * it via build-time replacement (browser bundler), and the SDK\n * auto-initializes on first use. This module centralises the env-var\n * contract so the rules stay in one place.\n *\n * Env vars (all optional unless noted) — must mirror the Python SDK's\n * `_internal/env.py`:\n *\n * - `MORSE_API_KEY` — triggers auto-init when set; absent = SDK dormant\n * - `MORSE_ENDPOINT` — override default ingestion URL\n * - `MORSE_FLUSH_INTERVAL_SECONDS` — override default 2.0s flush interval\n * - `MORSE_DISABLED` — \"1\"/\"true\" makes all SDK calls no-op\n * - `MORSE_SDK_DEBUG` — \"1\"/\"true\" raises internal-error log level\n * - `MORSE_SDK_DISABLE_TELEMETRY` — \"1\"/\"true\" suppresses out-of-band SDK\n * self-diagnostics (errors + delivery counters). Local logging is\n * unaffected — see SDKDIAG-10.\n * - `MORSE_DISABLE_AUTO_DETECT` — (MHQ-482, mirrors Python's `MORSE_DISABLE_AUTO_DETECT`)\n * \"1\"/\"true\" skips the zero-config adapter auto-detect scan\n * - `MORSE_SAMPLE_RATE` — (MHQ-482, mirrors Python MHQ-668/671) deterministic\n * trace-ID head sampling rate in [0.0, 1.0], default 1.0.\n * - `MORSE_MAX_FIELD_BYTES` — (MHQ-482) byte cap applied to input_data / output_data /\n * context_segments / custom metadata at attribute-set\n * time, default 65536.\n * - `MORSE_MAX_QUEUE_SIZE` — (MHQ-482) OTel BatchSpanProcessor queue size, default\n * 2048 (OTel SDK default).\n * - `MORSE_MAX_BATCH_SIZE` — (MHQ-482) OTel BatchSpanProcessor max export batch\n * size, default 512 (OTel SDK default).\n * - `MORSE_LEGACY_TRANSPORT` — (MHQ-482) \"1\"/\"true\" reverts run()/span()/runTraced()\n * to the pre-OTel JSON batch transport instead of OTLP.\n * Escape hatch for the migration window only;\n * record()/log() always use the JSON path.\n * - `MORSE_CAPTURE_DB` — (MHQ-482, mirrors Python's `infra_capture.py`)\n * \"1\"/\"true\" enables zero-config `db` span\n * auto-capture (pg / mysql2 / better-sqlite3).\n * Opt-in, same as the Python SDK.\n * - `MORSE_CAPTURE_INFRA` — (MHQ-482) \"1\"/\"true\" convenience alias that enables\n * ALL infra auto-capture (currently just DB — mirrors\n * Python's combined flag; HTTP capture is a separate\n * port not yet landed in the TS SDK).\n */\n\n/**\n * Default ingestion endpoint.\n *\n * Phase 6c targets the Railway dev URL until the custom domain is wired up\n * in Phase 6d. Mirrors the Python SDK constant in\n * `apps/sdk/python/src/morse/client.py`.\n */\nexport const DEFAULT_ENDPOINT = \"https://api.morsehq.dev/api/v1/traces/batch\";\n\n/**\n * Read an env var in a runtime-agnostic way.\n *\n * Handles Node (`process.env`), Deno (`Deno.env`), and browser\n * environments where `process` is undefined. In the browser the value\n * typically comes from a bundler-time replacement (Next.js inlines\n * `process.env.MORSE_API_KEY` at build time when the var is\n * exposed via `next.config.ts`).\n */\nfunction readEnv(key: string): string | undefined {\n // Node / Next.js (server / build-time replaced)\n if (typeof process !== \"undefined\" && process.env) {\n const v = process.env[key];\n if (typeof v === \"string\") return v;\n }\n // Deno\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const denoGlobal = (globalThis as any).Deno as\n | { env: { get(k: string): string | undefined } }\n | undefined;\n if (denoGlobal?.env?.get) {\n try {\n const v = denoGlobal.env.get(key);\n if (typeof v === \"string\") return v;\n } catch {\n // Permission denied — fall through.\n }\n }\n return undefined;\n}\n\nfunction truthy(value: string | undefined): boolean {\n if (!value) return false;\n return [\"1\", \"true\", \"yes\", \"on\"].includes(value.trim().toLowerCase());\n}\n\nexport function getApiKey(): string | undefined {\n const raw = readEnv(\"MORSE_API_KEY\");\n if (!raw) return undefined;\n const trimmed = raw.trim();\n return trimmed || undefined;\n}\n\nexport function getEndpoint(): string | undefined {\n const raw = readEnv(\"MORSE_ENDPOINT\");\n if (!raw) return undefined;\n const trimmed = raw.trim();\n return trimmed || undefined;\n}\n\nexport function getFlushIntervalSeconds(defaultSeconds = 2.0): number {\n const raw = readEnv(\"MORSE_FLUSH_INTERVAL_SECONDS\");\n if (!raw) return defaultSeconds;\n const parsed = Number.parseFloat(raw.trim());\n if (!Number.isFinite(parsed) || parsed <= 0) return defaultSeconds;\n return parsed;\n}\n\nexport function isDisabled(): boolean {\n return truthy(readEnv(\"MORSE_DISABLED\"));\n}\n\nexport function isDebug(): boolean {\n return truthy(readEnv(\"MORSE_SDK_DEBUG\"));\n}\n\nexport function isTelemetryDisabled(): boolean {\n return truthy(readEnv(\"MORSE_SDK_DISABLE_TELEMETRY\"));\n}\n\n/**\n * True when `MORSE_DISABLE_AUTO_DETECT=1` — the zero-config adapter scan\n * (`_internal/auto-detect.ts`) is skipped entirely. Mirrors the Python SDK's\n * `is_auto_detect_disabled()`. Customers can still call the adapter\n * `wrapX()` / `instrumentX()` functions directly.\n */\nexport function isAutoDetectDisabled(): boolean {\n return truthy(readEnv(\"MORSE_DISABLE_AUTO_DETECT\"));\n}\n\n/**\n * Resource-level \"source\" label for Morse's own dogfood emitters.\n *\n * Mirrors the Python SDK's `get_internal_source()` (PR #90). Only the\n * accepted whitelist values are honoured — any other value is treated\n * as unset so a typo in a customer's environment never accidentally\n * tags their data as internal.\n */\nconst VALID_INTERNAL_SOURCES = new Set([\"copilot\", \"investigator\", \"refagent\", \"ui-bot\"]);\n\nexport function getInternalSource(): string | undefined {\n const raw = readEnv(\"MORSE_INTERNAL_SOURCE\");\n if (!raw) return undefined;\n const trimmed = raw.trim().toLowerCase();\n if (!trimmed) return undefined;\n return VALID_INTERNAL_SOURCES.has(trimmed) ? trimmed : undefined;\n}\n\nexport function isValidInternalSource(value: string | null | undefined): boolean {\n return typeof value === \"string\" && VALID_INTERNAL_SOURCES.has(value);\n}\n\n/**\n * Deterministic trace-ID head sampling rate for the OTel export pipeline\n * (MHQ-482, mirrors Python `_internal/env.py::get_sample_rate`). Out-of-range\n * or unparseable values fall back to `default`.\n */\nexport function getSampleRate(defaultRate = 1.0): number {\n const raw = readEnv(\"MORSE_SAMPLE_RATE\");\n if (!raw) return defaultRate;\n const parsed = Number.parseFloat(raw.trim());\n if (!Number.isFinite(parsed) || parsed < 0.0 || parsed > 1.0) return defaultRate;\n return parsed;\n}\n\n/** Byte cap for input_data/output_data/context_segments/metadata attribute values. */\nexport function getMaxFieldBytes(defaultBytes = 65536): number {\n const raw = readEnv(\"MORSE_MAX_FIELD_BYTES\");\n if (!raw) return defaultBytes;\n const parsed = Number.parseInt(raw.trim(), 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultBytes;\n}\n\n/** OTel BatchSpanProcessor queue size (OTel SDK default: 2048). */\nexport function getMaxQueueSize(defaultSize = 2048): number {\n const raw = readEnv(\"MORSE_MAX_QUEUE_SIZE\");\n if (!raw) return defaultSize;\n const parsed = Number.parseInt(raw.trim(), 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultSize;\n}\n\n/** OTel BatchSpanProcessor max export batch size (OTel SDK default: 512). */\nexport function getMaxBatchSize(defaultSize = 512): number {\n const raw = readEnv(\"MORSE_MAX_BATCH_SIZE\");\n if (!raw) return defaultSize;\n const parsed = Number.parseInt(raw.trim(), 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : defaultSize;\n}\n\n/**\n * Escape hatch: `run()`/`span()`/`runTraced()` revert to the pre-OTel JSON\n * batch transport instead of OTLP when set. `record()`/`log()` always use\n * the JSON path regardless of this flag.\n */\nexport function isLegacyTransport(): boolean {\n return truthy(readEnv(\"MORSE_LEGACY_TRANSPORT\"));\n}\n\n/**\n * DB auto-capture opt-in (MHQ-482, mirrors Python's `infra_capture.py`'s\n * `MORSE_CAPTURE_DB` / `MORSE_CAPTURE_INFRA` env flags — see\n * `maybe_enable_from_env`). Opt-in while the approach is proven across\n * drivers, same posture as the Python SDK.\n */\nexport function isDbCaptureEnabled(): boolean {\n return truthy(readEnv(\"MORSE_CAPTURE_DB\")) || truthy(readEnv(\"MORSE_CAPTURE_INFRA\"));\n}\n","/**\n * Client-side PII redaction for the TypeScript SDK.\n *\n * Phase 6f Wave B G-02. Mirrors:\n * - `apps/sdk/python/src/morse/redaction.py` (Python SDK)\n * - `apps/api/apps/core/redaction/patterns.py` (server-side floor)\n *\n * The eight pattern catalogue is canonical across all three implementations.\n * The parity corpus at\n * `openspec/changes/phase-6f-g02-pii-redaction/tests/parity_corpus.json`\n * pins identical input → output behaviour on every row.\n *\n * Redaction runs default-on inside the SDK process so that sensitive strings\n * never leave the customer's runtime. Customers can:\n * - disable the whole SDK layer (`redaction.enabled = false`),\n * - turn off non-mandatory built-ins (`disabledPatterns`),\n * - inject custom regexes (`extraPatterns`).\n *\n * The four mandatory keys (`api_key_prefixed`, `jwt`, `credit_card`,\n * `ssn_us`) cannot be disabled at the SDK — attempting to do so throws at\n * `init()`. Disabling everything at the SDK still leaves the server-side\n * mandatory floor in place.\n */\n\n/* ------------------------------------------------------------------------ */\n/* Pattern catalogue */\n/* ------------------------------------------------------------------------ */\n\n/**\n * Canonical pattern keys. The redactor walks them in this order; once a\n * substring is replaced by a `[REDACTED:...]` marker, later patterns see\n * the replacement and don't re-match digit/word fragments inside it.\n *\n * Order MUST match `apps/api/apps/core/redaction/patterns.py` and\n * `apps/sdk/python/.../redaction.py` so the parity corpus produces\n * identical output across implementations.\n */\nexport const PATTERN_ORDER: readonly string[] = [\n \"api_key_prefixed\",\n \"jwt\",\n \"credit_card\",\n \"email\",\n \"phone_us\",\n \"phone_e164\",\n \"ssn_us\",\n \"ip_address\",\n] as const;\n\n/** Patterns that customers cannot disable at the SDK layer. */\nexport const MANDATORY_PATTERNS: ReadonlySet<string> = new Set([\n \"api_key_prefixed\",\n \"jwt\",\n \"credit_card\",\n \"ssn_us\",\n]);\n\n/** Patterns that ship disabled by default (opt-in). */\nexport const DEFAULT_OFF_PATTERNS: ReadonlySet<string> = new Set([\"ip_address\"]);\n\n/**\n * Short replacement keys. The replacement format is `[REDACTED:<short>]`.\n * `phone_us` and `phone_e164` collapse to `phone`.\n */\nconst SHORT_KEYS: Record<string, string> = {\n api_key_prefixed: \"api_key\",\n jwt: \"jwt\",\n credit_card: \"credit_card\",\n email: \"email\",\n phone_us: \"phone\",\n phone_e164: \"phone\",\n ssn_us: \"ssn\",\n ip_address: \"ip\",\n};\n\n/**\n * Compiled regexes for each pattern. The `g` flag is required so the\n * `String.replace(regex, ...)` call walks the whole string. `i` flag is\n * applied where the canonical Python form is case-insensitive (email,\n * ip_address) for lowercase IPv6 + uppercase email parity.\n *\n * NB: the Luhn-validating credit_card pattern returns *candidate* matches;\n * `redactString` runs Luhn before deciding to replace.\n */\nconst PATTERNS: Record<string, RegExp> = {\n api_key_prefixed: new RegExp(\n \"\\\\b(?:\" +\n \"sk-[A-Za-z0-9_-]{20,}\" +\n \"|sk_(?:live|test)_[A-Za-z0-9]{20,}\" +\n \"|mhq_[A-Za-z0-9]{20,}\" +\n \"|av_[A-Za-z0-9]{20,}\" +\n \"|ghp_[A-Za-z0-9]{36}\" +\n \"|gho_[A-Za-z0-9]{36}\" +\n \"|ghu_[A-Za-z0-9]{36}\" +\n \"|ghs_[A-Za-z0-9]{36}\" +\n \"|ghr_[A-Za-z0-9]{36}\" +\n \"|xox[bopsa]-[0-9A-Za-z\\\\-]{10,}\" +\n \"|(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA)[0-9A-Z]{16}\" +\n \")\\\\b\",\n \"g\",\n ),\n jwt: new RegExp(\n \"\\\\beyJ[A-Za-z0-9_=-]{16,}\\\\.eyJ[A-Za-z0-9_=-]{16,}\\\\.[A-Za-z0-9_=-]{16,}\\\\b\",\n \"g\",\n ),\n credit_card: new RegExp(\"\\\\b(?:\\\\d[ -]?){12,18}\\\\d\\\\b\", \"g\"),\n email: new RegExp(\"\\\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\\.[A-Za-z]{2,}\\\\b\", \"gi\"),\n // The leading `(?<!\\d)` and trailing `(?!\\d)` lookarounds prevent\n // the phone matcher from carving a 10-digit substring out of a longer\n // continuous digit run (e.g., a 16-digit credit-card-shaped number that\n // failed Luhn). Without them, `1234567890123456` would emit a\n // `[REDACTED:phone]` for digits 7-16 even though the whole run was\n // never a real phone number. The canonical Python regex needs the same\n // shim — see redaction.py.\n phone_us: new RegExp(\n \"(?<!\\\\d)(?:\\\\+?1[ \\\\-.])?\\\\(?[2-9]\\\\d{2}\\\\)?[ \\\\-.]?\\\\d{3}[ \\\\-.]?\\\\d{4}(?!\\\\d)\",\n \"g\",\n ),\n phone_e164: new RegExp(\"(?<!\\\\d)\\\\+(?:[0-9][ \\\\-.]?){8,14}[0-9](?!\\\\d)\", \"g\"),\n ssn_us: new RegExp(\n \"\\\\b(?!000|666|9\\\\d{2})\\\\d{3}[ \\\\-.](?!00)\\\\d{2}[ \\\\-.](?!0000)\\\\d{4}\\\\b\",\n \"g\",\n ),\n ip_address: new RegExp(\n \"\\\\b(?:\" +\n \"(?:25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)\" +\n \"(?:\\\\.(?:25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)){3}\" +\n \"|(?:[A-F0-9]{1,4}:){2,7}[A-F0-9]{1,4}\" +\n \")\\\\b\",\n \"gi\",\n ),\n};\n\n/* ------------------------------------------------------------------------ */\n/* Configuration */\n/* ------------------------------------------------------------------------ */\n\n/** Public SDK option. Mirrors `redaction` in `init()`. */\nexport interface RedactionOptions {\n /** Master switch. Default: `true`. */\n enabled?: boolean;\n /** Pattern keys to selectively disable (mandatory keys rejected). */\n disabledPatterns?: string[];\n /** Customer-supplied regex strings (ECMAScript syntax). */\n extraPatterns?: string[];\n}\n\n/** Validated, frozen config fed into `redactString` / `redactValue`. */\nexport interface RedactionConfig {\n enabled: boolean;\n /** Keys actually applied, in stable order. */\n enabledPatterns: ReadonlySet<string>;\n /** Custom compiled regexes — applied last, with `[REDACTED:custom]`. */\n extraCompiled: readonly RegExp[];\n}\n\n/** Hard caps mirroring server-side validation. */\nconst EXTRA_PATTERN_CAP = 10;\nconst EXTRA_PATTERN_CHAR_CAP = 256;\n\n/**\n * Validate raw user options and return a normalised config. Throws on:\n * - disabling a mandatory pattern,\n * - more than 10 extra patterns,\n * - any extra pattern over 256 chars,\n * - any extra pattern that fails to compile via `new RegExp(...)`.\n *\n * `enabled = false` short-circuits — no patterns are applied.\n */\nexport function buildRedactionConfig(options?: RedactionOptions): RedactionConfig {\n const opts = options ?? {};\n const enabled = opts.enabled !== false;\n\n if (!enabled) {\n return {\n enabled: false,\n enabledPatterns: new Set<string>(),\n extraCompiled: [],\n };\n }\n\n // Mandatory-pattern lock-down.\n const disabled = new Set(opts.disabledPatterns ?? []);\n for (const key of disabled) {\n if (MANDATORY_PATTERNS.has(key)) {\n throw new Error(`redaction pattern '${key}' cannot be disabled (server-side mandatory)`);\n }\n }\n\n // Active set: every catalogue key NOT in default-off NOT in disabled.\n const active = new Set<string>();\n for (const key of PATTERN_ORDER) {\n if (DEFAULT_OFF_PATTERNS.has(key)) continue;\n if (disabled.has(key)) continue;\n active.add(key);\n }\n // Re-add any default-off pattern the user explicitly opted in to via a\n // `disabledPatterns` membership check is the wrong direction — the only\n // way to enable `ip_address` from the SDK today is through a future\n // `enabledPatterns` option. The spec keeps it default-off; tests pass\n // an explicit `enabledPatterns` set via the lower-level `redactString`.\n\n // Custom regex validation.\n const extraInput = opts.extraPatterns ?? [];\n if (extraInput.length > EXTRA_PATTERN_CAP) {\n throw new Error(\n `too many redaction extra patterns: ${extraInput.length} (max ${EXTRA_PATTERN_CAP})`,\n );\n }\n const extraCompiled: RegExp[] = [];\n for (const raw of extraInput) {\n if (typeof raw !== \"string\") {\n throw new Error(`redaction extra pattern must be a string, got ${typeof raw}`);\n }\n if (raw.length > EXTRA_PATTERN_CHAR_CAP) {\n throw new Error(`redaction extra pattern exceeds ${EXTRA_PATTERN_CHAR_CAP} chars`);\n }\n let compiled: RegExp;\n try {\n compiled = new RegExp(raw, \"g\");\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new Error(`redaction extra pattern failed to compile: ${JSON.stringify(raw)} — ${msg}`);\n }\n extraCompiled.push(compiled);\n }\n\n return {\n enabled: true,\n enabledPatterns: active,\n extraCompiled,\n };\n}\n\n/* ------------------------------------------------------------------------ */\n/* Luhn check */\n/* ------------------------------------------------------------------------ */\n\n/** Standard mod-10 Luhn check on the digits of `s` (ignores spaces/dashes). */\nfunction luhnValid(s: string): boolean {\n let sum = 0;\n let alt = false;\n let digits = 0;\n for (let i = s.length - 1; i >= 0; i--) {\n const ch = s.charCodeAt(i);\n if (ch < 48 || ch > 57) continue; // skip non-digits (spaces, dashes)\n let n = ch - 48;\n if (alt) {\n n *= 2;\n if (n > 9) n -= 9;\n }\n sum += n;\n alt = !alt;\n digits++;\n }\n if (digits < 13 || digits > 19) return false;\n return sum % 10 === 0;\n}\n\n/* ------------------------------------------------------------------------ */\n/* String redactor */\n/* ------------------------------------------------------------------------ */\n\n/**\n * Internal: compute the active enabled set when callers pass an explicit\n * `enabledPatterns` (parity-corpus tests do this) vs. defaults.\n */\nfunction resolveEnabled(\n config: RedactionConfig,\n override?: ReadonlySet<string>,\n): ReadonlySet<string> {\n if (override !== undefined) return override;\n return config.enabledPatterns;\n}\n\n/**\n * Core redactor: walk patterns in canonical order, replace matches.\n *\n * `enabledOverride` allows tests (and the parity corpus) to specify an\n * exact enabled set, bypassing the config's default-on/off decisions.\n *\n * Customers calling through the SDK never see the override path — they\n * always pass through `RedactionConfig.enabledPatterns`.\n */\nexport function redactString(\n s: string,\n config: RedactionConfig,\n enabledOverride?: ReadonlySet<string>,\n): string {\n if (!config.enabled && enabledOverride === undefined) {\n return s;\n }\n if (s.length === 0) return s;\n\n const enabled = resolveEnabled(config, enabledOverride);\n let out = s;\n\n for (const key of PATTERN_ORDER) {\n if (!enabled.has(key)) continue;\n const re = PATTERNS[key];\n if (re === undefined) continue;\n // Reset `lastIndex` defensively (shared global regex state).\n re.lastIndex = 0;\n const replacement = `[REDACTED:${SHORT_KEYS[key]}]`;\n if (key === \"credit_card\") {\n out = out.replace(re, (m) => (luhnValid(m) ? replacement : m));\n } else {\n out = out.replace(re, replacement);\n }\n }\n\n // Custom patterns last.\n for (const re of config.extraCompiled) {\n re.lastIndex = 0;\n out = out.replace(re, \"[REDACTED:custom]\");\n }\n\n return out;\n}\n\n/* ------------------------------------------------------------------------ */\n/* JSON walker */\n/* ------------------------------------------------------------------------ */\n\nconst MAX_DEPTH = 10;\n\n/**\n * Recursively redact string leaves inside an arbitrary JSON-like value.\n * Booleans, numbers, nulls, undefined are passed through untouched.\n * Recursion is bounded at `MAX_DEPTH` to defend against pathological\n * payloads — beyond that, sub-trees are returned as-is.\n *\n * Arrays return new arrays; plain objects return new shallow-cloned\n * objects; non-plain objects (Date, Map, etc.) are returned as-is so we\n * don't accidentally serialise customer-internal types.\n */\nexport function redactValue(value: unknown, config: RedactionConfig, depth = 0): unknown {\n if (!config.enabled) return value;\n if (value === null || value === undefined) return value;\n if (typeof value === \"string\") return redactString(value, config);\n if (typeof value === \"number\" || typeof value === \"boolean\") return value;\n if (depth >= MAX_DEPTH) return value;\n\n if (Array.isArray(value)) {\n return value.map((item) => redactValue(item, config, depth + 1));\n }\n\n // Only walk plain objects (prototype is Object.prototype or null).\n if (typeof value === \"object\") {\n const proto = Object.getPrototypeOf(value);\n if (proto === Object.prototype || proto === null) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = redactValue(v, config, depth + 1);\n }\n return out;\n }\n }\n\n return value;\n}\n","/**\n * SDK self-diagnostics — Morse-owned internal error reporting (MHQ-908).\n *\n * Mirrors the Python SDK's `_internal/diagnostics.py`. Replaces the Sentry\n * reporter: when the SDK absorbs an internal exception (per the non-invasive\n * guarantee in `_internal/errors.ts`), it reports to Morse's own\n * `/api/v1/diagnostics/sdk` rather than to a third party the customer may not\n * have installed.\n *\n * Two channels, both silent on a healthy install:\n *\n * - **errors** — one absorbed exception with a *Morse-scoped* stack. Frames\n * inside this package go in full; every run of frames outside it collapses\n * to a count. No local variables, at any verbosity level.\n * - **counters** (SDKDIAG-09) — aggregate `{reason, category, quantity}` for\n * telemetry we discarded, adopted from Sentry's client reports, which is\n * what that vendor chose to send *instead of* SDK stack traces.\n *\n * **Transport is deliberately its own** (founder decision, 2026-08-03, Option\n * B): a bounded buffer plus a timer, created on the FIRST report and never\n * before. Routing through the shared transport would have been a smaller diff,\n * but that queue is bounded and drops, so a diagnostic storm would evict the\n * customer's telemetry. Lazy creation matters more in JS than in Python: an\n * armed timer keeps the Node event loop alive, so a healthy process must not\n * arm one. The timer is `unref()`d where available for the same reason.\n *\n * **Nothing here is private from the host.** Everything transmitted is also\n * written to the console, rate-limited, whether or not transmission succeeds\n * and even when the customer has opted out entirely (SDKDIAG-10).\n *\n * **Never throws.** A failure anywhere is swallowed — never retried, never\n * reported about itself (SDKDIAG-06).\n */\n\nimport { getApiKey, getEndpoint, isDebug, isDisabled, isTelemetryDisabled } from \"./env\";\nimport { type RedactionConfig, redactValue } from \"./redaction\";\n\n// Build-time define, same as transport.ts. Declared rather than imported so\n// this module stays a leaf — transport imports us for the drop counters, and a\n// cycle here would be resolved at module-init time on the error path.\ndeclare const __SDK_VERSION__: string | undefined;\nconst SDK_VERSION = typeof __SDK_VERSION__ === \"string\" ? __SDK_VERSION__ : \"0.0.0-dev\";\n\nexport const LEVEL_OFF = \"off\";\nexport const LEVEL_ERROR = \"error\";\nexport const LEVEL_DEBUG = \"debug\";\nconst VALID_LEVELS: ReadonlySet<string> = new Set([LEVEL_OFF, LEVEL_ERROR, LEVEL_DEBUG]);\n\n/**\n * Learned from the `X-Morse-Diagnostics` response header on traffic the SDK is\n * already sending. `error` until a header says otherwise — matching the server\n * model's default, so behaviour before the first response matches after.\n */\nlet level: string = LEVEL_ERROR;\n\nconst RATE_WINDOW_MS = 60_000;\nconst RATE_LIMIT_PER_WINDOW = 100;\n/** `debug` relaxes the send budget; it never relaxes what may be sent. */\nconst RATE_LIMIT_PER_WINDOW_DEBUG = 1000;\nconst rateBuckets: Map<string, number[]> = new Map();\n\n/**\n * Local emission is limited separately from transmission so our send budget is\n * never the host's visibility ceiling (SDKDIAG-10).\n */\nconst LOCAL_LOG_WINDOW_MS = 60_000;\nexport const LOCAL_LOG_LIMIT_PER_WINDOW = 10;\nconst localLogBuckets: Map<string, number[]> = new Map();\n\n// Payload caps — mirror apps/api/apps/diagnostics/schemas.py.\nexport const MAX_STACK_ENTRIES = 64;\nexport const MAX_MESSAGE_CHARS = 4096;\nexport const MAX_BATCH_EVENTS = 32;\nconst ALLOWED_EXTRA_KEYS: ReadonlySet<string> = new Set([\n \"adapter\",\n \"module\",\n \"function\",\n \"operation\",\n \"endpoint_host\",\n]);\n\nconst DIAGNOSTICS_PATH = \"/api/v1/diagnostics/sdk\";\nconst MAX_PENDING = 100;\nconst FLUSH_INTERVAL_MS = 5000;\nconst BREAKER_THRESHOLD = 3;\nconst BREAKER_COOLDOWN_MS = 300_000;\n\n// --- Delivery counters (SDKDIAG-09) ----------------------------------------\n\nexport const REASON_QUEUE_FULL = \"queue_full\";\nexport const REASON_RETRY_EXHAUSTED = \"retry_exhausted\";\nexport const REASON_QUOTA_REJECTED = \"quota_rejected\";\nexport const REASON_BREAKER_OPEN = \"breaker_open\";\nexport const REASON_ENCODE_FAILED = \"encode_failed\";\nexport const REASON_SHUTDOWN_DROP = \"shutdown_drop\";\n\ninterface CounterEntry {\n reason: string;\n category: string;\n quantity: number;\n}\n\nconst counters: Map<string, CounterEntry> = new Map();\n\ninterface DiagnosticEvent {\n kind: \"error\" | \"counters\";\n fingerprint: string;\n error_type?: string;\n message?: string;\n stack?: Array<Record<string, unknown>>;\n counters?: CounterEntry[];\n sdk_language: string;\n sdk_version: string;\n runtime_version?: string;\n platform?: string;\n extra?: Record<string, string>;\n}\n\n/**\n * Active redaction config, PUSHED here by `tracing.setRedactionConfig`.\n *\n * Push rather than pull so this module imports nothing but `env` and\n * `redaction`. A static import of `tracing` would close a cycle\n * (transport → diagnostics → tracing → transport) that resolves at module-init\n * time, and the error path is the worst place to discover a half-initialised\n * module.\n */\nlet activeRedactionConfig: RedactionConfig | null = null;\n\nexport function setRedactionConfig(config: RedactionConfig | null): void {\n activeRedactionConfig = config;\n}\n\nlet pending: DiagnosticEvent[] = [];\nlet timer: ReturnType<typeof setInterval> | null = null;\nlet consecutiveFailures = 0;\nlet breakerOpenUntil = 0;\n/** Re-entrancy fence (SDKDIAG-06). */\nlet reporting = false;\n\nexport function setLevel(raw: string | null | undefined): void {\n if (!raw) return;\n const value = String(raw).trim().toLowerCase();\n // Unrecognised values are ignored rather than treated as `off` — a future\n // server value must not silently mute an old SDK.\n if (!VALID_LEVELS.has(value)) return;\n level = value;\n}\n\nexport function getLevel(): string {\n return level;\n}\n\n/**\n * True when this process may put diagnostics on the wire. The customer's kill\n * switch beats every server-side setting — that ordering is the whole point of\n * having a client-side switch.\n */\nexport function transmissionAllowed(): boolean {\n if (isTelemetryDisabled() || isDisabled()) return false;\n return level !== LEVEL_OFF;\n}\n\nfunction checkBucket(\n buckets: Map<string, number[]>,\n key: string,\n limit: number,\n windowMs: number,\n): boolean {\n const now = Date.now();\n const bucket = buckets.get(key) ?? [];\n const cutoff = now - windowMs;\n while (bucket.length > 0 && (bucket[0] as number) < cutoff) bucket.shift();\n if (bucket.length >= limit) {\n buckets.set(key, bucket);\n return false;\n }\n bucket.push(now);\n buckets.set(key, bucket);\n return true;\n}\n\nexport function checkRateLimit(fingerprint: string): boolean {\n const limit = level === LEVEL_DEBUG ? RATE_LIMIT_PER_WINDOW_DEBUG : RATE_LIMIT_PER_WINDOW;\n return checkBucket(rateBuckets, fingerprint, limit, RATE_WINDOW_MS);\n}\n\n// --- Morse-scoped stack (SDKDIAG-02) ---------------------------------------\n\n/**\n * Frames mentioning this package are ours; everything else is the host's.\n *\n * Matching on the module path is a heuristic (a bundled build flattens paths),\n * and it fails CLOSED: an unrecognised frame is treated as the host's and\n * elided. Over-eliding costs us a debugging detail; under-eliding would ship\n * the customer's file layout.\n */\nconst MORSE_PATH_MARKERS = [\"@morsehq/sdk\", \"morse-sdk\", \"/morse/\", \"morse_ai\"];\n\nfunction isMorseFrame(line: string): boolean {\n return MORSE_PATH_MARKERS.some((marker) => line.includes(marker));\n}\n\n/** Parse `at fn (file:line:col)` into its parts, best-effort. */\nfunction parseFrame(line: string): { file?: string; lineNo?: number; fn?: string } {\n const withParens = /^\\s*at\\s+(.+?)\\s+\\((.+?):(\\d+):(\\d+)\\)\\s*$/.exec(line);\n if (withParens) {\n return {\n fn: withParens[1],\n file: withParens[2],\n lineNo: Number(withParens[3]),\n };\n }\n const bare = /^\\s*at\\s+(.+?):(\\d+):(\\d+)\\s*$/.exec(line);\n if (bare) return { file: bare[1], lineNo: Number(bare[2]) };\n return {};\n}\n\nexport function buildScopedStack(error: unknown): Array<Record<string, unknown>> {\n const frames: Array<Record<string, unknown>> = [];\n try {\n const stack = error instanceof Error ? (error.stack ?? \"\") : \"\";\n if (!stack) return frames;\n let elided = 0;\n for (const raw of stack.split(\"\\n\")) {\n if (!raw.trim().startsWith(\"at \")) continue; // the message line\n if (isMorseFrame(raw)) {\n if (elided > 0) {\n frames.push({ elided });\n elided = 0;\n }\n const { file, lineNo, fn } = parseFrame(raw);\n const frame: Record<string, unknown> = {};\n // Keep only the tail of the path: an absolute path leaks the host's\n // directory layout (usernames, deploy paths).\n if (file) frame.file = file.split(/[\\\\/]/).slice(-3).join(\"/\");\n if (typeof lineNo === \"number\" && !Number.isNaN(lineNo)) frame.line = lineNo;\n if (fn) frame.function = fn.slice(0, 255);\n frames.push(frame);\n } else {\n elided += 1;\n }\n }\n if (elided > 0) frames.push({ elided });\n } catch {\n // A partial stack beats no diagnostic.\n }\n return frames.length > MAX_STACK_ENTRIES ? frames.slice(-MAX_STACK_ENTRIES) : frames;\n}\n\n/**\n * Exception message, redacted and capped.\n *\n * An exception message is not automatically safe — it can name a customer key\n * or echo content — so it goes through the same redaction the telemetry path\n * uses. A redactor fault returns a placeholder rather than the raw string:\n * failing closed is the only acceptable direction here.\n */\nfunction redactedMessage(error: unknown): string {\n let raw: string;\n try {\n raw = error instanceof Error ? error.message : String(error);\n } catch {\n return \"\";\n }\n try {\n if (activeRedactionConfig) {\n const out = redactValue(raw, activeRedactionConfig);\n raw = typeof out === \"string\" ? out : String(out);\n }\n } catch {\n return \"<redaction unavailable>\";\n }\n return raw.slice(0, MAX_MESSAGE_CHARS);\n}\n\nexport function scrubExtra(extra: Record<string, unknown> | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n if (!extra) return out;\n for (const [key, value] of Object.entries(extra)) {\n if (ALLOWED_EXTRA_KEYS.has(key) && value != null) {\n out[key] = String(value).slice(0, 255);\n }\n }\n return out;\n}\n\n/**\n * Count telemetry we discarded. Never throws, never sends immediately.\n *\n * Delivery loss is what the customer's on-call most needs to know, so it is a\n * `console.warn` locally even though it is only a counter on the wire.\n */\nexport function recordDrop(reason: string, category: string, quantity = 1): void {\n try {\n if (quantity <= 0) return;\n const key = `${reason}:${category}`;\n const existing = counters.get(key);\n if (existing) existing.quantity += quantity;\n else counters.set(key, { reason, category, quantity });\n\n if (\n checkBucket(localLogBuckets, `drop:${key}`, LOCAL_LOG_LIMIT_PER_WINDOW, LOCAL_LOG_WINDOW_MS)\n ) {\n console.warn(`morse: dropped ${quantity} ${category} (${reason}) — telemetry is being lost`);\n }\n } catch {\n // Counter bookkeeping must never break a caller.\n }\n}\n\nexport function drainCounters(): CounterEntry[] {\n if (counters.size === 0) return [];\n const drained = [...counters.values()];\n counters.clear();\n return drained;\n}\n\nexport interface ReportOptions {\n fingerprint: string;\n extra?: Record<string, unknown>;\n}\n\n/**\n * Report an absorbed internal SDK error. Never throws.\n *\n * Signature is unchanged from the Sentry reporter it replaces, so every\n * `absorbErrors` call site keeps working untouched.\n */\nexport function report(error: unknown, options: ReportOptions): void {\n if (reporting) return; // SDKDIAG-06\n reporting = true;\n try {\n const errClass = error instanceof Error ? error.name : \"Error\";\n const errMessage = error instanceof Error ? error.message : String(error);\n\n // SDKDIAG-10: local FIRST, gated only by its own limiter. Transmission may\n // be off, blocked, or failing — the host still sees it.\n if (\n checkBucket(\n localLogBuckets,\n options.fingerprint,\n LOCAL_LOG_LIMIT_PER_WINDOW,\n LOCAL_LOG_WINDOW_MS,\n )\n ) {\n const line = `morse internal error [${options.fingerprint}]: ${errClass}: ${errMessage}`;\n if (isDebug()) console.error(line, error);\n else console.warn(line);\n }\n\n if (!transmissionAllowed()) return;\n if (!checkRateLimit(options.fingerprint)) return;\n\n enqueue({\n kind: \"error\",\n fingerprint: options.fingerprint.slice(0, 255),\n error_type: errClass.slice(0, 255),\n message: redactedMessage(error),\n stack: buildScopedStack(error),\n sdk_language: \"typescript\",\n sdk_version: sdkVersion(),\n runtime_version: runtimeVersion(),\n platform: platformLabel(),\n extra: scrubExtra(options.extra),\n });\n } catch {\n // Absolute last-resort: nothing here may propagate.\n } finally {\n reporting = false;\n }\n}\n\nfunction sdkVersion(): string {\n return SDK_VERSION;\n}\n\nfunction runtimeVersion(): string {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const proc = (globalThis as any).process;\n return proc?.version ? String(proc.version) : \"\";\n } catch {\n return \"\";\n }\n}\n\nfunction platformLabel(): string {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const proc = (globalThis as any).process;\n if (proc?.platform) return `${proc.platform}-${proc.arch ?? \"\"}`.slice(0, 128);\n return \"browser\";\n } catch {\n return \"\";\n }\n}\n\nfunction enqueue(event: DiagnosticEvent): void {\n // Oldest-first eviction: during an incident the newest diagnostics describe\n // what is happening now; a buffer of stale ones is worth less.\n pending.push(event);\n while (pending.length > MAX_PENDING) pending.shift();\n ensureTimer();\n}\n\n/**\n * Arm the flush timer on first use — never at import.\n *\n * Option B's lazy half, and it matters more here than in Python: an armed\n * `setInterval` keeps the Node event loop alive, so a healthy process that\n * armed one at import would refuse to exit. `unref()` where available means\n * even an armed timer never holds the process open.\n */\nfunction ensureTimer(): void {\n if (timer !== null) return;\n try {\n timer = setInterval(() => {\n void flushOnce();\n }, FLUSH_INTERVAL_MS);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (timer as any)?.unref?.();\n } catch {\n timer = null;\n }\n}\n\nfunction breakerBlocks(): boolean {\n return breakerOpenUntil > 0 && Date.now() < breakerOpenUntil;\n}\n\nfunction recordResult(ok: boolean): void {\n if (ok) {\n consecutiveFailures = 0;\n breakerOpenUntil = 0;\n return;\n }\n consecutiveFailures += 1;\n if (consecutiveFailures >= BREAKER_THRESHOLD) {\n // Open the breaker; when it lapses exactly one probe goes out (the counter\n // is not reset, so a failed probe re-opens it immediately).\n breakerOpenUntil = Date.now() + BREAKER_COOLDOWN_MS;\n }\n}\n\nexport async function flushOnce(): Promise<void> {\n try {\n const batch = pending.splice(0, MAX_BATCH_EVENTS);\n const drained = drainCounters();\n if (drained.length > 0) {\n batch.push({\n kind: \"counters\",\n fingerprint: \"morse.transport.delivery\",\n counters: drained,\n sdk_language: \"typescript\",\n sdk_version: sdkVersion(),\n });\n }\n // SDKDIAG-01/09: a healthy interval transmits nothing.\n if (batch.length === 0) return;\n if (breakerBlocks() || !transmissionAllowed()) return;\n\n const target = resolveTarget();\n if (target === null) return;\n\n let response: Response;\n try {\n response = await fetch(target.url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${target.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ events: batch }),\n });\n } catch {\n // Network fault. No retry — a retry loop here would amplify exactly the\n // situation we are reporting about (SDKDIAG-06).\n recordResult(false);\n return;\n }\n setLevel(response.headers.get(\"X-Morse-Diagnostics\"));\n recordResult(response.ok);\n } catch {\n // The flush loop must outlive any single batch.\n }\n}\n\n// MHQ-927: the live client's configuration, pushed in by `init()`.\n//\n// Python's `_resolve_target` reads `morse_ai._client` first and only falls\n// back to the environment. TS read the environment ONLY, so a consumer who\n// configured the SDK programmatically — `morse.init({ apiKey, endpoint })`,\n// the idiomatic and documented form — had no resolvable target and every\n// diagnostic was silently dropped. Traces still worked, because the transport\n// gets its config from `init()` directly.\n//\n// Pushed rather than pulled, mirroring `setDiagnosticsRedactionConfig`, to\n// keep diagnostics free of an import cycle back into `index.ts`.\nlet clientConfig: { apiKey?: string; endpoint?: string } | null = null;\n\nexport function setDiagnosticsClientConfig(\n config: { apiKey?: string; endpoint?: string } | null,\n): void {\n clientConfig = config;\n}\n\nfunction resolveTarget(): { apiKey: string; url: string } | null {\n try {\n const apiKey = clientConfig?.apiKey || getApiKey();\n if (!apiKey) return null; // No authenticated destination — local-log-only.\n const url = deriveDiagnosticsUrl(String(clientConfig?.endpoint || getEndpoint() || \"\"));\n if (!url) return null;\n return { apiKey: String(apiKey), url };\n } catch {\n return null;\n }\n}\n\nexport function deriveDiagnosticsUrl(tracesEndpoint: string): string | null {\n try {\n const parsed = new URL(tracesEndpoint);\n return `${parsed.protocol}//${parsed.host}${DIAGNOSTICS_PATH}`;\n } catch {\n return null;\n }\n}\n\n/**\n * Test-only reset hook.\n *\n * @internal\n */\nexport function _resetForTesting(): void {\n clientConfig = null;\n rateBuckets.clear();\n localLogBuckets.clear();\n counters.clear();\n pending = [];\n if (timer !== null) {\n clearInterval(timer);\n timer = null;\n }\n consecutiveFailures = 0;\n breakerOpenUntil = 0;\n reporting = false;\n level = LEVEL_ERROR;\n activeRedactionConfig = null;\n}\n\n/**\n * True when the flush timer is armed. Exported so tests can assert the\n * central Option B claim: a healthy process arms nothing.\n *\n * @internal\n */\nexport function _hasTimer(): boolean {\n return timer !== null;\n}\n","/**\n * Browser replacement for `otel-provider.ts` (MHQ-482 follow-up).\n *\n * Why this file exists\n * --------------------\n * `otel-provider.ts` is Node-only by construction — it statically imports\n * `@opentelemetry/sdk-trace-node`, `@opentelemetry/context-async-hooks`\n * (`async_hooks`), `@opentelemetry/instrumentation` (node `module`) and the\n * proto exporter's Node build. Because `index.ts` -> `tracing.ts` ->\n * `otel-provider.ts` is a static chain, ANY bundler targeting the browser\n * pulled those Node built-ins into the browser graph and failed to resolve\n * them. `tracing.ts`'s own docstring flagged this as a deferred decision\n * (\"a future browser-targeted build would need ... to keep the JSON path as\n * the browser default\"); this module is that decision, taken.\n *\n * The build swaps this module in for `otel-provider.ts` via the esbuild\n * plugin in `tsup.config.ts`, and `package.json`'s `\"browser\"` export\n * condition points browser bundlers at the resulting `dist/browser/*`. No\n * consumer configuration is involved — webpack, Turbopack, Vite, Rollup and\n * esbuild all honour the condition automatically.\n *\n * Behaviour, not a black hole\n * ---------------------------\n * Tracing still WORKS in the browser: `isOtelAvailable()` returns false, so\n * `tracing.ts::sendTrace` routes traces down the legacy JSON transport\n * (the same path `MORSE_LEGACY_TRANSPORT=1` selects in Node) instead of\n * dropping them. What is genuinely unavailable in a browser is the OTLP\n * span pipeline and DB-driver instrumentation; `noteBrowserRuntime()` says\n * so once, out loud, rather than leaving an integrator to wonder why their\n * spans look different from the Node docs.\n */\n\n/** Public surface mirrors `otel-provider.ts` exactly — see that module. */\nexport interface OtelEngineConfigureOptions {\n apiKey?: string | undefined;\n endpoint?: string | undefined;\n sampleRate?: number | undefined;\n maxFieldBytes?: number | undefined;\n redaction?: unknown;\n [key: string]: unknown;\n}\n\nexport interface TraceEntryLike {\n trace: Record<string, unknown>;\n spans: Record<string, unknown>[];\n}\n\nlet warned = false;\n\n/**\n * Emit the one-time \"you are on the browser build\" notice.\n *\n * Deliberately `console.info`, not `warn`: nothing is broken and nothing\n * needs fixing — a warning here would train integrators to ignore the\n * console. Fires only once per bundle, and only when the SDK is actually\n * configured (i.e. the app really did initialize Morse), so a page that\n * merely imports the SDK stays silent.\n */\nfunction noteBrowserRuntime(): void {\n if (warned) return;\n warned = true;\n try {\n console.info(\n \"[morse] Browser build active: OpenTelemetry span export and database \" +\n \"capture are Node-only, so traces are sent via Morse's JSON transport \" +\n \"instead. Everything else — run()/span()/track() and W3C traceparent \" +\n \"propagation — behaves identically. Server-side code (Next.js route \" +\n \"handlers, RSC, Node services) automatically gets the full OTel pipeline.\",\n );\n } catch {\n // A console-less runtime is not a reason to fail a customer's app.\n }\n}\n\n/**\n * Browser stand-in for `OtelEngine`. Every method is a safe no-op with the\n * same signature, so `index.ts` needs no `typeof window` branches.\n */\nexport class OtelEngine {\n // Params are declared (not dropped) so this class stays signature-compatible\n // with the real `OtelEngine` — the build swaps the modules, but anything\n // type-checking against this one must see the same shape. `void x` marks the\n // deliberate non-use for @typescript-eslint/no-unused-vars.\n configure(opts: OtelEngineConfigureOptions): void {\n void opts;\n noteBrowserRuntime();\n }\n\n shutdown(): void {}\n\n resetForTesting(): void {\n warned = false;\n }\n\n async flush(): Promise<void> {}\n\n resolveSampled(traceIdHex: string): boolean {\n void traceIdHex;\n // Sampling in the browser is decided by the JSON transport path, which\n // applies its own rate — claiming \"sampled\" here would double-apply it.\n return true;\n }\n\n registerInstrumentations(instrumentations: unknown[]): (() => void) | null {\n void instrumentations;\n // DB-driver instrumentation requires `require-in-the-middle`; there is\n // nothing to hook in a browser.\n return null;\n }\n}\n\nconst engine = new OtelEngine();\n\nexport function getEngine(): OtelEngine {\n return engine;\n}\n\n/**\n * False in the browser build — `tracing.ts::sendTrace` reads this to pick\n * the JSON transport instead of the (absent) OTLP pipeline.\n */\nexport function isOtelAvailable(): boolean {\n return false;\n}\n\n/**\n * Never called: `sendTrace` checks `isOtelAvailable()` first. Kept so the\n * module's shape matches `otel-provider.ts` (a shape mismatch would only\n * surface as a bundler error in a customer's build), and defensive — if it\n * ever IS reached, dropping the trace silently is the one outcome that must\n * not happen, so it reports rather than returning quietly.\n */\nexport function emitTraceEntry(entry: TraceEntryLike): void {\n void entry;\n noteBrowserRuntime();\n throw new Error(\"morse: OTLP export is unavailable in the browser build\");\n}\n\n/** No live OTel context to enter in a browser — run `fn` unchanged. */\nexport function withOtelSpanContext<T>(traceIdHex: string, spanIdHex: string, fn: () => T): T {\n void traceIdHex;\n void spanIdHex;\n return fn();\n}\n","/**\n * Span model — the wire format the SDK sends to Morse.\n *\n * Mirrors `apps/sdk/python/src/morse/spans.py` field-for-field. The\n * backend's `SpanType` choices are the source of truth.\n */\n\nexport const SpanType = {\n AGENT: \"agent\",\n LLM: \"llm\",\n TOOL: \"tool\",\n HTTP: \"http\",\n DB: \"db\",\n CUSTOM: \"custom\",\n MEMORY: \"memory\",\n // MHQ-482: matches Python's `SpanType.RETRIEVER` (apps/sdk/python/src/morse_ai/spans.py).\n // @beta — retriever span type is subject to change before SDK v1.0 (see\n // the plain-LangChain adapter's on_retriever_* callbacks in src/langchain/).\n RETRIEVER: \"retriever\",\n} as const;\n\nexport type SpanType = (typeof SpanType)[keyof typeof SpanType];\n\nexport type SpanStatus = \"completed\" | \"failed\" | \"timed_out\";\n\n/**\n * Wire-format shape of one context segment carried on an LLM span.\n *\n * Mirrors the Python `morse.context.ContextSegmentDict` — keep both\n * sides in lockstep with the backend `ContextSegmentIn` Pydantic schema.\n *\n * - `tokens` is intentionally optional on the wire; the server tokenizes\n * when omitted to keep client-side cost and dependency surface small.\n * - `source` accepts either underscored DB enum values (`memory_vector`)\n * or the dotted public-API form (`memory.vector`); the server\n * `normalize_segment_source` helper translates dots → underscores.\n */\nexport interface ContextSegment {\n position: number;\n source: string;\n content_hash: string;\n content?: string;\n content_truncated?: boolean;\n tokens?: number;\n tokens_estimated?: boolean;\n cache_state?: \"cold\" | \"cache_write\" | \"cache_hit\";\n attrs?: Record<string, unknown>;\n producer_span_id?: string;\n}\n\nexport interface SpanData {\n trace_id: string;\n span_id: string;\n type: SpanType;\n name: string;\n parent_span_id?: string;\n started_at: string;\n ended_at?: string;\n duration_ms?: number;\n status: SpanStatus;\n // LLM-specific\n model?: string;\n input_tokens?: number;\n output_tokens?: number;\n cached_input_tokens?: number;\n cache_write_tokens?: number;\n total_tokens?: number;\n cost_usd?: number;\n // Payload\n input_data?: unknown;\n output_data?: unknown;\n error_message?: string;\n metadata?: Record<string, unknown>;\n /**\n * Pre-segmented context profile (Anthropic / LangGraph adapters populate this).\n * `undefined` → server runs its messages-array classifier.\n * `[]` → SDK explicitly says no segments (server skips classifier).\n * Populated → server skips classification and persists as-is.\n */\n context_segments?: ContextSegment[];\n}\n\nexport interface TraceFields {\n trace_id: string;\n /** Backend `TracePayloadIn.agent` — matches Python SDK + Pydantic schema. */\n agent: string;\n status: SpanStatus;\n started_at: string;\n ended_at?: string;\n duration_ms?: number;\n error_message?: string;\n success?: boolean;\n outcome?: string;\n}\n\nexport interface TraceEntry {\n trace: TraceFields;\n spans: SpanData[];\n}\n\n/** 32-char hex (128-bit). Compatible with W3C trace_id format. */\nexport function generateTraceId(): string {\n return randomHex(32);\n}\n\n/**\n * 32-char hex (UUID4-style, 128-bit). Matches the backend's UUID-typed\n * `span_id` column and the sibling Python SDK (`uuid.uuid4().hex`).\n *\n * When the SDK emits a W3C traceparent header (see `src/propagation.ts`),\n * the first 16 hex chars are sliced off to fit the W3C `span_id` slot —\n * that interop is handled at the header-formatting layer, not here.\n *\n * Was 16 hex chars historically (W3C span_id format) until Phase 13\n * Option A dogfood surfaced silent backend rejection: the dev ingest\n * `TracePayloadIn` schema requires UUID-shaped span_ids and was tossing\n * every TS-emitted span with `Invalid span_id format (expected UUID)`.\n */\nexport function generateSpanId(): string {\n return randomHex(32);\n}\n\nfunction randomHex(chars: number): string {\n const bytes = new Uint8Array(Math.ceil(chars / 2));\n // Use Web Crypto when available (Node 19+, all browsers).\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cryptoObj = (globalThis as any).crypto as Crypto | undefined;\n if (cryptoObj?.getRandomValues) {\n cryptoObj.getRandomValues(bytes);\n } else {\n // Fallback: Math.random — non-cryptographic but acceptable for trace IDs.\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n let hex = \"\";\n for (const b of bytes) {\n hex += b.toString(16).padStart(2, \"0\");\n }\n return hex.slice(0, chars);\n}\n\nexport function nowIso(): string {\n return new Date().toISOString();\n}\n\n/** Serialize a SpanData, dropping undefined fields, matching Python's to_dict(). */\nexport function spanToWire(span: SpanData): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(span)) {\n if (v !== undefined && v !== null) {\n out[k] = v;\n }\n }\n return out;\n}\n\nexport function buildTraceEntry(\n fields: TraceFields,\n spans: SpanData[],\n): { trace: TraceFields; spans: Record<string, unknown>[] } {\n return {\n trace: fields,\n spans: spans.map(spanToWire),\n };\n}\n","/**\n * SDK V2 tracing core — TraceState, run(), span() context-manager-likes.\n *\n * Mirrors `apps/sdk/python/src/morse/tracing.py`. Key differences:\n *\n * - Python uses `contextvars.ContextVar` for async/coroutine isolation.\n * In Node we use `node:async_hooks.AsyncLocalStorage` when available\n * (server-side, including Next.js API routes). On the browser there\n * is no equivalent; we fall back to a module-global slot. This is\n * acceptable because in the browser there is exactly one event loop\n * and one user — no parallel traces.\n *\n * - \"Context manager\" idioms in TS use callback-style: `run(name, fn)`\n * and `span(name, type, fn)` accept a function and invoke it with\n * the active state on the stack. We keep an explicit `start/end`\n * pair on the public surface for callers who can't use callbacks\n * (e.g., when the work spans an SSE stream).\n *\n * - MHQ-482: `run()`/`span()`/`runTraced()`'s emission path now goes\n * through `./otel-provider` (real OTel spans over OTLP, Node-only —\n * mirrors the Python SDK's MHQ-668 `otel_provider.py`). This is a\n * deliberate Node-only deviation from this module's own browser\n * fallback for `AsyncLocalStorage` above: `otel-provider.ts` statically\n * imports `@opentelemetry/sdk-trace-node`, which pulls in Node built-ins\n * (`node:crypto`, `node:http`/`https`) that don't exist in a browser\n * bundle. A future browser-targeted build would need either a\n * browser-flavored OTel exporter swapped in at this call site or to\n * keep `MORSE_LEGACY_TRANSPORT=1`'s JSON path as the browser default —\n * out of scope for this port (see the PR report's deviation notes).\n *\n * - MHQ-482 (db-capture follow-up): `runSync`/`runAsync`/`spanSync`/\n * `spanAsync` now ALSO wrap `fn()` in a live OTel context via\n * `otel-provider.ts::withOtelSpanContext` (Node only — a no-op\n * passthrough everywhere else, including the browser fallback path,\n * since that helper itself no-ops when the OTel engine isn't\n * configured). This is what lets community DB-driver instrumentation\n * (`./db-capture.ts`) — which reads OTel's *global*\n * `context.active()`, not this module's `TraceState` — see the right\n * trace id and nest under the right parent span id when a query runs\n * inside an active `morse.span()`/`morse.run()` block. It's a\n * deliberately separate mechanism from `emitTraceEntry`'s\n * synthetic-parent trick: that one runs once at trace-close time over\n * already-built `SpanData`; this one runs live, for spans this module\n * never sees (they're built entirely inside the instrumentation\n * package and exported directly to the same `NodeTracerProvider`).\n */\n\nimport { isLegacyTransport, isValidInternalSource } from \"./env\";\nimport { emitTraceEntry, isOtelAvailable, withOtelSpanContext } from \"./otel-provider\";\nimport { setRedactionConfig as setDiagnosticsRedactionConfig } from \"./diagnostics\";\nimport { buildRedactionConfig, type RedactionConfig, redactValue } from \"./redaction\";\nimport type { SpanData, SpanStatus, SpanType } from \"./spans\";\nimport { generateSpanId, generateTraceId, nowIso } from \"./spans\";\n\n/* ------------------------------------------------------------------------ */\n/* Internal state */\n/* ------------------------------------------------------------------------ */\n\nexport interface TraceState {\n traceId: string;\n agentName: string;\n spanStack: SpanData[];\n completedSpans: SpanData[];\n // Mutable outcome fields — set by `run()` callers via the returned handle.\n success?: boolean;\n outcome?: string;\n errorMessage?: string;\n // Multi-turn attribution (MHQ-748). threadId groups traces in the same\n // conversation; userId is the app-layer end-user identifier. Both\n // optional — mirrors Python's `_TraceState.thread_id`/`user_id`.\n threadId?: string;\n userId?: string;\n // Cost-attribution dimensions — set via `run({ userMetadata })` at\n // trace-creation time, or mutated mid-trace via `setContext()` (MHQ-751).\n // Keys/values are always strings at the SDK boundary — mirrors Python's\n // `_TraceState.user_metadata`.\n userMetadata?: Record<string, string>;\n // Per-trace override of the resource-level `morse_ai.source` tag. Wins\n // over the process-level `_source` when set — mirrors Python's\n // `_TraceState.source_override`.\n sourceOverride?: string;\n // MHQ-859: framework recorded by whichever adapter fired first inside\n // this trace (`_internal/active-framework.ts`). Lifted onto the trace\n // resource as `morse_ai.framework` — mirrors Python's\n // `_TraceState.framework`. Absence is the signal; never defaulted.\n framework?: string;\n}\n\ntype AlsLike<T> = {\n getStore(): T | undefined;\n run<R>(value: T, fn: () => R): R;\n};\n\nlet als: AlsLike<TraceState> | null = null;\nlet alsLoaded = false;\nlet browserState: TraceState | null = null;\n\nfunction tryLoadAls(): AlsLike<TraceState> | null {\n if (alsLoaded) return als;\n alsLoaded = true;\n // Skip in the browser.\n if (typeof process === \"undefined\" || !process.versions?.node) {\n als = null;\n return als;\n }\n // MHQ-924: two resolution paths, tried in order. `require` alone is NOT\n // enough — it does not exist in ESM, so every `.mjs` / `\"type\": \"module\"`\n // consumer silently fell through to the browser fallback below. That\n // fallback is a module-global, which survives synchronous code but is lost\n // across the first `await`, so EVERY child span was dropped with \"no active\n // trace\" while the root span still persisted. Node consumers were never\n // getting AsyncLocalStorage at all.\n //\n // Order matters: getBuiltinModule first, because it is the only one of the\n // two that works in both module systems.\n //\n // 1. `process.getBuiltinModule` — Node 22.3+, synchronous, and identical\n // in ESM and CJS. Not a bundler-visible specifier, so the browser\n // build still cannot try to resolve `node:async_hooks`.\n // 2. runtime-eval'd `require` — CJS, and older Node versions.\n //\n // A dynamic `import()` is not an option: this function is synchronous and\n // is called on the hot path by getActiveTraceState().\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const getBuiltin = (process as any)?.getBuiltinModule as ((m: string) => unknown) | undefined;\n if (typeof getBuiltin === \"function\") {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod = getBuiltin(\"node:async_hooks\") as any;\n if (mod?.AsyncLocalStorage) {\n als = new mod.AsyncLocalStorage() as AlsLike<TraceState>;\n return als;\n }\n }\n } catch {\n // Fall through to the require path.\n }\n try {\n // Use a runtime-eval'd require so the browser bundler doesn't try\n // to resolve `node:async_hooks`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const dynamicRequire = Function(\"m\", \"return require(m)\") as any as (m: string) => unknown;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod = dynamicRequire(\"node:async_hooks\") as any;\n if (mod?.AsyncLocalStorage) {\n als = new mod.AsyncLocalStorage() as AlsLike<TraceState>;\n return als;\n }\n } catch {\n // Fall through to browser fallback.\n }\n // Genuinely no ALS: browser, or a Node old enough to have neither path.\n // The module-global fallback below is correct there — a browser has no\n // concurrent async contexts to confuse it.\n als = null;\n return als;\n}\n\nexport function getActiveTraceState(): TraceState | null {\n const store = tryLoadAls();\n if (store) {\n return store.getStore() ?? null;\n }\n return browserState;\n}\n\nfunction setActiveTraceState(state: TraceState | null): () => void {\n // Returns a \"reset\" callback. Used only on the browser path. On Node,\n // `als.run()` handles the lifecycle.\n const previous = browserState;\n browserState = state;\n return () => {\n browserState = previous;\n };\n}\n\n/* ------------------------------------------------------------------------ */\n/* Transport injection */\n/* ------------------------------------------------------------------------ */\n\nexport interface TransportLike {\n track(event: { traces: unknown[] } | Record<string, unknown>): boolean;\n}\n\nlet transport: TransportLike | null = null;\n\nexport function setTransport(t: TransportLike | null): void {\n transport = t;\n}\n\nexport function getTransport(): TransportLike | null {\n return transport;\n}\n\n/* ------------------------------------------------------------------------ */\n/* Redaction config — module-level, replaceable on init() */\n/* ------------------------------------------------------------------------ */\n\n// Default-on with the canonical catalogue. Replaced when `init()` runs\n// with explicit redaction options. Customers calling SDK helpers before\n// `init()` still get the default redaction floor.\nlet redactionConfig: RedactionConfig = buildRedactionConfig();\n\nexport function setRedactionConfig(config: RedactionConfig): void {\n redactionConfig = config;\n // Keep the diagnostics reporter's view in sync so an exception MESSAGE gets\n // the same redaction as span content (SDKDIAG-02). Pushed rather than pulled\n // to keep diagnostics free of a cycle back into tracing.\n setDiagnosticsRedactionConfig(config);\n}\n\nexport function getRedactionConfig(): RedactionConfig {\n return redactionConfig;\n}\n\n/* ------------------------------------------------------------------------ */\n/* Resource-level \"source\" label (dogfood emitter discrimination) */\n/* ------------------------------------------------------------------------ */\n\n// Process-level source tag. Lifted into each outgoing trace's `resource`\n// dict so the backend can discriminate Morse's own dogfood emitters\n// from customer traces. Mirrors the Python SDK's module-level `_source`.\nlet _source: string | null = null;\n\nexport function setSource(value: string | null | undefined): void {\n _source = value && value.length > 0 ? value : null;\n}\n\nexport function getSource(): string | null {\n return _source;\n}\n\nlet lastTrace: { trace: unknown; spans: unknown[] } | null = null;\n\nexport function getLastTrace(): { trace: unknown; spans: unknown[] } | null {\n return lastTrace;\n}\n\n/* ------------------------------------------------------------------------ */\n/* Trace lifecycle helpers */\n/* ------------------------------------------------------------------------ */\n\nfunction nowMonotonic(): number {\n // performance.now() is available in Node >= 16 globally and in all browsers.\n if (typeof performance !== \"undefined\" && typeof performance.now === \"function\") {\n return performance.now();\n }\n return Date.now();\n}\n\nfunction elapsedMs(startMonotonic: number): number {\n return Math.max(0, Math.round(nowMonotonic() - startMonotonic));\n}\n\nfunction finalizeSpan(\n span: SpanData,\n startMono: number,\n status: SpanStatus = \"completed\",\n errorMessage?: string,\n): void {\n span.ended_at = nowIso();\n span.duration_ms = elapsedMs(startMono);\n span.status = status;\n if (errorMessage !== undefined) {\n span.error_message = errorMessage;\n }\n}\n\n/**\n * Field allowlist for span-level redaction. Identifiers, timestamps,\n * counts, and types pass through untouched; user-supplied strings and\n * JSON blobs route through `redactValue`.\n */\nconst SPAN_REDACTABLE_FIELDS: ReadonlySet<string> = new Set([\n \"name\",\n \"input_data\",\n \"output_data\",\n \"error_message\",\n \"metadata\",\n]);\n\nconst TRACE_REDACTABLE_FIELDS: ReadonlySet<string> = new Set([\"agent\", \"outcome\", \"error_message\"]);\n\nfunction redactSpanDict(\n raw: Record<string, unknown>,\n config: RedactionConfig,\n): Record<string, unknown> {\n if (!config.enabled) return raw;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(raw)) {\n if (SPAN_REDACTABLE_FIELDS.has(k)) {\n out[k] = redactValue(v, config);\n } else {\n out[k] = v;\n }\n }\n return out;\n}\n\nfunction redactTraceDict(\n raw: Record<string, unknown>,\n config: RedactionConfig,\n): Record<string, unknown> {\n if (!config.enabled) return raw;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(raw)) {\n if (TRACE_REDACTABLE_FIELDS.has(k)) {\n out[k] = redactValue(v, config);\n } else {\n out[k] = v;\n }\n }\n return out;\n}\n\nfunction buildTraceDict(\n state: TraceState,\n rootSpan: SpanData,\n): {\n trace: Record<string, unknown>;\n spans: Record<string, unknown>[];\n} {\n const trace: Record<string, unknown> = {\n trace_id: state.traceId,\n // Wire-format field is `agent` (matches backend TracePayloadIn schema +\n // sibling Python SDK). Was `agent_name` historically — the mismatch\n // caused dev ingest to reject every TS-emitted trace with a 422\n // until Phase 13 Option A dogfood surfaced it.\n agent: state.agentName,\n status: rootSpan.status,\n started_at: rootSpan.started_at,\n };\n if (rootSpan.ended_at) trace.ended_at = rootSpan.ended_at;\n if (rootSpan.duration_ms !== undefined) trace.duration_ms = rootSpan.duration_ms;\n if (rootSpan.error_message) trace.error_message = rootSpan.error_message;\n if (state.success !== undefined) trace.success = state.success;\n if (state.outcome !== undefined) trace.outcome = state.outcome;\n // MHQ-748/MHQ-751: multi-turn + cost-attribution dimensions. Field names\n // (`thread_id`/`user_id`/`user_metadata`) match the backend's\n // `TracePayloadIn` schema exactly (apps/api/apps/traces/schemas.py) and\n // the sibling Python SDK's `_build_trace_dict` — do not camelCase these.\n if (state.threadId !== undefined) trace.thread_id = state.threadId;\n if (state.userId !== undefined) trace.user_id = state.userId;\n if (state.userMetadata && Object.keys(state.userMetadata).length > 0) {\n trace.user_metadata = state.userMetadata;\n }\n\n const allSpans = [rootSpan, ...state.completedSpans];\n const spans = allSpans.map((s) => {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(s)) {\n if (v !== undefined && v !== null) {\n out[k] = v;\n }\n }\n return out;\n });\n\n const config = redactionConfig;\n const out = {\n trace: redactTraceDict(trace, config),\n spans: spans.map((s) => redactSpanDict(s, config)),\n };\n // Per-trace `sourceOverride` wins over the process-level `_source` —\n // mirrors Python's `_build_trace_dict`'s `effective_source = state.source_override or _source`.\n const effectiveSource = state.sourceOverride || _source;\n // MHQ-859: `morse_ai.framework` rides the same resource envelope as\n // `morse_ai.source` — both are per-trace values a process-wide OTel\n // Resource cannot express, and `otel-provider.ts` already lifts both onto\n // the root span as `av.source` / `av.framework`. Python has stamped the\n // framework since AGE-240; TS never did, so every TS trace landed with\n // `framework` NULL.\n const resource: Record<string, unknown> = {};\n if (effectiveSource) {\n // Lift the source label onto the trace envelope so the backend can\n // route dogfood-emitter traces to the internal dashboards. Mirrors\n // Python's `resource[\"morse_ai.source\"]`.\n resource[\"morse_ai.source\"] = effectiveSource;\n }\n if (state.framework) {\n resource[\"morse_ai.framework\"] = state.framework;\n }\n if (Object.keys(resource).length > 0) {\n (out as Record<string, unknown>).resource = resource;\n }\n return out;\n}\n\n/**\n * `run()` / `span()` / `runTraced()`'s emission path: real OTel spans over\n * OTLP (MHQ-482, mirrors Python's `tracing.py::_finish_trace`, MHQ-668).\n * Always updates `lastTrace` (test/debug introspection — same bookkeeping\n * regardless of which pipeline actually ships the trace), then hands the\n * dict to `otel-provider.ts::emitTraceEntry()` — unless\n * `MORSE_LEGACY_TRANSPORT=1`, in which case it falls back to the old JSON\n * queue path instead (rollback escape hatch; never both, to avoid\n * double-ingesting the same trace).\n *\n * Exported (MHQ-746) so `index.ts::record()` can submit a synthetic\n * single-span trace through this same pipeline instead of the defunct\n * `runs`-shaped `state.transport.track()` path — mirrors the Python SDK's\n * `client.py::record()`, which builds a trace + span dict and calls this\n * module's `_send_trace()` directly rather than going through `track()`.\n */\nexport function sendTrace(entry: {\n trace: Record<string, unknown>;\n spans: Record<string, unknown>[];\n}): void {\n lastTrace = entry;\n\n // `!isOtelAvailable()` is the browser build (see `otel-provider.browser.ts`):\n // the OTLP pipeline is Node-only, so browser traces take the same JSON path\n // the legacy escape hatch uses rather than being dropped. Still never both.\n if (isLegacyTransport() || !isOtelAvailable()) {\n if (transport !== null) {\n try {\n transport.track({ traces: [entry] });\n } catch {\n // never propagate\n }\n }\n return;\n }\n\n try {\n emitTraceEntry(entry);\n } catch {\n // never propagate — mirrors the rest of the SDK's non-invasive guarantee\n }\n}\n\n/**\n * Run `fn` with the OTel-global active context set to a synthetic\n * `SpanContext` for `spanIdHex` under `traceId` (MHQ-482 db-capture\n * correlation — see the module docstring). No-op passthrough if the OTel\n * engine isn't configured (browser, uninitialized SDK, or\n * `otel-provider.ts` import failure) — never throws, mirrors the rest of\n * this module's non-invasive guarantee.\n */\nfunction withDbCaptureContext<T>(traceId: string, spanIdHex: string, fn: () => T): T {\n try {\n // OTel SpanId is 64-bit (16 hex chars); Morse's span_id is 128-bit\n // (32 hex chars) — same truncation convention `spans.ts::generateSpanId`\n // documents for W3C traceparent interop.\n return withOtelSpanContext(traceId, spanIdHex.slice(0, 16), fn);\n } catch {\n return fn();\n }\n}\n\n/* ------------------------------------------------------------------------ */\n/* Public-ish run() and span() — wrapped at the module surface */\n/* ------------------------------------------------------------------------ */\n\nexport interface RunOptions {\n agentName: string;\n /** W3C traceparent value to continue an upstream trace, when available. */\n incomingTraceparent?: string | null;\n /**\n * Application-layer conversation/thread identifier (MHQ-748). Groups all\n * traces from the same multi-turn session so the dashboard can show the\n * full conversation history for a thread. Mirrors Python's\n * `run(thread_id=...)`.\n */\n threadId?: string;\n /**\n * Application-layer end-user identifier (e.g. a user primary key or\n * email) (MHQ-748). Enables per-user filtering in the dashboard. Mirrors\n * Python's `run(user_id=...)`.\n */\n userId?: string;\n /**\n * Cost-attribution dimensions attached to this trace at creation time\n * (e.g. `customer_id`, `feature`, `env`, `team`) (MHQ-748). Values are\n * coerced to strings. Can also be set/merged mid-trace via\n * `setContext()` (MHQ-751). Mirrors Python's `run(user_metadata=...)`.\n */\n userMetadata?: Record<string, unknown>;\n /**\n * INTERNAL USE ONLY — per-trace override for the resource-level\n * `morse_ai.source` tag. Wins over the process-level source set at\n * `init({ source })`. Accepted values: `\"copilot\" | \"investigator\" |\n * \"refagent\" | \"ui-bot\"`; anything else is silently ignored and the\n * process-level source is used. Customer code should leave this unset.\n * Mirrors Python's `run(source=...)`.\n */\n source?: string;\n}\n\nexport interface RunHandle {\n setOutcome(success: boolean, outcome?: string): void;\n setError(message: string): void;\n /** Internal — set by `runSync`/`runAsync`. */\n _state: TraceState;\n}\n\nfunction buildRunHandle(state: TraceState): RunHandle {\n return {\n setOutcome(success, outcome) {\n state.success = success;\n if (outcome !== undefined) state.outcome = outcome;\n },\n setError(message) {\n state.errorMessage = message;\n state.success = false;\n },\n _state: state,\n };\n}\n\nfunction startTrace(opts: RunOptions): {\n state: TraceState;\n rootSpan: SpanData;\n startMono: number;\n} {\n let traceId: string | undefined;\n if (opts.incomingTraceparent) {\n // Lazy import to avoid a cycle.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { extractTraceparent } = require(\"../propagation\") as typeof import(\"../propagation\");\n const ctx = extractTraceparent(opts.incomingTraceparent);\n if (ctx) {\n traceId = ctx.traceId;\n }\n }\n if (!traceId) traceId = generateTraceId();\n\n const state: TraceState = {\n traceId,\n agentName: opts.agentName,\n spanStack: [],\n completedSpans: [],\n };\n if (opts.threadId !== undefined) state.threadId = opts.threadId;\n if (opts.userId !== undefined) state.userId = opts.userId;\n if (opts.userMetadata) {\n state.userMetadata = Object.fromEntries(\n Object.entries(opts.userMetadata).map(([k, v]) => [k, String(v)]),\n );\n }\n // Validate against the same whitelist as `init({ source })` — an invalid\n // value falls through to whatever the process has set (never throws).\n if (isValidInternalSource(opts.source)) {\n state.sourceOverride = opts.source;\n }\n const rootSpan: SpanData = {\n trace_id: traceId,\n span_id: generateSpanId(),\n type: \"agent\" as SpanType,\n name: opts.agentName,\n started_at: nowIso(),\n status: \"completed\",\n };\n state.spanStack.push(rootSpan);\n return { state, rootSpan, startMono: nowMonotonic() };\n}\n\nfunction endTrace(\n state: TraceState,\n rootSpan: SpanData,\n startMono: number,\n threwError: unknown,\n): void {\n state.spanStack.pop();\n if (threwError !== undefined) {\n const msg = state.errorMessage ?? errToString(threwError);\n finalizeSpan(rootSpan, startMono, \"failed\", msg);\n if (state.success === undefined) state.success = false;\n } else if (state.errorMessage !== undefined) {\n finalizeSpan(rootSpan, startMono, \"failed\", state.errorMessage);\n // setError() already set state.success = false.\n } else {\n finalizeSpan(rootSpan, startMono);\n if (state.success === undefined) state.success = true;\n }\n const dict = buildTraceDict(state, rootSpan);\n sendTrace(dict);\n}\n\nfunction errToString(e: unknown): string {\n if (e instanceof Error) return e.message;\n return String(e);\n}\n\n/* ------------------------------------------------------------------------ */\n/* Sync + async run() wrappers */\n/* ------------------------------------------------------------------------ */\n\n/** True for anything await-able, without assuming a real Promise. */\nfunction isThenable(v: unknown): v is PromiseLike<unknown> {\n return (\n v !== null &&\n (typeof v === \"object\" || typeof v === \"function\") &&\n typeof (v as { then?: unknown }).then === \"function\"\n );\n}\n\nexport function runSync<T>(opts: RunOptions, fn: (handle: RunHandle) => T): T | undefined {\n const { state, rootSpan, startMono } = startTrace(opts);\n const handle = buildRunHandle(state);\n const store = tryLoadAls();\n\n const runFn = (): T => withDbCaptureContext(state.traceId, rootSpan.span_id, () => fn(handle));\n\n // MHQ-924 (defect B): if `fn` is async, closing the trace here would send it\n // before the body has run, so `state.completedSpans` is still empty and\n // EVERY child span is lost. The root span still lands, so the trace looks\n // healthy — it is just silently truncated. `run()` accepts an async callback\n // (its signature cannot refuse one), so \"use runTraced() instead\" was a\n // documented footgun rather than a safeguard: three adapters and the pino\n // integration each landed exactly one span in live testing because of it.\n //\n // Settling first keeps the sync path byte-identical — a non-thenable result\n // still ends the trace inline — while making the async path correct.\n const settle = (result: T, onDone: () => void): T => {\n if (!isThenable(result)) {\n endTrace(state, rootSpan, startMono, undefined);\n onDone();\n return result;\n }\n return (result as PromiseLike<unknown>).then(\n (value) => {\n endTrace(state, rootSpan, startMono, undefined);\n onDone();\n return value;\n },\n (err) => {\n endTrace(state, rootSpan, startMono, err);\n onDone();\n throw err;\n },\n ) as unknown as T;\n };\n\n if (store) {\n try {\n return settle(store.run(state, runFn), () => {});\n } catch (err) {\n endTrace(state, rootSpan, startMono, err);\n throw err;\n }\n } else {\n // Browser fallback: the reset must not fire until an async body has\n // settled, or the module-global is cleared out from under it.\n const reset = setActiveTraceState(state);\n try {\n return settle(runFn(), reset);\n } catch (err) {\n endTrace(state, rootSpan, startMono, err);\n reset();\n throw err;\n }\n }\n}\n\nexport async function runAsync<T>(\n opts: RunOptions,\n fn: (handle: RunHandle) => Promise<T>,\n): Promise<T | undefined> {\n const { state, rootSpan, startMono } = startTrace(opts);\n const handle = buildRunHandle(state);\n const store = tryLoadAls();\n\n const runFn = (): Promise<T> =>\n withDbCaptureContext(state.traceId, rootSpan.span_id, () => fn(handle));\n\n if (store) {\n try {\n const result = await store.run(state, runFn);\n endTrace(state, rootSpan, startMono, undefined);\n return result;\n } catch (err) {\n endTrace(state, rootSpan, startMono, err);\n throw err;\n }\n } else {\n const reset = setActiveTraceState(state);\n try {\n const result = await runFn();\n endTrace(state, rootSpan, startMono, undefined);\n return result;\n } catch (err) {\n endTrace(state, rootSpan, startMono, err);\n throw err;\n } finally {\n reset();\n }\n }\n}\n\n/**\n * Attach cost-attribution dimensions to the active trace (MHQ-751).\n *\n * Call once per request (e.g. in Express/Next.js middleware) to propagate\n * `customer_id`, `feature`, `env`, `team`, etc. to all child spans\n * automatically. Mirrors Python's `morse_ai.set_context(**dims)`.\n *\n * morse.setContext({ customerId: request.customerId, feature: \"doc-qa\" });\n *\n * Values are coerced to strings via `String(v)` — mirrors Python's `str()`\n * coercion. Merges into any dimensions already set (e.g. via\n * `run({ userMetadata })`) rather than replacing them. No-op outside an\n * active trace — never throws.\n */\nexport function setContext(dims: Record<string, unknown>): void {\n const state = getActiveTraceState();\n if (state === null) return;\n if (state.userMetadata === undefined) state.userMetadata = {};\n for (const [k, v] of Object.entries(dims)) {\n state.userMetadata[k] = String(v);\n }\n}\n\n/* ------------------------------------------------------------------------ */\n/* span() child-span helpers */\n/* ------------------------------------------------------------------------ */\n\nexport interface SpanOptions {\n name: string;\n type?: SpanType;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SpanHandle {\n /** Mutate the underlying span data (e.g., set tokens / cost). */\n span: SpanData;\n end(error?: unknown): void;\n}\n\n// MHQ-806. Latches the \"no active trace\" warning to once per process — see\n// startSpan for why it warns at all, and why not on every call.\nlet spanOutsideTraceWarningEmitted = false;\n\n/** Test hook — clears the once-per-process latch. */\nexport function _resetSpanOutsideTraceWarning(): void {\n spanOutsideTraceWarningEmitted = false;\n}\n\n/** Start a child span under the active trace, returning a handle to close it. */\nexport function startSpan(opts: SpanOptions): SpanHandle | null {\n const state = getActiveTraceState();\n if (state === null) {\n // No active trace — returns null rather than throwing, because library\n // code may be instrumented but reached from an untraced path.\n //\n // The null is visible in the type here, unlike Python's context-manager\n // form, but callers routinely ignore it (`span({...}, () => { ... })`\n // never touches the handle), so the outcome is the same: no error, no\n // spans, nothing distinguishing it from working instrumentation.\n //\n // Warned once per process, matching the existing not-initialized warning\n // in index.ts — this sits inside request and agent loops, so per-call\n // logging would bury the signal. This is the single choke point for\n // startSpan / spanSync / spanAsync.\n if (!spanOutsideTraceWarningEmitted) {\n spanOutsideTraceWarningEmitted = true;\n console.warn(\n `morse: span(${JSON.stringify(opts.name)}) was called with no active trace, so nothing ` +\n `was recorded. Wrap the work in morse.run('<agent-name>', () => { ... }) — run() opens ` +\n `the trace that span() attaches to. This warning prints once per process.`,\n );\n }\n return null;\n }\n const parent = state.spanStack[state.spanStack.length - 1];\n const span: SpanData = {\n trace_id: state.traceId,\n span_id: generateSpanId(),\n type: opts.type ?? \"custom\",\n name: opts.name,\n parent_span_id: parent?.span_id,\n started_at: nowIso(),\n status: \"completed\",\n metadata: opts.metadata,\n };\n const startMono = nowMonotonic();\n state.spanStack.push(span);\n return {\n span,\n end(error?: unknown): void {\n // Pop only if still on top — defensive against out-of-order ends.\n if (state.spanStack[state.spanStack.length - 1] === span) {\n state.spanStack.pop();\n }\n if (error !== undefined) {\n finalizeSpan(span, startMono, \"failed\", errToString(error));\n } else {\n finalizeSpan(span, startMono);\n }\n state.completedSpans.push(span);\n },\n };\n}\n\n/** Sync callback wrapper for `startSpan` / `end`. No-op if no active trace. */\nexport function spanSync<T>(opts: SpanOptions, fn: (handle: SpanHandle | null) => T): T {\n const handle = startSpan(opts);\n try {\n const result = handle\n ? withDbCaptureContext(handle.span.trace_id, handle.span.span_id, () => fn(handle))\n : fn(handle);\n handle?.end();\n return result;\n } catch (err) {\n handle?.end(err);\n throw err;\n }\n}\n\n/** Async callback wrapper for `startSpan` / `end`. No-op if no active trace. */\nexport async function spanAsync<T>(\n opts: SpanOptions,\n fn: (handle: SpanHandle | null) => Promise<T>,\n): Promise<T> {\n const handle = startSpan(opts);\n try {\n const result = handle\n ? await withDbCaptureContext(handle.span.trace_id, handle.span.span_id, () => fn(handle))\n : await fn(handle);\n handle?.end();\n return result;\n } catch (err) {\n handle?.end(err);\n throw err;\n }\n}\n\n/* ------------------------------------------------------------------------ */\n/* Test helpers */\n/* ------------------------------------------------------------------------ */\n\nexport function _resetForTesting(): void {\n browserState = null;\n lastTrace = null;\n redactionConfig = buildRedactionConfig();\n // We do not reset `als` because re-loading it is expensive and the\n // store is process-scoped anyway.\n}\n","/**\n * W3C Trace Context propagation — inject and extract `traceparent` headers.\n *\n * W3C traceparent format: `{version}-{trace_id}-{span_id}-{flags}`\n * - version : \"00\" (fixed)\n * - trace_id : 32 lowercase hex chars (128-bit)\n * - span_id : 16 lowercase hex chars (64-bit)\n * - flags : \"01\" (sampled, always set for Morse)\n *\n * Example: `00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01`\n *\n * References:\n * https://www.w3.org/TR/trace-context/\n */\n\nimport { getActiveTraceState } from \"./_internal/tracing\";\n\nexport const W3C_TRACEPARENT_HEADER = \"traceparent\";\nexport const W3C_VERSION = \"00\";\nexport const W3C_FLAGS_SAMPLED = \"01\";\n\nconst TRACE_ID_LEN = 32;\nconst SPAN_ID_LEN = 16;\n\n/**\n * Build a W3C traceparent value from explicit IDs.\n *\n * Useful when you have a trace_id / span_id from somewhere other than\n * the active context (e.g., re-emitting an upstream trace's IDs).\n */\nexport function formatTraceparent(traceId: string, spanId: string): string {\n // We trust the caller; the \"build then validate\" assumption is documented.\n const tid = traceId.slice(0, TRACE_ID_LEN).padStart(TRACE_ID_LEN, \"0\").toLowerCase();\n const sid = spanId.slice(0, SPAN_ID_LEN).padStart(SPAN_ID_LEN, \"0\").toLowerCase();\n return `${W3C_VERSION}-${tid}-${sid}-${W3C_FLAGS_SAMPLED}`;\n}\n\n/**\n * Inject the W3C `traceparent` header derived from the active trace\n * context into the supplied headers object. Mutates and returns the\n * object for convenience.\n *\n * No-op (returns headers unchanged) if no trace is active.\n *\n * Accepts both `Headers` (from fetch) and a plain dict.\n */\nexport function injectTraceparent<T extends HeadersLike>(headers: T): T {\n const state = getActiveTraceState();\n if (state === null) return headers;\n\n const traceId = state.traceId;\n const span =\n state.spanStack.length > 0\n ? state.spanStack[state.spanStack.length - 1]\n : state.completedSpans[state.completedSpans.length - 1];\n const rawSpanId = span?.span_id ?? traceId;\n const spanId = rawSpanId.slice(0, SPAN_ID_LEN);\n\n const value = formatTraceparent(traceId, spanId);\n setHeader(headers, W3C_TRACEPARENT_HEADER, value);\n return headers;\n}\n\nexport interface ExtractedContext {\n traceId: string;\n parentSpanId: string;\n}\n\n/**\n * Parse a W3C traceparent header and return `{ traceId, parentSpanId }`,\n * or `null` if the header is missing or malformed.\n *\n * Validation per W3C §3.2.3:\n * - exactly 4 dash-separated fields\n * - version === \"00\"\n * - trace_id is 32 lowercase hex chars (and not all-zero)\n * - span_id is 16 lowercase hex chars (and not all-zero)\n */\nexport function extractTraceparent(\n headers: HeadersLike | string | null | undefined,\n): ExtractedContext | null {\n if (headers === null || headers === undefined) return null;\n const raw = typeof headers === \"string\" ? headers : getHeader(headers, W3C_TRACEPARENT_HEADER);\n if (!raw) return null;\n const parts = raw.split(\"-\");\n if (parts.length !== 4) return null;\n const [version, traceId, spanId] = parts as [string, string, string, string];\n if (version !== W3C_VERSION) return null;\n if (traceId.length !== TRACE_ID_LEN) return null;\n if (spanId.length !== SPAN_ID_LEN) return null;\n if (!/^[0-9a-f]+$/.test(traceId)) return null;\n if (!/^[0-9a-f]+$/.test(spanId)) return null;\n if (/^0+$/.test(traceId)) return null;\n if (/^0+$/.test(spanId)) return null;\n return { traceId, parentSpanId: spanId };\n}\n\n/**\n * Convenience for Next.js API routes / generic HTTP servers: pull the\n * traceparent off an incoming Request (or a header bag).\n */\nexport function extractFromRequest(req: { headers: HeadersLike }): ExtractedContext | null {\n return extractTraceparent(req.headers);\n}\n\n/**\n * Convenience for outbound `fetch`: build a fresh `Headers` object with\n * the traceparent injected, layered on top of the caller's input.\n */\nexport function injectIntoRequestInit(init?: RequestInit): RequestInit {\n const merged = new Headers(init?.headers ?? {});\n injectTraceparent(merged);\n return { ...(init ?? {}), headers: merged };\n}\n\n/* ------------------------------------------------------------------------ */\n/* Header polymorphism helpers */\n/* ------------------------------------------------------------------------ */\n\nexport type HeadersLike =\n | Headers\n | Record<string, string | string[] | undefined>\n | { get(name: string): string | null }\n | { [key: string]: unknown };\n\nfunction getHeader(headers: HeadersLike, name: string): string | null {\n if (headers instanceof Headers) {\n return headers.get(name);\n }\n // Object that exposes get() — e.g., Node's IncomingMessage doesn't, but\n // Next.js's headers() does.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const maybeGet = (headers as any).get;\n if (typeof maybeGet === \"function\") {\n const v = maybeGet.call(headers, name);\n if (typeof v === \"string\") return v;\n if (v === null || v === undefined) return null;\n }\n // Plain dict: case-insensitive lookup.\n const lower = name.toLowerCase();\n for (const [k, v] of Object.entries(headers as Record<string, unknown>)) {\n if (k.toLowerCase() === lower) {\n if (typeof v === \"string\") return v;\n if (Array.isArray(v) && v.length > 0 && typeof v[0] === \"string\") return v[0] as string;\n return null;\n }\n }\n return null;\n}\n\nfunction setHeader(headers: HeadersLike, name: string, value: string): void {\n if (headers instanceof Headers) {\n headers.set(name, value);\n return;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const maybeSet = (headers as any).set;\n if (typeof maybeSet === \"function\") {\n maybeSet.call(headers, name, value);\n return;\n }\n (headers as Record<string, string>)[name] = value;\n}\n"]}
|