footprintjs 4.12.2 → 4.13.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 (68) hide show
  1. package/CLAUDE.md +111 -0
  2. package/README.md +29 -1
  3. package/dist/esm/index.js +16 -3
  4. package/dist/esm/lib/engine/graph/StageNode.js +2 -3
  5. package/dist/esm/lib/engine/handlers/SubflowExecutor.js +29 -1
  6. package/dist/esm/lib/engine/handlers/types.js +1 -1
  7. package/dist/esm/lib/engine/index.js +1 -1
  8. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +176 -41
  9. package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.js +8 -3
  10. package/dist/esm/lib/engine/narrative/index.js +1 -1
  11. package/dist/esm/lib/engine/narrative/narrativeTypes.js +1 -1
  12. package/dist/esm/lib/engine/narrative/types.js +1 -1
  13. package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +60 -36
  14. package/dist/esm/lib/engine/types.js +1 -1
  15. package/dist/esm/lib/reactive/createTypedScope.js +6 -3
  16. package/dist/esm/lib/reactive/types.js +2 -1
  17. package/dist/esm/lib/recorder/CombinedRecorder.js +211 -0
  18. package/dist/esm/lib/recorder/EmitRecorder.js +62 -0
  19. package/dist/esm/lib/recorder/index.js +2 -1
  20. package/dist/esm/lib/runner/FlowChartExecutor.js +123 -1
  21. package/dist/esm/lib/scope/ScopeFacade.js +117 -1
  22. package/dist/esm/lib/scope/detectCircular.js +74 -5
  23. package/dist/esm/lib/scope/types.js +1 -1
  24. package/dist/esm/recorders.js +1 -1
  25. package/dist/index.js +50 -32
  26. package/dist/lib/engine/graph/StageNode.js +2 -3
  27. package/dist/lib/engine/handlers/SubflowExecutor.js +29 -1
  28. package/dist/lib/engine/handlers/types.js +1 -1
  29. package/dist/lib/engine/index.js +1 -1
  30. package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +176 -41
  31. package/dist/lib/engine/narrative/FlowRecorderDispatcher.js +8 -3
  32. package/dist/lib/engine/narrative/index.js +1 -1
  33. package/dist/lib/engine/narrative/narrativeTypes.js +1 -1
  34. package/dist/lib/engine/narrative/types.js +1 -1
  35. package/dist/lib/engine/traversal/FlowchartTraverser.js +60 -36
  36. package/dist/lib/engine/types.js +1 -1
  37. package/dist/lib/reactive/createTypedScope.js +6 -3
  38. package/dist/lib/reactive/types.js +2 -1
  39. package/dist/lib/recorder/CombinedRecorder.js +218 -0
  40. package/dist/lib/recorder/EmitRecorder.js +63 -0
  41. package/dist/lib/recorder/index.js +7 -2
  42. package/dist/lib/runner/FlowChartExecutor.js +123 -1
  43. package/dist/lib/scope/ScopeFacade.js +117 -1
  44. package/dist/lib/scope/detectCircular.js +74 -5
  45. package/dist/lib/scope/types.js +1 -1
  46. package/dist/recorders.js +1 -1
  47. package/dist/types/index.d.ts +36 -2
  48. package/dist/types/lib/engine/graph/StageNode.d.ts +3 -7
  49. package/dist/types/lib/engine/handlers/SubflowExecutor.d.ts +2 -3
  50. package/dist/types/lib/engine/handlers/types.d.ts +19 -3
  51. package/dist/types/lib/engine/index.d.ts +1 -1
  52. package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +38 -17
  53. package/dist/types/lib/engine/narrative/FlowRecorderDispatcher.d.ts +1 -1
  54. package/dist/types/lib/engine/narrative/index.d.ts +1 -1
  55. package/dist/types/lib/engine/narrative/narrativeTypes.d.ts +70 -6
  56. package/dist/types/lib/engine/narrative/types.d.ts +24 -2
  57. package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +18 -0
  58. package/dist/types/lib/engine/types.d.ts +66 -0
  59. package/dist/types/lib/reactive/types.d.ts +61 -3
  60. package/dist/types/lib/recorder/CombinedRecorder.d.ts +173 -0
  61. package/dist/types/lib/recorder/EmitRecorder.d.ts +135 -0
  62. package/dist/types/lib/recorder/index.d.ts +3 -0
  63. package/dist/types/lib/runner/FlowChartExecutor.d.ts +85 -0
  64. package/dist/types/lib/scope/ScopeFacade.d.ts +40 -0
  65. package/dist/types/lib/scope/detectCircular.d.ts +30 -3
  66. package/dist/types/lib/scope/types.d.ts +21 -0
  67. package/dist/types/recorders.d.ts +3 -2
  68. package/package.json +1 -2
