@mnemonica/otel 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +109 -0
  3. package/build/hooks/attach-hooks.d.ts +3 -0
  4. package/build/hooks/attach-hooks.d.ts.map +1 -0
  5. package/build/hooks/attach-hooks.js +52 -0
  6. package/build/index.d.ts +32 -0
  7. package/build/index.d.ts.map +1 -0
  8. package/build/index.js +32 -0
  9. package/build/providers/async-flow.provider.d.ts +40 -0
  10. package/build/providers/async-flow.provider.d.ts.map +1 -0
  11. package/build/providers/async-flow.provider.js +128 -0
  12. package/build/providers/dive-otel.provider.d.ts +51 -0
  13. package/build/providers/dive-otel.provider.d.ts.map +1 -0
  14. package/build/providers/dive-otel.provider.js +238 -0
  15. package/build/providers/mnemonica-otel.provider.d.ts +12 -0
  16. package/build/providers/mnemonica-otel.provider.d.ts.map +1 -0
  17. package/build/providers/mnemonica-otel.provider.js +113 -0
  18. package/build/request-scope.d.ts +41 -0
  19. package/build/request-scope.d.ts.map +1 -0
  20. package/build/request-scope.js +35 -0
  21. package/build/thunderstruck/feed-from-request.d.ts +21 -0
  22. package/build/thunderstruck/feed-from-request.d.ts.map +1 -0
  23. package/build/thunderstruck/feed-from-request.js +34 -0
  24. package/build/thunderstruck/pre-root.d.ts +67 -0
  25. package/build/thunderstruck/pre-root.d.ts.map +1 -0
  26. package/build/thunderstruck/pre-root.js +78 -0
  27. package/build/unblind.d.ts +46 -0
  28. package/build/unblind.d.ts.map +1 -0
  29. package/build/unblind.js +120 -0
  30. package/build/utils/dive-flow.d.ts +24 -0
  31. package/build/utils/dive-flow.d.ts.map +1 -0
  32. package/build/utils/dive-flow.js +33 -0
  33. package/build/utils/is-mnemonica-instance.d.ts +2 -0
  34. package/build/utils/is-mnemonica-instance.d.ts.map +1 -0
  35. package/build/utils/is-mnemonica-instance.js +9 -0
  36. package/build-cjs/hooks/attach-hooks.js +55 -0
  37. package/build-cjs/index.js +52 -0
  38. package/build-cjs/package.json +1 -0
  39. package/build-cjs/providers/async-flow.provider.js +132 -0
  40. package/build-cjs/providers/dive-otel.provider.js +242 -0
  41. package/build-cjs/providers/mnemonica-otel.provider.js +117 -0
  42. package/build-cjs/request-scope.js +38 -0
  43. package/build-cjs/thunderstruck/feed-from-request.js +37 -0
  44. package/build-cjs/thunderstruck/pre-root.js +83 -0
  45. package/build-cjs/unblind.js +127 -0
  46. package/build-cjs/utils/dive-flow.js +37 -0
  47. package/build-cjs/utils/is-mnemonica-instance.js +12 -0
  48. package/package.json +69 -0
