footprintjs 6.1.0 → 6.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -16,7 +16,7 @@ src/lib/
16
16
  ├── scope/ → Per-stage facades + recorders + providers
17
17
  ├── reactive/ → TypedScope<T> deep Proxy (typed property access, $-methods, cycle-safe)
18
18
  ├── decide/ → decide()/select() decision evidence capture (filter + function)
19
- ├── recorder/ → CompositeRecorder, KeyedRecorder<T>, SequenceRecorder<T>, BoundaryStateTracker<TState>, composition primitives
19
+ ├── recorder/ → CompositeRecorder, KeyedStore<T>, SequenceStore<T>, BoundaryStateStore<TState>, composition primitives
20
20
  ├── pause/ → Pause/Resume (PauseSignal, FlowchartCheckpoint, PausableHandler)
21
21
  ├── engine/ → DFS traversal + narrative + 13 handlers
22
22
  ├── runner/ → High-level executor (FlowChartExecutor)
@@ -27,7 +27,7 @@ Dependency DAG: `memory <- scope <- reactive <- engine <- runner`, `schema <- en
27
27
 
28
28
  Three entry points:
29
29
  - `import { ... } from 'footprintjs'` — public API
30
- - `import { ... } from 'footprintjs/trace'` — execution tracing: runtimeStageId, commitLog queries, KeyedRecorder, SequenceRecorder, BoundaryStateTracker
30
+ - `import { ... } from 'footprintjs/trace'` — execution tracing: runtimeStageId, commitLog queries, storage primitives (KeyedStore, SequenceStore, BoundaryStateStore)
31
31
  - `import { ... } from 'footprintjs/advanced'` — engine internals (also re-exports trace)
32
32
 
33
33
  ## Key API
@@ -120,7 +120,7 @@ scope.getEnv() // frozen execution environment (NOT tracked)
120
120
  ```typescript
121
121
  const executor = new FlowChartExecutor(chart);
122
122
  // With options (preferred over positional params):
123
- const executor = new FlowChartExecutor(chart, { scopeFactory: myFactory, enrichSnapshots: true });
123
+ const executor = new FlowChartExecutor(chart, { scopeFactory: myFactory });
124
124
  await executor.run({ input: data, env: { traceId: 'req-123' } });
125
125
 
126
126
  executor.attachRecorder(recorder) // plug scope observer
@@ -187,9 +187,9 @@ const subtree = getSubtreeSnapshot(snapshot, 'sf-payment');
187
187
  listSubflowPaths(snapshot); // ['sf-payment', 'sf-outer/sf-inner']
188
188
  ```
189
189
 
190
- ## Two Observer Systems
190
+ ## Observer Channels
191
191
 
192
- Both use `{ id, hooks } -> dispatcher -> error isolation -> attach/detach`. Intentionally NOT unified.
192
+ Four pluggable observer channels — three fire at runtime (Scope, Flow, Emit) and one fires at build time (Structure). All share `{ id, hooks } -> dispatcher -> error isolation -> attach/detach`. A recorder is routed to channels by runtime duck-typing of its `on*` methods. Intentionally NOT unified into one interface — each channel has a distinct invariant set.
193
193
 
194
194
  **Recorder ID contract:**
195
195
  - `attachRecorder` is **idempotent by ID** — same ID replaces, different IDs coexist. Prevents accidental double-counting.
@@ -201,22 +201,31 @@ Both use `{ id, hooks } -> dispatcher -> error isolation -> attach/detach`. Inte
201
201
  - Built-in: `MetricRecorder`, `DebugRecorder`
202
202
 
203
203
  **FlowRecorder** (control flow — fires AFTER stage execution):
204
- - `onStageExecuted`, `onNext`, `onDecision`, `onFork`, `onSelected`, `onSubflowEntry/Exit`, `onLoop`, `onBreak`, `onError`
205
- - All events carry `traversalContext: TraversalContext`
204
+ - `onStageExecuted` (universal "did this stage run", carries `stageType: 'linear' | 'decider' | 'fork' | 'selector' | 'subflow-mount'`), `onNext`, `onDecision`, `onFork`, `onSelected`, `onSubflowEntry/Exit`, `onSubflowRegistered`, `onLoop`, `onBreak`, `onError`, `onPause`/`onResume`, `onRunStart`/`onRunEnd`, `onRunFailed`
205
+ - All events carry `traversalContext: TraversalContext` (includes per-run `runId`)
206
206
  - `onDecision`/`onSelected` carry optional `evidence` from decide()/select()
207
207
  - Built-in: 8 strategies (Narrative, Adaptive, Windowed, RLE, Milestone, Progressive, Separate, Manifest, Silent)
208
208
 
209
- **CombinedNarrativeRecorder** implements BOTH interfaces. Attached via `executor.recorder(narrative())` at runtime.
209
+ **Emit Recorder** (consumer-emitted events fired by `scope.$emit(name, payload)`):
210
+ - `onEmit(EmitEvent)` — see the "Emit Channel" section below.
211
+
212
+ **Structure Recorder** (build-time chart shape — fires SYNCHRONOUSLY during builder operations, NOT runtime):
213
+ - `onStageAdded`, `onEdgeAdded`, `onLoopEdgeAdded`, `onDeciderComplete`, `onSubflowMounted`
214
+ - Attach via options bag — `flowChart('seed', fn, 'seed', { structureRecorders: [rec] })` — or fluent `.attachStructureRecorder(rec)`. MOUNT-ONLY: a builder's recorder sees only that builder's events; subflow internals arrive via the mount event's `subflowSpec` (walk with `walkSubflowSpec` from `footprintjs/trace`). Exported from the main `footprintjs` barrel.
215
+
216
+ **CombinedNarrativeRecorder** implements the Scope + Flow + Emit interfaces. Attached via `chart.recorder(narrative())` (fluent) or `executor.attachCombinedRecorder(narrative())` / `executor.enableNarrative()` at runtime.
210
217
 
211
218
  ## Event Ordering
212
219
 
213
220
  ```
221
+ 0. FlowRecorder.onRunStart — once per executor.run(), carries the run input
214
222
  1. Recorder.onStageStart — stage begins
215
223
  2. Recorder.onRead/onWrite — DURING execution (buffered per-stage)
216
224
  3. Recorder.onCommit — transaction flush
217
225
  4. Recorder.onStageEnd — stage completes
218
- 5. FlowRecorder.onStageExecuted — CombinedNarrativeRecorder flushes buffered ops
219
- 6. FlowRecorder.onNext/onDecision/onFork — control flow continues
226
+ 5. FlowRecorder.onStageExecuted — universal "stage ran" (stageType discriminator); CombinedNarrativeRecorder flushes buffered ops for LINEAR stages here
227
+ 6. FlowRecorder.onNext/onDecision/onFork/onSelected — control flow continues (non-linear onStageExecuted fires AFTER its specialized event)
228
+ 7. FlowRecorder.onRunEnd (clean) or onRunFailed (error) — once per run, closes the boundary symmetrically
220
229
  ```
221
230
 
222
231
  ## Execution Tracing (`footprintjs/trace`)
@@ -266,9 +275,13 @@ const llmCommit = findCommit(commitLog, 'call-llm', 'adapterRawResponse');
266
275
  | `findCommit(commitLog, stageId, key?)` | `CommitBundle \| undefined` | Find first commit by stageId |
267
276
  | `findCommits(commitLog, stageId)` | `CommitBundle[]` | Find all commits by stageId |
268
277
  | `findLastWriter(commitLog, key, beforeIdx?)` | `CommitBundle \| undefined` | Search backwards for who wrote a key |
269
- | `KeyedRecorder<T>` | abstract class | Base for 1:1 Map-based recorders (durable) |
270
- | `SequenceRecorder<T>` | abstract class | Base for 1:N ordered sequence recorders (durable; has `getEntryRanges()` for O(1) time-travel) |
271
- | `BoundaryStateTracker<TState>` | abstract class | Base for transient bracket-scoped state live state DURING a `[start, stop]` interval; clears on stop. O(1) reads via `getActive` / `hasActive` / `activeCount`. Subclass calls `startBoundary` / `updateBoundary` / `stopBoundary` from observer hooks. |
278
+ | `splitStageId(prefixedId)` | `{ localStageId, subflowPath }` | Decompose a bare prefixed id (`spec.id`, `CommitBundle.stageId`) |
279
+ | `walkSubflowSpec(spec, subflowPath, opts?)` | `Generator<WalkerItem>` | Walk a subflow spec from `StructureSubflowMountedEvent.subflowSpec` |
280
+ | `KeyedStore<T>` | class (v5 primary) | Storage shelf for 1:1 Map keyed by runtimeStageId (`set`/`get`/`aggregate`/`accumulate`/`filterByKeys`) |
281
+ | `SequenceStore<T>` | class (v5 primary) | Storage shelf for 1:N ordered entries (`push`/`getByKey`/`getEntryRanges()` for O(1) time-travel/`getEntriesUpTo`) |
282
+ | `BoundaryStateStore<TState>` | class (v5 primary) | Storage shelf for transient bracket-scoped state — live state DURING a `[start, stop]` interval; clears on stop. O(1) reads via `get` / `hasActive` / `activeCount`; lifecycle via `start` / `update` / `stop`. |
283
+ | `KeyedRecorder<T>` / `SequenceRecorder<T>` / `BoundaryStateTracker<TState>` | abstract bases — **DEPRECATED** | v5 migration window only, slated for removal. Superseded by the `*Store` classes above — new code MUST own a store as a field and implement the channel interface itself. |
284
+ | `CommitRangeIndex<TLabel>` | class | Interval index over commit indices (`open`/`close`/`enclosing`/`overlapping`) |
272
285
  | `topologyRecorder()` / `TopologyRecorder` | factory / class | Live composition graph for streaming consumers (subflow nodes + control-flow edges) |
273
286
  | `inOutRecorder()` / `InOutRecorder` | factory / class | Chart in/out stream — `entry`/`exit` pairs at every chart boundary (top-level run + every subflow) |
274
287
 
@@ -422,56 +435,54 @@ inOut.getEntryRanges(); // O(1) per-step range index for time-trave
422
435
 
423
436
  Example: [examples/runtime-features/flow-recorder/07-inout.ts](examples/runtime-features/flow-recorder/07-inout.ts)
424
437
 
425
- **Three recorder storage primitives** — choose based on data shape and durability:
438
+ **Three recorder STORAGE PRIMITIVES (v5 primary API)** — "one purpose per recorder": a store is storage ONLY. You own one as a field and implement the channel interface (`ScopeRecorder` / `FlowRecorder` / `EmitRecorder` / `CombinedRecorder`) yourself, delegating storage to the store. The abstract base classes (`KeyedRecorder` / `SequenceRecorder` / `BoundaryStateTracker`) are DEPRECATED — they exist only for the v5 migration window and are slated for removal. Choose a store by data shape and durability:
426
439
 
427
- | Base Class | Relationship | Time scope | Use When |
440
+ | Store | Relationship | Time scope | Use When |
428
441
  |------------|-------------|------------|----------|
429
- | `KeyedRecorder<T>` | 1:1 Map | durable | Each step produces one record (MetricRecorder, TokenRecorder) |
430
- | `SequenceRecorder<T>` | 1:N sequence + Map | durable | Multiple records per step, ordering matters (CombinedNarrativeRecorder) |
431
- | `BoundaryStateTracker<TState>` | Map\<key, TState\> active stack | transient — clears on stop | Live state DURING a `[start, stop]` bracket (LLM stream partial, tool args streaming) |
432
-
433
- A real recorder picks ONE observer interface AND ONE storage shelf, combining via `extends + implements`. Existing example: `BoundaryRecorder extends SequenceRecorder<DomainEvent> implements CombinedRecorder`.
442
+ | `KeyedStore<T>` | 1:1 Map | durable | Each step produces one record (token totals per step) |
443
+ | `SequenceStore<T>` | 1:N sequence + Map | durable | Multiple records per step, ordering matters (narrative, audit) |
444
+ | `BoundaryStateStore<TState>` | Map\<key, TState\> active bracket | transient — clears on stop | Live state DURING a `[start, stop]` bracket (LLM stream partial, tool args streaming) |
434
445
 
435
446
  ```typescript
436
- import { KeyedRecorder, SequenceRecorder } from 'footprintjs/trace';
447
+ import { KeyedStore, SequenceStore, BoundaryStateStore } from 'footprintjs/trace';
448
+ import type { FlowRecorder, EmitRecorder } from 'footprintjs';
437
449
 