@@ -0,0 +1,211 @@
1
+ /**
2
+ * CombinedRecorder — a single observer that can hook into MULTIPLE event
3
+ * streams (currently: scope data-flow + control-flow). One object, one `id`,
4
+ * one consistent view of the execution.
5
+ *
6
+ * ## Why this exists
7
+ *
8
+ * Before `CombinedRecorder`, a consumer who wanted to observe both streams
9
+ * had to:
10
+ * 1. Implement both `Recorder` (8 methods) and `FlowRecorder` (12 methods)
11
+ * fully — stubbing every event they didn't care about.
12
+ * 2. Remember to call BOTH `attachRecorder(r)` AND `attachFlowRecorder(r)`.
13
+ * Forgetting the second call silently dropped half their events — no
14
+ * warning, no runtime error.
15
+ * 3. Re-implement coordination logic (buffering, ordering) themselves.
16
+ *
17
+ * `CombinedRecorder` collapses that into a single type and a single attach
18
+ * call (`executor.attachCombinedRecorder(r)`), with the library handling the
19
+ * routing internally. Consumers implement only the events they care about
20
+ * (`Partial<...>`) and the attach method duck-types at runtime to dispatch
21
+ * to the relevant channels.
22
+ *
23
+ * ## Forward compatibility
24
+ *
25
+ * When a third observer type is added (e.g. an `OperationRecorder`), the
26
+ * `CombinedRecorder` type gains an `& Partial<OperationRecorder>` clause and
27
+ * `attachCombinedRecorder` gains one more runtime branch in its dispatch.
28
+ * Consumers writing a `CombinedRecorder` today are NOT affected — their
29
+ * code keeps compiling and attaching correctly, because every new layer is
30
+ * optional.
31
+ *
32
+ * ## Example
33
+ *
34
+ * ```typescript
35
+ * import type { CombinedRecorder } from 'footprintjs';
36
+ *
37
+ * const audit: CombinedRecorder = {
38
+ * id: 'audit',
39
+ * onWrite: (e) => logWrite(e.key, e.value), // Recorder method
40
+ * onDecision: (e) => logDecision(e.chosen), // FlowRecorder method
41
+ * };
42
+ *
43
+ * executor.attachCombinedRecorder(audit);
44
+ * // ^ internally: detects both sets of methods, routes to both channels.
45
+ * ```
46
+ *
47
+ * ## Contract with existing APIs
48
+ *
49
+ * - `attachRecorder(r)` and `attachFlowRecorder(r)` remain unchanged.
50
+ * Consumers who want only ONE channel keep using them — explicit is good.
51
+ * - `attachCombinedRecorder(r)` is the ONLY way to guarantee an object is
52
+ * hooked into every stream it has methods for, without maintaining two
53
+ * attach calls at the call site.
54
+ * - Idempotency by `id` is preserved across channels: re-attaching with the
55
+ * same `id` replaces the previous instance on BOTH channels, not just one.
56
+ */
57
+ /**
58
+ * Discriminator for the union payload types on `CombinedRecorder`'s shared
59
+ * methods (`onError`, `onPause`, `onResume`). Returns `true` if the event
60
+ * was emitted from the control-flow channel (FlowRecorder).
61
+ *
62
+ * ## How it discriminates
63
+ *
64
+ * Scope-channel events extend `RecorderContext`, which carries `pipelineId`.
65
+ * Flow-channel events do not carry `pipelineId` (they carry an optional
66
+ * `traversalContext` instead, but that field is optional and cannot be
67
+ * relied on as a positive signal). We detect the flow variant by the
68
+ * ABSENCE of `pipelineId` — this is schema-stable as long as scope events
69
+ * continue to extend `RecorderContext`.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * onError: (e) => {
74
+ * if (isFlowEvent(e)) {
75
+ * // Narrowed to FlowErrorEvent: has stageName, message, structuredError
76
+ * } else {
77
+ * // Narrowed to ErrorEvent: has error, operation, key?
78
+ * }
79
+ * }
80
+ * ```
81
+ */
82
+ export function isFlowEvent(event) {
83
+ if (typeof event !== 'object' || event === null)
84
+ return false;
85
+ return event.pipelineId === undefined;
86
+ }
87
+ /**
88
+ * Method names belonging to the `Recorder` (data-flow) interface.
89
+ * Kept as a single source of truth so the runtime duck-type detector stays
90
+ * in sync with the interface. If a method is added to `Recorder`, adding it
91
+ * here is the ONLY change required to route combined-recorders correctly.
92
+ */
93
+ const RECORDER_EVENT_METHODS = [
94
+ 'onRead',
95
+ 'onWrite',
96
+ 'onCommit',
97
+ 'onError',
98
+ 'onStageStart',
99
+ 'onStageEnd',
100
+ 'onPause',
101
+ 'onResume',
102
+ ];
103
+ /**
104
+ * Method names belonging to the `FlowRecorder` (control-flow) interface.
105
+ * See the note on `RECORDER_EVENT_METHODS`.
106
+ *
107
+ * NOTE: the `onError`, `onPause`, `onResume` methods exist on BOTH interfaces
108
+ * with DIFFERENT event payload shapes. A `CombinedRecorder` that implements
109
+ * any of these receives both variants (one from each channel). Consumers who
110
+ * care about the distinction can discriminate on the presence of
111
+ * `traversalContext` (which only control-flow events carry).
112
+ */
113
+ const FLOW_RECORDER_EVENT_METHODS = [
114
+ 'onStageExecuted',
115
+ 'onNext',
116
+ 'onDecision',
117
+ 'onFork',
118
+ 'onSelected',
119
+ 'onSubflowEntry',
120
+ 'onSubflowExit',
121
+ 'onSubflowRegistered',
122
+ 'onLoop',
123
+ 'onBreak',
124
+ 'onError',
125
+ 'onPause',
126
+ 'onResume',
127
+ ];
128
+ /**
129
+ * Method names belonging to the `EmitRecorder` (user-emitted events)
130
+ * interface. Same convention as the other two arrays above — kept as
131
+ * the single source of truth for duck-type detection.
132
+ */
133
+ const EMIT_RECORDER_EVENT_METHODS = ['onEmit'];
134
+ /**
135
+ * True iff the recorder declares a method named `m` either as an own
136
+ * property OR on its class-prototype chain — but NOT inherited from
137
+ * `Object.prototype`.
138
+ *
139
+ * ## Why this layered check
140
+ *
141
+ * A `CombinedRecorder` can be either a plain object literal (handlers as
142
+ * own properties) OR a class instance (handlers as class-prototype
143
+ * methods). Both are legitimate consumer patterns and both MUST attach.
144
+ *
145
+ * But handlers inherited from `Object.prototype` are ALWAYS accidental or
146
+ * malicious (nobody legitimately attaches recorder methods there). So we
147
+ * walk the prototype chain, STOPPING before `Object.prototype`. This
148
+ * accepts class methods while still blocking `Object.prototype`
149
+ * pollution attacks.
150
+ */
151
+ function hasOwnOrClassMethod(r, m) {
152
+ if (r === null || typeof r !== 'object')
153
+ return false;
154
+ if (Object.prototype.hasOwnProperty.call(r, m)) {
155
+ return typeof r[m] === 'function';
156
+ }
157
+ let proto = Object.getPrototypeOf(r);
158
+ while (proto !== null && proto !== Object.prototype) {
159
+ if (Object.prototype.hasOwnProperty.call(proto, m)) {
160
+ return typeof proto[m] === 'function';
161
+ }
162
+ proto = Object.getPrototypeOf(proto);
163
+ }
164
+ return false;
165
+ }
166
+ /**
167
+ * True iff the recorder implements at least one data-flow event method.
168
+ * Used by `executor.attachCombinedRecorder` to decide whether to hook into
169
+ * the scope data-flow channel.
170
+ *
171
+ * ## Detection rule
172
+ *
173
+ * Accepts both object-literal recorders (own-property handlers) AND class
174
+ * instances (handlers declared on the class prototype). Rejects handlers
175
+ * inherited from `Object.prototype` — that's always accidental or
176
+ * malicious pollution, never a legitimate recorder.
177
+ *
178
+ * ## Lifecycle exclusions
179
+ *
180
+ * `clear` and `toSnapshot` are NOT counted as event methods — a recorder
181
+ * that only implements those has nothing to observe and would be a no-op
182
+ * on either channel.
183
+ *
184
+ * ## Return type
185
+ *
186
+ * Returns plain `boolean` (not a type predicate). The full `Recorder`
187
+ * interface has payload types that diverge from `CombinedRecorder`'s union
188
+ * variants for shared methods, so a narrowing predicate would be unsound.
189
+ * Callers that need to treat the recorder as a `Recorder` do so explicitly
190
+ * at the attach site — the cast is the contract that each channel passes
191
+ * its own payload variant.
192
+ */
193
+ export function hasRecorderMethods(r) {
194
+ return RECORDER_EVENT_METHODS.some((m) => hasOwnOrClassMethod(r, m));
195
+ }
196
+ /**
197
+ * True iff the recorder implements at least one control-flow event method.
198
+ * See `hasRecorderMethods`.
199
+ */
200
+ export function hasFlowRecorderMethods(r) {
201
+ return FLOW_RECORDER_EVENT_METHODS.some((m) => hasOwnOrClassMethod(r, m));
202
+ }
203
+ /**
204
+ * True iff the recorder implements at least one emit-channel event method.
205
+ * See `hasRecorderMethods` for the ownership-detection rules (own or
206
+ * class-prototype methods count; `Object.prototype` pollution does not).
207
+ */
208
+ export function hasEmitRecorderMethods(r) {
209
+ return EMIT_RECORDER_EVENT_METHODS.some((m) => hasOwnOrClassMethod(r, m));
210
+ }
211
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29tYmluZWRSZWNvcmRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvcmVjb3JkZXIvQ29tYmluZWRSZWNvcmRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXVERztBQW1GSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0JHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FBSSxLQUFRO0lBQ3JDLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssS0FBSyxJQUFJO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDOUQsT0FBUSxLQUFpQyxDQUFDLFVBQVUsS0FBSyxTQUFTLENBQUM7QUFDckUsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxzQkFBc0IsR0FBRztJQUM3QixRQUFRO0lBQ1IsU0FBUztJQUNULFVBQVU7SUFDVixTQUFTO0lBQ1QsY0FBYztJQUNkLFlBQVk7SUFDWixTQUFTO0lBQ1QsVUFBVTtDQUNGLENBQUM7QUFFWDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLDJCQUEyQixHQUFHO0lBQ2xDLGlCQUFpQjtJQUNqQixRQUFRO0lBQ1IsWUFBWTtJQUNaLFFBQVE7SUFDUixZQUFZO0lBQ1osZ0JBQWdCO0lBQ2hCLGVBQWU7SUFDZixxQkFBcUI7SUFDckIsUUFBUTtJQUNSLFNBQVM7SUFDVCxTQUFTO0lBQ1QsU0FBUztJQUNULFVBQVU7Q0FDRixDQUFDO0FBRVg7Ozs7R0FJRztBQUNILE1BQU0sMkJBQTJCLEdBQUcsQ0FBQyxRQUFRLENBQVUsQ0FBQztBQUV4RDs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILFNBQVMsbUJBQW1CLENBQUMsQ0FBVSxFQUFFLENBQVM7SUFDaEQsSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVE7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUN0RCxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUMvQyxPQUFPLE9BQVEsQ0FBNkIsQ0FBQyxDQUFDLENBQUMsS0FBSyxVQUFVLENBQUM7SUFDakUsQ0FBQztJQUNELElBQUksS0FBSyxHQUFZLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUMsT0FBTyxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssS0FBSyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDcEQsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDbkQsT0FBTyxPQUFRLEtBQWlDLENBQUMsQ0FBQyxDQUFDLEtBQUssVUFBVSxDQUFDO1FBQ3JFLENBQUM7UUFDRCxLQUFLLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEJHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUFDLENBQW1CO0lBQ3BELE9BQU8sc0JBQXNCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2RSxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLHNCQUFzQixDQUFDLENBQW1CO0lBQ3hELE9BQU8sMkJBQTJCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1RSxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxzQkFBc0IsQ0FBQyxDQUFtQjtJQUN4RCxPQUFPLDJCQUEyQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDNUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29tYmluZWRSZWNvcmRlciDigJQgYSBzaW5nbGUgb2JzZXJ2ZXIgdGhhdCBjYW4gaG9vayBpbnRvIE1VTFRJUExFIGV2ZW50XG4gKiBzdHJlYW1zIChjdXJyZW50bHk6IHNjb3BlIGRhdGEtZmxvdyArIGNvbnRyb2wtZmxvdykuIE9uZSBvYmplY3QsIG9uZSBgaWRgLFxuICogb25lIGNvbnNpc3RlbnQgdmlldyBvZiB0aGUgZXhlY3V0aW9uLlxuICpcbiAqICMjIFdoeSB0aGlzIGV4aXN0c1xuICpcbiAqIEJlZm9yZSBgQ29tYmluZWRSZWNvcmRlcmAsIGEgY29uc3VtZXIgd2hvIHdhbnRlZCB0byBvYnNlcnZlIGJvdGggc3RyZWFtc1xuICogaGFkIHRvOlxuICogICAxLiBJbXBsZW1lbnQgYm90aCBgUmVjb3JkZXJgICg4IG1ldGhvZHMpIGFuZCBgRmxvd1JlY29yZGVyYCAoMTIgbWV0aG9kcylcbiAqICAgICAgZnVsbHkg4oCUIHN0dWJiaW5nIGV2ZXJ5IGV2ZW50IHRoZXkgZGlkbid0IGNhcmUgYWJvdXQuXG4gKiAgIDIuIFJlbWVtYmVyIHRvIGNhbGwgQk9USCBgYXR0YWNoUmVjb3JkZXIocilgIEFORCBgYXR0YWNoRmxvd1JlY29yZGVyKHIpYC5cbiAqICAgICAgRm9yZ2V0dGluZyB0aGUgc2Vjb25kIGNhbGwgc2lsZW50bHkgZHJvcHBlZCBoYWxmIHRoZWlyIGV2ZW50cyDigJQgbm9cbiAqICAgICAgd2FybmluZywgbm8gcnVudGltZSBlcnJvci5cbiAqICAgMy4gUmUtaW1wbGVtZW50IGNvb3JkaW5hdGlvbiBsb2dpYyAoYnVmZmVyaW5nLCBvcmRlcmluZykgdGhlbXNlbHZlcy5cbiAqXG4gKiBgQ29tYmluZWRSZWNvcmRlcmAgY29sbGFwc2VzIHRoYXQgaW50byBhIHNpbmdsZSB0eXBlIGFuZCBhIHNpbmdsZSBhdHRhY2hcbiAqIGNhbGwgKGBleGVjdXRvci5hdHRhY2hDb21iaW5lZFJlY29yZGVyKHIpYCksIHdpdGggdGhlIGxpYnJhcnkgaGFuZGxpbmcgdGhlXG4gKiByb3V0aW5nIGludGVybmFsbHkuIENvbnN1bWVycyBpbXBsZW1lbnQgb25seSB0aGUgZXZlbnRzIHRoZXkgY2FyZSBhYm91dFxuICogKGBQYXJ0aWFsPC4uLj5gKSBhbmQgdGhlIGF0dGFjaCBtZXRob2QgZHVjay10eXBlcyBhdCBydW50aW1lIHRvIGRpc3BhdGNoXG4gKiB0byB0aGUgcmVsZXZhbnQgY2hhbm5lbHMuXG4gKlxuICogIyMgRm9yd2FyZCBjb21wYXRpYmlsaXR5XG4gKlxuICogV2hlbiBhIHRoaXJkIG9ic2VydmVyIHR5cGUgaXMgYWRkZWQgKGUuZy4gYW4gYE9wZXJhdGlvblJlY29yZGVyYCksIHRoZVxuICogYENvbWJpbmVkUmVjb3JkZXJgIHR5cGUgZ2FpbnMgYW4gYCYgUGFydGlhbDxPcGVyYXRpb25SZWNvcmRlcj5gIGNsYXVzZSBhbmRcbiAqIGBhdHRhY2hDb21iaW5lZFJlY29yZGVyYCBnYWlucyBvbmUgbW9yZSBydW50aW1lIGJyYW5jaCBpbiBpdHMgZGlzcGF0Y2guXG4gKiBDb25zdW1lcnMgd3JpdGluZyBhIGBDb21iaW5lZFJlY29yZGVyYCB0b2RheSBhcmUgTk9UIGFmZmVjdGVkIOKAlCB0aGVpclxuICogY29kZSBrZWVwcyBjb21waWxpbmcgYW5kIGF0dGFjaGluZyBjb3JyZWN0bHksIGJlY2F1c2UgZXZlcnkgbmV3IGxheWVyIGlzXG4gKiBvcHRpb25hbC5cbiAqXG4gKiAjIyBFeGFtcGxlXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHR5cGUgeyBDb21iaW5lZFJlY29yZGVyIH0gZnJvbSAnZm9vdHByaW50anMnO1xuICpcbiAqIGNvbnN0IGF1ZGl0OiBDb21iaW5lZFJlY29yZGVyID0ge1xuICogICBpZDogJ2F1ZGl0JyxcbiAqICAgb25Xcml0ZTogKGUpID0+IGxvZ1dyaXRlKGUua2V5LCBlLnZhbHVlKSwgICAgICAgIC8vIFJlY29yZGVyIG1ldGhvZFxuICogICBvbkRlY2lzaW9uOiAoZSkgPT4gbG9nRGVjaXNpb24oZS5jaG9zZW4pLCAgICAgICAgLy8gRmxvd1JlY29yZGVyIG1ldGhvZFxuICogfTtcbiAqXG4gKiBleGVjdXRvci5hdHRhY2hDb21iaW5lZFJlY29yZGVyKGF1ZGl0KTtcbiAqIC8vIF4gaW50ZXJuYWxseTogZGV0ZWN0cyBib3RoIHNldHMgb2YgbWV0aG9kcywgcm91dGVzIHRvIGJvdGggY2hhbm5lbHMuXG4gKiBgYGBcbiAqXG4gKiAjIyBDb250cmFjdCB3aXRoIGV4aXN0aW5nIEFQSXNcbiAqXG4gKiAtIGBhdHRhY2hSZWNvcmRlcihyKWAgYW5kIGBhdHRhY2hGbG93UmVjb3JkZXIocilgIHJlbWFpbiB1bmNoYW5nZWQuXG4gKiAgIENvbnN1bWVycyB3aG8gd2FudCBvbmx5IE9ORSBjaGFubmVsIGtlZXAgdXNpbmcgdGhlbSDigJQgZXhwbGljaXQgaXMgZ29vZC5cbiAqIC0gYGF0dGFjaENvbWJpbmVkUmVjb3JkZXIocilgIGlzIHRoZSBPTkxZIHdheSB0byBndWFyYW50ZWUgYW4gb2JqZWN0IGlzXG4gKiAgIGhvb2tlZCBpbnRvIGV2ZXJ5IHN0cmVhbSBpdCBoYXMgbWV0aG9kcyBmb3IsIHdpdGhvdXQgbWFpbnRhaW5pbmcgdHdvXG4gKiAgIGF0dGFjaCBjYWxscyBhdCB0aGUgY2FsbCBzaXRlLlxuICogLSBJZGVtcG90ZW5jeSBieSBgaWRgIGlzIHByZXNlcnZlZCBhY3Jvc3MgY2hhbm5lbHM6IHJlLWF0dGFjaGluZyB3aXRoIHRoZVxuICogICBzYW1lIGBpZGAgcmVwbGFjZXMgdGhlIHByZXZpb3VzIGluc3RhbmNlIG9uIEJPVEggY2hhbm5lbHMsIG5vdCBqdXN0IG9uZS5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEZsb3dFcnJvckV2ZW50LCBGbG93UGF1c2VFdmVudCwgRmxvd1JlY29yZGVyLCBGbG93UmVzdW1lRXZlbnQgfSBmcm9tICcuLi9lbmdpbmUvbmFycmF0aXZlL3R5cGVzLmpzJztcbmltcG9ydCB0eXBlIHsgRXJyb3JFdmVudCwgUGF1c2VFdmVudCwgUmVjb3JkZXIsIFJlc3VtZUV2ZW50IH0gZnJvbSAnLi4vc2NvcGUvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBFbWl0UmVjb3JkZXIgfSBmcm9tICcuL0VtaXRSZWNvcmRlci5qcyc7XG5cbi8qKlxuICogTWV0aG9kIG5hbWVzIHRoYXQgYXBwZWFyIG9uIEJPVEggYFJlY29yZGVyYCBhbmQgYEZsb3dSZWNvcmRlcmAgYnV0IHdpdGhcbiAqIGRpZmZlcmVudCBldmVudCBwYXlsb2FkIHR5cGVzLiBGb3IgdGhlc2UsIGEgYENvbWJpbmVkUmVjb3JkZXJgIGRlY2xhcmVzXG4gKiBPTkUgaGFuZGxlciB0aGF0IHJlY2VpdmVzIHRoZSB1bmlvbiBvZiBib3RoIHBheWxvYWRzIOKAlCBjb25zdW1lcnNcbiAqIGRpc2NyaW1pbmF0ZSBvbiBgdHJhdmVyc2FsQ29udGV4dGAsIHdoaWNoIG9ubHkgY29udHJvbC1mbG93IGV2ZW50cyBjYXJyeS5cbiAqL1xudHlwZSBTaGFyZWRMaWZlY3ljbGVPdmVybGFwID0gJ29uRXJyb3InIHwgJ29uUGF1c2UnIHwgJ29uUmVzdW1lJztcblxuLyoqIExpZmVjeWNsZSBob29rcyAobm90IGV2ZW50LXNwZWNpZmljKSB0aGF0IGJvdGggaW50ZXJmYWNlcyBzaGFyZSBpZGVudGljYWxseS4gKi9cbnR5cGUgU2hhcmVkTGlmZWN5Y2xlID0gJ2lkJyB8ICdjbGVhcicgfCAndG9TbmFwc2hvdCc7XG5cbi8qKlxuICogQSByZWNvcmRlciB0aGF0IE1BWSBvYnNlcnZlIGFueSBjb21iaW5hdGlvbiBvZiBzdXBwb3J0ZWQgZXZlbnQgc3RyZWFtcy5cbiAqXG4gKiBUb2RheSdzIHN0cmVhbXM6XG4gKiAgIC0gU2NvcGUgZGF0YS1mbG93IChgUmVjb3JkZXJgOiBvblJlYWQvb25Xcml0ZS9vbkNvbW1pdC9vblN0YWdlU3RhcnQv4oCmKVxuICogICAtIENvbnRyb2wtZmxvdyAoYEZsb3dSZWNvcmRlcmA6IG9uRGVjaXNpb24vb25TdWJmbG93RW50cnkvb25Mb29wL+KApilcbiAqXG4gKiBBbGwgZXZlbnQgaGFuZGxlcnMgYXJlIG9wdGlvbmFsIOKAlCBpbXBsZW1lbnQgb25seSB3aGF0IHlvdSBjYXJlIGFib3V0LlxuICogYGlkYCBpcyByZXF1aXJlZCBzbyB0aGUgbGlicmFyeSBjYW4gZGVkdXBsaWNhdGUgcmUtYXR0YWNoZXMuXG4gKlxuICogIyMgU2hhcmVkIG1ldGhvZCBuYW1lcyAob25FcnJvciAvIG9uUGF1c2UgLyBvblJlc3VtZSlcbiAqXG4gKiBCb3RoIGBSZWNvcmRlcmAgYW5kIGBGbG93UmVjb3JkZXJgIGRlY2xhcmUgdGhlc2Ugd2l0aCBESUZGRVJFTlQgcGF5bG9hZFxuICogc2hhcGVzLiBJbiBhIGNvbWJpbmVkIHJlY29yZGVyLCBlYWNoIHN1Y2ggaGFuZGxlciBpcyBjYWxsZWQgYnkgQk9USFxuICogY2hhbm5lbHMgd2l0aCBpdHMgb3duIHZhcmlhbnQuIFRoZSBwYXJhbWV0ZXIgdHlwZSBpcyBhIHVuaW9uIOKAlCBjb25zdW1lcnNcbiAqIGNhbiBlaXRoZXIgaGFuZGxlIGJvdGggdmFyaWFudHMgdW5pZm9ybWx5LCBvciBkaXNjcmltaW5hdGUgKGNvbnRyb2wtZmxvd1xuICogdmFyaWFudHMgY2FycnkgYSBgdHJhdmVyc2FsQ29udGV4dGAgZmllbGQgdGhhdCBkYXRhLWZsb3cgdmFyaWFudHMgbGFjaykuXG4gKlxuICogIyMgRm9yd2FyZCBjb21wYXRpYmlsaXR5XG4gKlxuICogV2hlbiBhIHRoaXJkIG9ic2VydmVyIHR5cGUgc2hpcHMgKGUuZy4gYE9wZXJhdGlvblJlY29yZGVyYCksIHRoZSB0eXBlXG4gKiBnYWlucyBhbm90aGVyIGAmIFBhcnRpYWw84oCmPmAgY2xhdXNlLiBCZWNhdXNlIGV2ZXJ5IGNsYXVzZSBpcyBgUGFydGlhbGAsXG4gKiBleGlzdGluZyBgQ29tYmluZWRSZWNvcmRlcmAgaW1wbGVtZW50YXRpb25zIHJlbWFpbiB0eXBlLXZhbGlkLlxuICovXG5leHBvcnQgdHlwZSBDb21iaW5lZFJlY29yZGVyID0gUGFydGlhbDxPbWl0PFJlY29yZGVyLCBTaGFyZWRMaWZlY3ljbGVPdmVybGFwIHwgU2hhcmVkTGlmZWN5Y2xlPj4gJlxuICBQYXJ0aWFsPE9taXQ8Rmxvd1JlY29yZGVyLCBTaGFyZWRMaWZlY3ljbGVPdmVybGFwIHwgU2hhcmVkTGlmZWN5Y2xlPj4gJlxuICAvLyBFbWl0IGNoYW5uZWwg4oCUIG5ldyB0aGlyZCBzdHJlYW0gKFBoYXNlIDMpLiBObyBtZXRob2QtbmFtZSBvdmVybGFwIHdpdGhcbiAgLy8gdGhlIG90aGVyIHR3byBpbnRlcmZhY2VzLCBzbyBhIHBsYWluIGludGVyc2VjdGlvbiBpcyBzb3VuZCDigJQgbm9cbiAgLy8gdW5pb24tcGF5bG9hZCBkaXNjcmltaW5hdG9yIG5lZWRlZC5cbiAgUGFydGlhbDxPbWl0PEVtaXRSZWNvcmRlciwgU2hhcmVkTGlmZWN5Y2xlPj4gJiB7XG4gICAgcmVhZG9ubHkgaWQ6IHN0cmluZztcblxuICAgIC8vIFNoYXJlZCBsaWZlY3ljbGUgaG9va3Mg4oCUIHNhbWUgb24gYm90aCBpbnRlcmZhY2VzLCBzaGFwZSBjb21wYXRpYmxlLlxuICAgIGNsZWFyPygpOiB2b2lkO1xuICAgIHRvU25hcHNob3Q/KCk6IHtcbiAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICAgICAgcHJlZmVycmVkT3BlcmF0aW9uPzogJ3RyYW5zbGF0ZScgfCAnYWNjdW11bGF0ZScgfCAnYWdncmVnYXRlJztcbiAgICAgIGRhdGE6IHVua25vd247XG4gICAgfTtcblxuICAgIC8vIFNoYXJlZCBldmVudCBtZXRob2QgbmFtZXMgd2l0aCBESVZFUkdFTlQgcGF5bG9hZHMg4oCUIGRlY2xhcmVkIGFzIHVuaW9ucy5cbiAgICAvLyBDb25zdW1lcnMgZWl0aGVyIGhhbmRsZSBib3RoIHZhcmlhbnRzLCBvciBkaXNjcmltaW5hdGUgdXNpbmcgdGhlXG4gICAgLy8gZXhwb3J0ZWQgaGVscGVyIGBpc0Zsb3dFdmVudCgpYCAod2hpY2ggY2hlY2tzIGZvciB0aGVcbiAgICAvLyBgdHJhdmVyc2FsQ29udGV4dGAgZmllbGQg4oCUIHByZXNlbnQgb25seSBvbiBjb250cm9sLWZsb3cgdmFyaWFudHMpLlxuICAgIC8vXG4gICAgLy8gQGV4YW1wbGVcbiAgICAvLyBgYGB0c1xuICAgIC8vIGNvbnN0IGF1ZGl0OiBDb21iaW5lZFJlY29yZGVyID0ge1xuICAgIC8vICAgaWQ6ICdhdWRpdCcsXG4gICAgLy8gICBvbkVycm9yOiAoZSkgPT4ge1xuICAgIC8vICAgICBpZiAoaXNGbG93RXZlbnQoZSkpIHtcbiAgICAvLyAgICAgICAvLyBlIGlzIEZsb3dFcnJvckV2ZW50IOKAlCBoYXMgc3RhZ2VOYW1lLCBtZXNzYWdlLCBzdHJ1Y3R1cmVkRXJyb3JcbiAgICAvLyAgICAgICBsb2coJ2Zsb3cgZXJyb3IgaW4gc3RhZ2UnLCBlLnN0YWdlTmFtZSk7XG4gICAgLy8gICAgIH0gZWxzZSB7XG4gICAgLy8gICAgICAgLy8gZSBpcyBFcnJvckV2ZW50IOKAlCBoYXMgZXJyb3IsIG9wZXJhdGlvbiwga2V5P1xuICAgIC8vICAgICAgIGxvZygnc2NvcGUgZXJyb3IgZHVyaW5nJywgZS5vcGVyYXRpb24sIGUuZXJyb3IubWVzc2FnZSk7XG4gICAgLy8gICAgIH1cbiAgICAvLyAgIH0sXG4gICAgLy8gfTtcbiAgICAvLyBgYGBcbiAgICBvbkVycm9yPyhldmVudDogRXJyb3JFdmVudCB8IEZsb3dFcnJvckV2ZW50KTogdm9pZDtcbiAgICBvblBhdXNlPyhldmVudDogUGF1c2VFdmVudCB8IEZsb3dQYXVzZUV2ZW50KTogdm9pZDtcbiAgICBvblJlc3VtZT8oZXZlbnQ6IFJlc3VtZUV2ZW50IHwgRmxvd1Jlc3VtZUV2ZW50KTogdm9pZDtcbiAgfTtcblxuLyoqXG4gKiBEaXNjcmltaW5hdG9yIGZvciB0aGUgdW5pb24gcGF5bG9hZCB0eXBlcyBvbiBgQ29tYmluZWRSZWNvcmRlcmAncyBzaGFyZWRcbiAqIG1ldGhvZHMgKGBvbkVycm9yYCwgYG9uUGF1c2VgLCBgb25SZXN1bWVgKS4gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGV2ZW50XG4gKiB3YXMgZW1pdHRlZCBmcm9tIHRoZSBjb250cm9sLWZsb3cgY2hhbm5lbCAoRmxvd1JlY29yZGVyKS5cbiAqXG4gKiAjIyBIb3cgaXQgZGlzY3JpbWluYXRlc1xuICpcbiAqIFNjb3BlLWNoYW5uZWwgZXZlbnRzIGV4dGVuZCBgUmVjb3JkZXJDb250ZXh0YCwgd2hpY2ggY2FycmllcyBgcGlwZWxpbmVJZGAuXG4gKiBGbG93LWNoYW5uZWwgZXZlbnRzIGRvIG5vdCBjYXJyeSBgcGlwZWxpbmVJZGAgKHRoZXkgY2FycnkgYW4gb3B0aW9uYWxcbiAqIGB0cmF2ZXJzYWxDb250ZXh0YCBpbnN0ZWFkLCBidXQgdGhhdCBmaWVsZCBpcyBvcHRpb25hbCBhbmQgY2Fubm90IGJlXG4gKiByZWxpZWQgb24gYXMgYSBwb3NpdGl2ZSBzaWduYWwpLiBXZSBkZXRlY3QgdGhlIGZsb3cgdmFyaWFudCBieSB0aGVcbiAqIEFCU0VOQ0Ugb2YgYHBpcGVsaW5lSWRgIOKAlCB0aGlzIGlzIHNjaGVtYS1zdGFibGUgYXMgbG9uZyBhcyBzY29wZSBldmVudHNcbiAqIGNvbnRpbnVlIHRvIGV4dGVuZCBgUmVjb3JkZXJDb250ZXh0YC5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIG9uRXJyb3I6IChlKSA9PiB7XG4gKiAgIGlmIChpc0Zsb3dFdmVudChlKSkge1xuICogICAgIC8vIE5hcnJvd2VkIHRvIEZsb3dFcnJvckV2ZW50OiBoYXMgc3RhZ2VOYW1lLCBtZXNzYWdlLCBzdHJ1Y3R1cmVkRXJyb3JcbiAqICAgfSBlbHNlIHtcbiAqICAgICAvLyBOYXJyb3dlZCB0byBFcnJvckV2ZW50OiBoYXMgZXJyb3IsIG9wZXJhdGlvbiwga2V5P1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRmxvd0V2ZW50PFQ+KGV2ZW50OiBUKTogZXZlbnQgaXMgRXhjbHVkZTxULCB7IHBpcGVsaW5lSWQ6IHN0cmluZyB9PiB7XG4gIGlmICh0eXBlb2YgZXZlbnQgIT09ICdvYmplY3QnIHx8IGV2ZW50ID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiAoZXZlbnQgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLnBpcGVsaW5lSWQgPT09IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBNZXRob2QgbmFtZXMgYmVsb25naW5nIHRvIHRoZSBgUmVjb3JkZXJgIChkYXRhLWZsb3cpIGludGVyZmFjZS5cbiAqIEtlcHQgYXMgYSBzaW5nbGUgc291cmNlIG9mIHRydXRoIHNvIHRoZSBydW50aW1lIGR1Y2stdHlwZSBkZXRlY3RvciBzdGF5c1xuICogaW4gc3luYyB3aXRoIHRoZSBpbnRlcmZhY2UuIElmIGEgbWV0aG9kIGlzIGFkZGVkIHRvIGBSZWNvcmRlcmAsIGFkZGluZyBpdFxuICogaGVyZSBpcyB0aGUgT05MWSBjaGFuZ2UgcmVxdWlyZWQgdG8gcm91dGUgY29tYmluZWQtcmVjb3JkZXJzIGNvcnJlY3RseS5cbiAqL1xuY29uc3QgUkVDT1JERVJfRVZFTlRfTUVUSE9EUyA9IFtcbiAgJ29uUmVhZCcsXG4gICdvbldyaXRlJyxcbiAgJ29uQ29tbWl0JyxcbiAgJ29uRXJyb3InLFxuICAnb25TdGFnZVN0YXJ0JyxcbiAgJ29uU3RhZ2VFbmQnLFxuICAnb25QYXVzZScsXG4gICdvblJlc3VtZScsXG5dIGFzIGNvbnN0O1xuXG4vKipcbiAqIE1ldGhvZCBuYW1lcyBiZWxvbmdpbmcgdG8gdGhlIGBGbG93UmVjb3JkZXJgIChjb250cm9sLWZsb3cpIGludGVyZmFjZS5cbiAqIFNlZSB0aGUgbm90ZSBvbiBgUkVDT1JERVJfRVZFTlRfTUVUSE9EU2AuXG4gKlxuICogTk9URTogdGhlIGBvbkVycm9yYCwgYG9uUGF1c2VgLCBgb25SZXN1bWVgIG1ldGhvZHMgZXhpc3Qgb24gQk9USCBpbnRlcmZhY2VzXG4gKiB3aXRoIERJRkZFUkVOVCBldmVudCBwYXlsb2FkIHNoYXBlcy4gQSBgQ29tYmluZWRSZWNvcmRlcmAgdGhhdCBpbXBsZW1lbnRzXG4gKiBhbnkgb2YgdGhlc2UgcmVjZWl2ZXMgYm90aCB2YXJpYW50cyAob25lIGZyb20gZWFjaCBjaGFubmVsKS4gQ29uc3VtZXJzIHdob1xuICogY2FyZSBhYm91dCB0aGUgZGlzdGluY3Rpb24gY2FuIGRpc2NyaW1pbmF0ZSBvbiB0aGUgcHJlc2VuY2Ugb2ZcbiAqIGB0cmF2ZXJzYWxDb250ZXh0YCAod2hpY2ggb25seSBjb250cm9sLWZsb3cgZXZlbnRzIGNhcnJ5KS5cbiAqL1xuY29uc3QgRkxPV19SRUNPUkRFUl9FVkVOVF9NRVRIT0RTID0gW1xuICAnb25TdGFnZUV4ZWN1dGVkJyxcbiAgJ29uTmV4dCcsXG4gICdvbkRlY2lzaW9uJyxcbiAgJ29uRm9yaycsXG4gICdvblNlbGVjdGVkJyxcbiAgJ29uU3ViZmxvd0VudHJ5JyxcbiAgJ29uU3ViZmxvd0V4aXQnLFxuICAnb25TdWJmbG93UmVnaXN0ZXJlZCcsXG4gICdvbkxvb3AnLFxuICAnb25CcmVhaycsXG4gICdvbkVycm9yJyxcbiAgJ29uUGF1c2UnLFxuICAnb25SZXN1bWUnLFxuXSBhcyBjb25zdDtcblxuLyoqXG4gKiBNZXRob2QgbmFtZXMgYmVsb25naW5nIHRvIHRoZSBgRW1pdFJlY29yZGVyYCAodXNlci1lbWl0dGVkIGV2ZW50cylcbiAqIGludGVyZmFjZS4gU2FtZSBjb252ZW50aW9uIGFzIHRoZSBvdGhlciB0d28gYXJyYXlzIGFib3ZlIOKAlCBrZXB0IGFzXG4gKiB0aGUgc2luZ2xlIHNvdXJjZSBvZiB0cnV0aCBmb3IgZHVjay10eXBlIGRldGVjdGlvbi5cbiAqL1xuY29uc3QgRU1JVF9SRUNPUkRFUl9FVkVOVF9NRVRIT0RTID0gWydvbkVtaXQnXSBhcyBjb25zdDtcblxuLyoqXG4gKiBUcnVlIGlmZiB0aGUgcmVjb3JkZXIgZGVjbGFyZXMgYSBtZXRob2QgbmFtZWQgYG1gIGVpdGhlciBhcyBhbiBvd25cbiAqIHByb3BlcnR5IE9SIG9uIGl0cyBjbGFzcy1wcm90b3R5cGUgY2hhaW4g4oCUIGJ1dCBOT1QgaW5oZXJpdGVkIGZyb21cbiAqIGBPYmplY3QucHJvdG90eXBlYC5cbiAqXG4gKiAjIyBXaHkgdGhpcyBsYXllcmVkIGNoZWNrXG4gKlxuICogQSBgQ29tYmluZWRSZWNvcmRlcmAgY2FuIGJlIGVpdGhlciBhIHBsYWluIG9iamVjdCBsaXRlcmFsIChoYW5kbGVycyBhc1xuICogb3duIHByb3BlcnRpZXMpIE9SIGEgY2xhc3MgaW5zdGFuY2UgKGhhbmRsZXJzIGFzIGNsYXNzLXByb3RvdHlwZVxuICogbWV0aG9kcykuIEJvdGggYXJlIGxlZ2l0aW1hdGUgY29uc3VtZXIgcGF0dGVybnMgYW5kIGJvdGggTVVTVCBhdHRhY2guXG4gKlxuICogQnV0IGhhbmRsZXJzIGluaGVyaXRlZCBmcm9tIGBPYmplY3QucHJvdG90eXBlYCBhcmUgQUxXQVlTIGFjY2lkZW50YWwgb3JcbiAqIG1hbGljaW91cyAobm9ib2R5IGxlZ2l0aW1hdGVseSBhdHRhY2hlcyByZWNvcmRlciBtZXRob2RzIHRoZXJlKS4gU28gd2VcbiAqIHdhbGsgdGhlIHByb3RvdHlwZSBjaGFpbiwgU1RPUFBJTkcgYmVmb3JlIGBPYmplY3QucHJvdG90eXBlYC4gVGhpc1xuICogYWNjZXB0cyBjbGFzcyBtZXRob2RzIHdoaWxlIHN0aWxsIGJsb2NraW5nIGBPYmplY3QucHJvdG90eXBlYFxuICogcG9sbHV0aW9uIGF0dGFja3MuXG4gKi9cbmZ1bmN0aW9uIGhhc093bk9yQ2xhc3NNZXRob2QocjogdW5rbm93biwgbTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChyID09PSBudWxsIHx8IHR5cGVvZiByICE9PSAnb2JqZWN0JykgcmV0dXJuIGZhbHNlO1xuICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHIsIG0pKSB7XG4gICAgcmV0dXJuIHR5cGVvZiAociBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbbV0gPT09ICdmdW5jdGlvbic7XG4gIH1cbiAgbGV0IHByb3RvOiB1bmtub3duID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHIpO1xuICB3aGlsZSAocHJvdG8gIT09IG51bGwgJiYgcHJvdG8gIT09IE9iamVjdC5wcm90b3R5cGUpIHtcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHByb3RvLCBtKSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiAocHJvdG8gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW21dID09PSAnZnVuY3Rpb24nO1xuICAgIH1cbiAgICBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIFRydWUgaWZmIHRoZSByZWNvcmRlciBpbXBsZW1lbnRzIGF0IGxlYXN0IG9uZSBkYXRhLWZsb3cgZXZlbnQgbWV0aG9kLlxuICogVXNlZCBieSBgZXhlY3V0b3IuYXR0YWNoQ29tYmluZWRSZWNvcmRlcmAgdG8gZGVjaWRlIHdoZXRoZXIgdG8gaG9vayBpbnRvXG4gKiB0aGUgc2NvcGUgZGF0YS1mbG93IGNoYW5uZWwuXG4gKlxuICogIyMgRGV0ZWN0aW9uIHJ1bGVcbiAqXG4gKiBBY2NlcHRzIGJvdGggb2JqZWN0LWxpdGVyYWwgcmVjb3JkZXJzIChvd24tcHJvcGVydHkgaGFuZGxlcnMpIEFORCBjbGFzc1xuICogaW5zdGFuY2VzIChoYW5kbGVycyBkZWNsYXJlZCBvbiB0aGUgY2xhc3MgcHJvdG90eXBlKS4gUmVqZWN0cyBoYW5kbGVyc1xuICogaW5oZXJpdGVkIGZyb20gYE9iamVjdC5wcm90b3R5cGVgIOKAlCB0aGF0J3MgYWx3YXlzIGFjY2lkZW50YWwgb3JcbiAqIG1hbGljaW91cyBwb2xsdXRpb24sIG5ldmVyIGEgbGVnaXRpbWF0ZSByZWNvcmRlci5cbiAqXG4gKiAjIyBMaWZlY3ljbGUgZXhjbHVzaW9uc1xuICpcbiAqIGBjbGVhcmAgYW5kIGB0b1NuYXBzaG90YCBhcmUgTk9UIGNvdW50ZWQgYXMgZXZlbnQgbWV0aG9kcyDigJQgYSByZWNvcmRlclxuICogdGhhdCBvbmx5IGltcGxlbWVudHMgdGhvc2UgaGFzIG5vdGhpbmcgdG8gb2JzZXJ2ZSBhbmQgd291bGQgYmUgYSBuby1vcFxuICogb24gZWl0aGVyIGNoYW5uZWwuXG4gKlxuICogIyMgUmV0dXJuIHR5cGVcbiAqXG4gKiBSZXR1cm5zIHBsYWluIGBib29sZWFuYCAobm90IGEgdHlwZSBwcmVkaWNhdGUpLiBUaGUgZnVsbCBgUmVjb3JkZXJgXG4gKiBpbnRlcmZhY2UgaGFzIHBheWxvYWQgdHlwZXMgdGhhdCBkaXZlcmdlIGZyb20gYENvbWJpbmVkUmVjb3JkZXJgJ3MgdW5pb25cbiAqIHZhcmlhbnRzIGZvciBzaGFyZWQgbWV0aG9kcywgc28gYSBuYXJyb3dpbmcgcHJlZGljYXRlIHdvdWxkIGJlIHVuc291bmQuXG4gKiBDYWxsZXJzIHRoYXQgbmVlZCB0byB0cmVhdCB0aGUgcmVjb3JkZXIgYXMgYSBgUmVjb3JkZXJgIGRvIHNvIGV4cGxpY2l0bHlcbiAqIGF0IHRoZSBhdHRhY2ggc2l0ZSDigJQgdGhlIGNhc3QgaXMgdGhlIGNvbnRyYWN0IHRoYXQgZWFjaCBjaGFubmVsIHBhc3Nlc1xuICogaXRzIG93biBwYXlsb2FkIHZhcmlhbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNSZWNvcmRlck1ldGhvZHMocjogQ29tYmluZWRSZWNvcmRlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gUkVDT1JERVJfRVZFTlRfTUVUSE9EUy5zb21lKChtKSA9PiBoYXNPd25PckNsYXNzTWV0aG9kKHIsIG0pKTtcbn1cblxuLyoqXG4gKiBUcnVlIGlmZiB0aGUgcmVjb3JkZXIgaW1wbGVtZW50cyBhdCBsZWFzdCBvbmUgY29udHJvbC1mbG93IGV2ZW50IG1ldGhvZC5cbiAqIFNlZSBgaGFzUmVjb3JkZXJNZXRob2RzYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc0Zsb3dSZWNvcmRlck1ldGhvZHMocjogQ29tYmluZWRSZWNvcmRlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gRkxPV19SRUNPUkRFUl9FVkVOVF9NRVRIT0RTLnNvbWUoKG0pID0+IGhhc093bk9yQ2xhc3NNZXRob2QociwgbSkpO1xufVxuXG4vKipcbiAqIFRydWUgaWZmIHRoZSByZWNvcmRlciBpbXBsZW1lbnRzIGF0IGxlYXN0IG9uZSBlbWl0LWNoYW5uZWwgZXZlbnQgbWV0aG9kLlxuICogU2VlIGBoYXNSZWNvcmRlck1ldGhvZHNgIGZvciB0aGUgb3duZXJzaGlwLWRldGVjdGlvbiBydWxlcyAob3duIG9yXG4gKiBjbGFzcy1wcm90b3R5cGUgbWV0aG9kcyBjb3VudDsgYE9iamVjdC5wcm90b3R5cGVgIHBvbGx1dGlvbiBkb2VzIG5vdCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNFbWl0UmVjb3JkZXJNZXRob2RzKHI6IENvbWJpbmVkUmVjb3JkZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIEVNSVRfUkVDT1JERVJfRVZFTlRfTUVUSE9EUy5zb21lKChtKSA9PiBoYXNPd25PckNsYXNzTWV0aG9kKHIsIG0pKTtcbn1cbiJdfQ==
@@ -0,0 +1,62 @@
1
+ /**
2
+ * EmitRecorder — the third observer channel, alongside `Recorder`
3
+ * (scope data-flow) and `FlowRecorder` (control-flow).
4
+ *
5
+ * ## Why this exists
6
+ *
7
+ * The first two channels capture what the LIBRARY knows about — scope
8
+ * reads/writes fired by `setValue`, and control-flow events fired by the
9
+ * traverser. But **user-emitted structured events** — things a stage
10
+ * function wants to surface for observability (LLM tokens, billing metrics,
11
+ * auth decisions, domain milestones) — have nowhere to go today. They land
12
+ * in unobserved `DiagnosticCollector` side bags that no recorder watches.
13
+ *
14
+ * This channel closes that gap. Consumer calls `scope.$emit(name, payload)`
15
+ * from inside a stage; the library enriches the event with stage context
16
+ * and dispatches it synchronously to every attached `EmitRecorder`.
17
+ *
18
+ * ## Design properties
19
+ *
20
+ * - **Pass-through, not buffered.** Zero allocation when no recorder is
21
+ * attached. Events delivered synchronously, in-order, at call time.
22
+ * Same semantics as `onRead`/`onWrite` already use.
23
+ * - **Library-agnostic vocabulary.** Event names are consumer-chosen strings.
24
+ * Convention: hierarchical dotted names, e.g. `'agentfootprint.llm.tokens'`,
25
+ * `'myapp.billing.spend'`. Library enforces no registry.
26
+ * - **Auto-enriched context.** Every event carries `stageName`,
27
+ * `runtimeStageId`, `subflowPath`, `pipelineId`, `timestamp`. Consumers
28
+ * never need to thread execution context through their emit payloads.
29
+ * - **Redaction-aware.** `RedactionPolicy.emitPatterns` matches event names
30
+ * before dispatch — matched events have their payload replaced with
31
+ * `'[REDACTED]'` so secrets can't leak via emit.
32
+ *
33
+ * ## Relationship to existing channels
34
+ *
35
+ * | Channel | Fires when | Built-in consumers |
36
+ * |-----------------|------------------------------------|------------------------|
37
+ * | `Recorder` | scope read/write/commit | DebugRecorder, MetricRecorder |
38
+ * | `FlowRecorder` | traversal transitions | NarrativeFlowRecorder, etc. |
39
+ * | `EmitRecorder` | consumer calls `scope.$emit(...)` | (none ships today; Phase 3.X adds MemoryEmitRecorder) |
40
+ *
41
+ * `CombinedRecorder` (from `./CombinedRecorder.ts`) intersects all three
42
+ * via `Partial<...>`. A consumer can write ONE object implementing any
43
+ * combination; `executor.attachCombinedRecorder(r)` duck-types and routes
44
+ * to the right channel(s).
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const tokenMeter: EmitRecorder = {
49
+ * id: 'token-meter',
50
+ * onEmit(event) {
51
+ * if (event.name === 'agentfootprint.llm.tokens') {
52
+ * this.total += (event.payload as { input: number; output: number }).input;
53
+ * }
54
+ * },
55
+ * total: 0,
56
+ * } as any;
57
+ *
58
+ * executor.attachEmitRecorder(tokenMeter);
59
+ * ```
60
+ */
61
+ export {};
62
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRW1pdFJlY29yZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9yZWNvcmRlci9FbWl0UmVjb3JkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMkRHIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBFbWl0UmVjb3JkZXIg4oCUIHRoZSB0aGlyZCBvYnNlcnZlciBjaGFubmVsLCBhbG9uZ3NpZGUgYFJlY29yZGVyYFxuICogKHNjb3BlIGRhdGEtZmxvdykgYW5kIGBGbG93UmVjb3JkZXJgIChjb250cm9sLWZsb3cpLlxuICpcbiAqICMjIFdoeSB0aGlzIGV4aXN0c1xuICpcbiAqIFRoZSBmaXJzdCB0d28gY2hhbm5lbHMgY2FwdHVyZSB3aGF0IHRoZSBMSUJSQVJZIGtub3dzIGFib3V0IOKAlCBzY29wZVxuICogcmVhZHMvd3JpdGVzIGZpcmVkIGJ5IGBzZXRWYWx1ZWAsIGFuZCBjb250cm9sLWZsb3cgZXZlbnRzIGZpcmVkIGJ5IHRoZVxuICogdHJhdmVyc2VyLiBCdXQgKip1c2VyLWVtaXR0ZWQgc3RydWN0dXJlZCBldmVudHMqKiDigJQgdGhpbmdzIGEgc3RhZ2VcbiAqIGZ1bmN0aW9uIHdhbnRzIHRvIHN1cmZhY2UgZm9yIG9ic2VydmFiaWxpdHkgKExMTSB0b2tlbnMsIGJpbGxpbmcgbWV0cmljcyxcbiAqIGF1dGggZGVjaXNpb25zLCBkb21haW4gbWlsZXN0b25lcykg4oCUIGhhdmUgbm93aGVyZSB0byBnbyB0b2RheS4gVGhleSBsYW5kXG4gKiBpbiB1bm9ic2VydmVkIGBEaWFnbm9zdGljQ29sbGVjdG9yYCBzaWRlIGJhZ3MgdGhhdCBubyByZWNvcmRlciB3YXRjaGVzLlxuICpcbiAqIFRoaXMgY2hhbm5lbCBjbG9zZXMgdGhhdCBnYXAuIENvbnN1bWVyIGNhbGxzIGBzY29wZS4kZW1pdChuYW1lLCBwYXlsb2FkKWBcbiAqIGZyb20gaW5zaWRlIGEgc3RhZ2U7IHRoZSBsaWJyYXJ5IGVucmljaGVzIHRoZSBldmVudCB3aXRoIHN0YWdlIGNvbnRleHRcbiAqIGFuZCBkaXNwYXRjaGVzIGl0IHN5bmNocm9ub3VzbHkgdG8gZXZlcnkgYXR0YWNoZWQgYEVtaXRSZWNvcmRlcmAuXG4gKlxuICogIyMgRGVzaWduIHByb3BlcnRpZXNcbiAqXG4gKiAtICoqUGFzcy10aHJvdWdoLCBub3QgYnVmZmVyZWQuKiogWmVybyBhbGxvY2F0aW9uIHdoZW4gbm8gcmVjb3JkZXIgaXNcbiAqICAgYXR0YWNoZWQuIEV2ZW50cyBkZWxpdmVyZWQgc3luY2hyb25vdXNseSwgaW4tb3JkZXIsIGF0IGNhbGwgdGltZS5cbiAqICAgU2FtZSBzZW1hbnRpY3MgYXMgYG9uUmVhZGAvYG9uV3JpdGVgIGFscmVhZHkgdXNlLlxuICogLSAqKkxpYnJhcnktYWdub3N0aWMgdm9jYWJ1bGFyeS4qKiBFdmVudCBuYW1lcyBhcmUgY29uc3VtZXItY2hvc2VuIHN0cmluZ3MuXG4gKiAgIENvbnZlbnRpb246IGhpZXJhcmNoaWNhbCBkb3R0ZWQgbmFtZXMsIGUuZy4gYCdhZ2VudGZvb3RwcmludC5sbG0udG9rZW5zJ2AsXG4gKiAgIGAnbXlhcHAuYmlsbGluZy5zcGVuZCdgLiBMaWJyYXJ5IGVuZm9yY2VzIG5vIHJlZ2lzdHJ5LlxuICogLSAqKkF1dG8tZW5yaWNoZWQgY29udGV4dC4qKiBFdmVyeSBldmVudCBjYXJyaWVzIGBzdGFnZU5hbWVgLFxuICogICBgcnVudGltZVN0YWdlSWRgLCBgc3ViZmxvd1BhdGhgLCBgcGlwZWxpbmVJZGAsIGB0aW1lc3RhbXBgLiBDb25zdW1lcnNcbiAqICAgbmV2ZXIgbmVlZCB0byB0aHJlYWQgZXhlY3V0aW9uIGNvbnRleHQgdGhyb3VnaCB0aGVpciBlbWl0IHBheWxvYWRzLlxuICogLSAqKlJlZGFjdGlvbi1hd2FyZS4qKiBgUmVkYWN0aW9uUG9saWN5LmVtaXRQYXR0ZXJuc2AgbWF0Y2hlcyBldmVudCBuYW1lc1xuICogICBiZWZvcmUgZGlzcGF0Y2gg4oCUIG1hdGNoZWQgZXZlbnRzIGhhdmUgdGhlaXIgcGF5bG9hZCByZXBsYWNlZCB3aXRoXG4gKiAgIGAnW1JFREFDVEVEXSdgIHNvIHNlY3JldHMgY2FuJ3QgbGVhayB2aWEgZW1pdC5cbiAqXG4gKiAjIyBSZWxhdGlvbnNoaXAgdG8gZXhpc3RpbmcgY2hhbm5lbHNcbiAqXG4gKiB8IENoYW5uZWwgICAgICAgICB8IEZpcmVzIHdoZW4gICAgICAgICAgICAgICAgICAgICAgICAgfCBCdWlsdC1pbiBjb25zdW1lcnMgICAgIHxcbiAqIHwtLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfFxuICogfCBgUmVjb3JkZXJgICAgICAgfCBzY29wZSByZWFkL3dyaXRlL2NvbW1pdCAgICAgICAgICAgIHwgRGVidWdSZWNvcmRlciwgTWV0cmljUmVjb3JkZXIgfFxuICogfCBgRmxvd1JlY29yZGVyYCAgfCB0cmF2ZXJzYWwgdHJhbnNpdGlvbnMgICAgICAgICAgICAgIHwgTmFycmF0aXZlRmxvd1JlY29yZGVyLCBldGMuIHxcbiAqIHwgYEVtaXRSZWNvcmRlcmAgIHwgY29uc3VtZXIgY2FsbHMgYHNjb3BlLiRlbWl0KC4uLilgICB8IChub25lIHNoaXBzIHRvZGF5OyBQaGFzZSAzLlggYWRkcyBNZW1vcnlFbWl0UmVjb3JkZXIpIHxcbiAqXG4gKiBgQ29tYmluZWRSZWNvcmRlcmAgKGZyb20gYC4vQ29tYmluZWRSZWNvcmRlci50c2ApIGludGVyc2VjdHMgYWxsIHRocmVlXG4gKiB2aWEgYFBhcnRpYWw8Li4uPmAuIEEgY29uc3VtZXIgY2FuIHdyaXRlIE9ORSBvYmplY3QgaW1wbGVtZW50aW5nIGFueVxuICogY29tYmluYXRpb247IGBleGVjdXRvci5hdHRhY2hDb21iaW5lZFJlY29yZGVyKHIpYCBkdWNrLXR5cGVzIGFuZCByb3V0ZXNcbiAqIHRvIHRoZSByaWdodCBjaGFubmVsKHMpLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCB0b2tlbk1ldGVyOiBFbWl0UmVjb3JkZXIgPSB7XG4gKiAgIGlkOiAndG9rZW4tbWV0ZXInLFxuICogICBvbkVtaXQoZXZlbnQpIHtcbiAqICAgICBpZiAoZXZlbnQubmFtZSA9PT0gJ2FnZW50Zm9vdHByaW50LmxsbS50b2tlbnMnKSB7XG4gKiAgICAgICB0aGlzLnRvdGFsICs9IChldmVudC5wYXlsb2FkIGFzIHsgaW5wdXQ6IG51bWJlcjsgb3V0cHV0OiBudW1iZXIgfSkuaW5wdXQ7XG4gKiAgICAgfVxuICogICB9LFxuICogICB0b3RhbDogMCxcbiAqIH0gYXMgYW55O1xuICpcbiAqIGV4ZWN1dG9yLmF0dGFjaEVtaXRSZWNvcmRlcih0b2tlbk1ldGVyKTtcbiAqIGBgYFxuICovXG5cbmltcG9ydCB0eXBlIHsgUmVjb3JkZXJPcGVyYXRpb24gfSBmcm9tICcuL1JlY29yZGVyT3BlcmF0aW9uLmpzJztcblxuLyoqXG4gKiBFdmVudCBkZWxpdmVyZWQgdG8gYEVtaXRSZWNvcmRlci5vbkVtaXRgLlxuICpcbiAqIE5hbWUgKyBwYXlsb2FkIGFyZSBjb25zdW1lci1zdXBwbGllZCB2aWEgYHNjb3BlLiRlbWl0KG5hbWUsIHBheWxvYWQpYC5cbiAqIEV2ZXJ5dGhpbmcgZWxzZSBpcyBsaWJyYXJ5LWVucmljaGVkIGF0IGRpc3BhdGNoIHRpbWUgZnJvbSB0aGUgY3VycmVudFxuICogc3RhZ2UncyBleGVjdXRpb24gY29udGV4dC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbWl0RXZlbnQge1xuICAvKipcbiAgICogQ29uc3VtZXItc3VwcGxpZWQgZXZlbnQgbmFtZS4gQ29udmVudGlvbjogaGllcmFyY2hpY2FsIGRvdHRlZCBuYW1lc3BhY2VcbiAgICogKGUuZy4gYCdhZ2VudGZvb3RwcmludC5sbG0udG9rZW5zJ2AsIGAnbXlhcHAuYmlsbGluZy5zcGVuZCdgKS4gS2VlcHNcbiAgICogdm9jYWJ1bGFyaWVzIGNvbGxpc2lvbi1mcmVlIGFjcm9zcyBsaWJyYXJpZXMvYXBwcyB3aXRob3V0IHJlcXVpcmluZyBhXG4gICAqIGNlbnRyYWwgcmVnaXN0cnkuXG4gICAqL1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENvbnN1bWVyLXN1cHBsaWVkIHBheWxvYWQuIFNoYXBlIGlzIHVwIHRvIHRoZSBjb25zdW1lciBhbmQgdGhlaXJcbiAgICogY29udmVudGlvbjsgbGlicmFyeSB0cmVhdHMgaXQgYXMgb3BhcXVlIGFuZCBwYXNzZXMgdGhyb3VnaCB1bmNoYW5nZWRcbiAgICogKG1vZHVsbyByZWRhY3Rpb24g4oCUIHNlZSBgUmVkYWN0aW9uUG9saWN5LmVtaXRQYXR0ZXJuc2ApLlxuICAgKlxuICAgKiBXaGVuIHJlZGFjdGVkLCByZXBsYWNlZCB3aXRoIHRoZSBzdHJpbmcgYCdbUkVEQUNURURdJ2AuXG4gICAqL1xuICByZWFkb25seSBwYXlsb2FkOiB1bmtub3duO1xuXG4gIC8qKiBOYW1lIG9mIHRoZSBzdGFnZSB0aGF0IGVtaXR0ZWQgdGhpcyBldmVudC4gKi9cbiAgcmVhZG9ubHkgc3RhZ2VOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFVuaXF1ZSBwZXItZXhlY3V0aW9uLXN0ZXAgaWRlbnRpZmllciDigJQgdGhlIHNhbWUgdmFsdWUgcmVjb3JkZXIgZXZlbnRzXG4gICAqIGFuZCBjb21taXQtbG9nIGVudHJpZXMgY2FycnkuIFNlZSBgcnVudGltZVN0YWdlSWQudHNgIGZvciBmb3JtYXQuXG4gICAqL1xuICByZWFkb25seSBydW50aW1lU3RhZ2VJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTdWJmbG93IHBhdGggZnJvbSB0aGUgb3V0ZXJtb3N0IHBhcmVudCBkb3duIHRvIHRoZSBzdWJmbG93IHRoYXQgZW1pdHRlZFxuICAgKiB0aGlzIGV2ZW50LiBFbXB0eSBhcnJheSB3aGVuIHRoZSBlbWl0IGNhbWUgZnJvbSB0aGUgcm9vdCBmbG93Y2hhcnQuXG4gICAqIE1hdGNoZXMgdGhlIGNvbnZlbnRpb24gdXNlZCBieSBgRmxvd1BhdXNlRXZlbnQuc3ViZmxvd1BhdGhgLFxuICAgKiBgRmxvd2NoYXJ0Q2hlY2twb2ludC5zdWJmbG93UGF0aGAsIGV0Yy5cbiAgICovXG4gIHJlYWRvbmx5IHN1YmZsb3dQYXRoOiByZWFkb25seSBzdHJpbmdbXTtcblxuICAvKiogUGlwZWxpbmUvcnVuIGlkZW50aWZpZXIgKG1hdGNoZXMgYFJlY29yZGVyQ29udGV4dC5waXBlbGluZUlkYCkuICovXG4gIHJlYWRvbmx5IHBpcGVsaW5lSWQ6IHN0cmluZztcblxuICAvKiogRW1pc3Npb24gdGltZXN0YW1wIGluIG1pbGxpc2Vjb25kcyBzaW5jZSBlcG9jaCAoYERhdGUubm93KClgKS4gKi9cbiAgcmVhZG9ubHkgdGltZXN0YW1wOiBudW1iZXI7XG59XG5cbi8qKlxuICogUGx1Z2dhYmxlIG9ic2VydmVyIGZvciBjb25zdW1lci1lbWl0dGVkIHN0cnVjdHVyZWQgZXZlbnRzLlxuICpcbiAqIEFsbCBtZXRob2RzIGFyZSBvcHRpb25hbDsgaW1wbGVtZW50IG9ubHkgd2hhdCB5b3UgY2FyZSBhYm91dC4gUmVjb3JkZXJzXG4gKiBhcmUgaW52b2tlZCBzeW5jaHJvbm91c2x5IGluIGF0dGFjaG1lbnQgb3JkZXIuIElmIGEgcmVjb3JkZXIgdGhyb3dzLCB0aGVcbiAqIGVycm9yIGlzIGNhdWdodCBhbmQgaXNvbGF0ZWQg4oCUIG90aGVyIHJlY29yZGVycyBjb250aW51ZSB0byByZWNlaXZlIHRoZVxuICogZXZlbnQgYW5kIHRoZSBlbWl0dGluZyBzdGFnZSBpcyB1bmFmZmVjdGVkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVtaXRSZWNvcmRlciB7XG4gIC8qKlxuICAgKiBTdGFibGUgaWRlbnRpZmllciBmb3IgaWRlbXBvdGVudCBhdHRhY2gvZGV0YWNoLiBSZS1hdHRhY2hpbmcgd2l0aCB0aGVcbiAgICogc2FtZSBpZCByZXBsYWNlcyB0aGUgcHJldmlvdXMgcmVnaXN0cmF0aW9uIG9uIHRoZSBleGVjdXRvci5cbiAgICovXG4gIHJlYWRvbmx5IGlkOiBzdHJpbmc7XG5cbiAgLyoqIENhbGxlZCBmb3IgZXZlcnkgYHNjb3BlLiRlbWl0KG5hbWUsIHBheWxvYWQpYCBjYWxsIGluIGFueSBzdGFnZS4gKi9cbiAgb25FbWl0PyhldmVudDogRW1pdEV2ZW50KTogdm9pZDtcblxuICAvKipcbiAgICogT3B0aW9uYWw6IHJlc2V0IHJlY29yZGVyLWludGVybmFsIHN0YXRlIGJldHdlZW4gcnVucy4gQ2FsbGVkIGJ5IHRoZVxuICAgKiBleGVjdXRvciBiZWZvcmUgZWFjaCBgcnVuKClgLlxuICAgKi9cbiAgY2xlYXI/KCk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsOiBleHBvc2UgY29sbGVjdGVkIGRhdGEgZm9yIGluY2x1c2lvbiBpblxuICAgKiBgZXhlY3V0b3IuZ2V0U25hcHNob3QoKS5yZWNvcmRlcnNgLlxuICAgKi9cbiAgdG9TbmFwc2hvdD8oKToge1xuICAgIG5hbWU6IHN0cmluZztcbiAgICBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgICBwcmVmZXJyZWRPcGVyYXRpb24/OiBSZWNvcmRlck9wZXJhdGlvbjtcbiAgICBkYXRhOiB1bmtub3duO1xuICB9O1xufVxuIl19
@@ -1,5 +1,6 @@
1
+ export { hasEmitRecorderMethods, hasFlowRecorderMethods, hasRecorderMethods, isFlowEvent } from './CombinedRecorder.js';
1
2
  export { CompositeRecorder } from './CompositeRecorder.js';