@@ -0,0 +1,238 @@
1
+ import { SpanStatusCode, context as otelContext, trace } from '@opentelemetry/api';
2
+ import { registerHook, } from '@mnemonica/dive';
3
+ // Call/method/construct edges carry their callsite as `name`
4
+ // (`/abs/file.ts:line:col`, 1-based) — surfaced as OTEL semconv code.*
5
+ // attributes so Jaeger can link straight to the source (Wanted #4).
6
+ const CALLSITE_RE = /^(.*):(\d+):(\d+)$/;
7
+ // Wanted #2 (2026-09-01): the strategy push channel (an injected script,
8
+ // see strategy/cdp-scripts/ws-server.js) cannot see OTEL spans, so the
9
+ // adapter publishes edgeId → traceId on a bounded global map; the push
10
+ // mapper forwards it and mnemographica's Live Trace gains the "Open in
11
+ // Jaeger" jump. globalThis because adapter and injected script share a
12
+ // process, not a module graph.
13
+ const EDGE_TRACES_LIMIT = 10000;
14
+ function edgeTraceMap() {
15
+ const g = globalThis;
16
+ if (!g.__mnemonicaDiveTraceIds) {
17
+ g.__mnemonicaDiveTraceIds = new Map();
18
+ }
19
+ const map = g.__mnemonicaDiveTraceIds;
20
+ return map;
21
+ }
22
+ function recordEdgeTrace(edgeId, traceId) {
23
+ const map = edgeTraceMap();
24
+ if (map.has(edgeId)) {
25
+ map.delete(edgeId);
26
+ }
27
+ else if (map.size >= EDGE_TRACES_LIMIT) {
28
+ // FIFO: the oldest entry dies first — Map iterates insertion order
29
+ const oldest = map.keys().next();
30
+ if (!oldest.done) {
31
+ map.delete(oldest.value);
32
+ }
33
+ }
34
+ map.set(edgeId, traceId);
35
+ }
36
+ export class DiveOtelProvider {
37
+ tracer;
38
+ // open spans, keyed on dive edge id — drained by leave/settle
39
+ spans = new Map();
40
+ // edge id → parentId, for the root-edge walk (dive.root_edge_id span
41
+ // attribute). Never drained mid-flight: a completed edge can still
42
+ // parent later children (a create edge adopts the next wrapped call),
43
+ // so the map is bounded coarsely instead.
44
+ edgeParents = new Map();
45
+ static EDGE_PARENTS_LIMIT = 20000;
46
+ detachers = [];
47
+ constructor(tracer) {
48
+ this.tracer = tracer ?? trace.getTracer('@mnemonica/otel');
49
+ }
50
+ /**
51
+ * Subscribe to dive's edge lifecycle. Idempotent: attaching twice would
52
+ * double every span. Dive's clear() wipes subscribers — re-attach after it.
53
+ */
54
+ attach() {
55
+ if (this.detachers.length > 0) {
56
+ return;
57
+ }
58
+ this.detachers.push(registerHook('enter', (payload) => {
59
+ this.onEnter(payload);
60
+ }), registerHook('leave', (payload) => {
61
+ this.onLeave(payload);
62
+ }), registerHook('settle', (payload) => {
63
+ this.onSettle(payload);
64
+ }), registerHook('recontext', (payload) => {
65
+ this.onRecontext(payload);
66
+ }));
67
+ try {
68
+ this.detachers.push(registerHook('create', (payload) => {
69
+ this.onCreate(payload);
70
+ }));
71
+ }
72
+ catch {
73
+ // The 'create' event exists since dive 0.8.0; on 0.7.x registerHook
74
+ // throws on the unknown event. Skipping it there preserves exactly
75
+ // the pre-subscription behavior (constructions stay unspanned), so
76
+ // the widened ^0.7.0 || ^0.8.0 peer range stays honest.
77
+ }
78
+ }
79
+ detach() {
80
+ for (const detach of this.detachers) {
81
+ detach();
82
+ }
83
+ this.detachers = [];
84
+ }
85
+ onEnter({ edge }) {
86
+ const parentSpan = this.findParentSpan(edge);
87
+ const ctx = parentSpan
88
+ ? trace.setSpan(otelContext.active(), parentSpan)
89
+ : undefined;
90
+ const name = `dive.${edge.kind}:${edge.name}`;
91
+ const span = ctx
92
+ ? this.tracer.startSpan(name, {}, ctx)
93
+ : this.tracer.startSpan(name);
94
+ span.setAttribute('dive.edge_id', edge.id);
95
+ span.setAttribute('dive.kind', edge.kind);
96
+ span.setAttribute('dive.name', edge.name);
97
+ this.decorateSpan(span, edge);
98
+ this.spans.set(edge.id, span);
99
+ }
100
+ onLeave({ edge, result }) {
101
+ if (result instanceof Promise) {
102
+ // async work: the span closes at settle, not at the sync head —
103
+ // "the function returned" is not "the work is done"
104
+ return;
105
+ }
106
+ this.closeSpan(edge);
107
+ }
108
+ onSettle({ edge, error }) {
109
+ this.closeSpan(edge, error);
110
+ }
111
+ onRecontext({ edge, previousContext, context }) {
112
+ // One-shot span: the ownership transfer itself, parented on the OLD
113
+ // context's span (the handoff edge's parentId), so the trace shows
114
+ // where the callback's story crossed flows.
115
+ const parentSpan = this.findParentSpan(edge);
116
+ const ctx = parentSpan
117
+ ? trace.setSpan(otelContext.active(), parentSpan)
118
+ : undefined;
119
+ const name = `dive.${edge.kind}:${edge.name}`;
120
+ const span = ctx
121
+ ? this.tracer.startSpan(name, {}, ctx)
122
+ : this.tracer.startSpan(name);
123
+ span.setAttribute('dive.edge_id', edge.id);
124
+ span.setAttribute('dive.kind', edge.kind);
125
+ span.setAttribute('dive.name', edge.name);
126
+ span.setAttribute('dive.handoff', true);
127
+ span.setAttribute('dive.handoff.had_previous', previousContext !== undefined);
128
+ span.setAttribute('dive.handoff.has_context', context !== undefined);
129
+ this.decorateSpan(span, edge);
130
+ span.end();
131
+ }
132
+ onCreate({ edge, error }) {
133
+ // One-shot span: the construction already completed when recordCreation
134
+ // fired (the hook moment IS the completion), so the span starts and
135
+ // ends here — same shape as recontext. findParentSpan adopts the
136
+ // wrapped call's span via edge.parentId, or the active request span at
137
+ // a boundary, so constructions join the request trace instead of
138
+ // opening a root trace of their own.
139
+ const parentSpan = this.findParentSpan(edge);
140
+ const ctx = parentSpan
141
+ ? trace.setSpan(otelContext.active(), parentSpan)
142
+ : undefined;
143
+ const name = `dive.${edge.kind}:${edge.name}`;
144
+ const span = ctx
145
+ ? this.tracer.startSpan(name, {}, ctx)
146
+ : this.tracer.startSpan(name);
147
+ span.setAttribute('dive.edge_id', edge.id);
148
+ span.setAttribute('dive.kind', edge.kind);
149
+ span.setAttribute('dive.name', edge.name);
150
+ span.setAttribute('dive.status', edge.status);
151
+ if (edge.duration !== undefined) {
152
+ span.setAttribute('dive.duration_ms', edge.duration);
153
+ }
154
+ this.decorateSpan(span, edge);
155
+ if (edge.status === 'error') {
156
+ span.setStatus({ code: SpanStatusCode.ERROR });
157
+ if (error instanceof Error) {
158
+ span.recordException(error);
159
+ }
160
+ }
161
+ span.end();
162
+ }
163
+ findParentSpan(edge) {
164
+ if (edge.parentId !== null) {
165
+ const own = this.spans.get(edge.parentId);
166
+ if (own) {
167
+ return own;
168
+ }
169
+ }
170
+ // Boundary (or evicted parent): adopt the active OTel span — the HTTP
171
+ // request span becomes the root of the dive branch.
172
+ const active = trace.getSpan(otelContext.active());
173
+ return active;
174
+ }
175
+ closeSpan(edge, error) {
176
+ const span = this.spans.get(edge.id);
177
+ if (!span) {
178
+ return;
179
+ }
180
+ this.spans.delete(edge.id);
181
+ span.setAttribute('dive.status', edge.status);
182
+ if (edge.duration !== undefined) {
183
+ span.setAttribute('dive.duration_ms', edge.duration);
184
+ }
185
+ if (edge.status === 'error') {
186
+ // sync throws carry no error value in the leave payload — the
187
+ // edge's own status is the truthful signal; the exception record
188
+ // is available only when settle carried the rejection itself
189
+ span.setStatus({ code: SpanStatusCode.ERROR });
190
+ if (error instanceof Error) {
191
+ span.recordException(error);
192
+ }
193
+ }
194
+ span.end();
195
+ }
196
+ /**
197
+ * Cross-surface attributes every span gets, on every hook path:
198
+ * the edge's trace root id (Jaeger link → mnemographica's Live Trace,
199
+ * Wanted #1), the edgeId→traceId publication for the strategy push
200
+ * channel (Wanted #2), and code.filepath/line/column parsed from the
201
+ * callsite name (Wanted #4).
202
+ */
203
+ decorateSpan(span, edge) {
204
+ span.setAttribute('dive.root_edge_id', this.rootEdgeIdOf(edge));
205
+ recordEdgeTrace(edge.id, span.spanContext().traceId);
206
+ if (edge.kind !== 'call' && edge.kind !== 'method' && edge.kind !== 'construct') {
207
+ return;
208
+ }
209
+ const match = CALLSITE_RE.exec(edge.name);
210
+ if (!match) {
211
+ return;
212
+ }
213
+ span.setAttribute('code.filepath', match[1]);
214
+ span.setAttribute('code.lineno', Number(match[2]));
215
+ span.setAttribute('code.column', Number(match[3]));
216
+ }
217
+ // Walk dive's parentage to the root edge id. Parents are recorded as
218
+ // edges arrive (enter fires parent-before-child), so the chain is
219
+ // complete for anything still in flight; an evicted/unknown parent
220
+ // simply ends the walk at the deepest known id.
221
+ rootEdgeIdOf(edge) {
222
+ if (this.edgeParents.size >= DiveOtelProvider.EDGE_PARENTS_LIMIT) {
223
+ this.edgeParents.clear();
224
+ }
225
+ this.edgeParents.set(edge.id, edge.parentId);
226
+ let id = edge.id;
227
+ let parent = edge.parentId;
228
+ const seen = new Set([id]);
229
+ while (parent !== null && !seen.has(parent)) {
230
+ seen.add(parent);
231
+ id = parent;
232
+ const next = this.edgeParents.get(parent);
233
+ parent = next === undefined ? null : next;
234
+ }
235
+ return id;
236
+ }
237
+ }
238
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGl2ZS1vdGVsLnByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Byb3ZpZGVycy9kaXZlLW90ZWwucHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBb0JBLE9BQU8sRUFBRSxjQUFjLEVBQUUsT0FBTyxJQUFJLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNuRixPQUFPLEVBQ04sWUFBWSxHQU9aLE1BQU0saUJBQWlCLENBQUM7QUFFekIsNkRBQTZEO0FBQzdELHVFQUF1RTtBQUN2RSxvRUFBb0U7QUFDcEUsTUFBTSxXQUFXLEdBQUcsb0JBQW9CLENBQUM7QUFFekMseUVBQXlFO0FBQ3pFLHVFQUF1RTtBQUN2RSx1RUFBdUU7QUFDdkUsdUVBQXVFO0FBQ3ZFLHVFQUF1RTtBQUN2RSwrQkFBK0I7QUFDL0IsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUM7QUFFaEMsU0FBUyxZQUFZO0lBQ3BCLE1BQU0sQ0FBQyxHQUFHLFVBQXdELENBQUM7SUFDbkUsSUFBSSxDQUFDLENBQUMsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQ2hDLENBQUMsQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ3ZDLENBQUM7SUFDRCxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsdUJBQXVCLENBQUM7SUFDdEMsT0FBTyxHQUFHLENBQUM7QUFDWixDQUFDO0FBQ0QsU0FBUyxlQUFlLENBQUUsTUFBYyxFQUFFLE9BQWU7SUFDeEQsTUFBTSxHQUFHLEdBQUcsWUFBWSxFQUFFLENBQUM7SUFDM0IsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDckIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNwQixDQUFDO1NBQU0sSUFBSSxHQUFHLENBQUMsSUFBSSxJQUFJLGlCQUFpQixFQUFFLENBQUM7UUFDMUMsbUVBQW1FO1FBQ25F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ciBmb3IgZGl2ZSdzIGVkZ2UgbGlmZWN5Y2xlIGhvb2tzLlxuICpcbiAqIFdoZXJlIE1uZW1vbmljYU90ZWxQcm92aWRlciBzcGFucyBDT05TVFJVQ1RJT05TIChtbmVtb25pY2EgaG9va3MpLCB0aGlzXG4gKiBwcm92aWRlciBzcGFucyBFVkVSWSBXUkFQUEVEIENBTEwgKGRpdmUgaG9va3MpOiBjYWxsIC8gY29uc3RydWN0IC8gbWV0aG9kIC9cbiAqIHJlY29udGV4dCBlZGdlcyBlYWNoIGJlY29tZSBhIHNwYW4sIHBhcmVudGVkIG9uIHRoZSBzcGFuIG9mIHRoZSBlZGdlJ3NcbiAqIHBhcmVudElkIOKAlCBkaXZlJ3Mgb3duIHRyYWNlIHBhcmVudGFnZSwgbm90IEFMUy4gQXQgdW53cmFwcGVkIGJvdW5kYXJpZXNcbiAqIChwYXJlbnRJZCBudWxsKSB0aGUgc3BhbiBhZG9wdHMgdGhlIGN1cnJlbnRseSBBQ1RJVkUgT1RlbCBzcGFuIGFzIHBhcmVudCxcbiAqIHNvIGFuXG4gKiBIVFRQIHJlcXVlc3Qgc3BhbiBhZG9wdHMgdGhlIHdob2xlIGRpdmUgYnJhbmNoLiAnY3JlYXRlJyBlZGdlcyAobW5lbW9uaWNhXG4gKiBjb25zdHJ1Y3Rpb25zIHJlY29yZGVkIHZpYSByZWNvcmRDcmVhdGlvbi9yZWNvcmRDcmVhdGlvbkVycm9yKSBiZWNvbWVcbiAqIG9uZS1zaG90IHNwYW5zIG9uIHRoZSBzYW1lIHBhcmVudGFnZSDigJQgdGhlIGNvbnN0cnVjdGlvbiBIQVMgY29tcGxldGVkIHdoZW5cbiAqIHRoZSBob29rIGZpcmVzLCBzbyB0aGUgc3BhbiBzdGFydHMgYW5kIGVuZHMgaW5zaWRlIHRoZSBoYW5kbGVyLlxuICpcbiAqIEFzeW5jIHRydXRoZnVsbmVzczogYSBzcGFuIGRvZXMgTk9UIGVuZCBhdCB0aGUgc3luYyBjbG9zZSB3aGVuIHRoZSB3cmFwXG4gKiBwcm9kdWNlZCBhIHRhcHBlZCBwcm9taXNlIOKAlCBpdCBlbmRzIGF0IHNldHRsZSwgd2l0aCB0aGUgY2hhaW4ncyBvdXRjb21lLlxuICogU3BhbnMgYXJlIGtleWVkIG9uIGVkZ2UgaWQ7IGV2ZXJ5IHJlY29yZGVkIGVkZ2UgZmlyZXMgbGVhdmUgKGFuZCwgd2hlblxuICogYXN5bmMsIHNldHRsZSksIHNvIHRoZSBtYXAgYWx3YXlzIGRyYWlucy5cbiAqL1xuaW1wb3J0IHR5cGUgeyBTcGFuLCBUcmFjZXIgfSBmcm9tICdAb3BlbnRlbGVtZXRyeS9hcGknO1xuaW1wb3J0IHsgU3BhblN0YXR1c0NvZGUsIGNvbnRleHQgYXMgb3RlbENvbnRleHQsIHRyYWNlIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvYXBpJztcbmltcG9ydCB7XG5cdHJlZ2lzdGVySG9vayxcblx0dHlwZSBEaXZlQ3JlYXRlUGF5bG9hZCxcblx0dHlwZSBEaXZlRW50ZXJQYXlsb2FkLFxuXHR0eXBlIERpdmVMZWF2ZVBheWxvYWQsXG5cdHR5cGUgRGl2ZVJlY29udGV4dFBheWxvYWQsXG5cdHR5cGUgRGl2ZVNldHRsZVBheWxvYWQsXG5cdHR5cGUgRmxvd0VkZ2UsXG59IGZyb20gJ0BtbmVtb25pY2EvZGl2ZSc7XG5cbi8vIENhbGwvbWV0aG9kL2NvbnN0cnVjdCBlZGdlcyBjYXJyeSB0aGVpciBjYWxsc2l0ZSBhcyBgbmFtZWBcbi8vIChgL2Ficy9maWxlLnRzOmxpbmU6Y29sYCwgMS1iYXNlZCkg4oCUIHN1cmZhY2VkIGFzIE9URUwgc2VtY29udiBjb2RlLipcbi8vIGF0dHJpYnV0ZXMgc28gSmFlZ2VyIGNhbiBsaW5rIHN0cmFpZ2h0IHRvIHRoZSBzb3VyY2UgKFdhbnRlZCAjNCkuXG5jb25zdCBDQUxMU0lURV9SRSA9IC9eKC4qKTooXFxkKyk6KFxcZCspJC87XG5cbi8vIFdhbnRlZCAjMiAoMjAyNi0wOS0wMSk6IHRoZSBzdHJhdGVneSBwdXNoIGNoYW5uZWwgKGFuIGluamVjdGVkIHNjcmlwdCxcbi8vIHNlZSBzdHJhdGVneS9jZHAtc2NyaXB0cy93cy1zZXJ2ZXIuanMpIGNhbm5vdCBzZWUgT1RFTCBzcGFucywgc28gdGhlXG4vLyBhZGFwdGVyIHB1Ymxpc2hlcyBlZGdlSWQg4oaSIHRyYWNlSWQgb24gYSBib3VuZGVkIGdsb2JhbCBtYXA7IHRoZSBwdXNoXG4vLyBtYXBwZXIgZm9yd2FyZHMgaXQgYW5kIG1uZW1vZ3JhcGhpY2EncyBMaXZlIFRyYWNlIGdhaW5zIHRoZSBcIk9wZW4gaW5cbi8vIEphZWdlclwiIGp1bXAuIGdsb2JhbFRoaXMgYmVjYXVzZSBhZGFwdGVyIGFuZCBpbmplY3RlZCBzY3JpcHQgc2hhcmUgYVxuLy8gcHJvY2Vzcywgbm90IGEgbW9kdWxlIGdyYXBoLlxuY29uc3QgRURHRV9UUkFDRVNfTElNSVQgPSAxMDAwMDtcbnR5cGUgRWRnZVRyYWNlTWFwID0gTWFwPG51bWJlciwgc3RyaW5nPjtcbmZ1bmN0aW9uIGVkZ2VUcmFjZU1hcCAoKTogRWRnZVRyYWNlTWFwIHtcblx0Y29uc3QgZyA9IGdsb2JhbFRoaXMgYXMgeyBfX21uZW1vbmljYURpdmVUcmFjZUlkcz86IEVkZ2VUcmFjZU1hcCB9O1xuXHRpZiAoIWcuX19tbmVtb25pY2FEaXZlVHJhY2VJZHMpIHtcblx0XHRnLl9fbW5lbW9uaWNhRGl2ZVRyYWNlSWRzID0gbmV3IE1hcCgpO1xuXHR9XG5cdGNvbnN0IG1hcCA9IGcuX19tbmVtb25pY2FEaXZlVHJhY2VJZHM7XG5cdHJldHVybiBtYXA7XG59XG5mdW5jdGlvbiByZWNvcmRFZGdlVHJhY2UgKGVkZ2VJZDogbnVtYmVyLCB0cmFjZUlkOiBzdHJpbmcpOiB2b2lkIHtcblx0Y29uc3QgbWFwID0gZWRnZVRyYWNlTWFwKCk7XG5cdGlmIChtYXAuaGFzKGVkZ2VJZCkpIHtcblx0XHRtYXAuZGVsZXRlKGVkZ2VJZCk7XG5cdH0gZWxzZSBpZiAobWFwLnNpemUgPj0gRURHRV9UUkFDRVNfTElNSVQpIHtcblx0XHQvLyBGSUZPOiB0aGUgb2xkZXN0IGVudHJ5IGRpZXMgZmlyc3Qg4oCUIE1hcCBpdGVyYXRlcyBpbnNlcnRpb24gb3JkZXJcblx0XHRjb25zdCBvbGRlc3QgPSBtYXAua2V5cygpLm5leHQoKTtcblx0XHRpZiAoIW9sZGVzdC5kb25lKSB7XG5cdFx0XHRtYXAuZGVsZXRlKG9sZGVzdC52YWx1ZSk7XG5cdFx0fVxuXHR9XG5cdG1hcC5zZXQoZWRnZUlkLCB0cmFjZUlkKTtcbn1cblxuZXhwb3J0IGNsYXNzIERpdmVPdGVsUHJvdmlkZXIge1xuXHRwcml2YXRlIHRyYWNlcjogVHJhY2VyO1xuXHQvLyBvcGVuIHNwYW5zLCBrZXllZCBvbiBkaXZlIGVkZ2UgaWQg4oCUIGRyYWluZWQgYnkgbGVhdmUvc2V0dGxlXG5cdHByaXZhdGUgc3BhbnMgPSBuZXcgTWFwPG51bWJlciwgU3Bhbj4oKTtcblx0Ly8gZWRnZSBpZCDihpIgcGFyZW50SWQsIGZvciB0aGUgcm9vdC1lZGdlIHdhbGsgKGRpdmUucm9vdF9lZGdlX2lkIHNwYW5cblx0Ly8gYXR0cmlidXRlKS4gTmV2ZXIgZHJhaW5lZCBtaWQtZmxpZ2h0OiBhIGNvbXBsZXRlZCBlZGdlIGNhbiBzdGlsbFxuXHQvLyBwYXJlbnQgbGF0ZXIgY2hpbGRyZW4gKGEgY3JlYXRlIGVkZ2UgYWRvcHRzIHRoZSBuZXh0IHdyYXBwZWQgY2FsbCksXG5cdC8vIHNvIHRoZSBtYXAgaXMgYm91bmRlZCBjb2Fyc2VseSBpbnN0ZWFkLlxuXHRwcml2YXRlIGVkZ2VQYXJlbnRzID0gbmV3IE1hcDxudW1iZXIsIG51bWJlciB8IG51bGw+KCk7XG5cdHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IEVER0VfUEFSRU5UU19MSU1JVCA9IDIwMDAwO1xuXHRwcml2YXRlIGRldGFjaGVyczogQXJyYXk8KCkgPT4gdm9pZD4gPSBbXTtcblxuXHRjb25zdHJ1Y3RvciAodHJhY2VyPzogVHJhY2VyKSB7XG5cdFx0dGhpcy50cmFjZXIgPSB0cmFjZXIgPz8gdHJhY2UuZ2V0VHJhY2VyKCdAbW5lbW9uaWNhL290ZWwnKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTdWJzY3JpYmUgdG8gZGl2ZSdzIGVkZ2UgbGlmZWN5Y2xlLiBJZGVtcG90ZW50OiBhdHRhY2hpbmcgdHdpY2Ugd291bGRcblx0ICogZG91YmxlIGV2ZXJ5IHNwYW4uIERpdmUncyBjbGVhcigpIHdpcGVzIHN1YnNjcmliZXJzIOKAlCByZS1hdHRhY2ggYWZ0ZXIgaXQuXG5cdCAqL1xuXHRhdHRhY2ggKCk6IHZvaWQge1xuXHRcdGlmICh0aGlzLmRldGFjaGVycy5sZW5ndGggPiAwKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMuZGV0YWNoZXJzLnB1c2goXG5cdFx0XHRyZWdpc3Rlckhvb2soJ2VudGVyJywgKHBheWxvYWQpID0+IHtcblx0XHRcdFx0dGhpcy5vbkVudGVyKHBheWxvYWQpO1xuXHRcdFx0fSksXG5cdFx0XHRyZWdpc3Rlckhvb2soJ2xlYXZlJywgKHBheWxvYWQpID0+IHtcblx0XHRcdFx0dGhpcy5vbkxlYXZlKHBheWxvYWQpO1xuXHRcdFx0fSksXG5cdFx0XHRyZWdpc3Rlckhvb2soJ3NldHRsZScsIChwYXlsb2FkKSA9PiB7XG5cdFx0XHRcdHRoaXMub25TZXR0bGUocGF5bG9hZCk7XG5cdFx0XHR9KSxcblx0XHRcdHJlZ2lzdGVySG9vaygncmVjb250ZXh0JywgKHBheWxvYWQpID0+IHtcblx0XHRcdFx0dGhpcy5vblJlY29udGV4dChwYXlsb2FkKTtcblx0XHRcdH0pLFxuXHRcdCk7XG5cdFx0dHJ5IHtcblx0XHRcdHRoaXMuZGV0YWNoZXJzLnB1c2goXG5cdFx0XHRcdHJlZ2lzdGVySG9vaygnY3JlYXRlJywgKHBheWxvYWQpID0+IHtcblx0XHRcdFx0XHR0aGlzLm9uQ3JlYXRlKHBheWxvYWQpO1xuXHRcdFx0XHR9KSxcblx0XHRcdCk7XG5cdFx0fSBjYXRjaCB7XG5cdFx0XHQvLyBUaGUgJ2NyZWF0ZScgZXZlbnQgZXhpc3RzIHNpbmNlIGRpdmUgMC44LjA7IG9uIDAuNy54IHJlZ2lzdGVySG9va1xuXHRcdFx0Ly8gdGhyb3dzIG9uIHRoZSB1bmtub3duIGV2ZW50LiBTa2lwcGluZyBpdCB0aGVyZSBwcmVzZXJ2ZXMgZXhhY3RseVxuXHRcdFx0Ly8gdGhlIHByZS1zdWJzY3JpcHRpb24gYmVoYXZpb3IgKGNvbnN0cnVjdGlvbnMgc3RheSB1bnNwYW5uZWQpLCBzb1xuXHRcdFx0Ly8gdGhlIHdpZGVuZWQgXjAuNy4wIHx8IF4wLjguMCBwZWVyIHJhbmdlIHN0YXlzIGhvbmVzdC5cblx0XHR9XG5cdH1cblxuXHRkZXRhY2ggKCk6IHZvaWQge1xuXHRcdGZvciAoY29uc3QgZGV0YWNoIG9mIHRoaXMuZGV0YWNoZXJzKSB7XG5cdFx0XHRkZXRhY2goKTtcblx0XHR9XG5cdFx0dGhpcy5kZXRhY2hlcnMgPSBbXTtcblx0fVxuXG5cdHByaXZhdGUgb25FbnRlciAoeyBlZGdlIH06IERpdmVFbnRlclBheWxvYWQpOiB2b2lkIHtcblx0XHRjb25zdCBwYXJlbnRTcGFuID0gdGhpcy5maW5kUGFyZW50U3BhbihlZGdlKTtcblx0XHRjb25zdCBjdHggPSBwYXJlbnRTcGFuXG5cdFx0XHQ/IHRyYWNlLnNldFNwYW4ob3RlbENvbnRleHQuYWN0aXZlKCksIHBhcmVudFNwYW4pXG5cdFx0XHQ6IHVuZGVmaW5lZDtcblx0XHRjb25zdCBuYW1lID0gYGRpdmUuJHtlZGdlLmtpbmR9OiR7ZWRnZS5uYW1lfWA7XG5cdFx0Y29uc3Qgc3BhbiA9IGN0eFxuXHRcdFx0PyB0aGlzLnRyYWNlci5zdGFydFNwYW4obmFtZSwge30sIGN0eClcblx0XHRcdDogdGhpcy50cmFjZXIuc3RhcnRTcGFuKG5hbWUpO1xuXG5cdFx0c3Bhbi5zZXRBdHRyaWJ1dGUoJ2RpdmUuZWRnZV9pZCcsIGVkZ2UuaWQpO1xuXHRcdHNwYW4uc2V0QXR0cmlidXRlKCdkaXZlLmtpbmQnLCBlZGdlLmtpbmQpO1xuXHRcdHNwYW4uc2V0QXR0cmlidXRlKCdkaXZlLm5hbWUnLCBlZGdlLm5hbWUpO1xuXHRcdHRoaXMuZGVjb3JhdGVTcGFuKHNwYW4sIGVkZ2UpO1xuXG5cdFx0dGhpcy5zcGFucy5zZXQoZWRnZS5pZCwgc3Bhbik7XG5cdH1cblxuXHRwcml2YXRlIG9uTGVhdmUgKHsgZWRnZSwgcmVzdWx0IH06IERpdmVMZWF2ZVBheWxvYWQpOiB2b2lkIHtcblx0XHRpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuXHRcdFx0Ly8gYXN5bmMgd29yazogdGhlIHNwYW4gY2xvc2VzIGF0IHNldHRsZSwgbm90IGF0IHRoZSBzeW5jIGhlYWQg4oCUXG5cdFx0XHQvLyBcInRoZSBmdW5jdGlvbiByZXR1cm5lZFwiIGlzIG5vdCBcInRoZSB3b3JrIGlzIGRvbmVcIlxuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHR0aGlzLmNsb3NlU3BhbihlZGdlKTtcblx0fVxuXG5cdHByaXZhdGUgb25TZXR0bGUgKHsgZWRnZSwgZXJyb3IgfTogRGl2ZVNldHRsZVBheWxvYWQpOiB2b2lkIHtcblx0XHR0aGlzLmNsb3NlU3BhbihlZGdlLCBlcnJvcik7XG5cdH1cblxuXHRwcml2YXRlIG9uUmVjb250ZXh0ICh7IGVkZ2UsIHByZXZpb3VzQ29udGV4dCwgY29udGV4dCB9OiBEaXZlUmVjb250ZXh0UGF5bG9hZCk6IHZvaWQge1xuXHRcdC8vIE9uZS1zaG90IHNwYW46IHRoZSBvd25lcnNoaXAgdHJhbnNmZXIgaXRzZWxmLCBwYXJlbnRlZCBvbiB0aGUgT0xEXG5cdFx0Ly8gY29udGV4dCdzIHNwYW4gKHRoZSBoYW5kb2ZmIGVkZ2UncyBwYXJlbnRJZCksIHNvIHRoZSB0cmFjZSBzaG93c1xuXHRcdC8vIHdoZXJlIHRoZSBjYWxsYmFjaydzIHN0b3J5IGNyb3NzZWQgZmxvd3MuXG5cdFx0Y29uc3QgcGFyZW50U3BhbiA9IHRoaXMuZmluZFBhcmVudFNwYW4oZWRnZSk7XG5cdFx0Y29uc3QgY3R4ID0gcGFyZW50U3BhblxuXHRcdFx0PyB0cmFjZS5zZXRTcGFuKG90ZWxDb250ZXh0LmFjdGl2ZSgpLCBwYXJlbnRTcGFuKVxuXHRcdFx0OiB1bmRlZmluZWQ7XG5cdFx0Y29uc3QgbmFtZSA9IGBkaXZlLiR7ZWRnZS5raW5kfToke2VkZ2UubmFtZX1gO1xuXHRcdGNvbnN0IHNwYW4gPSBjdHhcblx0XHRcdD8gdGhpcy50cmFjZXIuc3RhcnRTcGFuKG5hbWUsIHt9LCBjdHgpXG5cdFx0XHQ6IHRoaXMudHJhY2VyLnN0YXJ0U3BhbihuYW1lKTtcblxuXHRcdHNwYW4uc2V0QXR0cmlidXRlKCdkaXZlLmVkZ2VfaWQnLCBlZGdlLmlkKTtcblx0XHRzcGFuLnNldEF0dHJpYnV0ZSgnZGl2ZS5raW5kJywgZWRnZS5raW5kKTtcblx0XHRzcGFuLnNldEF0dHJpYnV0ZSgnZGl2ZS5uYW1lJywgZWRnZS5uYW1lKTtcblx0XHRzcGFuLnNldEF0dHJpYnV0ZSgnZGl2ZS5oYW5kb2ZmJywgdHJ1ZSk7XG5cdFx0c3Bhbi5zZXRBdHRyaWJ1dGUoJ2RpdmUuaGFuZG9mZi5oYWRfcHJldmlvdXMnLCBwcmV2aW91c0NvbnRleHQgIT09IHVuZGVmaW5lZCk7XG5cdFx0c3Bhbi5zZXRBdHRyaWJ1dGUoJ2RpdmUuaGFuZG9mZi5oYXNfY29udGV4dCcsIGNvbnRleHQgIT09IHVuZGVmaW5lZCk7XG5cdFx0dGhpcy5kZWNvcmF0ZVNwYW4oc3BhbiwgZWRnZSk7XG5cdFx0c3Bhbi5lbmQoKTtcblx0fVxuXG5cdHByaXZhdGUgb25DcmVhdGUgKHsgZWRnZSwgZXJyb3IgfTogRGl2ZUNyZWF0ZVBheWxvYWQpOiB2b2lkIHtcblx0XHQvLyBPbmUtc2hvdCBzcGFuOiB0aGUgY29uc3RydWN0aW9uIGFscmVhZHkgY29tcGxldGVkIHdoZW4gcmVjb3JkQ3JlYXRpb25cblx0XHQvLyBmaXJlZCAodGhlIGhvb2sgbW9tZW50IElTIHRoZSBjb21wbGV0aW9uKSwgc28gdGhlIHNwYW4gc3RhcnRzIGFuZFxuXHRcdC8vIGVuZHMgaGVyZSDigJQgc2FtZSBzaGFwZSBhcyByZWNvbnRleHQuIGZpbmRQYXJlbnRTcGFuIGFkb3B0cyB0aGVcblx0XHQvLyB3cmFwcGVkIGNhbGwncyBzcGFuIHZpYSBlZGdlLnBhcmVudElkLCBvciB0aGUgYWN0aXZlIHJlcXVlc3Qgc3BhbiBhdFxuXHRcdC8vIGEgYm91bmRhcnksIHNvIGNvbnN0cnVjdGlvbnMgam9pbiB0aGUgcmVxdWVzdCB0cmFjZSBpbnN0ZWFkIG9mXG5cdFx0Ly8gb3BlbmluZyBhIHJvb3QgdHJhY2Ugb2YgdGhlaXIgb3duLlxuXHRcdGNvbnN0IHBhcmVudFNwYW4gPSB0aGlzLmZpbmRQYXJlbnRTcGFuKGVkZ2UpO1xuXHRcdGNvbnN0IGN0eCA9IHBhcmVudFNwYW5cblx0XHRcdD8gdHJhY2Uuc2V0U3BhbihvdGVsQ29udGV4dC5hY3RpdmUoKSwgcGFyZW50U3Bhbilcblx0XHRcdDogdW5kZWZpbmVkO1xuXHRcdGNvbnN0IG5hbWUgPSBgZGl2ZS4ke2VkZ2Uua2luZH06JHtlZGdlLm5hbWV9YDtcblx0XHRjb25zdCBzcGFuID0gY3R4XG5cdFx0XHQ/IHRoaXMudHJhY2VyLnN0YXJ0U3BhbihuYW1lLCB7fSwgY3R4KVxuXHRcdFx0OiB0aGlzLnRyYWNlci5zdGFydFNwYW4obmFtZSk7XG5cblx0XHRzcGFuLnNldEF0dHJpYnV0ZSgnZGl2ZS5lZGdlX2lkJywgZWRnZS5pZCk7XG5cdFx0c3Bhbi5zZXRBdHRyaWJ1dGUoJ2RpdmUua2luZCcsIGVkZ2Uua2luZCk7XG5cdFx0c3Bhbi5zZXRBdHRyaWJ1dGUoJ2RpdmUubmFtZScsIGVkZ2UubmFtZSk7XG5cdFx0c3Bhbi5zZXRBdHRyaWJ1dGUoJ2RpdmUuc3RhdHVzJywgZWRnZS5zdGF0dXMpO1xuXHRcdGlmIChlZGdlLmR1cmF0aW9uICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdHNwYW4uc2V0QXR0cmlidXRlKCdkaXZlLmR1cmF0aW9uX21zJywgZWRnZS5kdXJhdGlvbik7XG5cdFx0fVxuXHRcdHRoaXMuZGVjb3JhdGVTcGFuKHNwYW4sIGVkZ2UpO1xuXHRcdGlmIChlZGdlLnN0YXR1cyA9PT0gJ2Vycm9yJykge1xuXHRcdFx0c3Bhbi5zZXRTdGF0dXMoeyBjb2RlOiBTcGFuU3RhdHVzQ29kZS5FUlJPUiB9KTtcblx0XHRcdGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRcdHNwYW4ucmVjb3JkRXhjZXB0aW9uKGVycm9yKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0c3Bhbi5lbmQoKTtcblx0fVxuXG5cdHByaXZhdGUgZmluZFBhcmVudFNwYW4gKGVkZ2U6IEZsb3dFZGdlKTogU3BhbiB8IHVuZGVmaW5lZCB7XHRcdGlmIChlZGdlLnBhcmVudElkICE9PSBudWxsKSB7XG5cdFx0XHRjb25zdCBvd24gPSB0aGlzLnNwYW5zLmdldChlZGdlLnBhcmVudElkKTtcblx0XHRcdGlmIChvd24pIHtcblx0XHRcdFx0cmV0dXJuIG93bjtcblx0XHRcdH1cblx0XHR9XG5cdFx0Ly8gQm91bmRhcnkgKG9yIGV2aWN0ZWQgcGFyZW50KTogYWRvcHQgdGhlIGFjdGl2ZSBPVGVsIHNwYW4g4oCUIHRoZSBIVFRQXG5cdFx0Ly8gcmVxdWVzdCBzcGFuIGJlY29tZXMgdGhlIHJvb3Qgb2YgdGhlIGRpdmUgYnJhbmNoLlxuXHRcdGNvbnN0IGFjdGl2ZSA9IHRyYWNlLmdldFNwYW4ob3RlbENvbnRleHQuYWN0aXZlKCkpO1xuXHRcdHJldHVybiBhY3RpdmU7XG5cdH1cblxuXHRwcml2YXRlIGNsb3NlU3BhbiAoZWRnZTogRmxvd0VkZ2UsIGVycm9yPzogdW5rbm93bik6IHZvaWQge1xuXHRcdGNvbnN0IHNwYW4gPSB0aGlzLnNwYW5zLmdldChlZGdlLmlkKTtcblx0XHRpZiAoIXNwYW4pIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy5zcGFucy5kZWxldGUoZWRnZS5pZCk7XG5cblx0XHRzcGFuLnNldEF0dHJpYnV0ZSgnZGl2ZS5zdGF0dXMnLCBlZGdlLnN0YXR1cyk7XG5cdFx0aWYgKGVkZ2UuZHVyYXRpb24gIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0c3Bhbi5zZXRBdHRyaWJ1dGUoJ2RpdmUuZHVyYXRpb25fbXMnLCBlZGdlLmR1cmF0aW9uKTtcblx0XHR9XG5cdFx0aWYgKGVkZ2Uuc3RhdHVzID09PSAnZXJyb3InKSB7XG5cdFx0XHQvLyBzeW5jIHRocm93cyBjYXJyeSBubyBlcnJvciB2YWx1ZSBpbiB0aGUgbGVhdmUgcGF5bG9hZCDigJQgdGhlXG5cdFx0XHQvLyBlZGdlJ3Mgb3duIHN0YXR1cyBpcyB0aGUgdHJ1dGhmdWwgc2lnbmFsOyB0aGUgZXhjZXB0aW9uIHJlY29yZFxuXHRcdFx0Ly8gaXMgYXZhaWxhYmxlIG9ubHkgd2hlbiBzZXR0bGUgY2FycmllZCB0aGUgcmVqZWN0aW9uIGl0c2VsZlxuXHRcdFx0c3Bhbi5zZXRTdGF0dXMoeyBjb2RlOiBTcGFuU3RhdHVzQ29kZS5FUlJPUiB9KTtcblx0XHRcdGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRcdHNwYW4ucmVjb3JkRXhjZXB0aW9uKGVycm9yKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0c3Bhbi5lbmQoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcm9zcy1zdXJmYWNlIGF0dHJpYnV0ZXMgZXZlcnkgc3BhbiBnZXRzLCBvbiBldmVyeSBob29rIHBhdGg6XG5cdCAqIHRoZSBlZGdlJ3MgdHJhY2Ugcm9vdCBpZCAoSmFlZ2VyIGxpbmsg4oaSIG1uZW1vZ3JhcGhpY2EncyBMaXZlIFRyYWNlLFxuXHQgKiBXYW50ZWQgIzEpLCB0aGUgZWRnZUlk4oaSdHJhY2VJZCBwdWJsaWNhdGlvbiBmb3IgdGhlIHN0cmF0ZWd5IHB1c2hcblx0ICogY2hhbm5lbCAoV2FudGVkICMyKSwgYW5kIGNvZGUuZmlsZXBhdGgvbGluZS9jb2x1bW4gcGFyc2VkIGZyb20gdGhlXG5cdCAqIGNhbGxzaXRlIG5hbWUgKFdhbnRlZCAjNCkuXG5cdCAqL1xuXHRwcml2YXRlIGRlY29yYXRlU3BhbiAoc3BhbjogU3BhbiwgZWRnZTogRmxvd0VkZ2UpOiB2b2lkIHtcblx0XHRzcGFuLnNldEF0dHJpYnV0ZSgnZGl2ZS5yb290X2VkZ2VfaWQnLCB0aGlzLnJvb3RFZGdlSWRPZihlZGdlKSk7XG5cdFx0cmVjb3JkRWRnZVRyYWNlKGVkZ2UuaWQsIHNwYW4uc3BhbkNvbnRleHQoKS50cmFjZUlkKTtcblx0XHRpZiAoZWRnZS5raW5kICE9PSAnY2FsbCcgJiYgZWRnZS5raW5kICE9PSAnbWV0aG9kJyAmJiBlZGdlLmtpbmQgIT09ICdjb25zdHJ1Y3QnKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGNvbnN0IG1hdGNoID0gQ0FMTFNJVEVfUkUuZXhlYyhlZGdlLm5hbWUpO1xuXHRcdGlmICghbWF0Y2gpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0c3Bhbi5zZXRBdHRyaWJ1dGUoJ2NvZGUuZmlsZXBhdGgnLCBtYXRjaFsxXSk7XG5cdFx0c3Bhbi5zZXRBdHRyaWJ1dGUoJ2NvZGUubGluZW5vJywgTnVtYmVyKG1hdGNoWzJdKSk7XG5cdFx0c3Bhbi5zZXRBdHRyaWJ1dGUoJ2NvZGUuY29sdW1uJywgTnVtYmVyKG1hdGNoWzNdKSk7XG5cdH1cblxuXHQvLyBXYWxrIGRpdmUncyBwYXJlbnRhZ2UgdG8gdGhlIHJvb3QgZWRnZSBpZC4gUGFyZW50cyBhcmUgcmVjb3JkZWQgYXNcblx0Ly8gZWRnZXMgYXJyaXZlIChlbnRlciBmaXJlcyBwYXJlbnQtYmVmb3JlLWNoaWxkKSwgc28gdGhlIGNoYWluIGlzXG5cdC8vIGNvbXBsZXRlIGZvciBhbnl0aGluZyBzdGlsbCBpbiBmbGlnaHQ7IGFuIGV2aWN0ZWQvdW5rbm93biBwYXJlbnRcblx0Ly8gc2ltcGx5IGVuZHMgdGhlIHdhbGsgYXQgdGhlIGRlZXBlc3Qga25vd24gaWQuXG5cdHByaXZhdGUgcm9vdEVkZ2VJZE9mIChlZGdlOiBGbG93RWRnZSk6IG51bWJlciB7XG5cdFx0aWYgKHRoaXMuZWRnZVBhcmVudHMuc2l6ZSA+PSBEaXZlT3RlbFByb3ZpZGVyLkVER0VfUEFSRU5UU19MSU1JVCkge1xuXHRcdFx0dGhpcy5lZGdlUGFyZW50cy5jbGVhcigpO1xuXHRcdH1cblx0XHR0aGlzLmVkZ2VQYXJlbnRzLnNldChlZGdlLmlkLCBlZGdlLnBhcmVudElkKTtcblx0XHRsZXQgaWQgPSBlZGdlLmlkO1xuXHRcdGxldCBwYXJlbnQgPSBlZGdlLnBhcmVudElkO1xuXHRcdGNvbnN0IHNlZW4gPSBuZXcgU2V0PG51bWJlcj4oW2lkXSk7XG5cdFx0d2hpbGUgKHBhcmVudCAhPT0gbnVsbCAmJiAhc2Vlbi5oYXMocGFyZW50KSkge1xuXHRcdFx0c2Vlbi5hZGQocGFyZW50KTtcblx0XHRcdGlkID0gcGFyZW50O1xuXHRcdFx0Y29uc3QgbmV4dCA9IHRoaXMuZWRnZVBhcmVudHMuZ2V0KHBhcmVudCk7XG5cdFx0XHRwYXJlbnQgPSBuZXh0ID09PSB1bmRlZmluZWQgPyBudWxsIDogbmV4dDtcblx0XHR9XG5cdFx0cmV0dXJuIGlkO1xuXHR9XG59XG4iXX0=
@@ -0,0 +1,12 @@
1
+ import type { Tracer, Span } from '@opentelemetry/api';
2
+ import type { TypesCollection } from 'mnemonica/module';
3
+ export declare class MnemonicaOtelProvider {
4
+ private tracer;
5
+ private pendingSpans;
6
+ constructor(tracer?: Tracer);
7
+ getCurrentSpan(): Span | undefined;
8
+ runWithSpan<T>(span: Span, fn: () => T): T;
9
+ attachHooks(collection: TypesCollection): void;
10
+ private findParentSpan;
11
+ }
12
+ //# sourceMappingURL=mnemonica-otel.provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mnemonica-otel.provider.d.ts","sourceRoot":"","sources":["../../src/providers/mnemonica-otel.provider.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAa,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAKnE,qBAAa,qBAAqB;IACjC,OAAO,CAAC,MAAM,CAAS;IAGvB,OAAO,CAAC,YAAY,CAA+B;gBAEtC,MAAM,CAAC,EAAE,MAAM;IAI5B,cAAc,IAAK,IAAI,GAAG,SAAS;IAInC,WAAW,CAAC,CAAC,EAAG,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAI3C,WAAW,CAAE,UAAU,EAAE,eAAe,GAAG,IAAI;IAoF/C,OAAO,CAAC,cAAc;CAsBtB"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * OpenTelemetry provider for mnemonica lifecycle hooks.
3
+ *
4
+ * Creates spans for preCreation / postCreation / creationError,
5
+ * parents them along the prototype chain, and propagates
6
+ * context via AsyncLocalStorage.
7
+ */
8
+ import { AsyncLocalStorage } from 'async_hooks';
9
+ import { trace, context as otelContext } from '@opentelemetry/api';
10
+ const SymbolParentSpan = Symbol.for('mnemonica.span.parent');
11
+ const asyncStorage = new AsyncLocalStorage();
12
+ export class MnemonicaOtelProvider {
13
+ tracer;
14
+ // spans of constructions in flight, keyed on the per-call args array
15
+ // (the only value core guarantees identical between pre and post hooks)
16
+ pendingSpans = new WeakMap();
17
+ constructor(tracer) {
18
+ this.tracer = tracer ?? trace.getTracer('@mnemonica/otel');
19
+ }
20
+ getCurrentSpan() {
21
+ return asyncStorage.getStore();
22
+ }
23
+ runWithSpan(span, fn) {
24
+ return asyncStorage.run(span, fn);
25
+ }
26
+ attachHooks(collection) {
27
+ collection.registerHook('preCreation', (hookData) => {
28
+ const parentSpan = this.findParentSpan(hookData);
29
+ const ctx = parentSpan
30
+ ? trace.setSpan(otelContext.active(), parentSpan)
31
+ : undefined;
32
+ const span = parentSpan
33
+ ? this.tracer.startSpan(`mnemonica.${hookData.TypeName}`, {}, ctx)
34
+ : this.tracer.startSpan(`mnemonica.${hookData.TypeName}`);
35
+ span.setAttribute('mnemonica.type_name', hookData.TypeName);
36
+ span.setAttribute('mnemonica.hook', 'preCreation');
37
+ // Store the pending span keyed on the construction's args array:
38
+ // core passes the identical args reference to preCreation and to
39
+ // postCreation/creationError, and it is unique per construction call.
40
+ // Keying on the parent instance would collide when async constructions
41
+ // of siblings interleave (preA, preB, postB, postA — the second
42
+ // preCreation would overwrite the first).
43
+ this.pendingSpans.set(hookData.args, span);
44
+ });
45
+ collection.registerHook('postCreation', (hookData) => {
46
+ const newInstance = hookData.inheritedInstance;
47
+ if (newInstance == null || typeof newInstance !== 'object') {
48
+ return;
49
+ }
50
+ // Retrieve and remove the pending span for this construction
51
+ let span = this.pendingSpans.get(hookData.args);
52
+ this.pendingSpans.delete(hookData.args);
53
+ if (!span) {
54
+ // Fallback: create span here if preCreation didn't (shouldn't happen)
55
+ span = this.tracer.startSpan(`mnemonica.${hookData.TypeName}`);
56
+ span.setAttribute('mnemonica.type_name', hookData.TypeName);
57
+ }
58
+ span.setAttribute('mnemonica.hook', 'postCreation');
59
+ span.end();
60
+ // Store on new instance so its children can find the parent span
61
+ Object.defineProperty(newInstance, SymbolParentSpan, {
62
+ value: span,
63
+ configurable: true,
64
+ enumerable: false,
65
+ writable: true,
66
+ });
67
+ });
68
+ collection.registerHook('creationError', (hookData) => {
69
+ const newInstance = hookData.inheritedInstance;
70
+ if (newInstance == null || typeof newInstance !== 'object') {
71
+ return;
72
+ }
73
+ // Retrieve and remove the pending span for this construction
74
+ let span = this.pendingSpans.get(hookData.args);
75
+ this.pendingSpans.delete(hookData.args);
76
+ if (!span) {
77
+ span = this.tracer.startSpan(`mnemonica.${hookData.TypeName}`);
78
+ span.setAttribute('mnemonica.type_name', hookData.TypeName);
79
+ }
80
+ span.setAttribute('mnemonica.hook', 'creationError');
81
+ span.setAttribute('error.type', 'Error');
82
+ span.recordException(newInstance);
83
+ span.end();
84
+ // Store on error instance for chain tracing
85
+ Object.defineProperty(newInstance, SymbolParentSpan, {
86
+ value: span,
87
+ configurable: true,
88
+ enumerable: false,
89
+ writable: true,
90
+ });
91
+ });
92
+ }
93
+ findParentSpan(hookData) {
94
+ const stored = asyncStorage.getStore();
95
+ if (stored) {
96
+ return stored;
97
+ }
98
+ const parent = hookData.existentInstance;
99
+ if (parent == null || typeof parent !== 'object') {
100
+ return undefined;
101
+ }
102
+ let current = parent;
103
+ while (current) {
104
+ const span = current[SymbolParentSpan];
105
+ if (span) {
106
+ return span;
107
+ }
108
+ current = Object.getPrototypeOf(current);
109
+ }
110
+ return undefined;
111
+ }
112
+ }
113
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW5lbW9uaWNhLW90ZWwucHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJvdmlkZXJzL21uZW1vbmljYS1vdGVsLnByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUNILE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUVoRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sSUFBSSxXQUFXLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUduRSxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLENBQUMsQ0FBQztBQUM3RCxNQUFNLFlBQVksR0FBRyxJQUFJLGlCQUFpQixFQUFRLENBQUM7QUFFbkQsTUFBTSxPQUFPLHFCQUFxQjtJQUN6QixNQUFNLENBQVM7SUFDdkIscUVBQXFFO0lBQ3JFLHdFQUF3RTtJQUNoRSxZQUFZLEdBQUcsSUFBSSxPQUFPLEVBQWdCLENBQUM7SUFFbkQsWUFBYSxNQUFlO1FBQzNCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxJQUFJLEtBQUssQ0FBQyxTQUFTLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRUQsY0FBYztRQUNiLE9BQU8sWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxXQUFXLENBQUssSUFBVSxFQUFFLEVBQVc7UUFDdEMsT0FBTyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsV0FBVyxDQUFFLFVBQTJCO1FBQ3ZDLFVBQVUsQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLENBQUMsUUFBbUIsRUFBRSxFQUFFO1lBQzlELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDakQsTUFBTSxHQUFHLEdBQUcsVUFBVTtnQkFDckIsQ0FBQyxD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LE1BQU0sQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDMUMsQ0FBQztRQUVELE9BQU8sU0FBUyxDQUFDO0lBQ2xCLENBQUM7Q0FDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogT3BlblRlbGVtZXRyeSBwcm92aWRlciBmb3IgbW5lbW9uaWNhIGxpZmVjeWNsZSBob29rcy5cbiAqXG4gKiBDcmVhdGVzIHNwYW5zIGZvciBwcmVDcmVhdGlvbiAvIHBvc3RDcmVhdGlvbiAvIGNyZWF0aW9uRXJyb3IsXG4gKiBwYXJlbnRzIHRoZW0gYWxvbmcgdGhlIHByb3RvdHlwZSBjaGFpbiwgYW5kIHByb3BhZ2F0ZXNcbiAqIGNvbnRleHQgdmlhIEFzeW5jTG9jYWxTdG9yYWdlLlxuICovXG5pbXBvcnQgeyBBc3luY0xvY2FsU3RvcmFnZSB9IGZyb20gJ2FzeW5jX2hvb2tzJztcbmltcG9ydCB0eXBlIHsgVHJhY2VyLCBTcGFuIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvYXBpJztcbmltcG9ydCB7IHRyYWNlLCBjb250ZXh0IGFzIG90ZWxDb250ZXh0IH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvYXBpJztcbmltcG9ydCB0eXBlIHsgaG9va3NPcHRzLCBUeXBlc0NvbGxlY3Rpb24gfSBmcm9tICdtbmVtb25pY2EvbW9kdWxlJztcblxuY29uc3QgU3ltYm9sUGFyZW50U3BhbiA9IFN5bWJvbC5mb3IoJ21uZW1vbmljYS5zcGFuLnBhcmVudCcpO1xuY29uc3QgYXN5bmNTdG9yYWdlID0gbmV3IEFzeW5jTG9jYWxTdG9yYWdlPFNwYW4+KCk7XG5cbmV4cG9ydCBjbGFzcyBNbmVtb25pY2FPdGVsUHJvdmlkZXIge1xuXHRwcml2YXRlIHRyYWNlcjogVHJhY2VyO1xuXHQvLyBzcGFucyBvZiBjb25zdHJ1Y3Rpb25zIGluIGZsaWdodCwga2V5ZWQgb24gdGhlIHBlci1jYWxsIGFyZ3MgYXJyYXlcblx0Ly8gKHRoZSBvbmx5IHZhbHVlIGNvcmUgZ3VhcmFudGVlcyBpZGVudGljYWwgYmV0d2VlbiBwcmUgYW5kIHBvc3QgaG9va3MpXG5cdHByaXZhdGUgcGVuZGluZ1NwYW5zID0gbmV3IFdlYWtNYXA8b2JqZWN0LCBTcGFuPigpO1xuXG5cdGNvbnN0cnVjdG9yICh0cmFjZXI/OiBUcmFjZXIpIHtcblx0XHR0aGlzLnRyYWNlciA9IHRyYWNlciA/PyB0cmFjZS5nZXRUcmFjZXIoJ0BtbmVtb25pY2Evb3RlbCcpO1xuXHR9XG5cblx0Z2V0Q3VycmVudFNwYW4gKCk6IFNwYW4gfCB1bmRlZmluZWQge1xuXHRcdHJldHVybiBhc3luY1N0b3JhZ2UuZ2V0U3RvcmUoKTtcblx0fVxuXG5cdHJ1bldpdGhTcGFuPFQ+IChzcGFuOiBTcGFuLCBmbjogKCkgPT4gVCk6IFQge1xuXHRcdHJldHVybiBhc3luY1N0b3JhZ2UucnVuKHNwYW4sIGZuKTtcblx0fVxuXG5cdGF0dGFjaEhvb2tzIChjb2xsZWN0aW9uOiBUeXBlc0NvbGxlY3Rpb24pOiB2b2lkIHtcblx0XHRjb2xsZWN0aW9uLnJlZ2lzdGVySG9vaygncHJlQ3JlYXRpb24nLCAoaG9va0RhdGE6IGhvb2tzT3B0cykgPT4ge1xuXHRcdFx0Y29uc3QgcGFyZW50U3BhbiA9IHRoaXMuZmluZFBhcmVudFNwYW4oaG9va0RhdGEpO1xuXHRcdFx0Y29uc3QgY3R4ID0gcGFyZW50U3BhblxuXHRcdFx0XHQ/IHRyYWNlLnNldFNwYW4ob3RlbENvbnRleHQuYWN0aXZlKCksIHBhcmVudFNwYW4pXG5cdFx0XHRcdDogdW5kZWZpbmVkO1xuXHRcdFx0Y29uc3Qgc3BhbiA9IHBhcmVudFNwYW5cblx0XHRcdFx0PyB0aGlzLnRyYWNlci5zdGFydFNwYW4oXG5cdFx0XHRcdFx0YG1uZW1vbmljYS4ke2hvb2tEYXRhLlR5cGVOYW1lfWAsXG5cdFx0XHRcdFx0e30sXG5cdFx0XHRcdFx0Y3R4XG5cdFx0XHRcdClcblx0XHRcdFx0OiB0aGlzLnRyYWNlci5zdGFydFNwYW4oYG1uZW1vbmljYS4ke2hvb2tEYXRhLlR5cGVOYW1lfWApO1xuXG5cdFx0XHRzcGFuLnNldEF0dHJpYnV0ZSgnbW5lbW9uaWNhLnR5cGVfbmFtZScsIGhvb2tEYXRhLlR5cGVOYW1lKTtcblx0XHRcdHNwYW4uc2V0QXR0cmlidXRlKCdtbmVtb25pY2EuaG9vaycsICdwcmVDcmVhdGlvbicpO1xuXG5cdFx0XHQvLyBTdG9yZSB0aGUgcGVuZGluZyBzcGFuIGtleWVkIG9uIHRoZSBjb25zdHJ1Y3Rpb24ncyBhcmdzIGFycmF5OlxuXHRcdFx0Ly8gY29yZSBwYXNzZXMgdGhlIGlkZW50aWNhbCBhcmdzIHJlZmVyZW5jZSB0byBwcmVDcmVhdGlvbiBhbmQgdG9cblx0XHRcdC8vIHBvc3RDcmVhdGlvbi9jcmVhdGlvbkVycm9yLCBhbmQgaXQgaXMgdW5pcXVlIHBlciBjb25zdHJ1Y3Rpb24gY2FsbC5cblx0XHRcdC8vIEtleWluZyBvbiB0aGUgcGFyZW50IGluc3RhbmNlIHdvdWxkIGNvbGxpZGUgd2hlbiBhc3luYyBjb25zdHJ1Y3Rpb25zXG5cdFx0XHQvLyBvZiBzaWJsaW5ncyBpbnRlcmxlYXZlIChwcmVBLCBwcmVCLCBwb3N0QiwgcG9zdEEg4oCUIHRoZSBzZWNvbmRcblx0XHRcdC8vIHByZUNyZWF0aW9uIHdvdWxkIG92ZXJ3cml0ZSB0aGUgZmlyc3QpLlxuXHRcdFx0dGhpcy5wZW5kaW5nU3BhbnMuc2V0KGhvb2tEYXRhLmFyZ3MsIHNwYW4pO1xuXHRcdH0pO1xuXG5cdFx0Y29sbGVjdGlvbi5yZWdpc3Rlckhvb2soJ3Bvc3RDcmVhdGlvbicsIChob29rRGF0YTogaG9va3NPcHRzKSA9PiB7XG5cdFx0XHRjb25zdCBuZXdJbnN0YW5jZSA9IGhvb2tEYXRhLmluaGVyaXRlZEluc3RhbmNlO1xuXHRcdFx0aWYgKG5ld0luc3RhbmNlID09IG51bGwgfHwgdHlwZW9mIG5ld0luc3RhbmNlICE9PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJldHJpZXZlIGFuZCByZW1vdmUgdGhlIHBlbmRpbmcgc3BhbiBmb3IgdGhpcyBjb25zdHJ1Y3Rpb25cblx0XHRcdGxldCBzcGFuID0gdGhpcy5wZW5kaW5nU3BhbnMuZ2V0KGhvb2tEYXRhLmFyZ3MpO1xuXHRcdFx0dGhpcy5wZW5kaW5nU3BhbnMuZGVsZXRlKGhvb2tEYXRhLmFyZ3MpO1xuXG5cdFx0XHRpZiAoIXNwYW4pIHtcblx0XHRcdFx0Ly8gRmFsbGJhY2s6IGNyZWF0ZSBzcGFuIGhlcmUgaWYgcHJlQ3JlYXRpb24gZGlkbid0IChzaG91bGRuJ3QgaGFwcGVuKVxuXHRcdFx0XHRzcGFuID0gdGhpcy50cmFjZXIuc3RhcnRTcGFuKGBtbmVtb25pY2EuJHtob29rRGF0YS5UeXBlTmFtZX1gKTtcblx0XHRcdFx0c3Bhbi5zZXRBdHRyaWJ1dGUoJ21uZW1vbmljYS50eXBlX25hbWUnLCBob29rRGF0YS5UeXBlTmFtZSk7XG5cdFx0XHR9XG5cblx0XHRcdHNwYW4uc2V0QXR0cmlidXRlKCdtbmVtb25pY2EuaG9vaycsICdwb3N0Q3JlYXRpb24nKTtcblx0XHRcdHNwYW4uZW5kKCk7XG5cblx0XHRcdC8vIFN0b3JlIG9uIG5ldyBpbnN0YW5jZSBzbyBpdHMgY2hpbGRyZW4gY2FuIGZpbmQgdGhlIHBhcmVudCBzcGFuXG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkobmV3SW5zdGFuY2UsIFN5bWJvbFBhcmVudFNwYW4sIHtcblx0XHRcdFx0dmFsdWUgICAgICAgOiBzcGFuLFxuXHRcdFx0XHRjb25maWd1cmFibGU6IHRydWUsXG5cdFx0XHRcdGVudW1lcmFibGUgIDogZmFsc2UsXG5cdFx0XHRcdHdyaXRhYmxlICAgIDogdHJ1ZSxcblx0XHRcdH0pO1xuXHRcdH0pO1xuXG5cdFx0Y29sbGVjdGlvbi5yZWdpc3Rlckhvb2soJ2NyZWF0aW9uRXJyb3InLCAoaG9va0RhdGE6IGhvb2tzT3B0cykgPT4ge1xuXHRcdFx0Y29uc3QgbmV3SW5zdGFuY2UgPSBob29rRGF0YS5pbmhlcml0ZWRJbnN0YW5jZTtcblx0XHRcdGlmIChuZXdJbnN0YW5jZSA9PSBudWxsIHx8IHR5cGVvZiBuZXdJbnN0YW5jZSAhPT0gJ29iamVjdCcpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXRyaWV2ZSBhbmQgcmVtb3ZlIHRoZSBwZW5kaW5nIHNwYW4gZm9yIHRoaXMgY29uc3RydWN0aW9uXG5cdFx0XHRsZXQgc3BhbiA9IHRoaXMucGVuZGluZ1NwYW5zLmdldChob29rRGF0YS5hcmdzKTtcblx0XHRcdHRoaXMucGVuZGluZ1NwYW5zLmRlbGV0ZShob29rRGF0YS5hcmdzKTtcblxuXHRcdFx0aWYgKCFzcGFuKSB7XG5cdFx0XHRcdHNwYW4gPSB0aGlzLnRyYWNlci5zdGFydFNwYW4oYG1uZW1vbmljYS4ke2hvb2tEYXRhLlR5cGVOYW1lfWApO1xuXHRcdFx0XHRzcGFuLnNldEF0dHJpYnV0ZSgnbW5lbW9uaWNhLnR5cGVfbmFtZScsIGhvb2tEYXRhLlR5cGVOYW1lKTtcblx0XHRcdH1cblxuXHRcdFx0c3Bhbi5zZXRBdHRyaWJ1dGUoJ21uZW1vbmljYS5ob29rJywgJ2NyZWF0aW9uRXJyb3InKTtcblx0XHRcdHNwYW4uc2V0QXR0cmlidXRlKCdlcnJvci50eXBlJywgJ0Vycm9yJyk7XG5cdFx0XHRzcGFuLnJlY29yZEV4Y2VwdGlvbihuZXdJbnN0YW5jZSBhcyBFcnJvcik7XG5cdFx0XHRzcGFuLmVuZCgpO1xuXG5cdFx0XHQvLyBTdG9yZSBvbiBlcnJvciBpbnN0YW5jZSBmb3IgY2hhaW4gdHJhY2luZ1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG5ld0luc3RhbmNlLCBTeW1ib2xQYXJlbnRTcGFuLCB7XG5cdFx0XHRcdHZhbHVlICAgICAgIDogc3Bhbixcblx0XHRcdFx0Y29uZmlndXJhYmxlOiB0cnVlLFxuXHRcdFx0XHRlbnVtZXJhYmxlICA6IGZhbHNlLFxuXHRcdFx0XHR3cml0YWJsZSAgICA6IHRydWUsXG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdHByaXZhdGUgZmluZFBhcmVudFNwYW4gKGhvb2tEYXRhOiBob29rc09wdHMpOiBTcGFuIHwgdW5kZWZpbmVkIHtcblx0XHRjb25zdCBzdG9yZWQgPSBhc3luY1N0b3JhZ2UuZ2V0U3RvcmUoKTtcblx0XHRpZiAoc3RvcmVkKSB7XG5cdFx0XHRyZXR1cm4gc3RvcmVkO1xuXHRcdH1cblxuXHRcdGNvbnN0IHBhcmVudCA9IGhvb2tEYXRhLmV4aXN0ZW50SW5zdGFuY2U7XG5cdFx0aWYgKHBhcmVudCA9PSBudWxsIHx8IHR5cGVvZiBwYXJlbnQgIT09ICdvYmplY3QnKSB7XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblxuXHRcdGxldCBjdXJyZW50OiBvYmplY3QgfCBudWxsID0gcGFyZW50O1xuXHRcdHdoaWxlIChjdXJyZW50KSB7XG5cdFx0XHRjb25zdCBzcGFuID0gKGN1cnJlbnQgYXMgUmVjb3JkPHN5bWJvbCwgdW5rbm93bj4pW1N5bWJvbFBhcmVudFNwYW5dIGFzIFNwYW4gfCB1bmRlZmluZWQ7XG5cdFx0XHRpZiAoc3Bhbikge1xuXHRcdFx0XHRyZXR1cm4gc3Bhbjtcblx0XHRcdH1cblx0XHRcdGN1cnJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoY3VycmVudCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0fVxufVxuIl19
@@ -0,0 +1,41 @@
1
+ /**
2
+ * HTTP request scope — the framework-free half of the adapter's trace
3
+ * middleware: one OTel span per HTTP request, visible to mnemonica hooks
4
+ * through the provider's own ALS AND to dive spans through the OTEL global
5
+ * context, with the async-flow root frame outermost when provided.
6
+ *
7
+ * Framework mapping notes:
8
+ * - Express-style middleware: call with (req, res, deps, () => next()).
9
+ * - Fastify: onRequest hook — call with (request.raw, reply.raw, deps,
10
+ * () => done()); reply.raw is the underlying ServerResponse.
11
+ * - raw http: wrap the request listener; ServerResponse emits 'finish'.
12
+ */
13
+ import type { Tracer } from '@opentelemetry/api';
14
+ import { MnemonicaOtelProvider } from './providers/mnemonica-otel.provider.js';
15
+ import { AsyncFlowProvider } from './providers/async-flow.provider.js';
16
+ /** Structural minimum of the request. */
17
+ export interface HttpRequestLike {
18
+ method: string;
19
+ url: string;
20
+ /** Express exposes the matched route as req.route.path */
21
+ route?: {
22
+ path?: string;
23
+ };
24
+ }
25
+ /** Structural minimum of the response: a 'finish' event + statusCode. */
26
+ export interface HttpResponseLike {
27
+ statusCode: number;
28
+ on(event: 'finish', listener: () => void): unknown;
29
+ }
30
+ export interface RequestScopeDeps {
31
+ tracer: Tracer;
32
+ otel: MnemonicaOtelProvider;
33
+ asyncFlow?: AsyncFlowProvider;
34
+ }
35
+ /**
36
+ * Start the request span, hang its ending on response 'finish', and run
37
+ * `fn` inside the triple scope (provider ALS + OTEL global context +
38
+ * async-flow root frame). `fn` is the framework's "continue" callback.
39
+ */
40
+ export declare function runInRequestScope(req: HttpRequestLike, res: HttpResponseLike, deps: RequestScopeDeps, fn: () => void): void;
41
+ //# sourceMappingURL=request-scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-scope.d.ts","sourceRoot":"","sources":["../src/request-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAEvE,yCAAyC;AACzC,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAG,MAAM,CAAC;IAChB,GAAG,EAAM,MAAM,CAAC;IAChB,0DAA0D;IAC1D,KAAK,CAAC,EAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3B;AAED,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAChC,UAAU,EAAG,MAAM,CAAC;IACpB,EAAE,CAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;CACpD;AAED,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAO,MAAM,CAAC;IACpB,IAAI,EAAS,qBAAqB,CAAC;IACnC,SAAS,CAAC,EAAG,iBAAiB,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAChC,GAAG,EAAI,eAAe,EACtB,GAAG,EAAI,gBAAgB,EACvB,IAAI,EAAG,gBAAgB,EACvB,EAAE,EAAK,MAAM,IAAI,GACf,IAAI,CA6BN"}
@@ -0,0 +1,35 @@
1
+ import { context as otelContext, trace } from '@opentelemetry/api';
2
+ /**
3
+ * Start the request span, hang its ending on response 'finish', and run
4
+ * `fn` inside the triple scope (provider ALS + OTEL global context +
5
+ * async-flow root frame). `fn` is the framework's "continue" callback.
6
+ */
7
+ export function runInRequestScope(req, res, deps, fn) {
8
+ const route = req.route?.path ?? req.url;
9
+ const span = deps.tracer.startSpan(`HTTP ${req.method} ${route}`);
10
+ span.setAttribute('http.method', req.method);
11
+ span.setAttribute('http.url', req.url);
12
+ res.on('finish', () => {
13
+ span.setAttribute('http.status_code', res.statusCode);
14
+ span.end();
15
+ });
16
+ // runWithSpan covers the mnemonica-hook side (the provider's own ALS);
17
+ // the OTEL global context is what DiveOtelProvider reads when it looks
18
+ // for a parent span at wrap boundaries — without this second entry
19
+ // dive spans never adopt the request span and stay root traces.
20
+ // The async-flow root frame (when provided) is the outermost scope:
21
+ // every async hop of this request — wrapped or not — inherits it via
22
+ // ALS propagation.
23
+ const activeCtx = trace.setSpan(otelContext.active(), span);
24
+ const run = () => {
25
+ deps.otel.runWithSpan(span, () => {
26
+ otelContext.with(activeCtx, fn);
27
+ });
28
+ };
29
+ if (deps.asyncFlow) {
30
+ deps.asyncFlow.runInScope(run);
31
+ return;
32
+ }
33
+ run();
34
+ }
35
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdC1zY29wZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXF1ZXN0LXNjb3BlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWFBLE9BQU8sRUFBRSxPQUFPLElBQUksV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBd0JuRTs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUNoQyxHQUFzQixFQUN0QixHQUF1QixFQUN2QixJQUF1QixFQUN2QixFQUFpQjtJQUVqQixNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDO0lBQ3pDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsR0FBRyxDQUFDLE1BQU0sSUFBSSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQ2xFLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM3QyxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFdkMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFO1FBQ3JCLElBQUksQ0FBQyxZQUFZLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNaLENBQUMsQ0FBQyxDQUFDO0lBRUgsdUVBQXVFO0lBQ3ZFLHVFQUF1RTtJQUN2RSxtRUFBbUU7SUFDbkUsZ0VBQWdFO0lBQ2hFLG9FQUFvRTtJQUNwRSxxRUFBcUU7SUFDckUsbUJBQW1CO0lBQ25CLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzVELE1BQU0sR0FBRyxHQUFHLEdBQVMsRUFBRTtRQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFO1lBQ2hDLFdBQVcsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2pDLENBQUMsQ0FBQyxDQUFDO0lBQ0osQ0FBQyxDQUFDO0lBQ0YsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0IsT0FBTztJQUNSLENBQUM7SUFDRCxHQUFHLEVBQUUsQ0FBQztBQUNQLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEhUVFAgcmVxdWVzdCBzY29wZSDigJQgdGhlIGZyYW1ld29yay1mcmVlIGhhbGYgb2YgdGhlIGFkYXB0ZXIncyB0cmFjZVxuICogbWlkZGxld2FyZTogb25lIE9UZWwgc3BhbiBwZXIgSFRUUCByZXF1ZXN0LCB2aXNpYmxlIHRvIG1uZW1vbmljYSBob29rc1xuICogdGhyb3VnaCB0aGUgcHJvdmlkZXIncyBvd24gQUxTIEFORCB0byBkaXZlIHNwYW5zIHRocm91Z2ggdGhlIE9URUwgZ2xvYmFsXG4gKiBjb250ZXh0LCB3aXRoIHRoZSBhc3luYy1mbG93IHJvb3QgZnJhbWUgb3V0ZXJtb3N0IHdoZW4gcHJvdmlkZWQuXG4gKlxuICogRnJhbWV3b3JrIG1hcHBpbmcgbm90ZXM6XG4gKiAgLSBFeHByZXNzLXN0eWxlIG1pZGRsZXdhcmU6IGNhbGwgd2l0aCAocmVxLCByZXMsIGRlcHMsICgpID0+IG5leHQoKSkuXG4gKiAgLSBGYXN0aWZ5OiBvblJlcXVlc3QgaG9vayDigJQgY2FsbCB3aXRoIChyZXF1ZXN0LnJhdywgcmVwbHkucmF3LCBkZXBzLFxuICogICAgKCkgPT4gZG9uZSgpKTsgcmVwbHkucmF3IGlzIHRoZSB1bmRlcmx5aW5nIFNlcnZlclJlc3BvbnNlLlxuICogIC0gcmF3IGh0dHA6IHdyYXAgdGhlIHJlcXVlc3QgbGlzdGVuZXI7IFNlcnZlclJlc3BvbnNlIGVtaXRzICdmaW5pc2gnLlxuICovXG5pbXBvcnQgdHlwZSB7IFRyYWNlciB9IGZyb20gJ0BvcGVudGVsZW1ldHJ5L2FwaSc7XG5pbXBvcnQgeyBjb250ZXh0IGFzIG90ZWxDb250ZXh0LCB0cmFjZSB9IGZyb20gJ0BvcGVudGVsZW1ldHJ5L2FwaSc7XG5pbXBvcnQgeyBNbmVtb25pY2FPdGVsUHJvdmlkZXIgfSBmcm9tICcuL3Byb3ZpZGVycy9tbmVtb25pY2Etb3RlbC5wcm92aWRlci5qcyc7XG5pbXBvcnQgeyBBc3luY0Zsb3dQcm92aWRlciB9IGZyb20gJy4vcHJvdmlkZXJzL2FzeW5jLWZsb3cucHJvdmlkZXIuanMnO1xuXG4vKiogU3RydWN0dXJhbCBtaW5pbXVtIG9mIHRoZSByZXF1ZXN0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBIdHRwUmVxdWVzdExpa2Uge1xuXHRtZXRob2QgOiBzdHJpbmc7XG5cdHVybCAgICA6IHN0cmluZztcblx0LyoqIEV4cHJlc3MgZXhwb3NlcyB0aGUgbWF0Y2hlZCByb3V0ZSBhcyByZXEucm91dGUucGF0aCAqL1xuXHRyb3V0ZT8gOiB7IHBhdGg/OiBzdHJpbmcgfTtcbn1cblxuLyoqIFN0cnVjdHVyYWwgbWluaW11bSBvZiB0aGUgcmVzcG9uc2U6IGEgJ2ZpbmlzaCcgZXZlbnQgKyBzdGF0dXNDb2RlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBIdHRwUmVzcG9uc2VMaWtlIHtcblx0c3RhdHVzQ29kZSA6IG51bWJlcjtcblx0b24gKGV2ZW50OiAnZmluaXNoJywgbGlzdGVuZXI6ICgpID0+IHZvaWQpOiB1bmtub3duO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlcXVlc3RTY29wZURlcHMge1xuXHR0cmFjZXIgICAgIDogVHJhY2VyO1xuXHRvdGVsICAgICAgIDogTW5lbW9uaWNhT3RlbFByb3ZpZGVyO1xuXHRhc3luY0Zsb3c/IDogQXN5bmNGbG93UHJvdmlkZXI7XG59XG5cbi8qKlxuICogU3RhcnQgdGhlIHJlcXVlc3Qgc3BhbiwgaGFuZyBpdHMgZW5kaW5nIG9uIHJlc3BvbnNlICdmaW5pc2gnLCBhbmQgcnVuXG4gKiBgZm5gIGluc2lkZSB0aGUgdHJpcGxlIHNjb3BlIChwcm92aWRlciBBTFMgKyBPVEVMIGdsb2JhbCBjb250ZXh0ICtcbiAqIGFzeW5jLWZsb3cgcm9vdCBmcmFtZSkuIGBmbmAgaXMgdGhlIGZyYW1ld29yaydzIFwiY29udGludWVcIiBjYWxsYmFjay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJ1bkluUmVxdWVzdFNjb3BlIChcblx0cmVxICA6IEh0dHBSZXF1ZXN0TGlrZSxcblx0cmVzICA6IEh0dHBSZXNwb25zZUxpa2UsXG5cdGRlcHMgOiBSZXF1ZXN0U2NvcGVEZXBzLFxuXHRmbiAgIDogKCkgPT4gdm9pZCxcbik6IHZvaWQge1xuXHRjb25zdCByb3V0ZSA9IHJlcS5yb3V0ZT8ucGF0aCA/PyByZXEudXJsO1xuXHRjb25zdCBzcGFuID0gZGVwcy50cmFjZXIuc3RhcnRTcGFuKGBIVFRQICR7cmVxLm1ldGhvZH0gJHtyb3V0ZX1gKTtcblx0c3Bhbi5zZXRBdHRyaWJ1dGUoJ2h0dHAubWV0aG9kJywgcmVxLm1ldGhvZCk7XG5cdHNwYW4uc2V0QXR0cmlidXRlKCdodHRwLnVybCcsIHJlcS51cmwpO1xuXG5cdHJlcy5vbignZmluaXNoJywgKCkgPT4ge1xuXHRcdHNwYW4uc2V0QXR0cmlidXRlKCdodHRwLnN0YXR1c19jb2RlJywgcmVzLnN0YXR1c0NvZGUpO1xuXHRcdHNwYW4uZW5kKCk7XG5cdH0pO1xuXG5cdC8vIHJ1bldpdGhTcGFuIGNvdmVycyB0aGUgbW5lbW9uaWNhLWhvb2sgc2lkZSAodGhlIHByb3ZpZGVyJ3Mgb3duIEFMUyk7XG5cdC8vIHRoZSBPVEVMIGdsb2JhbCBjb250ZXh0IGlzIHdoYXQgRGl2ZU90ZWxQcm92aWRlciByZWFkcyB3aGVuIGl0IGxvb2tzXG5cdC8vIGZvciBhIHBhcmVudCBzcGFuIGF0IHdyYXAgYm91bmRhcmllcyDigJQgd2l0aG91dCB0aGlzIHNlY29uZCBlbnRyeVxuXHQvLyBkaXZlIHNwYW5zIG5ldmVyIGFkb3B0IHRoZSByZXF1ZXN0IHNwYW4gYW5kIHN0YXkgcm9vdCB0cmFjZXMuXG5cdC8vIFRoZSBhc3luYy1mbG93IHJvb3QgZnJhbWUgKHdoZW4gcHJvdmlkZWQpIGlzIHRoZSBvdXRlcm1vc3Qgc2NvcGU6XG5cdC8vIGV2ZXJ5IGFzeW5jIGhvcCBvZiB0aGlzIHJlcXVlc3Qg4oCUIHdyYXBwZWQgb3Igbm90IOKAlCBpbmhlcml0cyBpdCB2aWFcblx0Ly8gQUxTIHByb3BhZ2F0aW9uLlxuXHRjb25zdCBhY3RpdmVDdHggPSB0cmFjZS5zZXRTcGFuKG90ZWxDb250ZXh0LmFjdGl2ZSgpLCBzcGFuKTtcblx0Y29uc3QgcnVuID0gKCk6IHZvaWQgPT4ge1xuXHRcdGRlcHMub3RlbC5ydW5XaXRoU3BhbihzcGFuLCAoKSA9PiB7XG5cdFx0XHRvdGVsQ29udGV4dC53aXRoKGFjdGl2ZUN0eCwgZm4pO1xuXHRcdH0pO1xuXHR9O1xuXHRpZiAoZGVwcy5hc3luY0Zsb3cpIHtcblx0XHRkZXBzLmFzeW5jRmxvdy5ydW5JblNjb3BlKHJ1bik7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdHJ1bigpO1xufVxuIl19
@@ -0,0 +1,21 @@
1
+ /** Structural minimum of an HTTP request any framework can satisfy. */
2
+ export interface RequestLike {
3
+ method: string;
4
+ url: string;
5
+ params?: unknown;
6
+ query?: unknown;
7
+ body?: unknown;
8
+ headers?: unknown;
9
+ }
10
+ export interface FeedPreRootOptions {
11
+ /**
12
+ * Link the raw request object into the pre-root record (`raw.request`)
13
+ * AND stamp it as a correlation key, so getPreRoot(req) resolves from
14
+ * anywhere the request is reachable — e.g. an error boundary holding
15
+ * only the request. Retention is unchanged: the record dies with the
16
+ * request.
17
+ */
18
+ storeRequest?: boolean;
19
+ }
20
+ export declare function feedPreRootFromRequest(req: RequestLike, options?: FeedPreRootOptions): void;
21
+ //# sourceMappingURL=feed-from-request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feed-from-request.d.ts","sourceRoot":"","sources":["../../src/thunderstruck/feed-from-request.ts"],"names":[],"mappings":"AAoBA,uEAAuE;AACvE,MAAM,WAAW,WAAW;IAC3B,MAAM,EAAK,MAAM,CAAC;IAClB,GAAG,EAAQ,MAAM,CAAC;IAClB,MAAM,CAAC,EAAI,OAAO,CAAC;IACnB,KAAK,CAAC,EAAK,OAAO,CAAC;IACnB,IAAI,CAAC,EAAM,OAAO,CAAC;IACnB,OAAO,CAAC,EAAG,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IAClC;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,sBAAsB,CAAE,GAAG,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAa5F"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Thunderstruck boundary helper — the framework-free half of what a
3
+ * framework's interceptor/middleware does: shape any HTTP framework's
4
+ * request into the
5
+ * raw pre-root payload and stamp its part objects, so pipes and construct
6
+ * handlers correlate the payload by OBJECT IDENTITY (see pre-root.ts for
7
+ * the store's lifetime and correlation semantics).
8
+ *
9
+ * Framework mapping notes:
10
+ * - Express: pass `req` directly — method/url/params(→req.params)/
11
+ * query/body/headers all sit on it.
12
+ * - Fastify: pass the FastifyRequest — it exposes params/query/body/
13
+ * headers; `method`/`url` exist on it since Fastify v4 (fall back to
14
+ * `req.raw` if you target older majors).
15
+ * - raw http: `url`/`method` are on IncomingMessage; body/query/params
16
+ * are yours to parse first (or omit — primitives and missing parts
17
+ * simply don't correlate, the feed still records).
18
+ */
19
+ import { feedPreRoot } from './pre-root.js';
20
+ export function feedPreRootFromRequest(req, options) {
21
+ const raw = {
22
+ method: req.method,
23
+ url: req.url,
24
+ params: req.params,
25
+ query: req.query,
26
+ body: req.body,
27
+ headers: req.headers,
28
+ };
29
+ if (options?.storeRequest === true) {
30
+ raw.request = req;
31
+ }
32
+ feedPreRoot(raw);
33
+ }
34
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmVlZC1mcm9tLXJlcXVlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGh1bmRlcnN0cnVjay9mZWVkLWZyb20tcmVxdWVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxPQUFPLEVBQUUsV0FBVyxFQUEwQixNQUFNLGVBQWUsQ0FBQztBQXVCcEUsTUFBTSxVQUFVLHNCQUFzQixDQUFFLEdBQWdCLEVBQUUsT0FBNEI7SUFDckYsTUFBTSxHQUFHLEdBQXNCO1FBQzlCLE1BQU0sRUFBSyxHQUFHLENBQUMsTUFBTTtRQUNyQixHQUFHLEVBQVEsR0FBRyxDQUFDLEdBQUc7UUFDbEIsTUFBTSxFQUFLLEdBQUcsQ0FBQyxNQUFNO1FBQ3JCLEtBQUssRUFBTSxHQUFHLENBQUMsS0FBSztRQUNwQixJQUFJLEVBQU8sR0FBRyxDQUFDLElBQUk7UUFDbkIsT0FBTyxFQUFJLEdBQUcsQ0FBQyxPQUFPO0tBQ3RCLENBQUM7SUFDRixJQUFJLE9BQU8sRUFBRSxZQUFZLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDcEMsR0FBRyxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUM7SUFDbkIsQ0FBQztJQUNELFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNsQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaHVuZGVyc3RydWNrIGJvdW5kYXJ5IGhlbHBlciDigJQgdGhlIGZyYW1ld29yay1mcmVlIGhhbGYgb2Ygd2hhdCBhXG4gKiBmcmFtZXdvcmsncyBpbnRlcmNlcHRvci9taWRkbGV3YXJlIGRvZXM6IHNoYXBlIGFueSBIVFRQIGZyYW1ld29yaydzXG4gKiByZXF1ZXN0IGludG8gdGhlXG4gKiByYXcgcHJlLXJvb3QgcGF5bG9hZCBhbmQgc3RhbXAgaXRzIHBhcnQgb2JqZWN0cywgc28gcGlwZXMgYW5kIGNvbnN0cnVjdFxuICogaGFuZGxlcnMgY29ycmVsYXRlIHRoZSBwYXlsb2FkIGJ5IE9CSkVDVCBJREVOVElUWSAoc2VlIHByZS1yb290LnRzIGZvclxuICogdGhlIHN0b3JlJ3MgbGlmZXRpbWUgYW5kIGNvcnJlbGF0aW9uIHNlbWFudGljcykuXG4gKlxuICogRnJhbWV3b3JrIG1hcHBpbmcgbm90ZXM6XG4gKiAgLSBFeHByZXNzOiBwYXNzIGByZXFgIGRpcmVjdGx5IOKAlCBtZXRob2QvdXJsL3BhcmFtcyjihpJyZXEucGFyYW1zKS9cbiAqICAgIHF1ZXJ5L2JvZHkvaGVhZGVycyBhbGwgc2l0IG9uIGl0LlxuICogIC0gRmFzdGlmeTogcGFzcyB0aGUgRmFzdGlmeVJlcXVlc3Qg4oCUIGl0IGV4cG9zZXMgcGFyYW1zL3F1ZXJ5L2JvZHkvXG4gKiAgICBoZWFkZXJzOyBgbWV0aG9kYC9gdXJsYCBleGlzdCBvbiBpdCBzaW5jZSBGYXN0aWZ5IHY0IChmYWxsIGJhY2sgdG9cbiAqICAgIGByZXEucmF3YCBpZiB5b3UgdGFyZ2V0IG9sZGVyIG1ham9ycykuXG4gKiAgLSByYXcgaHR0cDogYHVybGAvYG1ldGhvZGAgYXJlIG9uIEluY29taW5nTWVzc2FnZTsgYm9keS9xdWVyeS9wYXJhbXNcbiAqICAgIGFyZSB5b3VycyB0byBwYXJzZSBmaXJzdCAob3Igb21pdCDigJQgcHJpbWl0aXZlcyBhbmQgbWlzc2luZyBwYXJ0c1xuICogICAgc2ltcGx5IGRvbid0IGNvcnJlbGF0ZSwgdGhlIGZlZWQgc3RpbGwgcmVjb3JkcykuXG4gKi9cbmltcG9ydCB7IGZlZWRQcmVSb290LCB0eXBlIFJhd1ByZVJvb3RQYXlsb2FkIH0gZnJvbSAnLi9wcmUtcm9vdC5qcyc7XG5cbi8qKiBTdHJ1Y3R1cmFsIG1pbmltdW0gb2YgYW4gSFRUUCByZXF1ZXN0IGFueSBmcmFtZXdvcmsgY2FuIHNhdGlzZnkuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlcXVlc3RMaWtlIHtcblx0bWV0aG9kICAgOiBzdHJpbmc7XG5cdHVybCAgICAgIDogc3RyaW5nO1xuXHRwYXJhbXM/ICA6IHVua25vd247XG5cdHF1ZXJ5PyAgIDogdW5rbm93bjtcblx0Ym9keT8gICAgOiB1bmtub3duO1xuXHRoZWFkZXJzPyA6IHVua25vd247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmVlZFByZVJvb3RPcHRpb25zIHtcblx0LyoqXG5cdCAqIExpbmsgdGhlIHJhdyByZXF1ZXN0IG9iamVjdCBpbnRvIHRoZSBwcmUtcm9vdCByZWNvcmQgKGByYXcucmVxdWVzdGApXG5cdCAqIEFORCBzdGFtcCBpdCBhcyBhIGNvcnJlbGF0aW9uIGtleSwgc28gZ2V0UHJlUm9vdChyZXEpIHJlc29sdmVzIGZyb21cblx0ICogYW55d2hlcmUgdGhlIHJlcXVlc3QgaXMgcmVhY2hhYmxlIOKAlCBlLmcuIGFuIGVycm9yIGJvdW5kYXJ5IGhvbGRpbmdcblx0ICogb25seSB0aGUgcmVxdWVzdC4gUmV0ZW50aW9uIGlzIHVuY2hhbmdlZDogdGhlIHJlY29yZCBkaWVzIHdpdGggdGhlXG5cdCAqIHJlcXVlc3QuXG5cdCAqL1xuXHRzdG9yZVJlcXVlc3Q/OiBib29sZWFuO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmVlZFByZVJvb3RGcm9tUmVxdWVzdCAocmVxOiBSZXF1ZXN0TGlrZSwgb3B0aW9ucz86IEZlZWRQcmVSb290T3B0aW9ucyk6IHZvaWQge1xuXHRjb25zdCByYXc6IFJhd1ByZVJvb3RQYXlsb2FkID0ge1xuXHRcdG1ldGhvZCAgIDogcmVxLm1ldGhvZCxcblx0XHR1cmwgICAgICA6IHJlcS51cmwsXG5cdFx0cGFyYW1zICAgOiByZXEucGFyYW1zLFxuXHRcdHF1ZXJ5ICAgIDogcmVxLnF1ZXJ5LFxuXHRcdGJvZHkgICAgIDogcmVxLmJvZHksXG5cdFx0aGVhZGVycyAgOiByZXEuaGVhZGVycyxcblx0fTtcblx0aWYgKG9wdGlvbnM/LnN0b3JlUmVxdWVzdCA9PT0gdHJ1ZSkge1xuXHRcdHJhdy5yZXF1ZXN0ID0gcmVxO1xuXHR9XG5cdGZlZWRQcmVSb290KHJhdyk7XG59XG4iXX0=