438
- // KeyedRecorder: one entry per step
439
- class TokenRecorder extends KeyedRecorder<TokenEntry> {
450
+ // KeyedStore: one entry per step. Own the store; implement the channel.
451
+ class TokenRecorder implements FlowRecorder {
440
452
  readonly id = 'tokens';
441
- onLLMCall(event) { this.store(event.runtimeStageId, { tokens: event.usage }); }
453
+ private store = new KeyedStore<{ tokens: number }>();
454
+ onStageExecuted(e) { this.store.set(e.traversalContext.runtimeStageId, { tokens: 0 }); }
455
+ byStep(rid: string) { return this.store.get(rid); } // Translate: per-step value
456
+ total() { return this.store.aggregate((sum, e) => sum + e.tokens, 0); } // Aggregate: grand total
457
+ upTo(keys: ReadonlySet<string>) { // Accumulate: up to slider
458
+ return this.store.accumulate((sum, e) => sum + e.tokens, 0, keys);
459
+ }
442
460
  }
443
- recorder.getByKey('call-llm#5'); // Translate: per-step value
444
- recorder.aggregate((sum, e) => sum + e.tokens, 0); // Aggregate: grand total
445
- recorder.accumulate((sum, e) => sum + e.tokens, 0, visibleKeys); // Accumulate: up to slider
446
461
 
447
- // SequenceRecorder: multiple entries per step, ordered
448
- class AuditRecorder extends SequenceRecorder<AuditEntry> {
462
+ // SequenceStore: multiple entries per step, ordered.
463
+ class AuditRecorder implements FlowRecorder {
449
464
  readonly id = 'audit';
450
- onRead(event) { this.emit({ runtimeStageId: event.runtimeStageId, type: 'read', key: event.key }); }
451
- onDecision(event) { this.emit({ runtimeStageId: event.traversalContext?.runtimeStageId, ... }); }
465
+ private store = new SequenceStore<{ runtimeStageId: string; type: string }>();
466
+ onDecision(e) { this.store.push({ runtimeStageId: e.traversalContext?.runtimeStageId, type: 'decision' }); }
467
+ forStep(rid: string) { return this.store.getByKey(rid); } // Translate: per-step entries
468
+ upTo(keys: ReadonlySet<string>) { return this.store.getEntriesUpTo(keys); } // Progressive: up to slider
469
+ ranges() { return this.store.getEntryRanges(); } // Range index: O(1) slider sync
452
470
  }
453
- recorder.getEntriesForStep('call-llm#5'); // Translate: per-step entries
454
- recorder.aggregate((count, _) => count + 1, 0); // Aggregate: grand total
455
- recorder.getEntriesUpTo(visibleKeys); // Progressive: up to slider
456
- recorder.getEntryRanges(); // Range index: O(1) slider sync
457
-
458
- // BoundaryStateTracker: transient state DURING a bracket; clears on stop
459
- class LiveLLMTracker extends BoundaryStateTracker<{ partial: string; tokens: number }>
460
- implements EmitRecorder
461
- {
471
+
472
+ // BoundaryStateStore: transient state DURING a bracket; clears on stop.
473
+ class LiveLLMTracker implements EmitRecorder {
462
474
  readonly id = 'live-llm';
475
+ private store = new BoundaryStateStore<{ partial: string; tokens: number }>();
463
476
  onEmit(e) {
464
- if (e.name === 'llm.start') this.startBoundary(e.runtimeStageId, { partial: '', tokens: 0 });
465
- if (e.name === 'llm.token') this.updateBoundary(e.runtimeStageId, s => ({ partial: s.partial + e.payload.content, tokens: s.tokens + 1 }));
466
- if (e.name === 'llm.end') this.stopBoundary(e.runtimeStageId);
477
+ if (e.name === 'llm.start') this.store.start(e.runtimeStageId, { partial: '', tokens: 0 });
478
+ if (e.name === 'llm.token') this.store.update(e.runtimeStageId, s => ({ partial: s.partial + e.payload.content, tokens: s.tokens + 1 }));
479
+ if (e.name === 'llm.end') this.store.stop(e.runtimeStageId);
467
480
  }
468
- isInFlight(): boolean { return this.hasActive; }
469
- getPartial(rid: string): string { return this.getActive(rid)?.partial ?? ''; }
481
+ isInFlight() { return this.store.hasActive; } // O(1) — live read
482
+ getPartial(rid: string) { return this.store.get(rid)?.partial ?? ''; } // O(1) — current state of one boundary
483
+ concurrent() { return this.store.activeCount; } // O(1) — how many concurrent boundaries
470
484
  }
471
- tracker.isInFlight(); // O(1) live read
472
- tracker.getActive(rid); // O(1) — current state of one boundary
473
- tracker.activeCount; // O(1) — how many concurrent boundaries
474
- // Lifecycle: clear() between runs; dev-mode warns on leaked-stop bugs.
485
+ // Lifecycle: call store.clear() between runs; dev-mode warns on leaked-stop bugs.
475
486
  ```
476
487
 
477
488
  **`getEntryRanges()`** returns a precomputed `Map<runtimeStageId, {firstIdx, endIdx}>` maintained during `emit()`. Use for O(1) per-step range lookups during time-travel scrubbing. Same shape as `buildEntryRangeIndex()` in `footprint-explainable-ui`.
package/CLAUDE.md CHANGED
@@ -16,7 +16,7 @@ src/lib/
16
16
  ├── scope/ → Per-stage facades + recorders + providers
17
17
  ├── reactive/ → TypedScope<T> deep Proxy (typed property access, $-methods, cycle-safe)
18
18
  ├── decide/ → decide()/select() decision evidence capture (filter + function)
19
- ├── recorder/ → CompositeRecorder, KeyedRecorder<T>, SequenceRecorder<T>, composition primitives
19
+ ├── recorder/ → CompositeRecorder, stores (KeyedStore/SequenceStore/BoundaryStateStore), CommitRangeIndex, composition primitives
20
20
  ├── pause/ → Pause/Resume (PauseSignal, FlowchartCheckpoint, PausableHandler)
21
21
  ├── engine/ → DFS traversal + narrative + 13 handlers
22
22
  ├── runner/ → High-level executor (FlowChartExecutor)
@@ -27,7 +27,7 @@ Dependency DAG: `memory <- scope <- reactive <- engine <- runner`, `schema <- en
27
27
 
28
28
  Three entry points:
29
29
  - `import { ... } from 'footprintjs'` — public API
30
- - `import { ... } from 'footprintjs/trace'` — execution tracing: runtimeStageId, commitLog queries, KeyedRecorder, SequenceRecorder
30
+ - `import { ... } from 'footprintjs/trace'` — execution tracing: runtimeStageId, commitLog queries, causal chain, recorder stores (`KeyedStore`/`SequenceStore`/`BoundaryStateStore`), `CommitRangeIndex`, `TopologyRecorder`/`InOutRecorder`/`QualityRecorder`
31
31
  - `import { ... } from 'footprintjs/advanced'` — engine internals (also re-exports trace)
32
32
 
33
33
  ## Key API
@@ -89,7 +89,7 @@ import { decide, select } from 'footprintjs';
89
89
  ```typescript
90
90
  import { flowChart, FlowChartBuilder } from 'footprintjs';
91
91
 
92
- const chart = flowChart('Stage1', fn1, 'stage-1', undefined, 'Description')
92
+ const chart = flowChart('Stage1', fn1, 'stage-1', { description: 'Description' })
93
93
  .addFunction('Stage2', fn2, 'stage-2', 'Description')
94
94
  .addDeciderFunction('Decide', deciderFn, 'decide', 'Route based on risk')
95
95
  .addFunctionBranch('high', 'Reject', rejectFn)
@@ -123,13 +123,14 @@ const executor = new FlowChartExecutor(chart);
123
123
  const executor = new FlowChartExecutor(chart, { scopeFactory: myFactory });
124
124
  await executor.run({ input: data, env: { traceId: 'req-123' } });
125
125
 
126
- executor.attachRecorder(recorder) // plug scope observer
127
- executor.getNarrative() // combined flow + data narrative
128
- executor.getNarrativeEntries() // structured entries with type/depth/stageName/stageId
129
- executor.getFlowNarrative() // flow-only (no data ops)
130
- executor.getSnapshot() // full memory state (includes recorder snapshots)
131
- executor.attachFlowRecorder(r) // plug flow observer
132
- executor.setRedactionPolicy({}) // PII protection
126
+ executor.attachScopeRecorder(recorder) // plug scope (data) observer
127
+ executor.attachFlowRecorder(r) // plug flow observer
128
+ executor.attachCombinedRecorder(r) // plug observer across all channels (routed by method-shape)
129
+ executor.attachEmitRecorder(r) // plug emit observer
130
+ executor.enableNarrative() // turn on the built-in combined narrative recorder
131
+ executor.getNarrativeEntries() // structured entries with type/depth/stageName/stageId
132
+ executor.getSnapshot() // full memory state (includes recorder snapshots)
133
+ executor.setRedactionPolicy({}) // PII protection
133
134
 
134
135
  // Pause/Resume — human-in-the-loop
135
136
  executor.isPaused() // true if last run paused
@@ -174,7 +175,7 @@ if (executor.isPaused()) {
174
175
 
175
176
  - `execute` returns data → pauses. Returns void → continues normally (conditional pause).
176
177
  - Checkpoint is JSON-serializable — no functions, no class instances.
177
- - `resume()` reuses the execution runtime — narrative, metrics, execution tree all accumulate.
178
+ - `resume()` resets narrative/recorder statecollect any narrative you need from the paused run BEFORE resuming. A fresh `runId` is generated for the resumed run.
178
179
  - `FlowRecorder.onPause`/`onResume` and `Recorder.onPause`/`onResume` fire on both observer systems.
179
180
 
180
181
  ### ComposableRunner & Snapshot Navigation
@@ -195,20 +196,20 @@ Intentionally NOT unified into one giant interface — each channel has
195
196
  a distinct invariant set.
196
197
 
197
198
  **Recorder ID contract:**
198
- - `attachRecorder` is **idempotent by ID** — same ID replaces, different IDs coexist. Prevents accidental double-counting.
199
+ - Every `attach*Recorder` call (`attachScopeRecorder` / `attachFlowRecorder` / `attachEmitRecorder` / `attachCombinedRecorder`) is **idempotent by ID** — same ID replaces, different IDs coexist. Prevents accidental double-counting.
199
200
  - Built-in recorders use auto-increment default IDs (`metrics-1`, `debug-1`, ...) so multiple instances with different configs coexist naturally.
200
201
  - Frameworks that auto-attach recorders should use a well-known ID (e.g., `new MetricRecorder('metrics')`) so the consumer can override it by passing the same ID, or add a second instance with `new MetricRecorder()` (gets unique ID).
201
202
 
202
- **Scope Recorder** (data ops — fires DURING stage execution):
203
- - `onRead`, `onWrite`, `onCommit`, `onError`, `onStageStart`, `onStageEnd`
203
+ **Scope Recorder** (`ScopeRecorder`; data ops — fires DURING stage execution):
204
+ - `onRead`, `onWrite`, `onCommit`, `onError`, `onStageStart`, `onStageEnd`, `onPause`/`onResume`, `onEmit`
204
205
  - Built-in: `MetricRecorder`, `DebugRecorder`
205
206
 
206
207
  **FlowRecorder** (control flow — fires AFTER stage execution):
207
- - `onStageExecuted`, `onNext`, `onDecision`, `onFork`, `onSelected`, `onSubflowEntry/Exit`, `onLoop`, `onBreak`, `onError`, `onPause`/`onResume`, `onRunStart`/`onRunEnd`
208
+ - `onStageExecuted`, `onNext`, `onDecision`, `onFork`, `onSelected`, `onSubflowEntry/Exit`, `onSubflowRegistered`, `onLoop`, `onBreak`, `onError`, `onPause`/`onResume`, `onRunStart`/`onRunEnd`, `onRunFailed` (terminal counterpart to `onRunEnd` — closes the run boundary on error)
208
209
  - All events carry `traversalContext: TraversalContext`
209
210
  - `onDecision`/`onSelected` carry optional `evidence` from decide()/select()
210
211
  - **`onStageExecuted` fires UNIFORMLY for every stage kind** (linear / decider / fork / selector / subflow-mount) as of v6.0+ proposal #003. Event payload carries `stageType: 'linear' | 'decider' | 'fork' | 'selector' | 'subflow-mount'`. Specialized events (`onDecision`/`onFork`/`onSelected`/`onSubflowEntry`) STILL fire — `onStageExecuted` is the universal "did this stage run" signal AFTER them.
211
- - Built-in: 8 strategies (Narrative, Adaptive, Windowed, RLE, Milestone, Progressive, Separate, Manifest, Silent)
212
+ - Built-in: 9 strategies (Narrative, Adaptive, Windowed, RLE, Milestone, Progressive, Separate, Manifest, Silent)
212
213
 
213
214
  **StructureRecorder** (build-time chart shape — fires SYNCHRONOUSLY during builder operations, NOT runtime):
214
215
  - `onStageAdded`, `onEdgeAdded`, `onLoopEdgeAdded`, `onDeciderComplete`, `onSubflowMounted`
@@ -218,7 +219,7 @@ a distinct invariant set.
218
219
 
219
220
  **EmitRecorder** (consumer-emitted events — third channel, see "Emit Channel" section below).
220
221
 
221
- **CombinedRecorder** is a union shape that routes by runtime method-shape detection — implement only the hooks you care about across all three channels; one `attachCombinedRecorder` call. `CombinedNarrativeRecorder` is the canonical built-in; attach via `executor.recorder(narrative())`.
222
+ **CombinedRecorder** is a union shape that routes by runtime method-shape detection — implement only the hooks you care about across all three channels; one `attachCombinedRecorder` call. `CombinedNarrativeRecorder` is the canonical built-in; attach via `chart.recorder(narrative())` (the chart's `.recorder()` sugar) or `executor.attachCombinedRecorder(narrative())`.
222
223
 
223
224
  **Stage type discrimination on `onStageExecuted`** — under proposal #003, consumers wanting linear-only behavior must filter:
224
225
  ```ts
@@ -290,10 +291,15 @@ const llmCommit = findCommit(commitLog, 'call-llm', 'adapterRawResponse');
290
291
  | `findCommit(commitLog, stageId, key?)` | `CommitBundle \| undefined` | Find first commit by stageId |
291
292
  | `findCommits(commitLog, stageId)` | `CommitBundle[]` | Find all commits by stageId |
292
293
  | `findLastWriter(commitLog, key, beforeIdx?)` | `CommitBundle \| undefined` | Search backwards for who wrote a key |
293
- | `KeyedRecorder<T>` | abstract class | Base for 1:1 Map-based recorders |
294
- | `SequenceRecorder<T>` | abstract class | Base for 1:N ordered sequence recorders (has `getEntryRanges()` for O(1) time-travel) |
294
+ | `causalChain` / `flattenCausalDAG` / `formatCausalChain` | functions | Backward program slicing over the commit-log DAG |
295
+ | `KeyedStore<T>` | class | **Primary** 1:1 Map store own as a field on your recorder |
296
+ | `SequenceStore<T>` | class | **Primary** 1:N ordered store (has `getEntryRanges()` for O(1) time-travel) |
297
+ | `BoundaryStateStore<T>` | class | **Primary** transient bracket-scoped state store |
298
+ | `CommitRangeIndex<TLabel>` | class | Interval index over commit indices (`open`/`close`/`enclosing`/`overlapping`) |
299
+ | `KeyedRecorder<T>` / `SequenceRecorder<T>` / `BoundaryStateTracker<T>` | abstract classes (DEPRECATED) | Legacy bases — migrate to the stores above |
295
300
  | `topologyRecorder()` / `TopologyRecorder` | factory / class | Live composition graph for streaming consumers (subflow nodes + control-flow edges) |
296
301
  | `inOutRecorder()` / `InOutRecorder` | factory / class | Chart in/out stream — `entry`/`exit` pairs at every chart boundary (top-level run + every subflow) |
302
+ | `QualityRecorder` + `qualityTrace`/`formatQualityTrace` | class / functions | Per-step quality scoring + Quality Stack Trace backtracking |
297
303
 
298
304
  ### TopologyRecorder — Composition Graph for Streaming Consumers
299
305
 
@@ -445,12 +451,13 @@ inOut.getEntryRanges(); // O(1) per-step range index for time-trave
445
451
 
446
452
  Example: [examples/runtime-features/flow-recorder/07-inout.ts](examples/runtime-features/flow-recorder/07-inout.ts)
447
453
 
448
- **Two recorder base classes** — choose based on data shape:
454
+ **Two recorder base classes (DEPRECATED — v5 migration window, slated for removal)** — choose based on data shape. New code MUST use the v5 stores instead (own a `KeyedStore<T>` / `SequenceStore<T>` / `BoundaryStateStore<T>` field and implement the channel interface yourself — see "Project conventions" Convention 1). These bases are kept only for downstream consumers that still extend them:
449
455
 
450
- | Base Class | Relationship | Use When |
451
- |------------|-------------|----------|
452
- | `KeyedRecorder<T>` | 1:1 Map | Each step produces one record (MetricRecorder, TokenRecorder) |
453
- | `SequenceRecorder<T>` | 1:N sequence + Map | Multiple records per step, ordering matters (CombinedNarrativeRecorder) |
456
+ | Base Class | Store replacement | Relationship | Use When |
457
+ |------------|-------------------|-------------|----------|
458
+ | `KeyedRecorder<T>` | `KeyedStore<T>` | 1:1 Map | Each step produces one record (MetricRecorder, TokenRecorder) |
459
+ | `SequenceRecorder<T>` | `SequenceStore<T>` | 1:N sequence + Map | Multiple records per step, ordering matters (CombinedNarrativeRecorder) |
460
+ | `BoundaryStateTracker<T>` | `BoundaryStateStore<T>` | bracket-scoped state | Live transient state during a `[start, stop]` event interval |
454
461
 
455
462
  ```typescript
456
463
  import { KeyedRecorder, SequenceRecorder } from 'footprintjs/trace';
@@ -670,7 +677,7 @@ const audit: CombinedRecorder = {
670
677
  executor.attachCombinedRecorder(audit);
671
678
  ```
672
679
 
673
- Built on `CombinedRecorder`: `CombinedNarrativeRecorder` (the `executor.enableNarrative()` default). Consumers implement ONLY the events they care about — `Partial<Recorder> & Partial<FlowRecorder>` under the hood.
680
+ Built on `CombinedRecorder`: `CombinedNarrativeRecorder` (the `executor.enableNarrative()` default). Consumers implement ONLY the events they care about — `Partial<ScopeRecorder> & Partial<FlowRecorder> & Partial<EmitRecorder>` under the hood.
674
681
 
675
682
  **Detection rule:** only OWN event-method properties count (prototype methods are ignored for security — prevents accidental `Object.prototype` pollution from attaching handlers).
676
683
 
@@ -683,7 +690,7 @@ Built on `CombinedRecorder`: `CombinedNarrativeRecorder` (the `executor.enableNa
683
690
  - Don't extract shared base for ScopeRecorder/FlowRecorder — two instances = coincidence
684
691
  - Don't use `getArgs()` for tracked data — use typed scope properties
685
692
  - Don't put infrastructure data in `getArgs()` — use `getEnv()` via `run({ env })`
686
- - Don't manually create `CombinedNarrativeRecorder` — `executor.recorder(narrative())` handles it
693
+ - Don't manually create `CombinedNarrativeRecorder` — `chart.recorder(narrative())` (or `executor.attachCombinedRecorder(narrative())`) handles it
687
694
  - Don't return full arrays from `outputMapper` without `arrayMerge: ArrayMergeMode.Replace` — default `applyOutputMapping` **concatenates** arrays (`[...parent, ...subflow]`). Either return only the **delta** (new items), or set `arrayMerge: ArrayMergeMode.Replace` on `SubflowMountOptions` to overwrite instead of concatenate. Scalars are always replaced regardless.
688
695
 
689
696
  ## Project conventions (5.0+)
package/README.md CHANGED
@@ -9,6 +9,8 @@
9
9
  <a href="https://github.com/footprintjs/footPrint/actions"><img src="https://github.com/footprintjs/footPrint/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
10
10
  <!-- coverage-badge --><img src="https://img.shields.io/badge/coverage-93%25-brightgreen.svg" alt="coverage: 93%"><!-- /coverage-badge -->
11
11
  <a href="https://www.npmjs.com/package/footprintjs"><img src="https://img.shields.io/npm/v/footprintjs.svg?style=flat" alt="npm version"></a>
12
+ <a href="https://bundlephobia.com/package/footprintjs"><img src="https://img.shields.io/bundlephobia/minzip/footprintjs?label=minzipped" alt="minzipped size"></a>
13
+ <a href="#tree-shakeable--esm-first"><img src="https://img.shields.io/badge/tree--shakeable-%E2%9C%93-success?style=flat" alt="tree-shakeable"></a>
12
14
  <a href="https://github.com/footprintjs/footPrint/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"></a>
13
15
  <a href="https://www.npmjs.com/package/footprintjs"><img src="https://img.shields.io/npm/dm/footprintjs.svg" alt="Downloads"></a>
14
16
  <a href="https://footprintjs.github.io/footprint-playground/samples/llm-agent-tool"><img src="https://img.shields.io/badge/Try_with_LLM-Live_Demo-7c6cf0?style=flat" alt="Try with LLM"></a>
@@ -166,7 +168,24 @@ The LLM calls the tool, gets back the decision and causal trace, and explains th
166
168
  | **Subflow break propagation** | Mount a subflow with `propagateBreak: true` &mdash; inner `$break` terminates the parent loop, with drill-down preserved |
167
169
  | **Emit channel** | `scope.$emit(name, payload)` &mdash; user-authored structured events to `EmitRecorder`, pass-through, zero-allocation when no recorder attached, redactable via `emitPatterns` |
168
170
  | **Detach** *(new in 4.17)* | `scope.$detachAndForget(driver, child, input)` and `scope.$detachAndJoinLater(driver, child, input)` &mdash; fire-and-forget child flowcharts via the `footprintjs/detach` subpath. Six built-in drivers (microtask / immediate / setImmediate / setTimeout / sendBeacon / workerThread) + custom-driver protocol. Builder-native composition (`addDetachAndForget` / `addDetachAndJoinLater`) makes detach a labeled chart stage. `flushAllDetached()` for graceful shutdown. [Guide →](https://footprintjs.github.io/footPrint/guides/patterns/detach/) |
169
- | **Boundary state tracking** *(new in 4.17.2)* | `BoundaryStateTracker<TState>` &mdash; third storage primitive on the recorder shelf alongside `SequenceRecorder<T>` (durable ordered) and `KeyedRecorder<T>` (durable 1:1). Tracks live transient state DURING a `[start, stop]` event interval (LLM stream partial, tool args streaming, agent turn state) and clears on stop. O(1) reads via `getActive` / `hasActive` / `activeCount`. Mental model: existing recorder *interfaces* are observers; storage primitives are *bookkeeping shelves*. A real recorder picks ONE observer interface AND ONE storage shelf via `extends + implements`. [Guide →](https://footprintjs.github.io/footPrint/guides/features/recorder-storage-primitives/) |
171
+ | **Recorder storage primitives** | `BoundaryStateStore<TState>` &mdash; one of three composable storage shelves alongside `SequenceStore<T>` (durable ordered, with `getEntryRanges()`) and `KeyedStore<T>` (durable 1:1). `BoundaryStateStore` tracks live transient state DURING a `[start, stop]` event interval (LLM stream partial, tool args streaming, agent turn state) and clears on stop. O(1) reads via `get` / `hasActive` / `activeCount`. Mental model: recorder *interfaces* (`ScopeRecorder` / `FlowRecorder` / `EmitRecorder`) are observers; stores are *bookkeeping shelves*. A real recorder picks ONE observer interface and OWNS the store as a field (composition &mdash; "one purpose per recorder"). The `Store` classes are exported from `footprintjs/trace`. (Older `KeyedRecorder` / `SequenceRecorder` / `BoundaryStateTracker` abstract bases are deprecated and slated for removal &mdash; use the stores.) [Guide →](https://footprintjs.github.io/footPrint/guides/features/recorder-storage-primitives/) |
172
+
173
+ ---
174
+
175
+ ## Tree-shakeable & ESM-first
176
+
177
+ Import one thing, ship one thing. footprintjs is built so your bundle grows only with what you actually use:
178
+
179
+ - **Dual build, true ESM.** Ships CommonJS (`require`) **and** real ECMAScript Modules (`import`) with TypeScript types. The ESM build is marked `type:module` and every internal import carries an explicit `.js` extension, so it loads as true ESM under Node, Vite, Next, Deno, and Bun — no compatibility shims.
180
+ - **Per-file modules + `sideEffects:false`.** The dist is emitted file-by-file (never pre-bundled) and declares zero side effects, so bundlers can drop every export you don't touch.
181
+ - **Subpath exports.** Pull execution tracing from `footprintjs/trace`, fire-and-forget children from `footprintjs/detach`, engine internals from `footprintjs/advanced` — each is independently tree-shakeable.
182
+
183
+ **Proven, not promised.** A CI smoke test bundles a minimal `import { flowChart } from 'footprintjs'` and asserts the recorder, detach, and trace layers are pruned — your flowchart core doesn't drag them in. See [`test/esm-packaging.test.ts`](test/esm-packaging.test.ts).
184
+
185
+ ```ts
186
+ // Only flowChart? The recorder/detach/trace layers are tree-shaken away.
187
+ import { flowChart } from 'footprintjs';
188
+ ```
170
189
 
171
190
  ---
172
191
 
@@ -34,4 +34,4 @@
34
34
  * - Type-level rejection of `outputMapper` on detach options
35
35
  */
36
36
  export {};
37
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2RldGFjaC90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtDRyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogZGV0YWNoL3R5cGVzLnRzIOKAlCBUeXBlIGRlZmluaXRpb25zIGZvciB0aGUgZmlyZS1hbmQtZm9yZ2V0IHByaW1pdGl2ZS5cbiAqXG4gKiBQYXR0ZXJuOiAgU3RyYXRlZ3kgKyBCcmlkZ2UgKEdvRikuIFNhbWUgc2hhcGUgYXMgY2FjaGUgc3RyYXRlZ2llcyBpblxuICogICAgICAgICAgIGFnZW50Zm9vdHByaW50IHYyLjYg4oCUIE9ORSBpbnRlcmZhY2UsIE4gY29uY3JldGUgZHJpdmVycyxcbiAqICAgICAgICAgICBjb25zdW1lciBwaWNrcyB2aWEgZXhwbGljaXQgaW1wb3J0LlxuICogUm9sZTogICAgIEZvdW5kYXRpb24uIEV2ZXJ5IG90aGVyIGRldGFjaCBmaWxlIGltcG9ydHMgZnJvbSBoZXJlLlxuICogICAgICAgICAgIFRoaXMgaXMgdGhlIGxvY2thYmxlIGNvbnRyYWN0OyBkb3duc3RyZWFtIGZpbGVzIGltcGxlbWVudCBpdC5cbiAqXG4gKiBUd28gc2libGluZyBjb25jZXB0czpcbiAqXG4gKiAgIDEuIGBEZXRhY2hEcml2ZXJgIOKAlCB0aGUgYWxnb3JpdGhtIHRoYXQgZGVjaWRlcyBXSEVOL0hPVyB0aGUgd29yayBydW5zLlxuICogICAgICBTaXggYnVpbHQtaW4gYWxnb3JpdGhtcyBzaGlwIGFzIGFsZ29yaXRobS1uYW1lZCBleHBvcnRzXG4gKiAgICAgIChgbWljcm90YXNrQmF0Y2hEcml2ZXJgLCBgc2V0SW1tZWRpYXRlRHJpdmVyYCwgYHNlbmRCZWFjb25Ecml2ZXJgLFxuICogICAgICBgc2V0VGltZW91dERyaXZlcmAsIGBpbW1lZGlhdGVEcml2ZXJgLCBgd29ya2VyVGhyZWFkRHJpdmVyYCkuXG4gKiAgICAgIENvbnN1bWVycyBjYW4gaW1wbGVtZW50IHRoZWlyIG93biAoQllPUyDigJQgYnJpbmcgeW91ciBvd24gZHJpdmVyKS5cbiAqXG4gKiAgIDIuIGBEZXRhY2hIYW5kbGVgIOKAlCB0aGUgY29uc3VtZXItZmFjaW5nIGhhbmRsZSByZXR1cm5lZCBieVxuICogICAgICBgZGV0YWNoQW5kSm9pbkxhdGVyYC4gRXhwb3NlcyBzdGF0dXMgYXMgUFJPUEVSVElFUyAoc3luYyByZWFkKVxuICogICAgICBhbmQgYHdhaXQoKWAgKFByb21pc2Ug4oCUIG9wdC1pbiBhc3luYyBqb2luKS4gU3R5bGUgMiBmcm9tIHRoZVxuICogICAgICBwYW5lbCByZXZpZXc6IHByb3BlcnRpZXMgZm9yIHN5bmMsIHNpbmdsZSBtZXRob2QgZm9yIGFzeW5jLlxuICpcbiAqIE5hbWluZyBwb2xpY3kgKGxvY2tlZCBmcm9tIG5hbWluZyByZXZpZXcpOlxuICogICAtIFB1YmxpYyBBUEkgdXNlcyBzaW1wbGUgdmVyYnMgLyBwcm9wZXJ0aWVzIChwcm9kdWN0LWVuZ2luZWVyIGZyaWVuZGx5KVxuICogICAtIEludGVybmFsIGNsYXNzIG5hbWVzIENBTiB1c2UgQ1MgdGVybXMgKFNjaGVkdWxlciwgQ29udGludWF0aW9uLCBldGMuKVxuICogICAtIERyaXZlcnMgYXJlIGFsZ29yaXRobS1uYW1lZCAoc2VtYW50aWMgYXQgdGhlIGFsZ29yaXRobSBsZXZlbClcbiAqXG4gKiBMb2NrZWQgZGVzaWduIGRlY2lzaW9ucyAocGFuZWwgcmV2aWV3IGNhcHR1cmVkIGluXG4gKiBgZG9jcy9pbnNwaXJhdGlvbi9kZXRhY2gtcHJpbWl0aXZlLm1kYCk6XG4gKiAgIC0gU3luYyBob3QgcGF0aDsgYXN5bmMgb25seSBhdCBmbHVzaCBib3VuZGFyaWVzXG4gKiAgIC0gRXJyb3JzIOKGkiBjb21taXRMb2cgKyB0eXBlZCBldmVudCwgTkVWRVIgdGhyb3duIHRvIHBhcmVudFxuICogICAtIFNjb3BlIGlzb2xhdGlvbiBiZXR3ZWVuIHBhcmVudCBhbmQgZGV0YWNoZWQgY2hpbGRcbiAqICAgLSBMaWZlY3ljbGUgdGllZCB0byBleGVjdXRvciBkaXNwb3NhbFxuICogICAtIFR5cGUtbGV2ZWwgcmVqZWN0aW9uIG9mIGBvdXRwdXRNYXBwZXJgIG9uIGRldGFjaCBvcHRpb25zXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBGbG93Q2hhcnQgfSBmcm9tICcuLi9idWlsZGVyL3R5cGVzLmpzJztcblxuLy8g4pSA4pSA4pSAIERldGFjaEhhbmRsZSDigJQgd2hhdCB0aGUgY29uc3VtZXIgZ2V0cyBiYWNrIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4vKipcbiAqIFNuYXBzaG90IG9mIGEgZGV0YWNoZWQgaGFuZGxlJ3Mgc3RhdGUuIFJldHVybmVkIGJ5IGBoYW5kbGUucG9sbCgpYFxuICogKHdoZW4gYWRkZWQgaW4gYSBmb2xsb3ctdXA7IHYxIGV4cG9zZXMgcHJvcGVydGllcyBkaXJlY3RseSBvblxuICogYERldGFjaEhhbmRsZWApLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERldGFjaFBvbGxSZXN1bHQge1xuICByZWFkb25seSBzdGF0dXM6IERldGFjaEhhbmRsZVsnc3RhdHVzJ107XG4gIC8qKiBQcmVzZW50IGlmZiBzdGF0dXMgPT09ICdkb25lJy4gKi9cbiAgcmVhZG9ubHkgcmVzdWx0PzogdW5rbm93bjtcbiAgLyoqIFByZXNlbnQgaWZmIHN0YXR1cyA9PT0gJ2ZhaWxlZCcuICovXG4gIHJlYWRvbmx5IGVycm9yPzogRXJyb3I7XG59XG5cbi8qKlxuICogUmVzdWx0IGRlbGl2ZXJlZCB3aGVuIHRoZSBoYW5kbGUncyBgd2FpdCgpYCBQcm9taXNlIHJlc29sdmVzXG4gKiBzdWNjZXNzZnVsbHkgKHN0YXR1cyByZWFjaGVkICdkb25lJykuIFJlamVjdGlvbiBkZWxpdmVycyB0aGVcbiAqIG5hdGl2ZSBgRXJyb3JgIGRpcmVjdGx5IOKAlCBubyB3cmFwcGluZyBzaGFwZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZXRhY2hXYWl0UmVzdWx0IHtcbiAgcmVhZG9ubHkgcmVzdWx0OiB1bmtub3duO1xufVxuXG4vKipcbiAqIEhhbmRsZSByZXR1cm5lZCBieSBgY2hhcnQuZGV0YWNoQW5kSm9pbkxhdGVyKC4uLilgIGFuZFxuICogYGV4ZWN1dG9yLmRldGFjaEFuZEpvaW5MYXRlciguLi4pYC4gRXhwb3NlcyBzdGF0dXMgYXMgUFJPUEVSVElFUyBzb1xuICogc3luYyBhY2Nlc3MgaXMgcHJvcGVydHktcmVhZCAoY2hlYXAsIG5vIGFsbG9jYXRpb24pLiBUaGUgc2luZ2xlXG4gKiBtZXRob2QgYHdhaXQoKWAgcmV0dXJucyBhIFByb21pc2UgZm9yIG9wdC1pbiBhc3luYyBqb2luLlxuICpcbiAqIFRoZSBoYW5kbGUgaXMgKipub3QqKiBQcm9taXNlLXNoYXBlZCAobm8gYC50aGVuKClgKSDigJQgdGhhdCB3b3VsZFxuICogbWFrZSBpdCBhY2NpZGVudGFsbHkgYXdhaXRhYmxlLCBkZWZlYXRpbmcgdGhlIGZpcmUtYW5kLWZvcmdldFxuICogc2VtYW50aWNzLiBUbyBhd2FpdCwgdGhlIGNvbnN1bWVyIG11c3QgY2FsbCBgLndhaXQoKWAgZXhwbGljaXRseS5cbiAqXG4gKiBMaWZlY3ljbGU6XG4gKlxuICogICBxdWV1ZWQgIOKGkiBkcml2ZXIgcmVjZWl2ZWQgdGhlIHdvcmssIGhhc24ndCBzdGFydGVkIGl0XG4gKiAgIHJ1bm5pbmcg4oaSIGRyaXZlciBzdGFydGVkIHRoZSB3b3JrXG4gKiAgIGRvbmUgICAg4oaSIHRlcm1pbmFsOiByZXN1bHQgYXZhaWxhYmxlXG4gKiAgIGZhaWxlZCAg4oaSIHRlcm1pbmFsOiBlcnJvciBhdmFpbGFibGVcbiAqXG4gKiBgZG9uZWAgYW5kIGBmYWlsZWRgIGFyZSBURVJNSU5BTCDigJQgb25jZSByZWFjaGVkLCBzdGF0dXMgbmV2ZXJcbiAqIGNoYW5nZXMgYWdhaW4uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGV0YWNoSGFuZGxlIHtcbiAgLyoqIFN0YWJsZSBpZCBhc3NpZ25lZCBhdCBkZXRhY2ggdGltZS4gVXNlZCBhcyB0aGUgbG9va3VwIGtleSBpblxuICAgKiAgYGRldGFjaFJlZ2lzdHJ5YCBhbmQgYXMgdGhlIHNjb3BlLXN0b3JhZ2Uga2V5IHByZWZpeC4gKi9cbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcblxuICAvKiogQ3VycmVudCBzdGF0ZS4gUmVhZCBkaXJlY3RseSBmb3Igc3luYyBhY2Nlc3MuICovXG4gIHJlYWRvbmx5IHN0YXR1czogJ3F1ZXVlZCcgfCAncnVubmluZycgfCAnZG9uZScgfCAnZmFpbGVkJztcblxuICAvKiogVGhlIHdvcmsncyByZXN1bHQuIFByZXNlbnQgaWZmIGBzdGF0dXMgPT09ICdkb25lJ2AuIFJlYWRpbmdcbiAgICogIGJlZm9yZSB0ZXJtaW5hbCByZXR1cm5zIGB1bmRlZmluZWRgLiAqL1xuICByZWFkb25seSByZXN1bHQ/OiB1bmtub3duO1xuXG4gIC8qKiBUaGUgd29yaydzIGVycm9yLiBQcmVzZW50IGlmZiBgc3RhdHVzID09PSAnZmFpbGVkJ2AuIFJlYWRpbmdcbiAgICogIGJlZm9yZSB0ZXJtaW5hbCByZXR1cm5zIGB1bmRlZmluZWRgLiAqL1xuICByZWFkb25seSBlcnJvcj86IEVycm9yO1xuXG4gIC8qKlxuICAgKiBPcHQtaW4gYXN5bmMgam9pbi4gUmV0dXJucyBhIFByb21pc2UgdGhhdDpcbiAgICogICAtIHJlc29sdmVzIHdpdGggYHsgcmVzdWx0IH1gIHdoZW4gc3RhdHVzIGJlY29tZXMgJ2RvbmUnXG4gICAqICAgLSByZWplY3RzIHdpdGggdGhlIGNhcHR1cmVkIGBFcnJvcmAgd2hlbiBzdGF0dXMgYmVjb21lcyAnZmFpbGVkJ1xuICAgKiAgIC0gcmVzb2x2ZXMvcmVqZWN0cyBJTU1FRElBVEVMWSBpZiBzdGF0dXMgaXMgYWxyZWFkeSB0ZXJtaW5hbFxuICAgKiAgIC0gcmV0dXJucyB0aGUgU0FNRSBjYWNoZWQgUHJvbWlzZSBvbiByZXBlYXRlZCBjYWxscyAobm9cbiAgICogICAgIHJlLXJ1bm5pbmcsIG5vIGR1cGxpY2F0ZWQgSS9PKVxuICAgKlxuICAgKiBDYWxsaW5nIGB3YWl0KClgIGRvZXMgTk9UIGNoYW5nZSB0aGUgaGFuZGxlJ3MgbGlmZWN5Y2xlIOKAlCBpdCdzXG4gICAqIHBhc3NpdmUgb2JzZXJ2YXRpb24uIElmIG5ldmVyIGNhbGxlZCwgdGhlIHdvcmsgc3RpbGwgY29tcGxldGVzO1xuICAgKiB0aGUgaGFuZGxlIGp1c3QgZ29lcyB1bmNvbGxlY3RlZCAocGFyZW50IGV4ZWN1dGlvbiB1bmFmZmVjdGVkKS5cbiAgICpcbiAgICogVXNlIHdoZW46XG4gICAqICAgLSBZb3UgYWN0dWFsbHkgbmVlZCB0aGUgcmVzdWx0IGFuZCB3YW50IHRvIGF3YWl0IGl0XG4gICAqICAgLSBDb29yZGluYXRpbmcgbXVsdGlwbGUgaGFuZGxlcyB2aWEgUHJvbWlzZS5hbGwgLyBQcm9taXNlLnJhY2VcbiAgICogICAtIEJhY2twcmVzc3VyZSAoXCJkb24ndCBmaXJlIG1vcmUgdGhhbiBOIGluIGZsaWdodFwiKVxuICAgKlxuICAgKiBEb24ndCB1c2Ugd2hlbjpcbiAgICogICAtIFB1cmUgZmlyZS1hbmQtZm9yZ2V0ICh1c2UgYGRldGFjaEFuZEZvcmdldGAg4oCUIG5vIGhhbmRsZSByZXR1cm5lZClcbiAgICogICAtIFlvdSBqdXN0IHdhbnQgdG8gY2hlY2sgc3RhdHVzIChyZWFkIGBoYW5kbGUuc3RhdHVzYCBkaXJlY3RseSlcbiAgICovXG4gIHdhaXQoKTogUHJvbWlzZTxEZXRhY2hXYWl0UmVzdWx0Pjtcbn1cblxuLy8g4pSA4pSA4pSAIERldGFjaERyaXZlciDigJQgdGhlIGFsZ29yaXRobSBpbnRlcmZhY2Ug4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbi8qKlxuICogQ2FwYWJpbGl0aWVzIGEgZHJpdmVyIGRlY2xhcmVzLiBEcml2ZXMgdGhlIHJ1bnRpbWUgZGVjaXNpb24gb2ZcbiAqIFwiaXMgdGhpcyBkcml2ZXIgYXBwcm9wcmlhdGUgZm9yIHRoZSBjdXJyZW50IGVudmlyb25tZW50P1wiIENvbnN1bWVyc1xuICogaW5zcGVjdCBhdCBjb25zdHJ1Y3Rpb247IHRoZSBmcmFtZXdvcmsgZG9lc24ndCBlbmZvcmNlLlxuICpcbiAqIEFsbCBjYXBhYmlsaXRpZXMgYXJlIG9wdGlvbmFsIGZsYWdzIOKAlCBmYWxzZSAvIHVuZGVmaW5lZCBtZWFucyBcIm5vdFxuICogc3VwcG9ydGVkIC8gbm8gY2xhaW0uXCIgQSBkcml2ZXIgdGhhdCBzdXBwb3J0cyBldmVyeXRoaW5nIHNldHMgYWxsXG4gKiB0byB0cnVlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERyaXZlckNhcGFiaWxpdGllcyB7XG4gIC8qKiBEcml2ZXIgd29ya3MgaW4gYnJvd3NlciBlbnZpcm9ubWVudHMgKHdpbmRvdywgZG9jdW1lbnQsIGV0Yy4pLiAqL1xuICByZWFkb25seSBicm93c2VyU2FmZT86IGJvb2xlYW47XG4gIC8qKiBEcml2ZXIgd29ya3MgaW4gTm9kZS5qcyBlbnZpcm9ubWVudHMuICovXG4gIHJlYWRvbmx5IG5vZGVTYWZlPzogYm9vbGVhbjtcbiAgLyoqIERyaXZlciB3b3JrcyBpbiBlZGdlIHJ1bnRpbWVzIChDbG91ZGZsYXJlIFdvcmtlcnMsIERlbm8gRGVwbG95LFxuICAgKiAgQnVuIGVkZ2UsIGV0Yy4g4oCUIHJlc3RyaWN0ZWQgZW52aXJvbm1lbnRzKS4gKi9cbiAgcmVhZG9ubHkgZWRnZVNhZmU/OiBib29sZWFuO1xuICAvKiogV29yayBzdXJ2aXZlcyBwYWdlLXVubG9hZCAvIHByb2Nlc3MtZXhpdC4gZS5nLixcbiAgICogIGBzZW5kQmVhY29uRHJpdmVyYCBzY2hlZHVsZXMgdmlhIGBuYXZpZ2F0b3Iuc2VuZEJlYWNvbmAgd2hpY2hcbiAgICogIHNoaXBzIGV2ZW4gb24gdGFiIGNsb3NlLiAqL1xuICByZWFkb25seSBzdXJ2aXZlc1VubG9hZD86IGJvb2xlYW47XG4gIC8qKiBXb3JrIHJ1bnMgb24gYSBzZXBhcmF0ZSBPUyB0aHJlYWQgKG5vIGV2ZW50LWxvb3AgYmxvY2spLlxuICAgKiAgZS5nLiwgYHdvcmtlclRocmVhZERyaXZlcmAuICovXG4gIHJlYWRvbmx5IGNwdUlzb2xhdGVkPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBBIGRyaXZlciBpcyB0aGUgV0hFTi9IT1cgb2YgdGhlIGRldGFjaC4gTWFwcyBgKGNoaWxkLCBpbnB1dCwgcmVmSWQpYFxuICogdG8gYSBgRGV0YWNoSGFuZGxlYCB3aG9zZSBsaWZlY3ljbGUgdGhlIGRyaXZlciBvd25zLlxuICpcbiAqIERyaXZlcnMgYXJlIHRoZW1zZWx2ZXMgZm9vdHByaW50anMgcHJpbWl0aXZlcyDigJQgaW50ZXJuYWxseSB0aGV5IG1heVxuICogYmUgYSBzaW5nbGUgZnVuY3Rpb24gb3IgYSBtdWx0aS1zdGFnZSBmbG93Q2hhcnQuIEVpdGhlciB3YXksIHRoZVxuICogaW50ZXJmYWNlIHRoZXkgZXhwb3NlIHRvIGNvbnN1bWVycyBpcyBgc2NoZWR1bGUoLi4uKWAuXG4gKlxuICogRHJpdmVycyBNVVNUOlxuICogICAtIFJldHVybiBzeW5jaHJvbm91c2x5ICh0aGUgYWdlbnQgbG9vcCBuZXZlciBibG9ja3Mgb24gc2NoZWR1bGUpXG4gKiAgIC0gTm90IHRocm93IOKAlCBlcnJvcnMgZHVyaW5nIHNjaGVkdWxpbmcgcm91dGUgdGhyb3VnaCB0aGUgaGFuZGxlXG4gKiAgICAgKGBoYW5kbGUuc3RhdHVzID0gJ2ZhaWxlZCdgLCBgaGFuZGxlLmVycm9yID0gLi4uYClcbiAqICAgLSBIb25vciB0aGUgcGFzc2l2ZS1yZWNvcmRlciBydWxlOiB0aGUgcGFyZW50J3MgYGRldGFjaCpgIGNhbGxcbiAqICAgICBuZXZlciB3YWl0cyBmb3IgdGhlIGRyaXZlcidzIGRlZmVycmVkIHdvcmsgdG8gY29tcGxldGVcbiAqXG4gKiBEcml2ZXJzIE1BWTpcbiAqICAgLSBJbXBsZW1lbnQgYHZhbGlkYXRlKClgIGZvciBvbmUtdGltZSBjb25maWd1cmF0aW9uIGNoZWNrcyBhdFxuICogICAgIHJlZ2lzdHJhdGlvbiAvIHVzZSB0aW1lIChlLmcuLCBhc3NlcnQgYG5hdmlnYXRvci5zZW5kQmVhY29uYCBleGlzdHMpXG4gKiAgIC0gQnVpbGQgdGhlaXIgaW50ZXJuYWwgcGlwZWxpbmUgYXMgYSBmb290cHJpbnRqcyBmbG93Q2hhcnQgZm9yXG4gKiAgICAgb2JzZXJ2YWJpbGl0eSDigJQgZHJpdmVyIGltcGxlbWVudGF0aW9uIGRldGFpbCwgbm90IGNvbnN1bWVyLWZhY2luZ1xuICpcbiAqIEBleGFtcGxlIEJ1aWx0LWluXG4gKiAgIGltcG9ydCB7IG1pY3JvdGFza0JhdGNoRHJpdmVyIH0gZnJvbSAnZm9vdHByaW50anMvZGV0YWNoJztcbiAqICAgY29uc3QgaGFuZGxlID0gZHJpdmVyLnNjaGVkdWxlKGNoaWxkLCBpbnB1dCwgcmVmSWQpO1xuICpcbiAqIEBleGFtcGxlIEN1c3RvbSAoQllPUylcbiAqICAgY29uc3QgbGFtYmRhRXh0ZW5zaW9uRHJpdmVyOiBEZXRhY2hEcml2ZXIgPSB7XG4gKiAgICAgbmFtZTogJ2xhbWJkYS1leHRlbnNpb24nLFxuICogICAgIGNhcGFiaWxpdGllczogeyBub2RlU2FmZTogdHJ1ZSwgc3Vydml2ZXNVbmxvYWQ6IHRydWUgfSxcbiAqICAgICBzY2hlZHVsZShjaGlsZCwgaW5wdXQsIHJlZklkKSB7XG4gKiAgICAgICBzaGFyZWRCdWZmZXIucHVzaCh7IHJlZklkLCBjaGlsZCwgaW5wdXQgfSk7XG4gKiAgICAgICByZXR1cm4gY3JlYXRlSGFuZGxlKHJlZklkLCAncXVldWVkJyk7XG4gKiAgICAgfSxcbiAqICAgfTtcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZXRhY2hEcml2ZXIge1xuICAvKiogU3RhYmxlIG5hbWUgZm9yIGRpYWdub3N0aWNzICsgcmVnaXN0cnkgbG9va3VwLiBDb252ZW50aW9uYWxseVxuICAgKiAgYWxnb3JpdGhtLW5hbWVkIChlLmcuIGAnbWljcm90YXNrLWJhdGNoJ2AsIGAnc2VuZC1iZWFjb24nYCkuICovXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAvKiogV2hhdCB0aGlzIGRyaXZlciBzdXBwb3J0cy4gVXNlZCBieSBjb25zdW1lcnMgdG8gcGljayB0aGUgcmlnaHRcbiAgICogIGRyaXZlciBmb3IgdGhlaXIgZW52aXJvbm1lbnQuICovXG4gIHJlYWRvbmx5IGNhcGFiaWxpdGllczogRHJpdmVyQ2FwYWJpbGl0aWVzO1xuXG4gIC8qKlxuICAgKiBIYW5kIHRoZSB3b3JrIHRvIHRoZSBkcml2ZXIncyBzY2hlZHVsaW5nIG1lY2hhbmlzbS4gTVVTVCByZXR1cm5cbiAgICogc3luY2hyb25vdXNseSB3aXRoIGEgZnJlc2ggYERldGFjaEhhbmRsZWAuIFRoZSBhY3R1YWwgd29yayBtYXlcbiAgICogcnVuIGxhdGVyIChuZXh0IG1pY3JvdGFzayAvIHNldEltbWVkaWF0ZSAvIGJyb3dzZXItYmVhY29uLWZsdXNoIC9cbiAgICogd29ya2VyLXRocmVhZCAvIGV0Yy4pIG9uIHRoZSBkcml2ZXIncyBjaG9zZW4gbWVjaGFuaXNtLlxuICAgKi9cbiAgc2NoZWR1bGUoY2hpbGQ6IEZsb3dDaGFydCwgaW5wdXQ6IHVua25vd24sIHJlZklkOiBzdHJpbmcpOiBEZXRhY2hIYW5kbGU7XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIG9uZS10aW1lIHZhbGlkYXRpb24gaG9vay4gQ2FsbGVkIGF0IGZpcnN0IHVzZSAob3JcbiAgICogcmVnaXN0cmF0aW9uIHRpbWUsIGRlcGVuZGluZyBvbiBkcml2ZXIpIOKAlCBkcml2ZXJzIHRocm93IGlmIHRoZWlyXG4gICAqIGNvbmZpZ3VyYXRpb24gaXMgaW52YWxpZCAobWlzc2luZyBwZWVyIGRlcCwgdW5yZWFjaGFibGUgZW5kcG9pbnQsXG4gICAqIHdyb25nIEFQSSBrZXkgc2hhcGUsIGV0Yy4pLlxuICAgKlxuICAgKiBFeGFtcGxlOiBgc2VuZEJlYWNvbkRyaXZlci52YWxpZGF0ZSgpYCBjaGVja3NcbiAgICogYHR5cGVvZiBuYXZpZ2F0b3I/LnNlbmRCZWFjb24gPT09ICdmdW5jdGlvbidgIGFuZCB0aHJvd3Mgd2l0aCBhXG4gICAqIGhlbHBmdWwgbWVzc2FnZSBpZiBhYnNlbnQgKGUuZy4sIGluIE5vZGUpLlxuICAgKlxuICAgKiBQZXIgdGhlIE5ldyBSZWxpYyBwYW5lbCByZXZpZXc6IGVhcmx5LWZhaWwtd2l0aC11c2VmdWwtbWVzc2FnZVxuICAgKiBiZWF0cyBzaWxlbnQgemVyby1lbWlzc2lvbi5cbiAgICovXG4gIHZhbGlkYXRlPygpOiB2b2lkO1xufVxuIl19
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2RldGFjaC90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtDRyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogZGV0YWNoL3R5cGVzLnRzIOKAlCBUeXBlIGRlZmluaXRpb25zIGZvciB0aGUgZmlyZS1hbmQtZm9yZ2V0IHByaW1pdGl2ZS5cbiAqXG4gKiBQYXR0ZXJuOiAgU3RyYXRlZ3kgKyBCcmlkZ2UgKEdvRikuIFNhbWUgc2hhcGUgYXMgY2FjaGUgc3RyYXRlZ2llcyBpblxuICogICAgICAgICAgIGFnZW50Zm9vdHByaW50IHYyLjYg4oCUIE9ORSBpbnRlcmZhY2UsIE4gY29uY3JldGUgZHJpdmVycyxcbiAqICAgICAgICAgICBjb25zdW1lciBwaWNrcyB2aWEgZXhwbGljaXQgaW1wb3J0LlxuICogUm9sZTogICAgIEZvdW5kYXRpb24uIEV2ZXJ5IG90aGVyIGRldGFjaCBmaWxlIGltcG9ydHMgZnJvbSBoZXJlLlxuICogICAgICAgICAgIFRoaXMgaXMgdGhlIGxvY2thYmxlIGNvbnRyYWN0OyBkb3duc3RyZWFtIGZpbGVzIGltcGxlbWVudCBpdC5cbiAqXG4gKiBUd28gc2libGluZyBjb25jZXB0czpcbiAqXG4gKiAgIDEuIGBEZXRhY2hEcml2ZXJgIOKAlCB0aGUgYWxnb3JpdGhtIHRoYXQgZGVjaWRlcyBXSEVOL0hPVyB0aGUgd29yayBydW5zLlxuICogICAgICBTaXggYnVpbHQtaW4gYWxnb3JpdGhtcyBzaGlwIGFzIGFsZ29yaXRobS1uYW1lZCBleHBvcnRzXG4gKiAgICAgIChgbWljcm90YXNrQmF0Y2hEcml2ZXJgLCBgc2V0SW1tZWRpYXRlRHJpdmVyYCwgYHNlbmRCZWFjb25Ecml2ZXJgLFxuICogICAgICBgc2V0VGltZW91dERyaXZlcmAsIGBpbW1lZGlhdGVEcml2ZXJgLCBgd29ya2VyVGhyZWFkRHJpdmVyYCkuXG4gKiAgICAgIENvbnN1bWVycyBjYW4gaW1wbGVtZW50IHRoZWlyIG93biAoQllPUyDigJQgYnJpbmcgeW91ciBvd24gZHJpdmVyKS5cbiAqXG4gKiAgIDIuIGBEZXRhY2hIYW5kbGVgIOKAlCB0aGUgY29uc3VtZXItZmFjaW5nIGhhbmRsZSByZXR1cm5lZCBieVxuICogICAgICBgZGV0YWNoQW5kSm9pbkxhdGVyYC4gRXhwb3NlcyBzdGF0dXMgYXMgUFJPUEVSVElFUyAoc3luYyByZWFkKVxuICogICAgICBhbmQgYHdhaXQoKWAgKFByb21pc2Ug4oCUIG9wdC1pbiBhc3luYyBqb2luKS4gU3R5bGUgMiBmcm9tIHRoZVxuICogICAgICBwYW5lbCByZXZpZXc6IHByb3BlcnRpZXMgZm9yIHN5bmMsIHNpbmdsZSBtZXRob2QgZm9yIGFzeW5jLlxuICpcbiAqIE5hbWluZyBwb2xpY3kgKGxvY2tlZCBmcm9tIG5hbWluZyByZXZpZXcpOlxuICogICAtIFB1YmxpYyBBUEkgdXNlcyBzaW1wbGUgdmVyYnMgLyBwcm9wZXJ0aWVzIChwcm9kdWN0LWVuZ2luZWVyIGZyaWVuZGx5KVxuICogICAtIEludGVybmFsIGNsYXNzIG5hbWVzIENBTiB1c2UgQ1MgdGVybXMgKFNjaGVkdWxlciwgQ29udGludWF0aW9uLCBldGMuKVxuICogICAtIERyaXZlcnMgYXJlIGFsZ29yaXRobS1uYW1lZCAoc2VtYW50aWMgYXQgdGhlIGFsZ29yaXRobSBsZXZlbClcbiAqXG4gKiBMb2NrZWQgZGVzaWduIGRlY2lzaW9ucyAocGFuZWwgcmV2aWV3IGNhcHR1cmVkIGluXG4gKiBgZG9jcy9pbnNwaXJhdGlvbi9kZXRhY2gtcHJpbWl0aXZlLm1kYCk6XG4gKiAgIC0gU3luYyBob3QgcGF0aDsgYXN5bmMgb25seSBhdCBmbHVzaCBib3VuZGFyaWVzXG4gKiAgIC0gRXJyb3JzIOKGkiBjb21taXRMb2cgKyB0eXBlZCBldmVudCwgTkVWRVIgdGhyb3duIHRvIHBhcmVudFxuICogICAtIFNjb3BlIGlzb2xhdGlvbiBiZXR3ZWVuIHBhcmVudCBhbmQgZGV0YWNoZWQgY2hpbGRcbiAqICAgLSBMaWZlY3ljbGUgdGllZCB0byBleGVjdXRvciBkaXNwb3NhbFxuICogICAtIFR5cGUtbGV2ZWwgcmVqZWN0aW9uIG9mIGBvdXRwdXRNYXBwZXJgIG9uIGRldGFjaCBvcHRpb25zXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBGbG93Q2hhcnQgfSBmcm9tICcuLi9idWlsZGVyL3R5cGVzLmpzJztcblxuLy8g4pSA4pSA4pSAIERldGFjaEhhbmRsZSDigJQgd2hhdCB0aGUgY29uc3VtZXIgZ2V0cyBiYWNrIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4vKipcbiAqIFNuYXBzaG90IG9mIGEgZGV0YWNoZWQgaGFuZGxlJ3Mgc3RhdGUuIFJldHVybmVkIGJ5IGBoYW5kbGUucG9sbCgpYFxuICogKHdoZW4gYWRkZWQgaW4gYSBmb2xsb3ctdXA7IHYxIGV4cG9zZXMgcHJvcGVydGllcyBkaXJlY3RseSBvblxuICogYERldGFjaEhhbmRsZWApLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERldGFjaFBvbGxSZXN1bHQge1xuICByZWFkb25seSBzdGF0dXM6IERldGFjaEhhbmRsZVsnc3RhdHVzJ107XG4gIC8qKiBQcmVzZW50IGlmZiBzdGF0dXMgPT09ICdkb25lJy4gKi9cbiAgcmVhZG9ubHkgcmVzdWx0PzogdW5rbm93bjtcbiAgLyoqIFByZXNlbnQgaWZmIHN0YXR1cyA9PT0gJ2ZhaWxlZCcuICovXG4gIHJlYWRvbmx5IGVycm9yPzogRXJyb3I7XG59XG5cbi8qKlxuICogUmVzdWx0IGRlbGl2ZXJlZCB3aGVuIHRoZSBoYW5kbGUncyBgd2FpdCgpYCBQcm9taXNlIHJlc29sdmVzXG4gKiBzdWNjZXNzZnVsbHkgKHN0YXR1cyByZWFjaGVkICdkb25lJykuIFJlamVjdGlvbiBkZWxpdmVycyB0aGVcbiAqIG5hdGl2ZSBgRXJyb3JgIGRpcmVjdGx5IOKAlCBubyB3cmFwcGluZyBzaGFwZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZXRhY2hXYWl0UmVzdWx0IHtcbiAgcmVhZG9ubHkgcmVzdWx0OiB1bmtub3duO1xufVxuXG4vKipcbiAqIEhhbmRsZSByZXR1cm5lZCBieSBgY2hhcnQuZGV0YWNoQW5kSm9pbkxhdGVyKC4uLilgIGFuZFxuICogYGV4ZWN1dG9yLmRldGFjaEFuZEpvaW5MYXRlciguLi4pYC4gRXhwb3NlcyBzdGF0dXMgYXMgUFJPUEVSVElFUyBzb1xuICogc3luYyBhY2Nlc3MgaXMgcHJvcGVydHktcmVhZCAoY2hlYXAsIG5vIGFsbG9jYXRpb24pLiBUaGUgc2luZ2xlXG4gKiBtZXRob2QgYHdhaXQoKWAgcmV0dXJucyBhIFByb21pc2UgZm9yIG9wdC1pbiBhc3luYyBqb2luLlxuICpcbiAqIFRoZSBoYW5kbGUgaXMgKipub3QqKiBQcm9taXNlLXNoYXBlZCAobm8gYC50aGVuKClgKSDigJQgdGhhdCB3b3VsZFxuICogbWFrZSBpdCBhY2NpZGVudGFsbHkgYXdhaXRhYmxlLCBkZWZlYXRpbmcgdGhlIGZpcmUtYW5kLWZvcmdldFxuICogc2VtYW50aWNzLiBUbyBhd2FpdCwgdGhlIGNvbnN1bWVyIG11c3QgY2FsbCBgLndhaXQoKWAgZXhwbGljaXRseS5cbiAqXG4gKiBMaWZlY3ljbGU6XG4gKlxuICogICBxdWV1ZWQgIOKGkiBkcml2ZXIgcmVjZWl2ZWQgdGhlIHdvcmssIGhhc24ndCBzdGFydGVkIGl0XG4gKiAgIHJ1bm5pbmcg4oaSIGRyaXZlciBzdGFydGVkIHRoZSB3b3JrXG4gKiAgIGRvbmUgICAg4oaSIHRlcm1pbmFsOiByZXN1bHQgYXZhaWxhYmxlXG4gKiAgIGZhaWxlZCAg4oaSIHRlcm1pbmFsOiBlcnJvciBhdmFpbGFibGVcbiAqXG4gKiBgZG9uZWAgYW5kIGBmYWlsZWRgIGFyZSBURVJNSU5BTCDigJQgb25jZSByZWFjaGVkLCBzdGF0dXMgbmV2ZXJcbiAqIGNoYW5nZXMgYWdhaW4uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGV0YWNoSGFuZGxlIHtcbiAgLyoqIFN0YWJsZSBpZCBhc3NpZ25lZCBhdCBkZXRhY2ggdGltZS4gVXNlZCBhcyB0aGUgbG9va3VwIGtleSBpblxuICAgKiAgYGRldGFjaFJlZ2lzdHJ5YCBhbmQgYXMgdGhlIHNjb3BlLXN0b3JhZ2Uga2V5IHByZWZpeC4gKi9cbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcblxuICAvKiogQ3VycmVudCBzdGF0ZS4gUmVhZCBkaXJlY3RseSBmb3Igc3luYyBhY2Nlc3MuICovXG4gIHJlYWRvbmx5IHN0YXR1czogJ3F1ZXVlZCcgfCAncnVubmluZycgfCAnZG9uZScgfCAnZmFpbGVkJztcblxuICAvKiogVGhlIHdvcmsncyByZXN1bHQuIFByZXNlbnQgaWZmIGBzdGF0dXMgPT09ICdkb25lJ2AuIFJlYWRpbmdcbiAgICogIGJlZm9yZSB0ZXJtaW5hbCByZXR1cm5zIGB1bmRlZmluZWRgLiAqL1xuICByZWFkb25seSByZXN1bHQ/OiB1bmtub3duO1xuXG4gIC8qKiBUaGUgd29yaydzIGVycm9yLiBQcmVzZW50IGlmZiBgc3RhdHVzID09PSAnZmFpbGVkJ2AuIFJlYWRpbmdcbiAgICogIGJlZm9yZSB0ZXJtaW5hbCByZXR1cm5zIGB1bmRlZmluZWRgLiAqL1xuICByZWFkb25seSBlcnJvcj86IEVycm9yO1xuXG4gIC8qKlxuICAgKiBPcHQtaW4gYXN5bmMgam9pbi4gUmV0dXJucyBhIFByb21pc2UgdGhhdDpcbiAgICogICAtIHJlc29sdmVzIHdpdGggYHsgcmVzdWx0IH1gIHdoZW4gc3RhdHVzIGJlY29tZXMgJ2RvbmUnXG4gICAqICAgLSByZWplY3RzIHdpdGggdGhlIGNhcHR1cmVkIGBFcnJvcmAgd2hlbiBzdGF0dXMgYmVjb21lcyAnZmFpbGVkJ1xuICAgKiAgIC0gcmVzb2x2ZXMvcmVqZWN0cyBJTU1FRElBVEVMWSBpZiBzdGF0dXMgaXMgYWxyZWFkeSB0ZXJtaW5hbFxuICAgKiAgIC0gcmV0dXJucyB0aGUgU0FNRSBjYWNoZWQgUHJvbWlzZSBvbiByZXBlYXRlZCBjYWxscyAobm9cbiAgICogICAgIHJlLXJ1bm5pbmcsIG5vIGR1cGxpY2F0ZWQgSS9PKVxuICAgKlxuICAgKiBDYWxsaW5nIGB3YWl0KClgIGRvZXMgTk9UIGNoYW5nZSB0aGUgaGFuZGxlJ3MgbGlmZWN5Y2xlIOKAlCBpdCdzXG4gICAqIHBhc3NpdmUgb2JzZXJ2YXRpb24uIElmIG5ldmVyIGNhbGxlZCwgdGhlIHdvcmsgc3RpbGwgY29tcGxldGVzO1xuICAgKiB0aGUgaGFuZGxlIGp1c3QgZ29lcyB1bmNvbGxlY3RlZCAocGFyZW50IGV4ZWN1dGlvbiB1bmFmZmVjdGVkKS5cbiAgICpcbiAgICogVXNlIHdoZW46XG4gICAqICAgLSBZb3UgYWN0dWFsbHkgbmVlZCB0aGUgcmVzdWx0IGFuZCB3YW50IHRvIGF3YWl0IGl0XG4gICAqICAgLSBDb29yZGluYXRpbmcgbXVsdGlwbGUgaGFuZGxlcyB2aWEgUHJvbWlzZS5hbGwgLyBQcm9taXNlLnJhY2VcbiAgICogICAtIEJhY2twcmVzc3VyZSAoXCJkb24ndCBmaXJlIG1vcmUgdGhhbiBOIGluIGZsaWdodFwiKVxuICAgKlxuICAgKiBEb24ndCB1c2Ugd2hlbjpcbiAgICogICAtIFB1cmUgZmlyZS1hbmQtZm9yZ2V0ICh1c2UgYGRldGFjaEFuZEZvcmdldGAg4oCUIG5vIGhhbmRsZSByZXR1cm5lZClcbiAgICogICAtIFlvdSBqdXN0IHdhbnQgdG8gY2hlY2sgc3RhdHVzIChyZWFkIGBoYW5kbGUuc3RhdHVzYCBkaXJlY3RseSlcbiAgICovXG4gIHdhaXQoKTogUHJvbWlzZTxEZXRhY2hXYWl0UmVzdWx0Pjtcbn1cblxuLy8g4pSA4pSA4pSAIERldGFjaERyaXZlciDigJQgdGhlIGFsZ29yaXRobSBpbnRlcmZhY2Ug4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbi8qKlxuICogQ2FwYWJpbGl0aWVzIGEgZHJpdmVyIGRlY2xhcmVzLiBEcml2ZXMgdGhlIHJ1bnRpbWUgZGVjaXNpb24gb2ZcbiAqIFwiaXMgdGhpcyBkcml2ZXIgYXBwcm9wcmlhdGUgZm9yIHRoZSBjdXJyZW50IGVudmlyb25tZW50P1wiIENvbnN1bWVyc1xuICogaW5zcGVjdCBhdCBjb25zdHJ1Y3Rpb247IHRoZSBmcmFtZXdvcmsgZG9lc24ndCBlbmZvcmNlLlxuICpcbiAqIEFsbCBjYXBhYmlsaXRpZXMgYXJlIG9wdGlvbmFsIGZsYWdzIOKAlCBmYWxzZSAvIHVuZGVmaW5lZCBtZWFucyBcIm5vdFxuICogc3VwcG9ydGVkIC8gbm8gY2xhaW0uXCIgQSBkcml2ZXIgdGhhdCBzdXBwb3J0cyBldmVyeXRoaW5nIHNldHMgYWxsXG4gKiB0byB0cnVlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERyaXZlckNhcGFiaWxpdGllcyB7XG4gIC8qKiBEcml2ZXIgd29ya3MgaW4gYnJvd3NlciBlbnZpcm9ubWVudHMgKHdpbmRvdywgZG9jdW1lbnQsIGV0Yy4pLiAqL1xuICByZWFkb25seSBicm93c2VyU2FmZT86IGJvb2xlYW47XG4gIC8qKiBEcml2ZXIgd29ya3MgaW4gTm9kZS5qcyBlbnZpcm9ubWVudHMuICovXG4gIHJlYWRvbmx5IG5vZGVTYWZlPzogYm9vbGVhbjtcbiAgLyoqIERyaXZlciB3b3JrcyBpbiBlZGdlIHJ1bnRpbWVzIChDbG91ZGZsYXJlIFdvcmtlcnMsIERlbm8gRGVwbG95LFxuICAgKiAgQnVuIGVkZ2UsIGV0Yy4g4oCUIHJlc3RyaWN0ZWQgZW52aXJvbm1lbnRzKS4gKi9cbiAgcmVhZG9ubHkgZWRnZVNhZmU/OiBib29sZWFuO1xuICAvKiogV29yayBzdXJ2aXZlcyBwYWdlLXVubG9hZCAvIHByb2Nlc3MtZXhpdC4gZS5nLixcbiAgICogIGBzZW5kQmVhY29uRHJpdmVyYCBzY2hlZHVsZXMgdmlhIGBuYXZpZ2F0b3Iuc2VuZEJlYWNvbmAgd2hpY2hcbiAgICogIHNoaXBzIGV2ZW4gb24gdGFiIGNsb3NlLiAqL1xuICByZWFkb25seSBzdXJ2aXZlc1VubG9hZD86IGJvb2xlYW47XG4gIC8qKiBXb3JrIHJ1bnMgb24gYSBzZXBhcmF0ZSBPUyB0aHJlYWQgKG5vIGV2ZW50LWxvb3AgYmxvY2spLlxuICAgKiAgZS5nLiwgYHdvcmtlclRocmVhZERyaXZlcmAuICovXG4gIHJlYWRvbmx5IGNwdUlzb2xhdGVkPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBBIGRyaXZlciBpcyB0aGUgV0hFTi9IT1cgb2YgdGhlIGRldGFjaC4gTWFwcyBgKGNoaWxkLCBpbnB1dCwgcmVmSWQpYFxuICogdG8gYSBgRGV0YWNoSGFuZGxlYCB3aG9zZSBsaWZlY3ljbGUgdGhlIGRyaXZlciBvd25zLlxuICpcbiAqIERyaXZlcnMgYXJlIHRoZW1zZWx2ZXMgZm9vdHByaW50anMgcHJpbWl0aXZlcyDigJQgaW50ZXJuYWxseSB0aGV5IG1heVxuICogYmUgYSBzaW5nbGUgZnVuY3Rpb24gb3IgYSBtdWx0aS1zdGFnZSBmbG93Q2hhcnQuIEVpdGhlciB3YXksIHRoZVxuICogaW50ZXJmYWNlIHRoZXkgZXhwb3NlIHRvIGNvbnN1bWVycyBpcyBgc2NoZWR1bGUoLi4uKWAuXG4gKlxuICogRHJpdmVycyBNVVNUOlxuICogICAtIFJldHVybiBzeW5jaHJvbm91c2x5ICh0aGUgYWdlbnQgbG9vcCBuZXZlciBibG9ja3Mgb24gc2NoZWR1bGUpXG4gKiAgIC0gTm90IHRocm93IOKAlCBlcnJvcnMgZHVyaW5nIHNjaGVkdWxpbmcgcm91dGUgdGhyb3VnaCB0aGUgaGFuZGxlXG4gKiAgICAgKGBoYW5kbGUuc3RhdHVzID0gJ2ZhaWxlZCdgLCBgaGFuZGxlLmVycm9yID0gLi4uYClcbiAqICAgLSBIb25vciB0aGUgcGFzc2l2ZS1yZWNvcmRlciBydWxlOiB0aGUgcGFyZW50J3MgYGRldGFjaCpgIGNhbGxcbiAqICAgICBuZXZlciB3YWl0cyBmb3IgdGhlIGRyaXZlcidzIGRlZmVycmVkIHdvcmsgdG8gY29tcGxldGVcbiAqXG4gKiBEcml2ZXJzIE1BWTpcbiAqICAgLSBJbXBsZW1lbnQgYHZhbGlkYXRlKClgIGZvciBvbmUtdGltZSBjb25maWd1cmF0aW9uIGNoZWNrcyBhdFxuICogICAgIHJlZ2lzdHJhdGlvbiAvIHVzZSB0aW1lIChlLmcuLCBhc3NlcnQgYG5hdmlnYXRvci5zZW5kQmVhY29uYCBleGlzdHMpXG4gKiAgIC0gQnVpbGQgdGhlaXIgaW50ZXJuYWwgcGlwZWxpbmUgYXMgYSBmb290cHJpbnRqcyBmbG93Q2hhcnQgZm9yXG4gKiAgICAgb2JzZXJ2YWJpbGl0eSDigJQgZHJpdmVyIGltcGxlbWVudGF0aW9uIGRldGFpbCwgbm90IGNvbnN1bWVyLWZhY2luZ1xuICpcbiAqIEBleGFtcGxlIEJ1aWx0LWluXG4gKiAgIGltcG9ydCB7IG1pY3JvdGFza0JhdGNoRHJpdmVyIH0gZnJvbSAnZm9vdHByaW50anMvZGV0YWNoJztcbiAqICAgY29uc3QgaGFuZGxlID0gZHJpdmVyLnNjaGVkdWxlKGNoaWxkLCBpbnB1dCwgcmVmSWQpO1xuICpcbiAqIEBleGFtcGxlIEN1c3RvbSAoQllPUylcbiAqICAgY29uc3QgbGFtYmRhRXh0ZW5zaW9uRHJpdmVyOiBEZXRhY2hEcml2ZXIgPSB7XG4gKiAgICAgbmFtZTogJ2xhbWJkYS1leHRlbnNpb24nLFxuICogICAgIGNhcGFiaWxpdGllczogeyBub2RlU2FmZTogdHJ1ZSwgc3Vydml2ZXNVbmxvYWQ6IHRydWUgfSxcbiAqICAgICBzY2hlZHVsZShjaGlsZCwgaW5wdXQsIHJlZklkKSB7XG4gKiAgICAgICBzaGFyZWRCdWZmZXIucHVzaCh7IHJlZklkLCBjaGlsZCwgaW5wdXQgfSk7XG4gKiAgICAgICByZXR1cm4gY3JlYXRlSGFuZGxlKHJlZklkKTtcbiAqICAgICB9LFxuICogICB9O1xuICovXG5leHBvcnQgaW50ZXJmYWNlIERldGFjaERyaXZlciB7XG4gIC8qKiBTdGFibGUgbmFtZSBmb3IgZGlhZ25vc3RpY3MgKyByZWdpc3RyeSBsb29rdXAuIENvbnZlbnRpb25hbGx5XG4gICAqICBhbGdvcml0aG0tbmFtZWQgKGUuZy4gYCdtaWNyb3Rhc2stYmF0Y2gnYCwgYCdzZW5kLWJlYWNvbidgKS4gKi9cbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuXG4gIC8qKiBXaGF0IHRoaXMgZHJpdmVyIHN1cHBvcnRzLiBVc2VkIGJ5IGNvbnN1bWVycyB0byBwaWNrIHRoZSByaWdodFxuICAgKiAgZHJpdmVyIGZvciB0aGVpciBlbnZpcm9ubWVudC4gKi9cbiAgcmVhZG9ubHkgY2FwYWJpbGl0aWVzOiBEcml2ZXJDYXBhYmlsaXRpZXM7XG5cbiAgLyoqXG4gICAqIEhhbmQgdGhlIHdvcmsgdG8gdGhlIGRyaXZlcidzIHNjaGVkdWxpbmcgbWVjaGFuaXNtLiBNVVNUIHJldHVyblxuICAgKiBzeW5jaHJvbm91c2x5IHdpdGggYSBmcmVzaCBgRGV0YWNoSGFuZGxlYC4gVGhlIGFjdHVhbCB3b3JrIG1heVxuICAgKiBydW4gbGF0ZXIgKG5leHQgbWljcm90YXNrIC8gc2V0SW1tZWRpYXRlIC8gYnJvd3Nlci1iZWFjb24tZmx1c2ggL1xuICAgKiB3b3JrZXItdGhyZWFkIC8gZXRjLikgb24gdGhlIGRyaXZlcidzIGNob3NlbiBtZWNoYW5pc20uXG4gICAqL1xuICBzY2hlZHVsZShjaGlsZDogRmxvd0NoYXJ0LCBpbnB1dDogdW5rbm93biwgcmVmSWQ6IHN0cmluZyk6IERldGFjaEhhbmRsZTtcblxuICAvKipcbiAgICogT3B0aW9uYWwgb25lLXRpbWUgdmFsaWRhdGlvbiBob29rLiBDYWxsZWQgYXQgZmlyc3QgdXNlIChvclxuICAgKiByZWdpc3RyYXRpb24gdGltZSwgZGVwZW5kaW5nIG9uIGRyaXZlcikg4oCUIGRyaXZlcnMgdGhyb3cgaWYgdGhlaXJcbiAgICogY29uZmlndXJhdGlvbiBpcyBpbnZhbGlkIChtaXNzaW5nIHBlZXIgZGVwLCB1bnJlYWNoYWJsZSBlbmRwb2ludCxcbiAgICogd3JvbmcgQVBJIGtleSBzaGFwZSwgZXRjLikuXG4gICAqXG4gICAqIEV4YW1wbGU6IGBzZW5kQmVhY29uRHJpdmVyLnZhbGlkYXRlKClgIGNoZWNrc1xuICAgKiBgdHlwZW9mIG5hdmlnYXRvcj8uc2VuZEJlYWNvbiA9PT0gJ2Z1bmN0aW9uJ2AgYW5kIHRocm93cyB3aXRoIGFcbiAgICogaGVscGZ1bCBtZXNzYWdlIGlmIGFic2VudCAoZS5nLiwgaW4gTm9kZSkuXG4gICAqXG4gICAqIFBlciB0aGUgTmV3IFJlbGljIHBhbmVsIHJldmlldzogZWFybHktZmFpbC13aXRoLXVzZWZ1bC1tZXNzYWdlXG4gICAqIGJlYXRzIHNpbGVudCB6ZXJvLWVtaXNzaW9uLlxuICAgKi9cbiAgdmFsaWRhdGU/KCk6IHZvaWQ7XG59XG4iXX0=
@@ -13,8 +13,8 @@
13
13
  * executor.attachFlowRecorder(recorder);
14
14
  * await executor.run();
15
15
  *
16
- * const mainNarrative = executor.getNarrative(); // No loop sentences
17
- * const loopDetail = recorder.getLoopSentences(); // All loop detail
16
+ * const mainEntries = executor.getNarrativeEntries(); // No loop sentences
17
+ * const loopDetail = recorder.getLoopSentences(); // All loop detail
18
18
  * ```
19
19
  */
20
20
  import { NarrativeFlowRecorder } from '../NarrativeFlowRecorder.js';
@@ -51,4 +51,4 @@ export class SeparateNarrativeFlowRecorder extends NarrativeFlowRecorder {
51
51
  this.loopCounts.clear();
52
52
  }
53
53
  }
54
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VwYXJhdGVOYXJyYXRpdmVGbG93UmVjb3JkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2VuZ2luZS9uYXJyYXRpdmUvcmVjb3JkZXJzL1NlcGFyYXRlTmFycmF0aXZlRmxvd1JlY29yZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFFSCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUdwRSxNQUFNLE9BQU8sNkJBQThCLFNBQVEscUJBQXFCO0lBQzlELGFBQWEsR0FBYSxFQUFFLENBQUM7SUFDN0IsVUFBVSxHQUF3QixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRXBELFlBQVksRUFBVztRQUNyQixLQUFLLENBQUMsRUFBRSxJQUFJLG9CQUFvQixDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVRLE1BQU0sQ0FBQyxLQUFvQjtRQUNsQyxzREFBc0Q7UUFFdEQsMEJBQTBCO1FBQzFCLE1BQU0sS0FBSyxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXpDLDRCQUE0QjtRQUM1QixJQUFJLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxXQUFXLEtBQUssQ0FBQyxTQUFTLEtBQUssS0FBSyxDQUFDLFdBQVcsU0FBUyxDQUFDLENBQUM7UUFDckYsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxXQUFXLEtBQUssQ0FBQyxTQUFTLFlBQVksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDakYsQ0FBQztJQUNILENBQUM7SUFFRCxtRUFBbUU7SUFDbkUsZ0JBQWdCO1FBQ2QsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRCwyQ0FBMkM7SUFDM0MsYUFBYTtRQUNYLE9BQU8sSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFUSxLQUFLO1FBQ1osS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2QsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUMxQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNlcGFyYXRlTmFycmF0aXZlRmxvd1JlY29yZGVyIOKAlCBDb2xsZWN0cyBsb29wIGl0ZXJhdGlvbnMgaW4gYSBzZXBhcmF0ZSBjaGFubmVsLlxuICpcbiAqIEtlZXBzIHRoZSBtYWluIG5hcnJhdGl2ZSBjbGVhbiAobm8gbG9vcCBzZW50ZW5jZXMpIHdoaWxlIHByZXNlcnZpbmcgZnVsbFxuICogaXRlcmF0aW9uIGRldGFpbCBpbiBhIHNlcGFyYXRlIGFjY2Vzc29yIGZvciBjb25zdW1lcnMgd2hvIG5lZWQgaXQuXG4gKlxuICogQmVzdCBmb3I6IFVJcyBvciByZXBvcnRzIHdoZXJlIGxvb3AgZGV0YWlsIGlzIGluIGEgY29sbGFwc2libGUgc2VjdGlvbixcbiAqIG9yIExMTSBwaXBlbGluZXMgd2hlcmUgbG9vcCBjb250ZXh0IHNob3VsZCBiZSBhdmFpbGFibGUgYnV0IG5vdCBpbiB0aGUgbWFpbiBwcm9tcHQuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHJlY29yZGVyID0gbmV3IFNlcGFyYXRlTmFycmF0aXZlRmxvd1JlY29yZGVyKCk7XG4gKiBleGVjdXRvci5hdHRhY2hGbG93UmVjb3JkZXIocmVjb3JkZXIpO1xuICogYXdhaXQgZXhlY3V0b3IucnVuKCk7XG4gKlxuICogY29uc3QgbWFpbk5hcnJhdGl2ZSA9IGV4ZWN1dG9yLmdldE5hcnJhdGl2ZSgpOyAgICAgLy8gTm8gbG9vcCBzZW50ZW5jZXNcbiAqIGNvbnN0IGxvb3BEZXRhaWwgPSByZWNvcmRlci5nZXRMb29wU2VudGVuY2VzKCk7ICAgIC8vIEFsbCBsb29wIGRldGFpbFxuICogYGBgXG4gKi9cblxuaW1wb3J0IHsgTmFycmF0aXZlRmxvd1JlY29yZGVyIH0gZnJvbSAnLi4vTmFycmF0aXZlRmxvd1JlY29yZGVyLmpzJztcbmltcG9ydCB0eXBlIHsgRmxvd0xvb3BFdmVudCB9IGZyb20gJy4uL3R5cGVzLmpzJztcblxuZXhwb3J0IGNsYXNzIFNlcGFyYXRlTmFycmF0aXZlRmxvd1JlY29yZGVyIGV4dGVuZHMgTmFycmF0aXZlRmxvd1JlY29yZGVyIHtcbiAgcHJpdmF0ZSBsb29wU2VudGVuY2VzOiBzdHJpbmdbXSA9IFtdO1xuICBwcml2YXRlIGxvb3BDb3VudHM6IE1hcDxzdHJpbmcsIG51bWJlcj4gPSBuZXcgTWFwKCk7XG5cbiAgY29uc3RydWN0b3IoaWQ/OiBzdHJpbmcpIHtcbiAgICBzdXBlcihpZCA/PyAnbmFycmF0aXZlLXNlcGFyYXRlJyk7XG4gIH1cblxuICBvdmVycmlkZSBvbkxvb3AoZXZlbnQ6IEZsb3dMb29wRXZlbnQpOiB2b2lkIHtcbiAgICAvLyBEb24ndCBjYWxsIHN1cGVyIOKAlCBrZWVwIGxvb3BzIG91dCBvZiBtYWluIG5hcnJhdGl2ZVxuXG4gICAgLy8gVHJhY2sgY291bnQgZm9yIHN1bW1hcnlcbiAgICBjb25zdCBjb3VudCA9ICh0aGlzLmxvb3BDb3VudHMuZ2V0KGV2ZW50LnRhcmdldCkgPz8gMCkgKyAxO1xuICAgIHRoaXMubG9vcENvdW50cy5zZXQoZXZlbnQudGFyZ2V0LCBjb3VudCk7XG5cbiAgICAvLyBTdG9yZSBpbiBzZXBhcmF0ZSBjaGFubmVsXG4gICAgaWYgKGV2ZW50LmRlc2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLmxvb3BTZW50ZW5jZXMucHVzaChgT24gcGFzcyAke2V2ZW50Lml0ZXJhdGlvbn06ICR7ZXZlbnQuZGVzY3JpcHRpb259IGFnYWluLmApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvb3BTZW50ZW5jZXMucHVzaChgT24gcGFzcyAke2V2ZW50Lml0ZXJhdGlvbn0gdGhyb3VnaCAke2V2ZW50LnRhcmdldH0uYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFJldHVybnMgYWxsIGxvb3AgaXRlcmF0aW9uIHNlbnRlbmNlcyAodGhlIHNlcGFyYXRlIGNoYW5uZWwpLiAqL1xuICBnZXRMb29wU2VudGVuY2VzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gWy4uLnRoaXMubG9vcFNlbnRlbmNlc107XG4gIH1cblxuICAvKiogUmV0dXJucyB0b3RhbCBsb29wIGNvdW50IHBlciB0YXJnZXQuICovXG4gIGdldExvb3BDb3VudHMoKTogTWFwPHN0cmluZywgbnVtYmVyPiB7XG4gICAgcmV0dXJuIG5ldyBNYXAodGhpcy5sb29wQ291bnRzKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGNsZWFyKCk6IHZvaWQge1xuICAgIHN1cGVyLmNsZWFyKCk7XG4gICAgdGhpcy5sb29wU2VudGVuY2VzID0gW107XG4gICAgdGhpcy5sb29wQ291bnRzLmNsZWFyKCk7XG4gIH1cbn1cbiJdfQ==
54
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VwYXJhdGVOYXJyYXRpdmVGbG93UmVjb3JkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2VuZ2luZS9uYXJyYXRpdmUvcmVjb3JkZXJzL1NlcGFyYXRlTmFycmF0aXZlRmxvd1JlY29yZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFFSCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUdwRSxNQUFNLE9BQU8sNkJBQThCLFNBQVEscUJBQXFCO0lBQzlELGFBQWEsR0FBYSxFQUFFLENBQUM7SUFDN0IsVUFBVSxHQUF3QixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRXBELFlBQVksRUFBVztRQUNyQixLQUFLLENBQUMsRUFBRSxJQUFJLG9CQUFvQixDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVRLE1BQU0sQ0FBQyxLQUFvQjtRQUNsQyxzREFBc0Q7UUFFdEQsMEJBQTBCO1FBQzFCLE1BQU0sS0FBSyxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXpDLDRCQUE0QjtRQUM1QixJQUFJLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxXQUFXLEtBQUssQ0FBQyxTQUFTLEtBQUssS0FBSyxDQUFDLFdBQVcsU0FBUyxDQUFDLENBQUM7UUFDckYsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxXQUFXLEtBQUssQ0FBQyxTQUFTLFlBQVksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDakYsQ0FBQztJQUNILENBQUM7SUFFRCxtRUFBbUU7SUFDbkUsZ0JBQWdCO1FBQ2QsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRCwyQ0FBMkM7SUFDM0MsYUFBYTtRQUNYLE9BQU8sSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFUSxLQUFLO1FBQ1osS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2QsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUMxQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNlcGFyYXRlTmFycmF0aXZlRmxvd1JlY29yZGVyIOKAlCBDb2xsZWN0cyBsb29wIGl0ZXJhdGlvbnMgaW4gYSBzZXBhcmF0ZSBjaGFubmVsLlxuICpcbiAqIEtlZXBzIHRoZSBtYWluIG5hcnJhdGl2ZSBjbGVhbiAobm8gbG9vcCBzZW50ZW5jZXMpIHdoaWxlIHByZXNlcnZpbmcgZnVsbFxuICogaXRlcmF0aW9uIGRldGFpbCBpbiBhIHNlcGFyYXRlIGFjY2Vzc29yIGZvciBjb25zdW1lcnMgd2hvIG5lZWQgaXQuXG4gKlxuICogQmVzdCBmb3I6IFVJcyBvciByZXBvcnRzIHdoZXJlIGxvb3AgZGV0YWlsIGlzIGluIGEgY29sbGFwc2libGUgc2VjdGlvbixcbiAqIG9yIExMTSBwaXBlbGluZXMgd2hlcmUgbG9vcCBjb250ZXh0IHNob3VsZCBiZSBhdmFpbGFibGUgYnV0IG5vdCBpbiB0aGUgbWFpbiBwcm9tcHQuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHJlY29yZGVyID0gbmV3IFNlcGFyYXRlTmFycmF0aXZlRmxvd1JlY29yZGVyKCk7XG4gKiBleGVjdXRvci5hdHRhY2hGbG93UmVjb3JkZXIocmVjb3JkZXIpO1xuICogYXdhaXQgZXhlY3V0b3IucnVuKCk7XG4gKlxuICogY29uc3QgbWFpbkVudHJpZXMgPSBleGVjdXRvci5nZXROYXJyYXRpdmVFbnRyaWVzKCk7IC8vIE5vIGxvb3Agc2VudGVuY2VzXG4gKiBjb25zdCBsb29wRGV0YWlsID0gcmVjb3JkZXIuZ2V0TG9vcFNlbnRlbmNlcygpOyAgICAgLy8gQWxsIGxvb3AgZGV0YWlsXG4gKiBgYGBcbiAqL1xuXG5pbXBvcnQgeyBOYXJyYXRpdmVGbG93UmVjb3JkZXIgfSBmcm9tICcuLi9OYXJyYXRpdmVGbG93UmVjb3JkZXIuanMnO1xuaW1wb3J0IHR5cGUgeyBGbG93TG9vcEV2ZW50IH0gZnJvbSAnLi4vdHlwZXMuanMnO1xuXG5leHBvcnQgY2xhc3MgU2VwYXJhdGVOYXJyYXRpdmVGbG93UmVjb3JkZXIgZXh0ZW5kcyBOYXJyYXRpdmVGbG93UmVjb3JkZXIge1xuICBwcml2YXRlIGxvb3BTZW50ZW5jZXM6IHN0cmluZ1tdID0gW107XG4gIHByaXZhdGUgbG9vcENvdW50czogTWFwPHN0cmluZywgbnVtYmVyPiA9IG5ldyBNYXAoKTtcblxuICBjb25zdHJ1Y3RvcihpZD86IHN0cmluZykge1xuICAgIHN1cGVyKGlkID8/ICduYXJyYXRpdmUtc2VwYXJhdGUnKTtcbiAgfVxuXG4gIG92ZXJyaWRlIG9uTG9vcChldmVudDogRmxvd0xvb3BFdmVudCk6IHZvaWQge1xuICAgIC8vIERvbid0IGNhbGwgc3VwZXIg4oCUIGtlZXAgbG9vcHMgb3V0IG9mIG1haW4gbmFycmF0aXZlXG5cbiAgICAvLyBUcmFjayBjb3VudCBmb3Igc3VtbWFyeVxuICAgIGNvbnN0IGNvdW50ID0gKHRoaXMubG9vcENvdW50cy5nZXQoZXZlbnQudGFyZ2V0KSA/PyAwKSArIDE7XG4gICAgdGhpcy5sb29wQ291bnRzLnNldChldmVudC50YXJnZXQsIGNvdW50KTtcblxuICAgIC8vIFN0b3JlIGluIHNlcGFyYXRlIGNoYW5uZWxcbiAgICBpZiAoZXZlbnQuZGVzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMubG9vcFNlbnRlbmNlcy5wdXNoKGBPbiBwYXNzICR7ZXZlbnQuaXRlcmF0aW9ufTogJHtldmVudC5kZXNjcmlwdGlvbn0gYWdhaW4uYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9vcFNlbnRlbmNlcy5wdXNoKGBPbiBwYXNzICR7ZXZlbnQuaXRlcmF0aW9ufSB0aHJvdWdoICR7ZXZlbnQudGFyZ2V0fS5gKTtcbiAgICB9XG4gIH1cblxuICAvKiogUmV0dXJucyBhbGwgbG9vcCBpdGVyYXRpb24gc2VudGVuY2VzICh0aGUgc2VwYXJhdGUgY2hhbm5lbCkuICovXG4gIGdldExvb3BTZW50ZW5jZXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBbLi4udGhpcy5sb29wU2VudGVuY2VzXTtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHRvdGFsIGxvb3AgY291bnQgcGVyIHRhcmdldC4gKi9cbiAgZ2V0TG9vcENvdW50cygpOiBNYXA8c3RyaW5nLCBudW1iZXI+IHtcbiAgICByZXR1cm4gbmV3IE1hcCh0aGlzLmxvb3BDb3VudHMpO1xuICB9XG5cbiAgb3ZlcnJpZGUgY2xlYXIoKTogdm9pZCB7XG4gICAgc3VwZXIuY2xlYXIoKTtcbiAgICB0aGlzLmxvb3BTZW50ZW5jZXMgPSBbXTtcbiAgICB0aGlzLmxvb3BDb3VudHMuY2xlYXIoKTtcbiAgfVxufVxuIl19
@@ -95,11 +95,8 @@
95
95
  * @example Build a live LLM tracker (combining storage + observer):
96
96
  *
97
97
  * ```typescript
98
- * import {
99
- * BoundaryStateTracker,
100
- * type CombinedRecorder,
101
- * type EmitEvent,
102
- * } from 'footprintjs';
98
+ * import { BoundaryStateTracker } from 'footprintjs/trace';
99
+ * import { type CombinedRecorder, type EmitEvent } from 'footprintjs';
103
100
  *
104
101
  * interface LLMLiveState {
105
102
  * readonly partial: string;
@@ -260,4 +257,4 @@ export class BoundaryStateTracker {
260
257
  this.missedUpdates.clear();
261
258
  }
262
259
  }
263
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQm91bmRhcnlTdGF0ZVRyYWNrZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3JlY29yZGVyL0JvdW5kYXJ5U3RhdGVUcmFja2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnSkc7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFdkQsTUFBTSxPQUFnQixvQkFBb0I7SUFJeEMsMERBQTBEO0lBQ3pDLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUVwRDs7b0RBRWdEO0lBQy9CLGFBQWEsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUUzRCx1RUFBdUU7SUFFdkU7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNPLGFBQWEsQ0FBQyxHQUFXLEVBQUUsT0FBZTtRQUNsRCxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLFNBQVMsRUFBRSxFQUFFLENBQUM7WUFDeEMsT0FBTyxDQUFDLElBQUksQ0FDVixJQUFJLElBQUksQ0FBQyxFQUFFLG9CQUFvQixHQUFHLHFEQUFxRDtnQkFDckYsa0VBQWtFLENBQ3JFLENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNPLGNBQWMsQ0FBQyxHQUFXLEVBQUUsT0FBaUM7UUFDckUsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7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Y2VzQ29udGVudCI6WyIvKipcbiAqIEJvdW5kYXJ5U3RhdGVUcmFja2VyPFRTdGF0ZT4g4oCUIHRoaXJkIHN0b3JhZ2UgcHJpbWl0aXZlIG9uIHRoZSByZWNvcmRlclxuICogc2hlbGYsIGFsb25nc2lkZSBgU2VxdWVuY2VSZWNvcmRlcjxUPmAgYW5kIGBLZXllZFJlY29yZGVyPFQ+YC5cbiAqXG4gKiAqKk1lbnRhbCBtb2RlbCDigJQgb2JzZXJ2ZXJzIHZzLiBib29ra2VlcGVyczoqKlxuICpcbiAqICAgYFNjb3BlUmVjb3JkZXJgIC8gYEZsb3dSZWNvcmRlcmAgLyBgRW1pdFJlY29yZGVyYCAvIGBDb21iaW5lZFJlY29yZGVyYFxuICogICAgIGFyZSBPQlNFUlZFUiBpbnRlcmZhY2VzIOKAlCB0aGV5IGRlc2NyaWJlIGhvdyBhIHJlY29yZGVyIGhlYXJzXG4gKiAgICAgZXZlbnRzIGZyb20gdGhlIGV4ZWN1dG9yLlxuICpcbiAqICAgYFNlcXVlbmNlUmVjb3JkZXI8VD5gIC8gYEtleWVkUmVjb3JkZXI8VD5gIC8gYEJvdW5kYXJ5U3RhdGVUcmFja2VyPFRTdGF0ZT5gXG4gKiAgICAgYXJlIFNUT1JBR0UgcHJpbWl0aXZlcyDigJQgdGhyZWUgZGlmZmVyZW50IGJvb2trZWVwaW5nIHNoZWx2ZXMgd2l0aFxuICogICAgIGRpZmZlcmVudCBkdXJhYmlsaXR5IGFuZCBpbmRleGluZyBwcm9wZXJ0aWVzLiBBIHJlYWwgcmVjb3JkZXJcbiAqICAgICBjbGFzcyB0eXBpY2FsbHkgcGlja3MgT05FIG9ic2VydmVyIGludGVyZmFjZSBBTkQgT05FIHN0b3JhZ2VcbiAqICAgICBzaGVsZiwgY29tYmluaW5nIHRoZW0gdmlhIGBleHRlbmRzICsgaW1wbGVtZW50c2AuXG4gKlxuICogKipXaGF0IHRoaXMgcHJpbWl0aXZlIGFuc3dlcnM6KiogXCJBdCBhbnkgbW9tZW50IGR1cmluZyB0aGUgcnVuLCB3aGF0XG4gKiBpcyB0aGUgTElWRSB0cmFuc2llbnQgc3RhdGUgb2YgZXZlcnkgY3VycmVudGx5LWFjdGl2ZSBib3VuZGFyeT9cIlxuICpcbiAqIEEgXCJib3VuZGFyeVwiIGlzIGEgbWF0Y2hlZCBldmVudCBwYWlyIGBbc3RhcnQsIHN0b3BdYCBicmFja2V0aW5nIGFuXG4gKiBpbnRlcnZhbCDigJQgZm9yIGV4YW1wbGUsIGAobGxtX3N0YXJ0LCBsbG1fZW5kKWAgZm9yIGFuIExMTSBjYWxsLFxuICogYCh0b29sX3N0YXJ0LCB0b29sX2VuZClgIGZvciB0b29sIGV4ZWN1dGlvbiwgYCh0dXJuX3N0YXJ0LCB0dXJuX2VuZClgXG4gKiBmb3IgYW4gYWdlbnQgdHVybi4gQmV0d2VlbiB0aGUgYnJhY2tldHMsIGludGVybWVkaWF0ZSBldmVudHMgZXZvbHZlXG4gKiB0aGUgYm91bmRhcnkncyBzdGF0ZSAodG9rZW4gY2h1bmtzIGFjY3VtdWxhdGluZyBpbnRvIGEgcGFydGlhbFxuICogYW5zd2VyLCBhcmdzIHN0cmVhbWluZyBpbiwgZXRjLikuIE9uIGBzdG9wYCwgdGhlIHN0YXRlIGNsZWFycy5cbiAqXG4gKiBBbGdvcml0aG1pY2FsbHkgdGhpcyBpcyB0aGUgKipERlMgYnJhY2tldC1zZXF1ZW5jZSBwYXR0ZXJuKiog4oCUXG4gKiBzdGFjay1mcmFtZSBzdGF0ZSBkdXJpbmcgYSBncmFwaC10cmF2ZXJzYWwgaW50ZXJ2YWwuIFNhbWUgc2hhcGUgdXNlZFxuICogYnkgVGFyamFuJ3MgU0NDIGFsZ29yaXRobSwgdHJlZSBkZWNvbXBvc2l0aW9uLCBhbmQgcHVzaC1kb3duXG4gKiBhdXRvbWF0YS4gVGhlIGBhY3RpdmVgIG1hcCBpcyB0aGUgb3Blbi1icmFja2V0cyBzdGFjayBhdCBhbnkgbW9tZW50LlxuICpcbiAqICoqQ29tcGFyaXNvbiB3aXRoIHRoZSBvdGhlciBzdG9yYWdlIHByaW1pdGl2ZXM6KipcbiAqXG4gKiB8IFByaW1pdGl2ZSAgICAgICAgICAgICAgICAgICAgICAgfCBTdG9yZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBUaW1lIHNjb3BlICAgICAgICAgIHwgTWVtb3J5ICAgICAgfFxuICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLXxcbiAqIHwgYFNlcXVlbmNlUmVjb3JkZXI8VD5gICAgICAgICAgICB8IGFwcGVuZC1vbmx5IG9yZGVyZWQgKyBrZXllZCBlbnRyaWVzICB8IGR1cmFibGUgYWNyb3NzIHJ1biAgfCBPKE4gZXZlbnRzKSB8XG4gKiB8IGBLZXllZFJlY29yZGVyPFQ+YCAgICAgICAgICAgICAgfCAxOjEgZW50cnkgcGVyIGBydW50aW1lU3RhZ2VJZGAgICAgICAgfCBkdXJhYmxlIGFjcm9zcyBydW4gIHwgTyhOIHN0ZXBzKSAgfFxuICogfCBgQm91bmRhcnlTdGF0ZVRyYWNrZXI8VFN0YXRlPmAgIHwgdHJhbnNpZW50IGJyYWNrZXQtc2NvcGVkIHN0YXRlICAgICAgIHwgbGl2ZTsgY2xlYXJzIG9uIHN0b3AgfCBPKEsgYWN0aXZlKSB8XG4gKlxuICogKipXaGVuIHRvIHBpY2sgd2hpY2g6KipcbiAqXG4gKiAgIC0gXCJJIG5lZWQgdG8ga2VlcCBhIHBlcm1hbmVudCBsb2cgb2YgZXZlcnkgZXZlbnQgZm9yIHRpbWUtdHJhdmVsXCJcbiAqICAgICAg4oaSIGBTZXF1ZW5jZVJlY29yZGVyPFQ+YFxuICogICAtIFwiSSB3YW50IG9uZSBkdXJhYmxlIHJlY29yZCBwZXIgc3RhZ2UgZXhlY3V0aW9uIChlLmcuLCBtZXRyaWNzKVwiXG4gKiAgICAgIOKGkiBgS2V5ZWRSZWNvcmRlcjxUPmBcbiAqICAgLSBcIkkgbmVlZCB0byBrbm93IHdoYXQncyBoYXBwZW5pbmcgUklHSFQgTk9XIGluc2lkZSBhbiBpbi1mbGlnaHRcbiAqICAgICBib3VuZGFyeSAoZS5nLiwgcGFydGlhbCBMTE0gc3RyZWFtLCBwYXJ0aWFsIHRvb2wgYXJncylcIlxuICogICAgICDihpIgYEJvdW5kYXJ5U3RhdGVUcmFja2VyPFRTdGF0ZT5gICh0aGlzIGNsYXNzKVxuICpcbiAqICoqV2hhdCB0aGlzIGlzIE5PVCBmb3I6KipcbiAqXG4gKiAgIC0gVGltZS10cmF2ZWwgcXVlcmllcyAoXCJ3aGF0IHdhcyB0aGUgc3RhdGUgYXQgcGFzdCBzbGlkZXIgc3RlcCBOP1wiKVxuICogICAgIOKAlCB0cmFuc2llbnQgc3RhdGUgY2xlYXJzIG9uIHN0b3AuIEZvciB0aW1lLXRyYXZlbCwgc25hcHNob3QgdGhlXG4gKiAgICAgc3RhdGUgYXQgZWFjaCBlbWl0IGludG8gYSBzZXBhcmF0ZSBgU2VxdWVuY2VSZWNvcmRlcjxUU3RhdGU+YCxcbiAqICAgICBvciB3YWl0IGZvciBhIGZ1dHVyZSBgQm91bmRhcnlTbmFwc2hvdFJlY29yZGVyPFRTdGF0ZT5gIHByaW1pdGl2ZS5cbiAqXG4gKiAgIC0gQWdncmVnYXRpb25zIGFjcm9zcyB0aGUgd2hvbGUgcnVuICh0b3RhbHMsIGNvdW50cykg4oCUIHRob3NlIGFyZVxuICogICAgIGBTZXF1ZW5jZVJlY29yZGVyLmFnZ3JlZ2F0ZSgpYCAvIGBLZXllZFJlY29yZGVyLmFnZ3JlZ2F0ZSgpYC5cbiAqXG4gKiAgIC0gU3RhZ2UtbGV2ZWwgY29uY2VybnMg4oCUIHRob3NlIHVzZSBgU2NvcGVSZWNvcmRlci5vblN0YWdlU3RhcnRgIC9cbiAqICAgICBgU2NvcGVSZWNvcmRlci5vblN0YWdlRW5kYC4gVGhpcyBwcmltaXRpdmUgb3BlcmF0ZXMgYXQgZmluZXJcbiAqICAgICBncmFudWxhcml0eSAoZXZlbnRzIGVtaXR0ZWQgRFVSSU5HIGEgc3RhZ2UgZXhlY3V0aW9uKS5cbiAqXG4gKiAqKkxpZmVjeWNsZSBjb250cmFjdCDigJQgU1RSSUNUOioqXG4gKlxuICogICBFdmVyeSBgc3RhcnRCb3VuZGFyeShrZXksIC4uLilgIGNhbGwgTVVTVCBiZSBwYWlyZWQgd2l0aCBhXG4gKiAgIGBzdG9wQm91bmRhcnkoa2V5KWAgY2FsbC4gRmFpbHVyZSB0byB3aXJlIHRoZSBzdG9wIHNpZGUgcHJvZHVjZXMgYVxuICogICBtZW1vcnkgbGVhazogdGhlIGFjdGl2ZSBtYXAgZ3Jvd3Mgd2l0aG91dCBib3VuZCwgYW5kIGBnZXRBbGxBY3RpdmUoKWBcbiAqICAgcmV0dXJucyBzdGFsZSBlbnRyaWVzIHRoYXQgbG9vayBpbi1mbGlnaHQgYnV0IGFyZW4ndC4gQ29tbW9uIGNhdXNlOlxuICogICBzdWJjbGFzcyB3aXJlcyBgc3RhcnRgIHRvIG9uZSBldmVudCBoYW5kbGVyIGFuZCBmb3JnZXRzIHRvIHdpcmVcbiAqICAgYHN0b3BgLiAqKkFsd2F5cyB3aXJlIGJvdGggYXQgdGhlIHNhbWUgdGltZS4qKlxuICpcbiAqICAgRGV2IG1vZGUgKGBlbmFibGVEZXZNb2RlKClgKSBkZXRlY3RzIGxlYWtzIGF0IGBjbGVhcigpYCB0aW1lIOKAlFxuICogICB3YXJuaW5nIGluY2x1ZGVzIHRoZSBsZWFrZWQga2V5cyBzbyB5b3UgY2FuIGZpbmQgdGhlIG1pc3Npbmcgd2lyaW5nLlxuICpcbiAqICoqQ29uY3VycmVuY3kgLyBuZXN0aW5nOioqXG4gKlxuICogICAtIENvbmN1cnJlbnQgYm91bmRhcmllcyAocGFyYWxsZWwgYnJhbmNoZXMgd2l0aCB0d28gTExNIGNhbGxzXG4gKiAgICAgYWN0aXZlIGF0IG9uY2UpIHdvcmsgY29ycmVjdGx5OiBlYWNoIGlzIGtleWVkIGluZGVwZW5kZW50bHkgaW5cbiAqICAgICB0aGUgYWN0aXZlIG1hcC5cbiAqICAgLSBOZXN0ZWQgYm91bmRhcmllcyBvZiBESUZGRVJFTlQgS0lORFMgKEFnZW50IGJvdW5kYXJ5IGNvbnRhaW5zXG4gKiAgICAgTExNIGJvdW5kYXJ5KSByZXF1aXJlIFNFUEFSQVRFIHRyYWNrZXIgaW5zdGFuY2VzIOKAlCBvbmUgcGVyIGtpbmQuXG4gKiAgICAgVGhlIGJhc2UgY2xhc3MgdHJhY2tzIG9uZSBib3VuZGFyeSBraW5kIHBlciBpbnN0YW5jZS5cbiAqXG4gKiAqKktleSBjb252ZW50aW9uOioqXG4gKlxuICogICBUaGUgYGtleTogc3RyaW5nYCBpcyB3aGF0ZXZlciB5b3VyIHN1YmNsYXNzIHBpY2tzLiBDb252ZW50aW9uOlxuICogICB1c2UgYHJ1bnRpbWVTdGFnZUlkYCB3aGVuIHRoZSBib3VuZGFyeSBtYXBzIDE6MSB0byBhIHN0YWdlXG4gKiAgIGV4ZWN1dGlvbiDigJQgdGhpcyBnaXZlcyBmcmVlIGludGVyb3Agd2l0aCBgU2VxdWVuY2VSZWNvcmRlclxuICogICAuZ2V0RW50cmllc0ZvclN0ZXBgLCBgS2V5ZWRSZWNvcmRlci5nZXRCeUtleWAsIGBmaW5kQ29tbWl0YCAvXG4gKiAgIGBmaW5kTGFzdFdyaXRlcmAsIGFuZCB0aGUgcmVzdCBvZiB0aGUgdHJhY2UgZWNvc3lzdGVtLiBVc2UgYSBtb3JlXG4gKiAgIGdyYW51bGFyIGtleSAoZS5nLiwgYHRvb2xDYWxsSWRgKSBvbmx5IHdoZW4gdGhlcmUgYXJlIG11bHRpcGxlXG4gKiAgIGNvbmN1cnJlbnQgYm91bmRhcmllcyBXSVRISU4gb25lIHN0YWdlIGV4ZWN1dGlvbi5cbiAqXG4gKiBAZXhhbXBsZSBCdWlsZCBhIGxpdmUgTExNIHRyYWNrZXIgKGNvbWJpbmluZyBzdG9yYWdlICsgb2JzZXJ2ZXIpOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7XG4gKiAgIEJvdW5kYXJ5U3RhdGVUcmFja2VyLFxuICogICB0eXBlIENvbWJpbmVkUmVjb3JkZXIsXG4gKiAgIHR5cGUgRW1pdEV2ZW50LFxuICogfSBmcm9tICdmb290cHJpbnRqcyc7XG4gKlxuICogaW50ZXJmYWNlIExMTUxpdmVTdGF0ZSB7XG4gKiAgIHJlYWRvbmx5IHBhcnRpYWw6IHN0cmluZztcbiAqICAgcmVhZG9ubHkgdG9rZW5zOiBudW1iZXI7XG4gKiB9XG4gKlxuICogY2xhc3MgTGl2ZUxMTVRyYWNrZXJcbiAqICAgZXh0ZW5kcyBCb3VuZGFyeVN0YXRlVHJhY2tlcjxMTE1MaXZlU3RhdGU+ICAgLy8gU1RPUkFHRSBzaGVsZlxuICogICBpbXBsZW1lbnRzIENvbWJpbmVkUmVjb3JkZXIgICAgICAgICAgICAgICAgICAgLy8gT0JTRVJWRVIgaW50ZXJmYWNlXG4gKiB7XG4gKiAgIHJlYWRvbmx5IGlkID0gJ2xpdmUtbGxtJztcbiAqXG4gKiAgIC8vIE9ic2VydmVyIGhhbGYg4oCUIHRyYW5zbGF0ZSBldmVudHMgaW50byBicmFja2V0IG11dGF0aW9ucy5cbiAqICAgb25FbWl0KGV2ZW50OiBFbWl0RXZlbnQpOiB2b2lkIHtcbiAqICAgICBpZiAoZXZlbnQubmFtZSA9PT0gJ2FnZW50Zm9vdHByaW50LnN0cmVhbS5sbG1fc3RhcnQnKSB7XG4gKiAgICAgICB0aGlzLnN0YXJ0Qm91bmRhcnkoZXZlbnQucnVudGltZVN0YWdlSWQsIHsgcGFydGlhbDogJycsIHRva2VuczogMCB9KTtcbiAqICAgICB9IGVsc2UgaWYgKGV2ZW50Lm5hbWUgPT09ICdhZ2VudGZvb3RwcmludC5zdHJlYW0ubGxtX2VuZCcpIHtcbiAqICAgICAgIHRoaXMuc3RvcEJvdW5kYXJ5KGV2ZW50LnJ1bnRpbWVTdGFnZUlkKTtcbiAqICAgICB9IGVsc2UgaWYgKGV2ZW50Lm5hbWUgPT09ICdhZ2VudGZvb3RwcmludC5zdHJlYW0udG9rZW4nKSB7XG4gKiAgICAgICB0aGlzLnVwZGF0ZUJvdW5kYXJ5KGV2ZW50LnJ1bnRpbWVTdGFnZUlkLCAocykgPT4gKHtcbiAqICAgICAgICAgcGFydGlhbDogcy5wYXJ0aWFsICsgKGV2ZW50LnBheWxvYWQgYXMgeyBjb250ZW50OiBzdHJpbmcgfSkuY29udGVudCxcbiAqICAgICAgICAgdG9rZW5zOiBzLnRva2VucyArIDEsXG4gKiAgICAgICB9KSk7XG4gKiAgICAgfVxuICogICB9XG4gKlxuICogICAvLyBQdWJsaWMgcmVhZCBBUEkg4oCUIE8oMSkgYXQgYW55IG1vbWVudC5cbiAqICAgaXNJbkZsaWdodCgpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMuaGFzQWN0aXZlOyB9XG4gKiAgIGdldFBhcnRpYWwoc3RhZ2VJZDogc3RyaW5nKTogc3RyaW5nIHtcbiAqICAgICByZXR1cm4gdGhpcy5nZXRBY3RpdmUoc3RhZ2VJZCk/LnBhcnRpYWwgPz8gJyc7XG4gKiAgIH1cbiAqIH1cbiAqXG4gKiAvLyBBdHRhY2hlZCB0aGUgc2FtZSB3YXkgYXMgYW55IG90aGVyIENvbWJpbmVkUmVjb3JkZXIuXG4gKiBjb25zdCB0cmFja2VyID0gbmV3IExpdmVMTE1UcmFja2VyKCk7XG4gKiBleGVjdXRvci5hdHRhY2hDb21iaW5lZFJlY29yZGVyKHRyYWNrZXIpO1xuICogYXdhaXQgZXhlY3V0b3IucnVuKHsgaW5wdXQgfSk7XG4gKlxuICogLy8gUmVhZCBsaXZlIHN0YXRlIGF0IGFueSB0aW1lIGR1cmluZyBvciBhZnRlciB0aGUgcnVuLlxuICogdHJhY2tlci5pc0luRmxpZ2h0KCk7XG4gKiB0cmFja2VyLmdldFBhcnRpYWwocmlkKTtcbiAqIGBgYFxuICovXG5cbmltcG9ydCB7IGlzRGV2TW9kZSB9IGZyb20gJy4uL3Njb3BlL2RldGVjdENpcmN1bGFyLmpzJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJvdW5kYXJ5U3RhdGVUcmFja2VyPFRTdGF0ZT4ge1xuICAvKiogU3RhYmxlIGlkIOKAlCBzYW1lIGlkZW1wb3RlbmN5IGNvbnRyYWN0IGFzIG90aGVyIHJlY29yZGVycy4gKi9cbiAgYWJzdHJhY3QgcmVhZG9ubHkgaWQ6IHN0cmluZztcblxuICAvKiogT3Blbi1icmFja2V0cyBzdGFjazoga2V5IOKGkiBjdXJyZW50IHRyYW5zaWVudCBzdGF0ZS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBhY3RpdmUgPSBuZXcgTWFwPHN0cmluZywgVFN0YXRlPigpO1xuXG4gIC8qKiBQZXIta2V5IGNvdW50IG9mIGB1cGRhdGVCb3VuZGFyeWAgY2FsbHMgdGhhdCBsYW5kZWQgd2l0aG91dCBhXG4gICAqICBtYXRjaGluZyBhY3RpdmUgYm91bmRhcnkuIERyaXZlcyByYXRlLWxpbWl0ZWQgZGV2LW1vZGUgd2FybmluZ3NcbiAgICogIHNvIGEgc3R1Y2sgbG9vcCBkb2Vzbid0IHNwYW0gdGhlIGNvbnNvbGUuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgbWlzc2VkVXBkYXRlcyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG5cbiAgLy8g4pSA4pSAIE11dGF0b3IgQVBJIChzdWJjbGFzcyBjYWxscyB0aGVzZSBmcm9tIG9ic2VydmVyIGhvb2tzKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKipcbiAgICogT3BlbiBhIG5ldyBib3VuZGFyeSB3aXRoIGluaXRpYWwgdHJhbnNpZW50IHN0YXRlLlxuICAgKlxuICAgKiBJZiBhIGJvdW5kYXJ5IHdpdGggdGhlIHNhbWUgYGtleWAgaXMgYWxyZWFkeSBhY3RpdmUsIHRoZSBwcmlvclxuICAgKiBzdGF0ZSBpcyBvdmVyd3JpdHRlbiAobGFzdC13cml0ZXItd2lucykuIEluIGRldiBtb2RlLCBhIHdhcm5pbmdcbiAgICogaXMgbG9nZ2VkIGJlY2F1c2UgcmUtc3RhcnRpbmcgYW4gYWN0aXZlIGtleSB1c3VhbGx5IGluZGljYXRlcyBhXG4gICAqIG1pc3NlZCBgc3RvcEJvdW5kYXJ5YCBjYWxsIHVwc3RyZWFtLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IEJvdW5kYXJ5IGlkZW50aWZpZXIg4oCUIGJ5IGNvbnZlbnRpb24sIGBydW50aW1lU3RhZ2VJZGBcbiAgICogICAgICAgICAgICBmb3IgMToxLXdpdGgtc3RhZ2UgYm91bmRhcmllcywgb3IgYSBtb3JlIGdyYW51bGFyIGlkXG4gICAqICAgICAgICAgICAgKGUuZy4sIGB0b29sQ2FsbElkYCkgd2hlbiBtdWx0aXBsZSBjb25jdXJyZW50IGJvdW5kYXJpZXNcbiAgICogICAgICAgICAgICBydW4gd2l0aGluIG9uZSBzdGFnZSBleGVjdXRpb24uXG4gICAqIEBwYXJhbSBpbml0aWFsIEluaXRpYWwgc3RhdGUg4oCUIHR5cGVkIGJ5IGBUU3RhdGVgLlxuICAgKi9cbiAgcHJvdGVjdGVkIHN0YXJ0Qm91bmRhcnkoa2V5OiBzdHJpbmcsIGluaXRpYWw6IFRTdGF0ZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLmFjdGl2ZS5oYXMoa2V5KSAmJiBpc0Rldk1vZGUoKSkge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgWyR7dGhpcy5pZH1dIHN0YXJ0Qm91bmRhcnkoJyR7a2V5fScpIGNhbGxlZCB3aGlsZSBhbiBhY3RpdmUgYm91bmRhcnkgYWxyZWFkeSBleGlzdHMuIGAgK1xuICAgICAgICAgICdPdmVyd3JpdGluZyBwcmlvciBzdGF0ZSDigJQgbGlrZWx5IGEgbWlzc2VkIHN0b3BCb3VuZGFyeSB1cHN0cmVhbS4nLFxuICAgICAgKTtcbiAgICB9XG4gICAgdGhpcy5hY3RpdmUuc2V0KGtleSwgaW5pdGlhbCk7XG4gIH1cblxuICAvKipcbiAgICogRXZvbHZlIHRoZSB0cmFuc2llbnQgc3RhdGUgb2YgYW4gYWN0aXZlIGJvdW5kYXJ5IHVzaW5nIGFuIHVwZGF0ZXJcbiAgICogZnVuY3Rpb24uIFNpbGVudCBuby1vcCBpZiBubyBib3VuZGFyeSBpcyBhY3RpdmUgZm9yIGBrZXlgXG4gICAqIChkZWZlbnNpdmUgYWdhaW5zdCBvdXQtb2Ytb3JkZXIgZXZlbnRzKS4gSW4gZGV2IG1vZGUsIGEgcmF0ZS1saW1pdGVkXG4gICAqIHdhcm5pbmcgaXMgbG9nZ2VkIG9uIHRoZSAxc3QsIDEwdGgsIGFuZCAxMDB0aCBtaXNzZWQgdXBkYXRlIHBlciBrZXkuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgICAgICBCb3VuZGFyeSBpZGVudGlmaWVyIChtdXN0IG1hdGNoIGEgcHJpb3IgYHN0YXJ0Qm91bmRhcnlgKS5cbiAgICogQHBhcmFtIHVwZGF0ZXIgIFB1cmUgZnVuY3Rpb246IHByZXZpb3VzIHN0YXRlIOKGkiBuZXh0IHN0YXRlLlxuICAgKi9cbiAgcHJvdGVjdGVkIHVwZGF0ZUJvdW5kYXJ5KGtleTogc3RyaW5nLCB1cGRhdGVyOiAocHJldjogVFN0YXRlKSA9PiBUU3RhdGUpOiB2b2lkIHtcbiAgICBjb25zdCBjdXIgPSB0aGlzLmFjdGl2ZS5nZXQoa2V5KTtcbiAgICBpZiAoY3VyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgICBjb25zdCBuID0gKHRoaXMubWlzc2VkVXBkYXRlcy5nZXQoa2V5KSA/PyAwKSArIDE7XG4gICAgICAgIHRoaXMubWlzc2VkVXBkYXRlcy5zZXQoa2V5LCBuKTtcbiAgICAgICAgaWYgKG4gPT09IDEpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oYFske3RoaXMuaWR9XSB1cGRhdGVCb3VuZGFyeSgnJHtrZXl9Jykg4oCUIG5vIGFjdGl2ZSBib3VuZGFyeS4gVXBkYXRlIGRyb3BwZWQuYCk7XG4gICAgICAgIH0gZWxzZSBpZiAobiA9PT0gMTAgfHwgbiA9PT0gMTAwKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKGBbJHt0aGlzLmlkfV0gdXBkYXRlQm91bmRhcnkoJyR7a2V5fScpIOKAlCAke259IGRyb3BwZWQgdXBkYXRlcy4gV2lyaW5nIGJ1Zz9gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmFjdGl2ZS5zZXQoa2V5LCB1cGRhdGVyKGN1cikpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlIHRoZSBib3VuZGFyeSBpZGVudGlmaWVkIGJ5IGBrZXlgIGFuZCByZXR1cm4gaXRzIEZJTkFMXG4gICAqIHRyYW5zaWVudCBzdGF0ZSAoZm9yIGFueSBjbGVhbnVwIHRoZSBzdWJjbGFzcyB3YW50cyDigJQgZS5nLiwgZW1pdCBhXG4gICAqIHNuYXBzaG90IHRvIGEgU2VxdWVuY2VSZWNvcmRlciBmb3IgZHVyYWJsZSBzdG9yYWdlKS5cbiAgICpcbiAgICogQHBhcmFtIGtleSBCb3VuZGFyeSBpZGVudGlmaWVyLlxuICAgKiBAcmV0dXJucyBUaGUgZmluYWwgc3RhdGUsIG9yIGB1bmRlZmluZWRgIGlmIG5vIGJvdW5kYXJ5IHdhcyBhY3RpdmUuXG4gICAqL1xuICBwcm90ZWN0ZWQgc3RvcEJvdW5kYXJ5KGtleTogc3RyaW5nKTogVFN0YXRlIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBmaW5hbCA9IHRoaXMuYWN0aXZlLmdldChrZXkpO1xuICAgIHRoaXMuYWN0aXZlLmRlbGV0ZShrZXkpO1xuICAgIHJldHVybiBmaW5hbDtcbiAgfVxuXG4gIC8vIOKUgOKUgCBSZWFkIEFQSSAoY29uc3VtZXJzIGNhbGwgdGhlc2Ug4oCUIE8oMSkpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBDdXJyZW50IHRyYW5zaWVudCBzdGF0ZSBvZiBPTkUgYWN0aXZlIGJvdW5kYXJ5LiBgdW5kZWZpbmVkYCBpZiBub1xuICAgKiAgYm91bmRhcnkgaXMgYWN0aXZlIGZvciBga2V5YC4gKi9cbiAgZ2V0QWN0aXZlKGtleTogc3RyaW5nKTogVFN0YXRlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5hY3RpdmUuZ2V0KGtleSk7XG4gIH1cblxuICAvKipcbiAgICogQWxsIGN1cnJlbnRseS1hY3RpdmUgYm91bmRhcmllcy5cbiAgICpcbiAgICogKipUeXBlLW9ubHkgcmVhZG9ubHk6KiogdGhlIHJldHVybmVkIHJlZmVyZW5jZSBJUyB0aGUgaW50ZXJuYWwgTWFwLlxuICAgKiBUeXBlU2NyaXB0IHByZXZlbnRzIG11dGF0aW9uIHRocm91Z2ggdGhlIGBSZWFkb25seU1hcGAgdHlwZSwgYnV0IGFcbiAgICogcnVudGltZSBjYXN0IG9yIG5vbi1UUyBjb25zdW1lciBjYW4gbXV0YXRlIGl0IGFuZCBjb3JydXB0IGludGVybmFsXG4gICAqIHN0YXRlLiAqKkRvIG5vdCBtdXRhdGUuKipcbiAgICovXG4gIGdldEFsbEFjdGl2ZSgpOiBSZWFkb25seU1hcDxzdHJpbmcsIFRTdGF0ZT4ge1xuICAgIHJldHVybiB0aGlzLmFjdGl2ZTtcbiAgfVxuXG4gIC8qKiBUcnVlIGlmIGFueSBib3VuZGFyeSBpcyBjdXJyZW50bHkgYWN0aXZlLiBPKDEpLiAqL1xuICBnZXQgaGFzQWN0aXZlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmFjdGl2ZS5zaXplID4gMDtcbiAgfVxuXG4gIC8qKiBOdW1iZXIgb2YgY3VycmVudGx5LWFjdGl2ZSBib3VuZGFyaWVzLiBPKDEpLiAqL1xuICBnZXQgYWN0aXZlQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5hY3RpdmUuc2l6ZTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBMaWZlY3ljbGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqXG4gICAqIFJlc2V0IGFsbCB0cmFuc2llbnQgc3RhdGUuIENhbGxlZCBieSBleGVjdXRvcnMgYmVmb3JlIGVhY2ggYHJ1bigpYFxuICAgKiBzbyBjb25zdW1lcnMgZ2V0IGEgY2xlYW4gc2xhdGUgcGVyIHJ1biDigJQgc2FtZSBsaWZlY3ljbGUgY29udHJhY3RcbiAgICogYXMgYFNlcXVlbmNlUmVjb3JkZXIuY2xlYXIoKWAuXG4gICAqXG4gICAqIEluIGRldiBtb2RlLCB3YXJucyBpZiBhbnkgYm91bmRhcmllcyBhcmUgc3RpbGwgYWN0aXZlIHdoZW4gY2FsbGVkXG4gICAqIOKAlCBsaWtlbHkgaW5kaWNhdGVzIGEgbWlzc2VkIGBzdG9wQm91bmRhcnlgIHVwc3RyZWFtLiBUaGUgbGVha2VkXG4gICAqIGtleXMgYXJlIGxpc3RlZCAodHJ1bmNhdGVkIHRvIDEwKSBzbyB0aGUgd2lyaW5nIGJ1ZyBpcyBmaW5kYWJsZS5cbiAgICovXG4gIGNsZWFyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmFjdGl2ZS5zaXplID4gMCAmJiBpc0Rldk1vZGUoKSkge1xuICAgICAgY29uc3Qga2V5cyA9IFsuLi50aGlzLmFjdGl2ZS5rZXlzKCldO1xuICAgICAgY29uc3QgaGVhZCA9IGtleXMuc2xpY2UoMCwgMTApLmpvaW4oJywgJyk7XG4gICAgICBjb25zdCBtb3JlID0ga2V5cy5sZW5ndGggPiAxMCA/IGAgLi4uKCske2tleXMubGVuZ3RoIC0gMTB9IG1vcmUpYCA6ICcnO1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgWyR7dGhpcy5pZH1dIGNsZWFyKCkgY2FsbGVkIHdpdGggJHt0aGlzLmFjdGl2ZS5zaXplfSBgICtcbiAgICAgICAgICAnc3RpbGwtYWN0aXZlIGJvdW5kYXJpZXMuIE1pc3NlZCBzdG9wQm91bmRhcnk/ICcgK1xuICAgICAgICAgIGBMZWFrZWQga2V5czogJHtoZWFkfSR7bW9yZX1gLFxuICAgICAgKTtcbiAgICB9XG4gICAgdGhpcy5hY3RpdmUuY2xlYXIoKTtcbiAgICB0aGlzLm1pc3NlZFVwZGF0ZXMuY2xlYXIoKTtcbiAgfVxufVxuIl19
260
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQm91bmRhcnlTdGF0ZVRyYWNrZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3JlY29yZGVyL0JvdW5kYXJ5U3RhdGVUcmFja2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2SUc7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFdkQsTUFBTSxPQUFnQixvQkFBb0I7SUFJeEMsMERBQTBEO0lBQ3pDLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUVwRDs7b0RBRWdEO0lBQy9CLGFBQWEsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUUzRCx1RUFBdUU7SUFFdkU7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNPLGFBQWEsQ0FBQyxHQUFXLEVBQUUsT0FBZTtRQUNsRCxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLFNBQVMsRUFBRSxFQUFFLENBQUM7WUFDeEMsT0FBTyxDQUFDLElBQUksQ0FDVixJQUFJLElBQUksQ0FBQyxFQUFFLG9CQUFvQixHQUFHLHFEQUFxRDtnQkFDckYsa0VBQWtFLENBQ3JFLENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNPLGNBQWMsQ0FBQyxHQUFXLEVBQUUsT0FBaUM7UUFDckUsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFD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Q29udGVudCI6WyIvKipcbiAqIEJvdW5kYXJ5U3RhdGVUcmFja2VyPFRTdGF0ZT4g4oCUIHRoaXJkIHN0b3JhZ2UgcHJpbWl0aXZlIG9uIHRoZSByZWNvcmRlclxuICogc2hlbGYsIGFsb25nc2lkZSBgU2VxdWVuY2VSZWNvcmRlcjxUPmAgYW5kIGBLZXllZFJlY29yZGVyPFQ+YC5cbiAqXG4gKiAqKk1lbnRhbCBtb2RlbCDigJQgb2JzZXJ2ZXJzIHZzLiBib29ra2VlcGVyczoqKlxuICpcbiAqICAgYFNjb3BlUmVjb3JkZXJgIC8gYEZsb3dSZWNvcmRlcmAgLyBgRW1pdFJlY29yZGVyYCAvIGBDb21iaW5lZFJlY29yZGVyYFxuICogICAgIGFyZSBPQlNFUlZFUiBpbnRlcmZhY2VzIOKAlCB0aGV5IGRlc2NyaWJlIGhvdyBhIHJlY29yZGVyIGhlYXJzXG4gKiAgICAgZXZlbnRzIGZyb20gdGhlIGV4ZWN1dG9yLlxuICpcbiAqICAgYFNlcXVlbmNlUmVjb3JkZXI8VD5gIC8gYEtleWVkUmVjb3JkZXI8VD5gIC8gYEJvdW5kYXJ5U3RhdGVUcmFja2VyPFRTdGF0ZT5gXG4gKiAgICAgYXJlIFNUT1JBR0UgcHJpbWl0aXZlcyDigJQgdGhyZWUgZGlmZmVyZW50IGJvb2trZWVwaW5nIHNoZWx2ZXMgd2l0aFxuICogICAgIGRpZmZlcmVudCBkdXJhYmlsaXR5IGFuZCBpbmRleGluZyBwcm9wZXJ0aWVzLiBBIHJlYWwgcmVjb3JkZXJcbiAqICAgICBjbGFzcyB0eXBpY2FsbHkgcGlja3MgT05FIG9ic2VydmVyIGludGVyZmFjZSBBTkQgT05FIHN0b3JhZ2VcbiAqICAgICBzaGVsZiwgY29tYmluaW5nIHRoZW0gdmlhIGBleHRlbmRzICsgaW1wbGVtZW50c2AuXG4gKlxuICogKipXaGF0IHRoaXMgcHJpbWl0aXZlIGFuc3dlcnM6KiogXCJBdCBhbnkgbW9tZW50IGR1cmluZyB0aGUgcnVuLCB3aGF0XG4gKiBpcyB0aGUgTElWRSB0cmFuc2llbnQgc3RhdGUgb2YgZXZlcnkgY3VycmVudGx5LWFjdGl2ZSBib3VuZGFyeT9cIlxuICpcbiAqIEEgXCJib3VuZGFyeVwiIGlzIGEgbWF0Y2hlZCBldmVudCBwYWlyIGBbc3RhcnQsIHN0b3BdYCBicmFja2V0aW5nIGFuXG4gKiBpbnRlcnZhbCDigJQgZm9yIGV4YW1wbGUsIGAobGxtX3N0YXJ0LCBsbG1fZW5kKWAgZm9yIGFuIExMTSBjYWxsLFxuICogYCh0b29sX3N0YXJ0LCB0b29sX2VuZClgIGZvciB0b29sIGV4ZWN1dGlvbiwgYCh0dXJuX3N0YXJ0LCB0dXJuX2VuZClgXG4gKiBmb3IgYW4gYWdlbnQgdHVybi4gQmV0d2VlbiB0aGUgYnJhY2tldHMsIGludGVybWVkaWF0ZSBldmVudHMgZXZvbHZlXG4gKiB0aGUgYm91bmRhcnkncyBzdGF0ZSAodG9rZW4gY2h1bmtzIGFjY3VtdWxhdGluZyBpbnRvIGEgcGFydGlhbFxuICogYW5zd2VyLCBhcmdzIHN0cmVhbWluZyBpbiwgZXRjLikuIE9uIGBzdG9wYCwgdGhlIHN0YXRlIGNsZWFycy5cbiAqXG4gKiBBbGdvcml0aG1pY2FsbHkgdGhpcyBpcyB0aGUgKipERlMgYnJhY2tldC1zZXF1ZW5jZSBwYXR0ZXJuKiog4oCUXG4gKiBzdGFjay1mcmFtZSBzdGF0ZSBkdXJpbmcgYSBncmFwaC10cmF2ZXJzYWwgaW50ZXJ2YWwuIFNhbWUgc2hhcGUgdXNlZFxuICogYnkgVGFyamFuJ3MgU0NDIGFsZ29yaXRobSwgdHJlZSBkZWNvbXBvc2l0aW9uLCBhbmQgcHVzaC1kb3duXG4gKiBhdXRvbWF0YS4gVGhlIGBhY3RpdmVgIG1hcCBpcyB0aGUgb3Blbi1icmFja2V0cyBzdGFjayBhdCBhbnkgbW9tZW50LlxuICpcbiAqICoqQ29tcGFyaXNvbiB3aXRoIHRoZSBvdGhlciBzdG9yYWdlIHByaW1pdGl2ZXM6KipcbiAqXG4gKiB8IFByaW1pdGl2ZSAgICAgICAgICAgICAgICAgICAgICAgfCBTdG9yZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBUaW1lIHNjb3BlICAgICAgICAgIHwgTWVtb3J5ICAgICAgfFxuICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLXxcbiAqIHwgYFNlcXVlbmNlUmVjb3JkZXI8VD5gICAgICAgICAgICB8IGFwcGVuZC1vbmx5IG9yZGVyZWQgKyBrZXllZCBlbnRyaWVzICB8IGR1cmFibGUgYWNyb3NzIHJ1biAgfCBPKE4gZXZlbnRzKSB8XG4gKiB8IGBLZXllZFJlY29yZGVyPFQ+YCAgICAgICAgICAgICAgfCAxOjEgZW50cnkgcGVyIGBydW50aW1lU3RhZ2VJZGAgICAgICAgfCBkdXJhYmxlIGFjcm9zcyBydW4gIHwgTyhOIHN0ZXBzKSAgfFxuICogfCBgQm91bmRhcnlTdGF0ZVRyYWNrZXI8VFN0YXRlPmAgIHwgdHJhbnNpZW50IGJyYWNrZXQtc2NvcGVkIHN0YXRlICAgICAgIHwgbGl2ZTsgY2xlYXJzIG9uIHN0b3AgfCBPKEsgYWN0aXZlKSB8XG4gKlxuICogKipXaGVuIHRvIHBpY2sgd2hpY2g6KipcbiAqXG4gKiAgIC0gXCJJIG5lZWQgdG8ga2VlcCBhIHBlcm1hbmVudCBsb2cgb2YgZXZlcnkgZXZlbnQgZm9yIHRpbWUtdHJhdmVsXCJcbiAqICAgICAg4oaSIGBTZXF1ZW5jZVJlY29yZGVyPFQ+YFxuICogICAtIFwiSSB3YW50IG9uZSBkdXJhYmxlIHJlY29yZCBwZXIgc3RhZ2UgZXhlY3V0aW9uIChlLmcuLCBtZXRyaWNzKVwiXG4gKiAgICAgIOKGkiBgS2V5ZWRSZWNvcmRlcjxUPmBcbiAqICAgLSBcIkkgbmVlZCB0byBrbm93IHdoYXQncyBoYXBwZW5pbmcgUklHSFQgTk9XIGluc2lkZSBhbiBpbi1mbGlnaHRcbiAqICAgICBib3VuZGFyeSAoZS5nLiwgcGFydGlhbCBMTE0gc3RyZWFtLCBwYXJ0aWFsIHRvb2wgYXJncylcIlxuICogICAgICDihpIgYEJvdW5kYXJ5U3RhdGVUcmFja2VyPFRTdGF0ZT5gICh0aGlzIGNsYXNzKVxuICpcbiAqICoqV2hhdCB0aGlzIGlzIE5PVCBmb3I6KipcbiAqXG4gKiAgIC0gVGltZS10cmF2ZWwgcXVlcmllcyAoXCJ3aGF0IHdhcyB0aGUgc3RhdGUgYXQgcGFzdCBzbGlkZXIgc3RlcCBOP1wiKVxuICogICAgIOKAlCB0cmFuc2llbnQgc3RhdGUgY2xlYXJzIG9uIHN0b3AuIEZvciB0aW1lLXRyYXZlbCwgc25hcHNob3QgdGhlXG4gKiAgICAgc3RhdGUgYXQgZWFjaCBlbWl0IGludG8gYSBzZXBhcmF0ZSBgU2VxdWVuY2VSZWNvcmRlcjxUU3RhdGU+YCxcbiAqICAgICBvciB3YWl0IGZvciBhIGZ1dHVyZSBgQm91bmRhcnlTbmFwc2hvdFJlY29yZGVyPFRTdGF0ZT5gIHByaW1pdGl2ZS5cbiAqXG4gKiAgIC0gQWdncmVnYXRpb25zIGFjcm9zcyB0aGUgd2hvbGUgcnVuICh0b3RhbHMsIGNvdW50cykg4oCUIHRob3NlIGFyZVxuICogICAgIGBTZXF1ZW5jZVJlY29yZGVyLmFnZ3JlZ2F0ZSgpYCAvIGBLZXllZFJlY29yZGVyLmFnZ3JlZ2F0ZSgpYC5cbiAqXG4gKiAgIC0gU3RhZ2UtbGV2ZWwgY29uY2VybnMg4oCUIHRob3NlIHVzZSBgU2NvcGVSZWNvcmRlci5vblN0YWdlU3RhcnRgIC9cbiAqICAgICBgU2NvcGVSZWNvcmRlci5vblN0YWdlRW5kYC4gVGhpcyBwcmltaXRpdmUgb3BlcmF0ZXMgYXQgZmluZXJcbiAqICAgICBncmFudWxhcml0eSAoZXZlbnRzIGVtaXR0ZWQgRFVSSU5HIGEgc3RhZ2UgZXhlY3V0aW9uKS5cbiAqXG4gKiAqKkxpZmVjeWNsZSBjb250cmFjdCDigJQgU1RSSUNUOioqXG4gKlxuICogICBFdmVyeSBgc3RhcnRCb3VuZGFyeShrZXksIC4uLilgIGNhbGwgTVVTVCBiZSBwYWlyZWQgd2l0aCBhXG4gKiAgIGBzdG9wQm91bmRhcnkoa2V5KWAgY2FsbC4gRmFpbHVyZSB0byB3aXJlIHRoZSBzdG9wIHNpZGUgcHJvZHVjZXMgYVxuICogICBtZW1vcnkgbGVhazogdGhlIGFjdGl2ZSBtYXAgZ3Jvd3Mgd2l0aG91dCBib3VuZCwgYW5kIGBnZXRBbGxBY3RpdmUoKWBcbiAqICAgcmV0dXJucyBzdGFsZSBlbnRyaWVzIHRoYXQgbG9vayBpbi1mbGlnaHQgYnV0IGFyZW4ndC4gQ29tbW9uIGNhdXNlOlxuICogICBzdWJjbGFzcyB3aXJlcyBgc3RhcnRgIHRvIG9uZSBldmVudCBoYW5kbGVyIGFuZCBmb3JnZXRzIHRvIHdpcmVcbiAqICAgYHN0b3BgLiAqKkFsd2F5cyB3aXJlIGJvdGggYXQgdGhlIHNhbWUgdGltZS4qKlxuICpcbiAqICAgRGV2IG1vZGUgKGBlbmFibGVEZXZNb2RlKClgKSBkZXRlY3RzIGxlYWtzIGF0IGBjbGVhcigpYCB0aW1lIOKAlFxuICogICB3YXJuaW5nIGluY2x1ZGVzIHRoZSBsZWFrZWQga2V5cyBzbyB5b3UgY2FuIGZpbmQgdGhlIG1pc3Npbmcgd2lyaW5nLlxuICpcbiAqICoqQ29uY3VycmVuY3kgLyBuZXN0aW5nOioqXG4gKlxuICogICAtIENvbmN1cnJlbnQgYm91bmRhcmllcyAocGFyYWxsZWwgYnJhbmNoZXMgd2l0aCB0d28gTExNIGNhbGxzXG4gKiAgICAgYWN0aXZlIGF0IG9uY2UpIHdvcmsgY29ycmVjdGx5OiBlYWNoIGlzIGtleWVkIGluZGVwZW5kZW50bHkgaW5cbiAqICAgICB0aGUgYWN0aXZlIG1hcC5cbiAqICAgLSBOZXN0ZWQgYm91bmRhcmllcyBvZiBESUZGRVJFTlQgS0lORFMgKEFnZW50IGJvdW5kYXJ5IGNvbnRhaW5zXG4gKiAgICAgTExNIGJvdW5kYXJ5KSByZXF1aXJlIFNFUEFSQVRFIHRyYWNrZXIgaW5zdGFuY2VzIOKAlCBvbmUgcGVyIGtpbmQuXG4gKiAgICAgVGhlIGJhc2UgY2xhc3MgdHJhY2tzIG9uZSBib3VuZGFyeSBraW5kIHBlciBpbnN0YW5jZS5cbiAqXG4gKiAqKktleSBjb252ZW50aW9uOioqXG4gKlxuICogICBUaGUgYGtleTogc3RyaW5nYCBpcyB3aGF0ZXZlciB5b3VyIHN1YmNsYXNzIHBpY2tzLiBDb252ZW50aW9uOlxuICogICB1c2UgYHJ1bnRpbWVTdGFnZUlkYCB3aGVuIHRoZSBib3VuZGFyeSBtYXBzIDE6MSB0byBhIHN0YWdlXG4gKiAgIGV4ZWN1dGlvbiDigJQgdGhpcyBnaXZlcyBmcmVlIGludGVyb3Agd2l0aCBgU2VxdWVuY2VSZWNvcmRlclxuICogICAuZ2V0RW50cmllc0ZvclN0ZXBgLCBgS2V5ZWRSZWNvcmRlci5nZXRCeUtleWAsIGBmaW5kQ29tbWl0YCAvXG4gKiAgIGBmaW5kTGFzdFdyaXRlcmAsIGFuZCB0aGUgcmVzdCBvZiB0aGUgdHJhY2UgZWNvc3lzdGVtLiBVc2UgYSBtb3JlXG4gKiAgIGdyYW51bGFyIGtleSAoZS5nLiwgYHRvb2xDYWxsSWRgKSBvbmx5IHdoZW4gdGhlcmUgYXJlIG11bHRpcGxlXG4gKiAgIGNvbmN1cnJlbnQgYm91bmRhcmllcyBXSVRISU4gb25lIHN0YWdlIGV4ZWN1dGlvbi5cbiAqXG4gKiBAZXhhbXBsZSBCdWlsZCBhIGxpdmUgTExNIHRyYWNrZXIgKGNvbWJpbmluZyBzdG9yYWdlICsgb2JzZXJ2ZXIpOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IEJvdW5kYXJ5U3RhdGVUcmFja2VyIH0gZnJvbSAnZm9vdHByaW50anMvdHJhY2UnO1xuICogaW1wb3J0IHsgdHlwZSBDb21iaW5lZFJlY29yZGVyLCB0eXBlIEVtaXRFdmVudCB9IGZyb20gJ2Zvb3RwcmludGpzJztcbiAqXG4gKiBpbnRlcmZhY2UgTExNTGl2ZVN0YXRlIHtcbiAqICAgcmVhZG9ubHkgcGFydGlhbDogc3RyaW5nO1xuICogICByZWFkb25seSB0b2tlbnM6IG51bWJlcjtcbiAqIH1cbiAqXG4gKiBjbGFzcyBMaXZlTExNVHJhY2tlclxuICogICBleHRlbmRzIEJvdW5kYXJ5U3RhdGVUcmFja2VyPExMTUxpdmVTdGF0ZT4gICAvLyBTVE9SQUdFIHNoZWxmXG4gKiAgIGltcGxlbWVudHMgQ29tYmluZWRSZWNvcmRlciAgICAgICAgICAgICAgICAgICAvLyBPQlNFUlZFUiBpbnRlcmZhY2VcbiAqIHtcbiAqICAgcmVhZG9ubHkgaWQgPSAnbGl2ZS1sbG0nO1xuICpcbiAqICAgLy8gT2JzZXJ2ZXIgaGFsZiDigJQgdHJhbnNsYXRlIGV2ZW50cyBpbnRvIGJyYWNrZXQgbXV0YXRpb25zLlxuICogICBvbkVtaXQoZXZlbnQ6IEVtaXRFdmVudCk6IHZvaWQge1xuICogICAgIGlmIChldmVudC5uYW1lID09PSAnYWdlbnRmb290cHJpbnQuc3RyZWFtLmxsbV9zdGFydCcpIHtcbiAqICAgICAgIHRoaXMuc3RhcnRCb3VuZGFyeShldmVudC5ydW50aW1lU3RhZ2VJZCwgeyBwYXJ0aWFsOiAnJywgdG9rZW5zOiAwIH0pO1xuICogICAgIH0gZWxzZSBpZiAoZXZlbnQubmFtZSA9PT0gJ2FnZW50Zm9vdHByaW50LnN0cmVhbS5sbG1fZW5kJykge1xuICogICAgICAgdGhpcy5zdG9wQm91bmRhcnkoZXZlbnQucnVudGltZVN0YWdlSWQpO1xuICogICAgIH0gZWxzZSBpZiAoZXZlbnQubmFtZSA9PT0gJ2FnZW50Zm9vdHByaW50LnN0cmVhbS50b2tlbicpIHtcbiAqICAgICAgIHRoaXMudXBkYXRlQm91bmRhcnkoZXZlbnQucnVudGltZVN0YWdlSWQsIChzKSA9PiAoe1xuICogICAgICAgICBwYXJ0aWFsOiBzLnBhcnRpYWwgKyAoZXZlbnQucGF5bG9hZCBhcyB7IGNvbnRlbnQ6IHN0cmluZyB9KS5jb250ZW50LFxuICogICAgICAgICB0b2tlbnM6IHMudG9rZW5zICsgMSxcbiAqICAgICAgIH0pKTtcbiAqICAgICB9XG4gKiAgIH1cbiAqXG4gKiAgIC8vIFB1YmxpYyByZWFkIEFQSSDigJQgTygxKSBhdCBhbnkgbW9tZW50LlxuICogICBpc0luRmxpZ2h0KCk6IGJvb2xlYW4geyByZXR1cm4gdGhpcy5oYXNBY3RpdmU7IH1cbiAqICAgZ2V0UGFydGlhbChzdGFnZUlkOiBzdHJpbmcpOiBzdHJpbmcge1xuICogICAgIHJldHVybiB0aGlzLmdldEFjdGl2ZShzdGFnZUlkKT8ucGFydGlhbCA/PyAnJztcbiAqICAgfVxuICogfVxuICpcbiAqIC8vIEF0dGFjaGVkIHRoZSBzYW1lIHdheSBhcyBhbnkgb3RoZXIgQ29tYmluZWRSZWNvcmRlci5cbiAqIGNvbnN0IHRyYWNrZXIgPSBuZXcgTGl2ZUxMTVRyYWNrZXIoKTtcbiAqIGV4ZWN1dG9yLmF0dGFjaENvbWJpbmVkUmVjb3JkZXIodHJhY2tlcik7XG4gKiBhd2FpdCBleGVjdXRvci5ydW4oeyBpbnB1dCB9KTtcbiAqXG4gKiAvLyBSZWFkIGxpdmUgc3RhdGUgYXQgYW55IHRpbWUgZHVyaW5nIG9yIGFmdGVyIHRoZSBydW4uXG4gKiB0cmFja2VyLmlzSW5GbGlnaHQoKTtcbiAqIHRyYWNrZXIuZ2V0UGFydGlhbChyaWQpO1xuICogYGBgXG4gKi9cblxuaW1wb3J0IHsgaXNEZXZNb2RlIH0gZnJvbSAnLi4vc2NvcGUvZGV0ZWN0Q2lyY3VsYXIuanMnO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQm91bmRhcnlTdGF0ZVRyYWNrZXI8VFN0YXRlPiB7XG4gIC8qKiBTdGFibGUgaWQg4oCUIHNhbWUgaWRlbXBvdGVuY3kgY29udHJhY3QgYXMgb3RoZXIgcmVjb3JkZXJzLiAqL1xuICBhYnN0cmFjdCByZWFkb25seSBpZDogc3RyaW5nO1xuXG4gIC8qKiBPcGVuLWJyYWNrZXRzIHN0YWNrOiBrZXkg4oaSIGN1cnJlbnQgdHJhbnNpZW50IHN0YXRlLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGFjdGl2ZSA9IG5ldyBNYXA8c3RyaW5nLCBUU3RhdGU+KCk7XG5cbiAgLyoqIFBlci1rZXkgY291bnQgb2YgYHVwZGF0ZUJvdW5kYXJ5YCBjYWxscyB0aGF0IGxhbmRlZCB3aXRob3V0IGFcbiAgICogIG1hdGNoaW5nIGFjdGl2ZSBib3VuZGFyeS4gRHJpdmVzIHJhdGUtbGltaXRlZCBkZXYtbW9kZSB3YXJuaW5nc1xuICAgKiAgc28gYSBzdHVjayBsb29wIGRvZXNuJ3Qgc3BhbSB0aGUgY29uc29sZS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBtaXNzZWRVcGRhdGVzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcblxuICAvLyDilIDilIAgTXV0YXRvciBBUEkgKHN1YmNsYXNzIGNhbGxzIHRoZXNlIGZyb20gb2JzZXJ2ZXIgaG9va3MpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKlxuICAgKiBPcGVuIGEgbmV3IGJvdW5kYXJ5IHdpdGggaW5pdGlhbCB0cmFuc2llbnQgc3RhdGUuXG4gICAqXG4gICAqIElmIGEgYm91bmRhcnkgd2l0aCB0aGUgc2FtZSBga2V5YCBpcyBhbHJlYWR5IGFjdGl2ZSwgdGhlIHByaW9yXG4gICAqIHN0YXRlIGlzIG92ZXJ3cml0dGVuIChsYXN0LXdyaXRlci13aW5zKS4gSW4gZGV2IG1vZGUsIGEgd2FybmluZ1xuICAgKiBpcyBsb2dnZWQgYmVjYXVzZSByZS1zdGFydGluZyBhbiBhY3RpdmUga2V5IHVzdWFsbHkgaW5kaWNhdGVzIGFcbiAgICogbWlzc2VkIGBzdG9wQm91bmRhcnlgIGNhbGwgdXBzdHJlYW0uXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgQm91bmRhcnkgaWRlbnRpZmllciDigJQgYnkgY29udmVudGlvbiwgYHJ1bnRpbWVTdGFnZUlkYFxuICAgKiAgICAgICAgICAgIGZvciAxOjEtd2l0aC1zdGFnZSBib3VuZGFyaWVzLCBvciBhIG1vcmUgZ3JhbnVsYXIgaWRcbiAgICogICAgICAgICAgICAoZS5nLiwgYHRvb2xDYWxsSWRgKSB3aGVuIG11bHRpcGxlIGNvbmN1cnJlbnQgYm91bmRhcmllc1xuICAgKiAgICAgICAgICAgIHJ1biB3aXRoaW4gb25lIHN0YWdlIGV4ZWN1dGlvbi5cbiAgICogQHBhcmFtIGluaXRpYWwgSW5pdGlhbCBzdGF0ZSDigJQgdHlwZWQgYnkgYFRTdGF0ZWAuXG4gICAqL1xuICBwcm90ZWN0ZWQgc3RhcnRCb3VuZGFyeShrZXk6IHN0cmluZywgaW5pdGlhbDogVFN0YXRlKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYWN0aXZlLmhhcyhrZXkpICYmIGlzRGV2TW9kZSgpKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBbJHt0aGlzLmlkfV0gc3RhcnRCb3VuZGFyeSgnJHtrZXl9JykgY2FsbGVkIHdoaWxlIGFuIGFjdGl2ZSBib3VuZGFyeSBhbHJlYWR5IGV4aXN0cy4gYCArXG4gICAgICAgICAgJ092ZXJ3cml0aW5nIHByaW9yIHN0YXRlIOKAlCBsaWtlbHkgYSBtaXNzZWQgc3RvcEJvdW5kYXJ5IHVwc3RyZWFtLicsXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLmFjdGl2ZS5zZXQoa2V5LCBpbml0aWFsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFdm9sdmUgdGhlIHRyYW5zaWVudCBzdGF0ZSBvZiBhbiBhY3RpdmUgYm91bmRhcnkgdXNpbmcgYW4gdXBkYXRlclxuICAgKiBmdW5jdGlvbi4gU2lsZW50IG5vLW9wIGlmIG5vIGJvdW5kYXJ5IGlzIGFjdGl2ZSBmb3IgYGtleWBcbiAgICogKGRlZmVuc2l2ZSBhZ2FpbnN0IG91dC1vZi1vcmRlciBldmVudHMpLiBJbiBkZXYgbW9kZSwgYSByYXRlLWxpbWl0ZWRcbiAgICogd2FybmluZyBpcyBsb2dnZWQgb24gdGhlIDFzdCwgMTB0aCwgYW5kIDEwMHRoIG1pc3NlZCB1cGRhdGUgcGVyIGtleS5cbiAgICpcbiAgICogQHBhcmFtIGtleSAgICAgIEJvdW5kYXJ5IGlkZW50aWZpZXIgKG11c3QgbWF0Y2ggYSBwcmlvciBgc3RhcnRCb3VuZGFyeWApLlxuICAgKiBAcGFyYW0gdXBkYXRlciAgUHVyZSBmdW5jdGlvbjogcHJldmlvdXMgc3RhdGUg4oaSIG5leHQgc3RhdGUuXG4gICAqL1xuICBwcm90ZWN0ZWQgdXBkYXRlQm91bmRhcnkoa2V5OiBzdHJpbmcsIHVwZGF0ZXI6IChwcmV2OiBUU3RhdGUpID0+IFRTdGF0ZSk6IHZvaWQge1xuICAgIGNvbnN0IGN1ciA9IHRoaXMuYWN0aXZlLmdldChrZXkpO1xuICAgIGlmIChjdXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGlzRGV2TW9kZSgpKSB7XG4gICAgICAgIGNvbnN0IG4gPSAodGhpcy5taXNzZWRVcGRhdGVzLmdldChrZXkpID8/IDApICsgMTtcbiAgICAgICAgdGhpcy5taXNzZWRVcGRhdGVzLnNldChrZXksIG4pO1xuICAgICAgICBpZiAobiA9PT0gMSkge1xuICAgICAgICAgIGNvbnNvbGUud2FybihgWyR7dGhpcy5pZH1dIHVwZGF0ZUJvdW5kYXJ5KCcke2tleX0nKSDigJQgbm8gYWN0aXZlIGJvdW5kYXJ5LiBVcGRhdGUgZHJvcHBlZC5gKTtcbiAgICAgICAgfSBlbHNlIGlmIChuID09PSAxMCB8fCBuID09PSAxMDApIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oYFske3RoaXMuaWR9XSB1cGRhdGVCb3VuZGFyeSgnJHtrZXl9Jykg4oCUICR7bn0gZHJvcHBlZCB1cGRhdGVzLiBXaXJpbmcgYnVnP2ApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYWN0aXZlLnNldChrZXksIHVwZGF0ZXIoY3VyKSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2UgdGhlIGJvdW5kYXJ5IGlkZW50aWZpZWQgYnkgYGtleWAgYW5kIHJldHVybiBpdHMgRklOQUxcbiAgICogdHJhbnNpZW50IHN0YXRlIChmb3IgYW55IGNsZWFudXAgdGhlIHN1YmNsYXNzIHdhbnRzIOKAlCBlLmcuLCBlbWl0IGFcbiAgICogc25hcHNob3QgdG8gYSBTZXF1ZW5jZVJlY29yZGVyIGZvciBkdXJhYmxlIHN0b3JhZ2UpLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IEJvdW5kYXJ5IGlkZW50aWZpZXIuXG4gICAqIEByZXR1cm5zIFRoZSBmaW5hbCBzdGF0ZSwgb3IgYHVuZGVmaW5lZGAgaWYgbm8gYm91bmRhcnkgd2FzIGFjdGl2ZS5cbiAgICovXG4gIHByb3RlY3RlZCBzdG9wQm91bmRhcnkoa2V5OiBzdHJpbmcpOiBUU3RhdGUgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGZpbmFsID0gdGhpcy5hY3RpdmUuZ2V0KGtleSk7XG4gICAgdGhpcy5hY3RpdmUuZGVsZXRlKGtleSk7XG4gICAgcmV0dXJuIGZpbmFsO1xuICB9XG5cbiAgLy8g4pSA4pSAIFJlYWQgQVBJIChjb25zdW1lcnMgY2FsbCB0aGVzZSDigJQgTygxKSkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIEN1cnJlbnQgdHJhbnNpZW50IHN0YXRlIG9mIE9ORSBhY3RpdmUgYm91bmRhcnkuIGB1bmRlZmluZWRgIGlmIG5vXG4gICAqICBib3VuZGFyeSBpcyBhY3RpdmUgZm9yIGBrZXlgLiAqL1xuICBnZXRBY3RpdmUoa2V5OiBzdHJpbmcpOiBUU3RhdGUgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmFjdGl2ZS5nZXQoa2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBbGwgY3VycmVudGx5LWFjdGl2ZSBib3VuZGFyaWVzLlxuICAgKlxuICAgKiAqKlR5cGUtb25seSByZWFkb25seToqKiB0aGUgcmV0dXJuZWQgcmVmZXJlbmNlIElTIHRoZSBpbnRlcm5hbCBNYXAuXG4gICAqIFR5cGVTY3JpcHQgcHJldmVudHMgbXV0YXRpb24gdGhyb3VnaCB0aGUgYFJlYWRvbmx5TWFwYCB0eXBlLCBidXQgYVxuICAgKiBydW50aW1lIGNhc3Qgb3Igbm9uLVRTIGNvbnN1bWVyIGNhbiBtdXRhdGUgaXQgYW5kIGNvcnJ1cHQgaW50ZXJuYWxcbiAgICogc3RhdGUuICoqRG8gbm90IG11dGF0ZS4qKlxuICAgKi9cbiAgZ2V0QWxsQWN0aXZlKCk6IFJlYWRvbmx5TWFwPHN0cmluZywgVFN0YXRlPiB7XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlO1xuICB9XG5cbiAgLyoqIFRydWUgaWYgYW55IGJvdW5kYXJ5IGlzIGN1cnJlbnRseSBhY3RpdmUuIE8oMSkuICovXG4gIGdldCBoYXNBY3RpdmUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlLnNpemUgPiAwO1xuICB9XG5cbiAgLyoqIE51bWJlciBvZiBjdXJyZW50bHktYWN0aXZlIGJvdW5kYXJpZXMuIE8oMSkuICovXG4gIGdldCBhY3RpdmVDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmFjdGl2ZS5zaXplO1xuICB9XG5cbiAgLy8g4pSA4pSAIExpZmVjeWNsZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKipcbiAgICogUmVzZXQgYWxsIHRyYW5zaWVudCBzdGF0ZS4gQ2FsbGVkIGJ5IGV4ZWN1dG9ycyBiZWZvcmUgZWFjaCBgcnVuKClgXG4gICAqIHNvIGNvbnN1bWVycyBnZXQgYSBjbGVhbiBzbGF0ZSBwZXIgcnVuIOKAlCBzYW1lIGxpZmVjeWNsZSBjb250cmFjdFxuICAgKiBhcyBgU2VxdWVuY2VSZWNvcmRlci5jbGVhcigpYC5cbiAgICpcbiAgICogSW4gZGV2IG1vZGUsIHdhcm5zIGlmIGFueSBib3VuZGFyaWVzIGFyZSBzdGlsbCBhY3RpdmUgd2hlbiBjYWxsZWRcbiAgICog4oCUIGxpa2VseSBpbmRpY2F0ZXMgYSBtaXNzZWQgYHN0b3BCb3VuZGFyeWAgdXBzdHJlYW0uIFRoZSBsZWFrZWRcbiAgICoga2V5cyBhcmUgbGlzdGVkICh0cnVuY2F0ZWQgdG8gMTApIHNvIHRoZSB3aXJpbmcgYnVnIGlzIGZpbmRhYmxlLlxuICAgKi9cbiAgY2xlYXIoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYWN0aXZlLnNpemUgPiAwICYmIGlzRGV2TW9kZSgpKSB7XG4gICAgICBjb25zdCBrZXlzID0gWy4uLnRoaXMuYWN0aXZlLmtleXMoKV07XG4gICAgICBjb25zdCBoZWFkID0ga2V5cy5zbGljZSgwLCAxMCkuam9pbignLCAnKTtcbiAgICAgIGNvbnN0IG1vcmUgPSBrZXlzLmxlbmd0aCA+IDEwID8gYCAuLi4oKyR7a2V5cy5sZW5ndGggLSAxMH0gbW9yZSlgIDogJyc7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBbJHt0aGlzLmlkfV0gY2xlYXIoKSBjYWxsZWQgd2l0aCAke3RoaXMuYWN0aXZlLnNpemV9IGAgK1xuICAgICAgICAgICdzdGlsbC1hY3RpdmUgYm91bmRhcmllcy4gTWlzc2VkIHN0b3BCb3VuZGFyeT8gJyArXG4gICAgICAgICAgYExlYWtlZCBrZXlzOiAke2hlYWR9JHttb3JlfWAsXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLmFjdGl2ZS5jbGVhcigpO1xuICAgIHRoaXMubWlzc2VkVXBkYXRlcy5jbGVhcigpO1xuICB9XG59XG4iXX0=