2
3
  export { KeyedRecorder } from './KeyedRecorder.js';
3
4
  export { RecorderOperation } from './RecorderOperation.js';
4
5
  export { SequenceRecorder } from './SequenceRecorder.js';
5
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3JlY29yZGVyL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzNELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMzRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIHsgQ29tcG9zaXRlU25hcHNob3QgfSBmcm9tICcuL0NvbXBvc2l0ZVJlY29yZGVyLmpzJztcbmV4cG9ydCB7IENvbXBvc2l0ZVJlY29yZGVyIH0gZnJvbSAnLi9Db21wb3NpdGVSZWNvcmRlci5qcyc7XG5leHBvcnQgeyBLZXllZFJlY29yZGVyIH0gZnJvbSAnLi9LZXllZFJlY29yZGVyLmpzJztcbmV4cG9ydCB7IFJlY29yZGVyT3BlcmF0aW9uIH0gZnJvbSAnLi9SZWNvcmRlck9wZXJhdGlvbi5qcyc7XG5leHBvcnQgeyBTZXF1ZW5jZVJlY29yZGVyIH0gZnJvbSAnLi9TZXF1ZW5jZVJlY29yZGVyLmpzJztcbiJdfQ==
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3JlY29yZGVyL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxzQkFBc0IsRUFBRSxrQkFBa0IsRUFBRSxXQUFXLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUV4SCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUUzRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sdUJBQXVCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgdHlwZSB7IENvbWJpbmVkUmVjb3JkZXIgfSBmcm9tICcuL0NvbWJpbmVkUmVjb3JkZXIuanMnO1xuZXhwb3J0IHsgaGFzRW1pdFJlY29yZGVyTWV0aG9kcywgaGFzRmxvd1JlY29yZGVyTWV0aG9kcywgaGFzUmVjb3JkZXJNZXRob2RzLCBpc0Zsb3dFdmVudCB9IGZyb20gJy4vQ29tYmluZWRSZWNvcmRlci5qcyc7XG5leHBvcnQgdHlwZSB7IENvbXBvc2l0ZVNuYXBzaG90IH0gZnJvbSAnLi9Db21wb3NpdGVSZWNvcmRlci5qcyc7XG5leHBvcnQgeyBDb21wb3NpdGVSZWNvcmRlciB9IGZyb20gJy4vQ29tcG9zaXRlUmVjb3JkZXIuanMnO1xuZXhwb3J0IHR5cGUgeyBFbWl0RXZlbnQsIEVtaXRSZWNvcmRlciB9IGZyb20gJy4vRW1pdFJlY29yZGVyLmpzJztcbmV4cG9ydCB7IEtleWVkUmVjb3JkZXIgfSBmcm9tICcuL0tleWVkUmVjb3JkZXIuanMnO1xuZXhwb3J0IHsgUmVjb3JkZXJPcGVyYXRpb24gfSBmcm9tICcuL1JlY29yZGVyT3BlcmF0aW9uLmpzJztcbmV4cG9ydCB7IFNlcXVlbmNlUmVjb3JkZXIgfSBmcm9tICcuL1NlcXVlbmNlUmVjb3JkZXIuanMnO1xuIl19