footprintjs 9.17.0 → 9.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CLAUDE.md +2 -2
  2. package/dist/esm/lib/memory/utils.d.ts +15 -5
  3. package/dist/esm/lib/memory/utils.js +37 -9
  4. package/dist/esm/lib/time-travel/axis.d.ts +119 -0
  5. package/dist/esm/lib/time-travel/axis.js +179 -0
  6. package/dist/esm/lib/time-travel/bundles.d.ts +77 -0
  7. package/dist/esm/lib/time-travel/bundles.js +124 -0
  8. package/dist/esm/lib/time-travel/chain.d.ts +93 -0
  9. package/dist/esm/lib/time-travel/chain.js +186 -0
  10. package/dist/esm/lib/time-travel/commitStops.d.ts +8 -0
  11. package/dist/esm/lib/time-travel/commitStops.js +9 -1
  12. package/dist/esm/lib/time-travel/index.d.ts +4 -1
  13. package/dist/esm/lib/time-travel/index.js +3 -1
  14. package/dist/esm/lib/time-travel/stateAt.d.ts +39 -10
  15. package/dist/esm/lib/time-travel/stateAt.js +88 -44
  16. package/dist/esm/lib/time-travel/timeTravel.d.ts +30 -3
  17. package/dist/esm/lib/time-travel/timeTravel.js +132 -24
  18. package/dist/esm/lib/time-travel/types.d.ts +227 -45
  19. package/dist/esm/lib/time-travel/types.js +1 -1
  20. package/dist/esm/trace.d.ts +2 -2
  21. package/dist/esm/trace.js +2 -2
  22. package/dist/lib/memory/utils.js +39 -11
  23. package/dist/lib/time-travel/axis.js +184 -0
  24. package/dist/lib/time-travel/bundles.js +132 -0
  25. package/dist/lib/time-travel/chain.js +191 -0
  26. package/dist/lib/time-travel/commitStops.js +9 -1
  27. package/dist/lib/time-travel/index.js +7 -2
  28. package/dist/lib/time-travel/stateAt.js +91 -46
  29. package/dist/lib/time-travel/timeTravel.js +131 -23
  30. package/dist/lib/time-travel/types.js +1 -1
  31. package/dist/trace.js +6 -3
  32. package/dist/types/lib/memory/utils.d.ts +15 -5
  33. package/dist/types/lib/time-travel/axis.d.ts +119 -0
  34. package/dist/types/lib/time-travel/bundles.d.ts +77 -0
  35. package/dist/types/lib/time-travel/chain.d.ts +93 -0
  36. package/dist/types/lib/time-travel/commitStops.d.ts +8 -0
  37. package/dist/types/lib/time-travel/index.d.ts +4 -1
  38. package/dist/types/lib/time-travel/stateAt.d.ts +39 -10
  39. package/dist/types/lib/time-travel/timeTravel.d.ts +30 -3
  40. package/dist/types/lib/time-travel/types.d.ts +227 -45
  41. package/dist/types/trace.d.ts +2 -2
  42. package/package.json +1 -1
package/CLAUDE.md CHANGED
@@ -17,7 +17,7 @@ Entry points: `footprintjs` (public API) · `/recorders` (factories) · `/trace`
17
17
  | decide/ | decide()/select() evidence capture |
18
18
  | recorder/ | stores (KeyedStore/SequenceStore/BoundaryStateStore), CombinedRecorder routing, built-ins (Topology/InOut/ControlDep/Quality) |
19
19
  | slice/ | variable-first backward slicing (triage query layer): sliceForKey (anchor at last writer → causalChain) + arrayProvenance/elementProvenance (append-fold element births — the agent mega-key fix) + KeysReadSource strategies. Pure post-hoc queries; imports memory/ ONLY (see src/lib/slice/README.md) |
20
- | time-travel/ | the READER'S cursor over a finished trace (9.17.0): `timeTravel()` stops/moves/marks/`drill()`, `stateAt()` fold + honesty basis, `TimeTravelStrategy` seam (one shipped: `commitStops`). Read-time only — never a second live cursor. Imports memory/ + `engine/runtimeStageId` (see src/lib/time-travel/README.md) |
20
+ | time-travel/ | the READER'S cursor over a finished trace (9.17.0): `timeTravel()` stops/moves/marks/`drill()`, `stateAt()` fold + honesty basis, `TimeTravelStrategy<TMeta>` seam (one shipped: `commitStops`). 9.18.0 composer's side: axis.ts (`splitAxis` = the ONE guard of the `[start,…stages,end]` contract; `filterStops` = filter + re-partition + `Stop.meta` vocabulary + `Stop.prologue` on an absorbing start — a FLAG, deliberately not a 5th StopKind), bundles.ts (per-bundle narrowing of `unknown[]` rows → index-holding GAPS in `FoldedState.skipped`), chain.ts (`timeTravel([paused, resumed])`: commit indices stay RUN-LOCAL + `Stop.sourceIdx`; refused unless execution indices are monotonic across legs and no id repeats). Read-time only — never a second live cursor. Imports memory/ + `engine/runtimeStageId` (see src/lib/time-travel/README.md) |
21
21
  | pause/ | PauseSignal / FlowchartCheckpoint types + `interrupt(scope, payload)` (throws InterruptSignal; converted to PauseSignal at the StageRunner boundary, `pausedBy:'interrupt'`) |
22
22
  | engine/ | FlowchartTraverser + handlers/; narrative/ = the whole FlowRecorder channel (dispatcher + 9 strategies), not just text; branchSegment.ts = the ONE owner of the generated-segment grammar (`<stageId>~<index>`, marker `~` RESERVED); `executeStage` (:720) = the ONE funnel every stage fn passes through — and therefore the ONE owner of the declarative `retry` loop |
23
23
  | runner/ | FlowChartExecutor wiring (runtime, recorders, pause/resume, snapshot, DeferredObserverTier). RunContext.ts is a fluent run builder, NOT the threaded per-run context |
@@ -66,7 +66,7 @@ loop: Phase 6 sees isLoopRef → ContinuationResolver.resolveTarget (:107): id-m
66
66
  end: onRunEnd (throw → onRunFailed; pause → neither) → deferred terminalFlush → getSnapshot() = {sharedState (LIVE view; dev-mode frozen clone), initialState (the fold base), commitLog (detached+frozen), executionTree, subflowResults (dual-keyed), recorders}.
67
67
 
68
68
  ## Backtracking
69
- Seven mechanisms, no state rollback anywhere: **M1** TransactionBuffer staging + net-change commit — commit-on-error by design, explicitly NOT rollback (TransactionBuffer.ts:13-18; error path commits then rethrows). **M2** Pause/Resume checkpointing — the only resume-from-prior-point; TWO raise shapes, ONE checkpoint: `addPausableFunction` (resume runs `resumeFn`) and `interrupt(scope, payload)` (resume RE-RUNS THE STAGE FUNCTION FROM ITS TOP — stages are atomic; the answer returns out of the `interrupt()` call via a WeakMap keyed by the scope), discriminated by `checkpoint.pausedBy`; checkpoint is one detached structuredClone; resume rebuilds the cursor from pausedStageId+subflowPath and only overrides the LEAF subflow root (2+-deep pause re-executes outer pre-mount stages). **M3** commit-log replay (EventLog.materialise, commitValueAt — required under delta mode). **M4** loopTo re-entry — forward execution over accumulated state, bounded by maxIterations + dynamicNextHops. **M5** causalChain backward slicing (read-only analysis; honesty flags for untracked reads; `edgeAttribution: 'per-write'` refines edges via `TraceEntry.readKeys` when the writeProvenance dial recorded them — worklist, subset-of-ceiling safe). **M6 (query layer)** slice/ — variable-first triage: sliceForKey + append-fold element provenance + the ONLY safe serializations (sliceToJSON/formatSlice — never JSON.stringify a slice root). **M7 (read-time cursor)** time-travel/ — `timeTravel(snapshot)` walks stops over the finished log with `stateAt()` folding M3's replay at each one (base = `RuntimeSnapshot.initialState`, which now travels with the log); it is a READER, never a second live cursor, and `drill(mount)` opens a separate cursor over a subflow's own isolated log. Deep dive + step tables: [.claude/rules/backtracking.md](.claude/rules/backtracking.md).
69
+ Seven mechanisms, no state rollback anywhere: **M1** TransactionBuffer staging + net-change commit — commit-on-error by design, explicitly NOT rollback (TransactionBuffer.ts:13-18; error path commits then rethrows). **M2** Pause/Resume checkpointing — the only resume-from-prior-point; TWO raise shapes, ONE checkpoint: `addPausableFunction` (resume runs `resumeFn`) and `interrupt(scope, payload)` (resume RE-RUNS THE STAGE FUNCTION FROM ITS TOP — stages are atomic; the answer returns out of the `interrupt()` call via a WeakMap keyed by the scope), discriminated by `checkpoint.pausedBy`; checkpoint is one detached structuredClone; resume rebuilds the cursor from pausedStageId+subflowPath and only overrides the LEAF subflow root (2+-deep pause re-executes outer pre-mount stages). **M3** commit-log replay (EventLog.materialise, commitValueAt — required under delta mode). **M4** loopTo re-entry — forward execution over accumulated state, bounded by maxIterations + dynamicNextHops. **M5** causalChain backward slicing (read-only analysis; honesty flags for untracked reads; `edgeAttribution: 'per-write'` refines edges via `TraceEntry.readKeys` when the writeProvenance dial recorded them — worklist, subset-of-ceiling safe). **M6 (query layer)** slice/ — variable-first triage: sliceForKey + append-fold element provenance + the ONLY safe serializations (sliceToJSON/formatSlice — never JSON.stringify a slice root). **M7 (read-time cursor)** time-travel/ — `timeTravel(snapshot)` walks stops over the finished log with `stateAt()` folding M3's replay at each one (base = `RuntimeSnapshot.initialState`, which now travels with the log); it is a READER, never a second live cursor, and `drill(mount)` opens a separate cursor over a subflow's own isolated log. 9.18.0: `timeTravel([paused, resumed])` chains a cross-executor M2 resume into ONE axis — the resumed leg's `initialState` (= the state at the pause) restarts the fold, commit indices stay run-local (`Stop.sourceIdx` names the leg), and the chain is refused unless the never-reset execution counter is monotonic across legs. Deep dive + step tables: [.claude/rules/backtracking.md](.claude/rules/backtracking.md).
70
70
 
71
71
  ## Invariants (assumed, not stated)
72
72
  - Committed state immutable-after-swap; first-touch views hold bare references on that guarantee — in-place mutation of SharedMemory.context corrupts every in-flight stage.
@@ -79,11 +79,13 @@ export declare function normalisePath(path: (string | number)[]): string;
79
79
  * - Primitive comparisons (the bulk of state) are O(1) via the `===` /
80
80
  * `Object.is` fast paths; only nested objects/arrays incur a walk, bounded
81
81
  * by the value's own size.
82
- * - Assumes ACYCLIC, JSON-shaped values the same contract the memory layer
83
- * already relies on (committed state is `structuredClone`d and must be
84
- * JSON-serialisable for checkpoints). A cyclic value is out of contract
85
- * here exactly as it is for checkpointing; dev mode flags cycles at write
86
- * time via `ScopeFacade.setValue`.
82
+ * - Terminates on CYCLIC values (9.18.1): a state value must survive
83
+ * `structuredClone`, and `structuredClone` preserves cycles — so a
84
+ * self-referencing value is a legal value, not an out-of-contract one. A
85
+ * pair of objects already under comparison is treated as equal (the
86
+ * structural answer, lodash `isEqual` semantics); acyclic inputs see no
87
+ * change. Dev mode still warns about cycles at write time
88
+ * (`ScopeFacade.setValue`) because they surprise narrative and JSON.
87
89
  */
88
90
  export declare function deepEqual(a: any, b: any): boolean;
89
91
  /**
@@ -95,6 +97,14 @@ export declare function deepEqual(a: any, b: any): boolean;
95
97
  * impossible to distinguish from a bug.
96
98
  * - Objects: recursive merge
97
99
  * - Primitives: source wins
100
+ *
101
+ * Terminates on a CYCLIC `src` (9.18.1, same law as {@link deepEqual}: a
102
+ * state value survives `structuredClone`, which preserves cycles). A `src`
103
+ * object re-entered while it is still being merged higher up the stack hands
104
+ * back the output being built for it, so the merged value mirrors the cycle
105
+ * instead of unrolling it forever. Only the ancestors on the stack are
106
+ * guarded — a shared (acyclic) `src` reference met again at a different
107
+ * `dst` merges against THAT `dst`, exactly as before.
98
108
  */
99
109
  export declare function deepSmartMerge(dst: any, src: any): any;
100
110
  /**
@@ -145,13 +145,18 @@ export function normalisePath(path) {
145
145
  * - Primitive comparisons (the bulk of state) are O(1) via the `===` /
146
146
  * `Object.is` fast paths; only nested objects/arrays incur a walk, bounded
147
147
  * by the value's own size.
148
- * - Assumes ACYCLIC, JSON-shaped values the same contract the memory layer
149
- * already relies on (committed state is `structuredClone`d and must be
150
- * JSON-serialisable for checkpoints). A cyclic value is out of contract
151
- * here exactly as it is for checkpointing; dev mode flags cycles at write
152
- * time via `ScopeFacade.setValue`.
148
+ * - Terminates on CYCLIC values (9.18.1): a state value must survive
149
+ * `structuredClone`, and `structuredClone` preserves cycles — so a
150
+ * self-referencing value is a legal value, not an out-of-contract one. A
151
+ * pair of objects already under comparison is treated as equal (the
152
+ * structural answer, lodash `isEqual` semantics); acyclic inputs see no
153
+ * change. Dev mode still warns about cycles at write time
154
+ * (`ScopeFacade.setValue`) because they surprise narrative and JSON.
153
155
  */
154
156
  export function deepEqual(a, b) {
157
+ return equalPairs(a, b, undefined);
158
+ }
159
+ function equalPairs(a, b, seen) {
155
160
  if (a === b)
156
161
  return true; // same reference or identical primitive
157
162
  if (typeof a !== typeof b)
@@ -163,11 +168,19 @@ export function deepEqual(a, b) {
163
168
  const aIsArray = Array.isArray(a);
164
169
  if (aIsArray !== Array.isArray(b))
165
170
  return false; // array vs plain object
171
+ // Cycle guard — a pair we are already inside is equal by assumption.
172
+ seen ??= new WeakMap();
173
+ let partners = seen.get(a);
174
+ if (partners?.has(b))
175
+ return true;
176
+ if (!partners)
177
+ seen.set(a, (partners = new WeakSet()));
178
+ partners.add(b);
166
179
  if (aIsArray) {
167
180
  if (a.length !== b.length)
168
181
  return false;
169
182
  for (let i = 0; i < a.length; i++) {
170
- if (!deepEqual(a[i], b[i]))
183
+ if (!equalPairs(a[i], b[i], seen))
171
184
  return false;
172
185
  }
173
186
  return true;
@@ -179,7 +192,7 @@ export function deepEqual(a, b) {
179
192
  for (const key of aKeys) {
180
193
  if (!Object.prototype.hasOwnProperty.call(b, key))
181
194
  return false;
182
- if (!deepEqual(a[key], b[key]))
195
+ if (!equalPairs(a[key], b[key], seen))
183
196
  return false;
184
197
  }
185
198
  return true;
@@ -193,8 +206,19 @@ export function deepEqual(a, b) {
193
206
  * impossible to distinguish from a bug.
194
207
  * - Objects: recursive merge
195
208
  * - Primitives: source wins
209
+ *
210
+ * Terminates on a CYCLIC `src` (9.18.1, same law as {@link deepEqual}: a
211
+ * state value survives `structuredClone`, which preserves cycles). A `src`
212
+ * object re-entered while it is still being merged higher up the stack hands
213
+ * back the output being built for it, so the merged value mirrors the cycle
214
+ * instead of unrolling it forever. Only the ancestors on the stack are
215
+ * guarded — a shared (acyclic) `src` reference met again at a different
216
+ * `dst` merges against THAT `dst`, exactly as before.
196
217
  */
197
218
  export function deepSmartMerge(dst, src) {
219
+ return mergeGuarded(dst, src, undefined);
220
+ }
221
+ function mergeGuarded(dst, src, inFlight) {
198
222
  if (src === null || typeof src !== 'object')
199
223
  return src;
200
224
  if (Array.isArray(src)) {
@@ -204,11 +228,15 @@ export function deepSmartMerge(dst, src) {
204
228
  return [...new Set([...dst, ...src])];
205
229
  return [...src];
206
230
  }
231
+ if (inFlight?.has(src))
232
+ return inFlight.get(src); // cycle — re-enter the value being built
207
233
  const out = { ...(dst && typeof dst === 'object' ? dst : {}) };
234
+ (inFlight ??= new WeakMap()).set(src, out);
208
235
  // Object.keys() is own-enumerable-only by spec — no DENIED check needed here.
209
236
  for (const k of Object.keys(src)) {
210
- out[k] = deepSmartMerge(out[k], src[k]);
237
+ out[k] = mergeGuarded(out[k], src[k], inFlight);
211
238
  }
239
+ inFlight.delete(src);
212
240
  return out;
213
241
  }
214
242
  /**
@@ -256,4 +284,4 @@ export function applySmartMerge(base, updates, overwrite, trace) {
256
284
  }
257
285
  return out;
258
286
  }
259
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL21lbW9yeS91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUVILE9BQU8sRUFBRSxZQUFZLEVBQUUsU0FBUyxJQUFJLElBQUksRUFBRSxTQUFTLElBQUksSUFBSSxFQUFFLFNBQVMsSUFBSSxJQUFJLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFHckcsaUZBQWlGO0FBQ2pGLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUM7QUFJOUI7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUFDLEtBQWMsRUFBRSxPQUE0QixFQUFFO0lBQ2pGLE9BQU87UUFDTCxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztRQUNyRCxVQUFVLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQztLQUN0QixDQUFDO0FBQ0osQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FDNUIsR0FBaUIsRUFDakIsS0FBYSxFQUNiLEtBQWUsRUFDZixLQUFhLEVBQ2IsS0FBUSxFQUNSLGFBQXVCO0lBRXZCLE1BQU0sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsb0JBQW9CLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ25FLE1BQU0sSUFBSSxHQUFHLE9BQU8sSUFBSSxVQUFVLENBQUM7SUFDbkMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQzNCLElBQUksT0FBTyxHQUFpQixHQUFHLENBQUM7SUFDaEMsT0FBTyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzNCLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxLQUFLLEVBQVksQ0FBQztRQUN2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RCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2hDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoRyxDQUFDO2FBQU0sSUFBSSxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDN0IsWUFBWSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMxQixDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3RDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEUsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIHV0aWxzLnRzIOKAlCBIZWxwZXIgZnVuY3Rpb25zIGZvciBuZXN0ZWQgb2JqZWN0IG1hbmlwdWxhdGlvblxuICpcbiAqIFByb3ZpZGVzIGNvbnNpc3RlbnQgcGF0aCB0cmF2ZXJzYWwgYW5kIHZhbHVlIG1hbmlwdWxhdGlvbiBmb3IgdGhlIG1lbW9yeSBzeXN0ZW0uXG4gKiBaZXJvIGV4dGVybmFsIGRlcGVuZGVuY2llcy5cbiAqL1xuXG5pbXBvcnQgeyBuYXRpdmVEZWxldGUsIG5hdGl2ZUdldCBhcyBfZ2V0LCBuYXRpdmVIYXMgYXMgX2hhcywgbmF0aXZlU2V0IGFzIF9zZXQgfSBmcm9tICcuL3BhdGhPcHMuanMnO1xuaW1wb3J0IHR5cGUgeyBNZW1vcnlQYXRjaCwgVHJhY2VFbnRyeSB9IGZyb20gJy4vdHlwZXMuanMnO1xuXG4vKiogQVNDSUkgVW5pdC1TZXBhcmF0b3Ig4oCUIGNhbm5vdCBhcHBlYXIgaW4gSlMgaWRlbnRpZmllcnMsIGludmlzaWJsZSBpbiBsb2dzLiAqL1xuZXhwb3J0IGNvbnN0IERFTElNID0gJ1xcdTAwMUYnO1xuXG50eXBlIE5lc3RlZE9iamVjdCA9IHsgW2tleTogc3RyaW5nXTogYW55IH07XG5cbi8qKlxuICogUmVzb2x2ZXMgcnVuLW5hbWVzcGFjZWQgYW5kIGdsb2JhbCBwYXRocy5cbiAqIEVhY2ggZmxvd2NoYXJ0IGV4ZWN1dGlvbiAocnVuKSBzdG9yZXMgZGF0YSB1bmRlciBgcnVucy97aWR9L2AgdG8gcHJldmVudCBjb2xsaXNpb25zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UnVuQW5kR2xvYmFsUGF0aHMocnVuSWQ/OiBzdHJpbmcsIHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW10gPSBbXSkge1xuICByZXR1cm4ge1xuICAgIHJ1blBhdGg6IHJ1bklkID8gWydydW5zJywgcnVuSWQsIC4uLnBhdGhdIDogdW5kZWZpbmVkLFxuICAgIGdsb2JhbFBhdGg6IFsuLi5wYXRoXSxcbiAgfTtcbn1cblxuLyoqXG4gKiBTZXRzIGEgdmFsdWUgYXQgYSBuZXN0ZWQgcGF0aCwgY3JlYXRpbmcgaW50ZXJtZWRpYXRlIG9iamVjdHMgYXMgbmVlZGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0TmVzdGVkVmFsdWU8VD4oXG4gIG9iajogTmVzdGVkT2JqZWN0LFxuICBydW5JZDogc3RyaW5nLFxuICBfcGF0aDogc3RyaW5nW10sXG4gIGZpZWxkOiBzdHJpbmcsXG4gIHZhbHVlOiBULFxuICBkZWZhdWx0VmFsdWVzPzogdW5rbm93bixcbik6IE5lc3RlZE9iamVjdCB7XG4gIGNvbnN0IHsgcnVuUGF0aCwgZ2xvYmFsUGF0aCB9ID0gZ2V0UnVuQW5kR2xvYmFsUGF0aHMocnVuSWQsIF9wYXRoKTtcbiAgY29uc3QgcGF0aCA9IHJ1blBhdGggfHwgZ2xvYmFsUGF0aDtcbiAgY29uc3QgcGF0aENvcHkgPSBbLi4ucGF0aF07XG4gIGxldCBjdXJyZW50OiBOZXN0ZWRPYmplY3QgPSBvYmo7XG4gIHdoaWxlIChwYXRoQ29weS5sZW5ndGggPiAwKSB7XG4gICAgY29uc3Qga2V5ID0gcGF0aENvcHkuc2hpZnQoKSBhcyBzdHJpbmc7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY3VycmVudCwga2V5KSkge1xuICAgICAgY3VycmVudFtrZXldID0ga2V5ID09PSBydW5JZCAmJiBkZWZhdWx0VmFsdWVzID8gZGVmYXVsdFZhbHVlcyA6IHt9O1xuICAgIH1cbiAgICBjdXJyZW50ID0gY3VycmVudFtrZXldO1xuICB9XG4gIGN1cnJlbnRbZmllbGRdID0gdmFsdWU7XG4gIHJldHVybiBvYmo7XG59XG5cbi8qKlxuICogRGVlcC1tZXJnZXMgYSB2YWx1ZSBpbnRvIHRoZSBvYmplY3QgYXQgdGhlIHNwZWNpZmllZCBwYXRoLlxuICogLSBBcnJheXM6IGNvbmNhdGVuYXRlXG4gKiAtIE9iamVjdHM6IHNoYWxsb3cgbWVyZ2UgYXQgZWFjaCBsZXZlbFxuICogLSBQcmltaXRpdmVzOiByZXBsYWNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVOZXN0ZWRWYWx1ZTxUPihcbiAgb2JqOiBhbnksXG4gIHJ1bklkOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIF9wYXRoOiAoc3RyaW5nIHwgbnVtYmVyKVtdLFxuICBmaWVsZDogc3RyaW5nIHwgbnVtYmVyLFxuICB2YWx1ZTogVCxcbiAgZGVmYXVsdFZhbHVlcz86IHVua25vd24sXG4pOiBhbnkge1xuICBjb25zdCB7IHJ1blBhdGgsIGdsb2JhbFBhdGggfSA9IGdldFJ1bkFuZEdsb2JhbFBhdGhzKHJ1bklkLCBfcGF0aCk7XG4gIGNvbnN0IHBhdGggPSBydW5QYXRoIHx8IGdsb2JhbFBhdGg7XG4gIGNvbnN0IHBhdGhDb3B5ID0gWy4uLnBhdGhdO1xuICBsZXQgY3VycmVudDogTmVzdGVkT2JqZWN0ID0gb2JqO1xuICB3aGlsZSAocGF0aENvcHkubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IGtleSA9IHBhdGhDb3B5LnNoaWZ0KCkgYXMgc3RyaW5nO1xuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGN1cnJlbnQsIGtleSkpIHtcbiAgICAgIGN1cnJlbnRba2V5XSA9IGtleSA9PT0gcnVuSWQgJiYgZGVmYXVsdFZhbHVlcyA/IGRlZmF1bHRWYWx1ZXMgOiB7fTtcbiAgICB9XG4gICAgY3VycmVudCA9IGN1cnJlbnRba2V5XTtcbiAgfVxuICB1cGRhdGVWYWx1ZShjdXJyZW50LCBmaWVsZCwgdmFsdWUpO1xuICByZXR1cm4gb2JqO1xufVxuXG4vKipcbiAqIEluLXBsYWNlIHZhbHVlIHVwZGF0ZSB3aXRoIG1lcmdlIHNlbWFudGljcy5cbiAqIC0gQXJyYXlzIChub24tZW1wdHkpOiBjb25jYXRlbmF0ZSBvbnRvIGV4aXN0aW5nXG4gKiAtIEFycmF5cyAoZW1wdHkpOiAgICAgZGlyZWN0IHJlcGxhY2Ug4oCUIHdyaXRpbmcgYFtdYCBjbGVhcnMgdGhlIGZpZWxkXG4gKiAtIE9iamVjdHMgKG5vbi1lbXB0eSk6IHNoYWxsb3cgbWVyZ2UgKHNwcmVhZClcbiAqIC0gT2JqZWN0cyAoZW1wdHkpOiAgICBkaXJlY3QgcmVwbGFjZSDigJQgd3JpdGluZyBge31gIGNsZWFycyB0aGUgZmllbGRcbiAqIC0gUHJpbWl0aXZlczogZGlyZWN0IGFzc2lnbm1lbnRcbiAqXG4gKiBOb3RlIG9uIGVtcHR5IGFycmF5czogYm90aCBgdmFsdWUgJiYgQXJyYXkuaXNBcnJheSh2YWx1ZSlgIGFuZFxuICogYEFycmF5LmlzQXJyYXkodmFsdWUpYCBldmFsdWF0ZSB0aGUgc2FtZSBmb3IgYXJyYXlzIOKAlCBgW11gIGlzIHRydXRoeSBpblxuICogSmF2YVNjcmlwdCwgc28gdGhlIGAmJmAgZ3VhcmQgd2FzIG5ldmVyIHRoZSBpc3N1ZS4gVGhlIGFjdHVhbCBidWcgd2FzIHRoZVxuICogY29uY2F0IHBhdGg6IGBbLi4uY3VyLCAuLi5bXV1gIHNpbGVudGx5IHJldHVybmVkIGBjdXJgIHVuY2hhbmdlZCB3aGVuIGB2YWx1ZWBcbiAqIHdhcyBgW11gLCBtYWtpbmcgYHVwZGF0ZVZhbHVlKG9iaiwgJ3RhZ3MnLCBbXSlgIGEgbm8tb3AgaW5zdGVhZCBvZiBhIGNsZWFyLlxuICogVGhlIGZpeCBpcyB0aGUgZXhwbGljaXQgYHZhbHVlLmxlbmd0aCA9PT0gMGAgZWFybHktcmV0dXJuIGJyYW5jaC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVZhbHVlKG9iamVjdDogYW55LCBrZXk6IHN0cmluZyB8IG51bWJlciwgdmFsdWU6IGFueSk6IHZvaWQge1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBpZiAodmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICBvYmplY3Rba2V5XSA9IHZhbHVlOyAvLyBjbGVhcjogW10gcmVwbGFjZXMgd2hhdGV2ZXIgd2FzIHRoZXJlXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGN1ciA9IG9iamVjdFtrZXldIGFzIGFueTtcbiAgICAgIG9iamVjdFtrZXldID0gY3VyID09PSB1bmRlZmluZWQgPyB2YWx1ZSA6IFsuLi5jdXIsIC4uLnZhbHVlXTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoKSB7XG4gICAgY29uc3QgY3VyID0gb2JqZWN0W2tleV0gYXMgYW55O1xuICAgIG9iamVjdFtrZXldID0gY3VyID09PSB1bmRlZmluZWQgPyB2YWx1ZSA6IHsgLi4uY3VyLCAuLi52YWx1ZSB9O1xuICB9IGVsc2Uge1xuICAgIG9iamVjdFtrZXldID0gdmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBHZXRzIGEgdmFsdWUgYXQgYSBuZXN0ZWQgcGF0aCB3aXRoIHByb3RvdHlwZS1wb2xsdXRpb24gcHJvdGVjdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE5lc3RlZFZhbHVlKHJvb3Q6IGFueSwgcGF0aDogKHN0cmluZyB8IG51bWJlcilbXSwgZmllbGQ/OiBzdHJpbmcgfCBudW1iZXIpOiBhbnkge1xuICBjb25zdCBub2RlID0gcGF0aCAmJiBwYXRoLmxlbmd0aCA+IDAgPyBfZ2V0KHJvb3QsIHBhdGgpIDogcm9vdDtcbiAgaWYgKGZpZWxkID09PSB1bmRlZmluZWQgfHwgbm9kZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gbm9kZTtcbiAgaWYgKG5vZGUgIT09IG51bGwgJiYgdHlwZW9mIG5vZGUgPT09ICdvYmplY3QnICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChub2RlLCBmaWVsZCkpIHtcbiAgICByZXR1cm4gbm9kZVtmaWVsZF07XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZWRhY3RzIHNlbnNpdGl2ZSB2YWx1ZXMgaW4gYSBwYXRjaCBmb3IgbG9nZ2luZy9kZWJ1Z2dpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWRhY3RQYXRjaChwYXRjaDogTWVtb3J5UGF0Y2gsIHJlZGFjdGVkU2V0OiBTZXQ8c3RyaW5nPik6IE1lbW9yeVBhdGNoIHtcbiAgY29uc3Qgb3V0ID0gc3RydWN0dXJlZENsb25lKHBhdGNoKTtcbiAgZm9yIChjb25zdCBmbGF0IG9mIHJlZGFjdGVkU2V0KSB7XG4gICAgY29uc3QgcGF0aEFyciA9IGZsYXQuc3BsaXQoREVMSU0pO1xuICAgIGlmIChfaGFzKG91dCwgcGF0aEFycikpIHtcbiAgICAgIGNvbnN0IGN1cnIgPSBfZ2V0KG91dCwgcGF0aEFycik7XG4gICAgICBpZiAodHlwZW9mIGN1cnIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIF9zZXQob3V0LCBwYXRoQXJyLCAnUkVEQUNURUQnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBOb3JtYWxpc2VzIGFuIGFycmF5IHBhdGggaW50byBhIHN0YWJsZSBzdHJpbmcga2V5IHVzaW5nIERFTElNLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXNlUGF0aChwYXRoOiAoc3RyaW5nIHwgbnVtYmVyKVtdKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhdGgubWFwKFN0cmluZykuam9pbihERUxJTSk7XG59XG5cbi8qKlxuICogU3RydWN0dXJhbCBkZWVwIGVxdWFsaXR5IGZvciBjb21taXR0ZWQtc3RhdGUgdmFsdWVzLlxuICpcbiAqIFVzZWQgYnkge0BsaW5rIFRyYW5zYWN0aW9uQnVmZmVyfSB0byBkZWNpZGUgd2hldGhlciBhIHN0YWdlIGFjdHVhbGx5IENIQU5HRURcbiAqIGEgcGF0aCBvciBtZXJlbHkgcmUtd3JvdGUgLyByZXZlcnRlZCBpdCB0byB0aGUgdmFsdWUgaXQgYWxyZWFkeSBoZWxkIChhXG4gKiBcIm5vLW9wIHdyaXRlXCIpLiBDb21taXR0ZWQgc3RhdGUgaXMgSlNPTi1zaGFwZWQg4oCUIGl0IG11c3Qgc3Vydml2ZVxuICogYHN0cnVjdHVyZWRDbG9uZWAg4oCUIHNvIHRoaXMgb25seSBuZWVkcyB0byBoYW5kbGUgdGhlIHNoYXBlcyB0aGF0IGNhbiByZWFjaCBhXG4gKiBjb21taXQ6IHByaW1pdGl2ZXMsIGFycmF5cywgYW5kIHBsYWluIG9iamVjdHMuXG4gKlxuICogU2VtYW50aWNzOlxuICogICAtIHJlZmVyZW5jZSAvIGlkZW50aWNhbC1wcmltaXRpdmUgc2hvcnQtY2lyY3VpdHMgZmlyc3QgKGNoZWFwIGZhc3QgcGF0aClcbiAqICAgLSBgTmFOYCBlcXVhbHMgYE5hTmAgKHByaW1pdGl2ZSBjb21wYXJlIGZhbGxzIGJhY2sgdG8gYE9iamVjdC5pc2ApXG4gKiAgIC0gYXJyYXlzOiBlcXVhbCBsZW5ndGggQU5EIGRlZXAtZXF1YWwgZWxlbWVudC13aXNlIChvcmRlci1zZW5zaXRpdmUpXG4gKiAgIC0gb2JqZWN0czogaWRlbnRpY2FsIG93bi1rZXkgc2V0IEFORCBkZWVwLWVxdWFsIHBlciBrZXlcbiAqICAgLSBtaXNtYXRjaGVkIGtpbmRzIChhcnJheSB2cyBvYmplY3QsIG9iamVjdCB2cyBudWxsKSDihpIgbm90IGVxdWFsXG4gKlxuICogQ29zdCAmIHNhZmV0eTpcbiAqICAgLSBBbGxvY2F0ZXMgTk9USElORyBidXQgdHJhbnNpZW50IGBPYmplY3Qua2V5c2AgYXJyYXlzIOKAlCBubyBjbG9uZXMuIEl0IGlzXG4gKiAgICAgc3RyaWN0bHkgY2hlYXBlciB0aGFuIHRoZSBgc3RydWN0dXJlZENsb25lYCB0aGUgY29tbWl0IGFscmVhZHkgcGVyZm9ybXMuXG4gKiAgIC0gUHJpbWl0aXZlIGNvbXBhcmlzb25zICh0aGUgYnVsayBvZiBzdGF0ZSkgYXJlIE8oMSkgdmlhIHRoZSBgPT09YCAvXG4gKiAgICAgYE9iamVjdC5pc2AgZmFzdCBwYXRoczsgb25seSBuZXN0ZWQgb2JqZWN0cy9hcnJheXMgaW5jdXIgYSB3YWxrLCBib3VuZGVkXG4gKiAgICAgYnkgdGhlIHZhbHVlJ3Mgb3duIHNpemUuXG4gKiAgIC0gQXNzdW1lcyBBQ1lDTElDLCBKU09OLXNoYXBlZCB2YWx1ZXMg4oCUIHRoZSBzYW1lIGNvbnRyYWN0IHRoZSBtZW1vcnkgbGF5ZXJcbiAqICAgICBhbHJlYWR5IHJlbGllcyBvbiAoY29tbWl0dGVkIHN0YXRlIGlzIGBzdHJ1Y3R1cmVkQ2xvbmVgZCBhbmQgbXVzdCBiZVxuICogICAgIEpTT04tc2VyaWFsaXNhYmxlIGZvciBjaGVja3BvaW50cykuIEEgY3ljbGljIHZhbHVlIGlzIG91dCBvZiBjb250cmFjdFxuICogICAgIGhlcmUgZXhhY3RseSBhcyBpdCBpcyBmb3IgY2hlY2twb2ludGluZzsgZGV2IG1vZGUgZmxhZ3MgY3ljbGVzIGF0IHdyaXRlXG4gKiAgICAgdGltZSB2aWEgYFNjb3BlRmFjYWRlLnNldFZhbHVlYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZXBFcXVhbChhOiBhbnksIGI6IGFueSk6IGJvb2xlYW4ge1xuICBpZiAoYSA9PT0gYikgcmV0dXJuIHRydWU7IC8vIHNhbWUgcmVmZXJlbmNlIG9yIGlkZW50aWNhbCBwcmltaXRpdmVcbiAgaWYgKHR5cGVvZiBhICE9PSB0eXBlb2YgYikgcmV0dXJuIGZhbHNlO1xuICBpZiAoYSA9PT0gbnVsbCB8fCBiID09PSBudWxsKSByZXR1cm4gYSA9PT0gYjsgLy8gb25lIGlzIG51bGwsIHRoZSBvdGhlciBpc24ndFxuICBpZiAodHlwZW9mIGEgIT09ICdvYmplY3QnKSByZXR1cm4gT2JqZWN0LmlzKGEsIGIpOyAvLyBOYU4tc2FmZSBwcmltaXRpdmUgY29tcGFyZVxuXG4gIGNvbnN0IGFJc0FycmF5ID0gQXJyYXkuaXNBcnJheShhKTtcbiAgaWYgKGFJc0FycmF5ICE9PSBBcnJheS5pc0FycmF5KGIpKSByZXR1cm4gZmFsc2U7IC8vIGFycmF5IHZzIHBsYWluIG9iamVjdFxuXG4gIGlmIChhSXNBcnJheSkge1xuICAgIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghZGVlcEVxdWFsKGFbaV0sIGJbaV0pKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgY29uc3QgYUtleXMgPSBPYmplY3Qua2V5cyhhKTtcbiAgY29uc3QgYktleXMgPSBPYmplY3Qua2V5cyhiKTtcbiAgaWYgKGFLZXlzLmxlbmd0aCAhPT0gYktleXMubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gIGZvciAoY29uc3Qga2V5IG9mIGFLZXlzKSB7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwga2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghZGVlcEVxdWFsKGFba2V5XSwgYltrZXldKSkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIERlZXAgdW5pb24gbWVyZ2UgaGVscGVyLlxuICogLSBBcnJheXMgKG5vbi1lbXB0eSk6IHVuaW9uIHdpdGhvdXQgZHVwbGljYXRlcyAoZW5jb3VudGVyIG9yZGVyIHByZXNlcnZlZClcbiAqIC0gQXJyYXlzIChlbXB0eSk6ICAgICByZXBsYWNlIOKAlCBzcmMgYFtdYCBjbGVhcnMgdGhlIGRlc3RpbmF0aW9uIGFycmF5LlxuICogICBSYXRpb25hbGU6IHdyaXRpbmcgYHNjb3BlLnRhZ3MgPSBbXWAgbWVhbnMgXCJjbGVhciB0YWdzXCIsIG5vdCBcImFwcGVuZCBub3RoaW5nXCIuXG4gKiAgIFdpdGhvdXQgdGhpcyBydWxlLCBhbiBlbXB0eS1hcnJheSB3cml0ZSBzaWxlbnRseSBiZWNvbWVzIGEgbm8tb3Agd2hpY2ggaXNcbiAqICAgaW1wb3NzaWJsZSB0byBkaXN0aW5ndWlzaCBmcm9tIGEgYnVnLlxuICogLSBPYmplY3RzOiByZWN1cnNpdmUgbWVyZ2VcbiAqIC0gUHJpbWl0aXZlczogc291cmNlIHdpbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZXBTbWFydE1lcmdlKGRzdDogYW55LCBzcmM6IGFueSk6IGFueSB7XG4gIGlmIChzcmMgPT09IG51bGwgfHwgdHlwZW9mIHNyYyAhPT0gJ29iamVjdCcpIHJldHVybiBzcmM7XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkoc3JjKSkge1xuICAgIGlmIChzcmMubGVuZ3RoID09PSAwKSByZXR1cm4gW107IC8vIGVtcHR5IHNyYyA9IGNsZWFyLCBub3Qgbm8tb3BcbiAgICBpZiAoQXJyYXkuaXNBcnJheShkc3QpKSByZXR1cm4gWy4uLm5ldyBTZXQoWy4uLmRzdCwgLi4uc3JjXSldO1xuICAgIHJldHVybiBbLi4uc3JjXTtcbiAgfVxuXG4gIGNvbnN0IG91dDogYW55ID0geyAuLi4oZHN0ICYmIHR5cGVvZiBkc3QgPT09ICdvYmplY3QnID8gZHN0IDoge30pIH07XG4gIC8vIE9iamVjdC5rZXlzKCkgaXMgb3duLWVudW1lcmFibGUtb25seSBieSBzcGVjIOKAlCBubyBERU5JRUQgY2hlY2sgbmVlZGVkIGhlcmUuXG4gIGZvciAoY29uc3QgayBvZiBPYmplY3Qua2V5cyhzcmMpKSB7XG4gICAgb3V0W2tdID0gZGVlcFNtYXJ0TWVyZ2Uob3V0W2tdLCBzcmNba10pO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKlxuICogQXBwbGllcyBhIGNvbW1pdCBidW5kbGUgdG8gYSBiYXNlIHN0YXRlIGJ5IHJlcGxheWluZyBvcGVyYXRpb25zIGluIG9yZGVyLlxuICogR3VhcmFudGVlcyBcImxhc3Qgd3JpdGVyIHdpbnNcIiBzZW1hbnRpY3MuXG4gKlxuICogVGhlIHNpbmdsZSByZXBsYXkgcHJpbWl0aXZlIOKAlCB0aHJlZSBjb25zdW1lcnMgaW5oZXJpdCBldmVyeSB2ZXJiIGZyb20gaXQ6XG4gKiBsaXZlIHN0YXRlIChgU2hhcmVkTWVtb3J5LmFwcGx5UGF0Y2hgKSwgdGltZSB0cmF2ZWxcbiAqIChgRXZlbnRMb2cubWF0ZXJpYWxpc2VgKSwgYW5kIHRoZSByZWRhY3RlZCBtaXJyb3JcbiAqIChgU3RhZ2VDb250ZXh0LmNvbW1pdGAncyBzZWNvbmQgYGFwcGx5UGF0Y2hgKS5cbiAqXG4gKiBWZXJiIGFybXM6XG4gKiAgIC0gYCdzZXQnYCAgICDigJQgb3ZlcndyaXRlIHdpdGggYG92ZXJ3cml0ZVtwYXRoXWAgKHRoZSBmdWxsIGZpbmFsIHZhbHVlKS5cbiAqICAgLSBgJ21lcmdlJ2AgIOKAlCBgZGVlcFNtYXJ0TWVyZ2VgIHRoZSBhY2N1bXVsYXRlZCBgdXBkYXRlc1twYXRoXWAgZGVsdGEgaW4uXG4gKiAgIC0gYCdhcHBlbmQnYCDigJQgKCMxM2MtQiBkZWx0YSBtb2RlKSBgb3ZlcndyaXRlW3BhdGhdYCBob2xkcyBPTkxZIHRoZSB0YWlsO1xuICogICAgIHJlY29uc3RydWN0IGJ5IGNvbmNhdGVuYXRpbmcgaXQgb250byB0aGUgY3VycmVudCBhcnJheS4gV2hlbiB0aGVcbiAqICAgICBjdXJyZW50IHZhbHVlIG9yIHRoZSByZWNvcmRlZCB0YWlsIGlzIG5vdCBhbiBhcnJheSAob3V0LW9mLW9yZGVyXG4gKiAgICAgcmVwbGF5IGJhc2UsIG9yIGEgUkVEQUNURUQgdGFpbCDigJQgYHJlZGFjdFBhdGNoYCByZXBsYWNlcyBtYXRjaGVkXG4gKiAgICAgcGF5bG9hZHMgd2l0aCB0aGUgYCdSRURBQ1RFRCdgIHN0cmluZyksIGRlZ3JhZGUgdG8gYSBkaXJlY3Qgc2V0IG9mIHRoZVxuICogICAgIHJlY29yZGVkIHZhbHVlIOKAlCB0aGUgc2FtZSB0ZXJtaW5hbCB2YWx1ZSBhIHJlZGFjdGVkL2NvcnJ1cHQgYCdzZXQnYFxuICogICAgIHByb2R1Y2VzLlxuICogICAtIGAnZGVsZXRlJ2Ag4oCUICgjMTNjLUIgZGVsdGEgbW9kZSkgcmVtb3ZlIHRoZSBrZXkgKGBuYXRpdmVEZWxldGVgLFxuICogICAgIHByb3RvdHlwZS1wb2xsdXRpb24tc2FmZSkuIFRoZSBwYXRoIHN0YXlzIGVudW1lcmF0ZWQgaW4gYG92ZXJ3cml0ZWBcbiAqICAgICAodmFsdWUgYHVuZGVmaW5lZGApIGZvciBrZXktc2V0IGNvbnN1bWVyczsgcmVwbGF5IGlnbm9yZXMgdGhhdCB2YWx1ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5U21hcnRNZXJnZShiYXNlOiBhbnksIHVwZGF0ZXM6IE1lbW9yeVBhdGNoLCBvdmVyd3JpdGU6IE1lbW9yeVBhdGNoLCB0cmFjZTogVHJhY2VFbnRyeVtdKTogYW55IHtcbiAgY29uc3Qgb3V0ID0gc3RydWN0dXJlZENsb25lKGJhc2UpO1xuICBmb3IgKGNvbnN0IHsgcGF0aCwgdmVyYiB9IG9mIHRyYWNlKSB7XG4gICAgY29uc3Qgc2VncyA9IHBhdGguc3BsaXQoREVMSU0pO1xuICAgIGlmICh2ZXJiID09PSAnc2V0Jykge1xuICAgICAgX3NldChvdXQsIHNlZ3MsIHN0cnVjdHVyZWRDbG9uZShfZ2V0KG92ZXJ3cml0ZSwgc2VncykpKTtcbiAgICB9IGVsc2UgaWYgKHZlcmIgPT09ICdhcHBlbmQnKSB7XG4gICAgICBjb25zdCB0YWlsID0gc3RydWN0dXJlZENsb25lKF9nZXQob3ZlcndyaXRlLCBzZWdzKSk7XG4gICAgICBjb25zdCBjdXJyZW50ID0gX2dldChvdXQsIHNlZ3MpO1xuICAgICAgX3NldChvdXQsIHNlZ3MsIEFycmF5LmlzQXJyYXkoY3VycmVudCkgJiYgQXJyYXkuaXNBcnJheSh0YWlsKSA/IFsuLi5jdXJyZW50LCAuLi50YWlsXSA6IHRhaWwpO1xuICAgIH0gZWxzZSBpZiAodmVyYiA9PT0gJ2RlbGV0ZScpIHtcbiAgICAgIG5hdGl2ZURlbGV0ZShvdXQsIHNlZ3MpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBjdXJyZW50ID0gX2dldChvdXQsIHNlZ3MpID8/IHt9O1xuICAgICAgX3NldChvdXQsIHNlZ3MsIGRlZXBTbWFydE1lcmdlKGN1cnJlbnQsIF9nZXQodXBkYXRlcywgc2VncykpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cbiJdfQ==
287
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL21lbW9yeS91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUVILE9BQU8sRUFBRSxZQUFZLEVBQUUsU0FBUyxJQUFJLElBQUksRUFBRSxTQUFTLElBQUksSUFBSSxFQUFFLFNBQVMsSUFBSSxJQUFJLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFHckcsaUZBQWlGO0FBQ2pGLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUM7QUFJOUI7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUFDLEtBQWMsRUFBRSxPQUE0QixFQUFFO0lBQ2pGLE9BQU87UUFDTCxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztRQUNyRCxVQUFVLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQztLQUN0QixDQUFDO0FBQ0osQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FDNUIsR0FBaUIsRUFDakIsS0FBYSxFQUNiLEtBQWUsRUFDZixLQUFhLEVBQ2IsS0FBUSxFQUNSLGFBQXVCO0lBRXZCLE1BQU0sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsb0JBQW9CLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ25FLE1BQU0sSUFBSSxHQUFHLE9BQU8sSUFBSSxVQUFVLENBQUM7SUFDbkMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQzNCLElBQUksT0FBTyxHQUFpQixHQUFHLENBQUM7SUFDaEMsT0FBTyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzNCLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxLQUFLLEVBQVksQ0FBQztRQUN2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QUMsT0FBTyxDQUFDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoRyxDQUFDO2FBQU0sSUFBSSxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDN0IsWUFBWSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMxQixDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3RDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEUsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIHV0aWxzLnRzIOKAlCBIZWxwZXIgZnVuY3Rpb25zIGZvciBuZXN0ZWQgb2JqZWN0IG1hbmlwdWxhdGlvblxuICpcbiAqIFByb3ZpZGVzIGNvbnNpc3RlbnQgcGF0aCB0cmF2ZXJzYWwgYW5kIHZhbHVlIG1hbmlwdWxhdGlvbiBmb3IgdGhlIG1lbW9yeSBzeXN0ZW0uXG4gKiBaZXJvIGV4dGVybmFsIGRlcGVuZGVuY2llcy5cbiAqL1xuXG5pbXBvcnQgeyBuYXRpdmVEZWxldGUsIG5hdGl2ZUdldCBhcyBfZ2V0LCBuYXRpdmVIYXMgYXMgX2hhcywgbmF0aXZlU2V0IGFzIF9zZXQgfSBmcm9tICcuL3BhdGhPcHMuanMnO1xuaW1wb3J0IHR5cGUgeyBNZW1vcnlQYXRjaCwgVHJhY2VFbnRyeSB9IGZyb20gJy4vdHlwZXMuanMnO1xuXG4vKiogQVNDSUkgVW5pdC1TZXBhcmF0b3Ig4oCUIGNhbm5vdCBhcHBlYXIgaW4gSlMgaWRlbnRpZmllcnMsIGludmlzaWJsZSBpbiBsb2dzLiAqL1xuZXhwb3J0IGNvbnN0IERFTElNID0gJ1xcdTAwMUYnO1xuXG50eXBlIE5lc3RlZE9iamVjdCA9IHsgW2tleTogc3RyaW5nXTogYW55IH07XG5cbi8qKlxuICogUmVzb2x2ZXMgcnVuLW5hbWVzcGFjZWQgYW5kIGdsb2JhbCBwYXRocy5cbiAqIEVhY2ggZmxvd2NoYXJ0IGV4ZWN1dGlvbiAocnVuKSBzdG9yZXMgZGF0YSB1bmRlciBgcnVucy97aWR9L2AgdG8gcHJldmVudCBjb2xsaXNpb25zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UnVuQW5kR2xvYmFsUGF0aHMocnVuSWQ/OiBzdHJpbmcsIHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW10gPSBbXSkge1xuICByZXR1cm4ge1xuICAgIHJ1blBhdGg6IHJ1bklkID8gWydydW5zJywgcnVuSWQsIC4uLnBhdGhdIDogdW5kZWZpbmVkLFxuICAgIGdsb2JhbFBhdGg6IFsuLi5wYXRoXSxcbiAgfTtcbn1cblxuLyoqXG4gKiBTZXRzIGEgdmFsdWUgYXQgYSBuZXN0ZWQgcGF0aCwgY3JlYXRpbmcgaW50ZXJtZWRpYXRlIG9iamVjdHMgYXMgbmVlZGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0TmVzdGVkVmFsdWU8VD4oXG4gIG9iajogTmVzdGVkT2JqZWN0LFxuICBydW5JZDogc3RyaW5nLFxuICBfcGF0aDogc3RyaW5nW10sXG4gIGZpZWxkOiBzdHJpbmcsXG4gIHZhbHVlOiBULFxuICBkZWZhdWx0VmFsdWVzPzogdW5rbm93bixcbik6IE5lc3RlZE9iamVjdCB7XG4gIGNvbnN0IHsgcnVuUGF0aCwgZ2xvYmFsUGF0aCB9ID0gZ2V0UnVuQW5kR2xvYmFsUGF0aHMocnVuSWQsIF9wYXRoKTtcbiAgY29uc3QgcGF0aCA9IHJ1blBhdGggfHwgZ2xvYmFsUGF0aDtcbiAgY29uc3QgcGF0aENvcHkgPSBbLi4ucGF0aF07XG4gIGxldCBjdXJyZW50OiBOZXN0ZWRPYmplY3QgPSBvYmo7XG4gIHdoaWxlIChwYXRoQ29weS5sZW5ndGggPiAwKSB7XG4gICAgY29uc3Qga2V5ID0gcGF0aENvcHkuc2hpZnQoKSBhcyBzdHJpbmc7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY3VycmVudCwga2V5KSkge1xuICAgICAgY3VycmVudFtrZXldID0ga2V5ID09PSBydW5JZCAmJiBkZWZhdWx0VmFsdWVzID8gZGVmYXVsdFZhbHVlcyA6IHt9O1xuICAgIH1cbiAgICBjdXJyZW50ID0gY3VycmVudFtrZXldO1xuICB9XG4gIGN1cnJlbnRbZmllbGRdID0gdmFsdWU7XG4gIHJldHVybiBvYmo7XG59XG5cbi8qKlxuICogRGVlcC1tZXJnZXMgYSB2YWx1ZSBpbnRvIHRoZSBvYmplY3QgYXQgdGhlIHNwZWNpZmllZCBwYXRoLlxuICogLSBBcnJheXM6IGNvbmNhdGVuYXRlXG4gKiAtIE9iamVjdHM6IHNoYWxsb3cgbWVyZ2UgYXQgZWFjaCBsZXZlbFxuICogLSBQcmltaXRpdmVzOiByZXBsYWNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVOZXN0ZWRWYWx1ZTxUPihcbiAgb2JqOiBhbnksXG4gIHJ1bklkOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIF9wYXRoOiAoc3RyaW5nIHwgbnVtYmVyKVtdLFxuICBmaWVsZDogc3RyaW5nIHwgbnVtYmVyLFxuICB2YWx1ZTogVCxcbiAgZGVmYXVsdFZhbHVlcz86IHVua25vd24sXG4pOiBhbnkge1xuICBjb25zdCB7IHJ1blBhdGgsIGdsb2JhbFBhdGggfSA9IGdldFJ1bkFuZEdsb2JhbFBhdGhzKHJ1bklkLCBfcGF0aCk7XG4gIGNvbnN0IHBhdGggPSBydW5QYXRoIHx8IGdsb2JhbFBhdGg7XG4gIGNvbnN0IHBhdGhDb3B5ID0gWy4uLnBhdGhdO1xuICBsZXQgY3VycmVudDogTmVzdGVkT2JqZWN0ID0gb2JqO1xuICB3aGlsZSAocGF0aENvcHkubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IGtleSA9IHBhdGhDb3B5LnNoaWZ0KCkgYXMgc3RyaW5nO1xuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGN1cnJlbnQsIGtleSkpIHtcbiAgICAgIGN1cnJlbnRba2V5XSA9IGtleSA9PT0gcnVuSWQgJiYgZGVmYXVsdFZhbHVlcyA/IGRlZmF1bHRWYWx1ZXMgOiB7fTtcbiAgICB9XG4gICAgY3VycmVudCA9IGN1cnJlbnRba2V5XTtcbiAgfVxuICB1cGRhdGVWYWx1ZShjdXJyZW50LCBmaWVsZCwgdmFsdWUpO1xuICByZXR1cm4gb2JqO1xufVxuXG4vKipcbiAqIEluLXBsYWNlIHZhbHVlIHVwZGF0ZSB3aXRoIG1lcmdlIHNlbWFudGljcy5cbiAqIC0gQXJyYXlzIChub24tZW1wdHkpOiBjb25jYXRlbmF0ZSBvbnRvIGV4aXN0aW5nXG4gKiAtIEFycmF5cyAoZW1wdHkpOiAgICAgZGlyZWN0IHJlcGxhY2Ug4oCUIHdyaXRpbmcgYFtdYCBjbGVhcnMgdGhlIGZpZWxkXG4gKiAtIE9iamVjdHMgKG5vbi1lbXB0eSk6IHNoYWxsb3cgbWVyZ2UgKHNwcmVhZClcbiAqIC0gT2JqZWN0cyAoZW1wdHkpOiAgICBkaXJlY3QgcmVwbGFjZSDigJQgd3JpdGluZyBge31gIGNsZWFycyB0aGUgZmllbGRcbiAqIC0gUHJpbWl0aXZlczogZGlyZWN0IGFzc2lnbm1lbnRcbiAqXG4gKiBOb3RlIG9uIGVtcHR5IGFycmF5czogYm90aCBgdmFsdWUgJiYgQXJyYXkuaXNBcnJheSh2YWx1ZSlgIGFuZFxuICogYEFycmF5LmlzQXJyYXkodmFsdWUpYCBldmFsdWF0ZSB0aGUgc2FtZSBmb3IgYXJyYXlzIOKAlCBgW11gIGlzIHRydXRoeSBpblxuICogSmF2YVNjcmlwdCwgc28gdGhlIGAmJmAgZ3VhcmQgd2FzIG5ldmVyIHRoZSBpc3N1ZS4gVGhlIGFjdHVhbCBidWcgd2FzIHRoZVxuICogY29uY2F0IHBhdGg6IGBbLi4uY3VyLCAuLi5bXV1gIHNpbGVudGx5IHJldHVybmVkIGBjdXJgIHVuY2hhbmdlZCB3aGVuIGB2YWx1ZWBcbiAqIHdhcyBgW11gLCBtYWtpbmcgYHVwZGF0ZVZhbHVlKG9iaiwgJ3RhZ3MnLCBbXSlgIGEgbm8tb3AgaW5zdGVhZCBvZiBhIGNsZWFyLlxuICogVGhlIGZpeCBpcyB0aGUgZXhwbGljaXQgYHZhbHVlLmxlbmd0aCA9PT0gMGAgZWFybHktcmV0dXJuIGJyYW5jaC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVZhbHVlKG9iamVjdDogYW55LCBrZXk6IHN0cmluZyB8IG51bWJlciwgdmFsdWU6IGFueSk6IHZvaWQge1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBpZiAodmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICBvYmplY3Rba2V5XSA9IHZhbHVlOyAvLyBjbGVhcjogW10gcmVwbGFjZXMgd2hhdGV2ZXIgd2FzIHRoZXJlXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGN1ciA9IG9iamVjdFtrZXldIGFzIGFueTtcbiAgICAgIG9iamVjdFtrZXldID0gY3VyID09PSB1bmRlZmluZWQgPyB2YWx1ZSA6IFsuLi5jdXIsIC4uLnZhbHVlXTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoKSB7XG4gICAgY29uc3QgY3VyID0gb2JqZWN0W2tleV0gYXMgYW55O1xuICAgIG9iamVjdFtrZXldID0gY3VyID09PSB1bmRlZmluZWQgPyB2YWx1ZSA6IHsgLi4uY3VyLCAuLi52YWx1ZSB9O1xuICB9IGVsc2Uge1xuICAgIG9iamVjdFtrZXldID0gdmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBHZXRzIGEgdmFsdWUgYXQgYSBuZXN0ZWQgcGF0aCB3aXRoIHByb3RvdHlwZS1wb2xsdXRpb24gcHJvdGVjdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE5lc3RlZFZhbHVlKHJvb3Q6IGFueSwgcGF0aDogKHN0cmluZyB8IG51bWJlcilbXSwgZmllbGQ/OiBzdHJpbmcgfCBudW1iZXIpOiBhbnkge1xuICBjb25zdCBub2RlID0gcGF0aCAmJiBwYXRoLmxlbmd0aCA+IDAgPyBfZ2V0KHJvb3QsIHBhdGgpIDogcm9vdDtcbiAgaWYgKGZpZWxkID09PSB1bmRlZmluZWQgfHwgbm9kZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gbm9kZTtcbiAgaWYgKG5vZGUgIT09IG51bGwgJiYgdHlwZW9mIG5vZGUgPT09ICdvYmplY3QnICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChub2RlLCBmaWVsZCkpIHtcbiAgICByZXR1cm4gbm9kZVtmaWVsZF07XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZWRhY3RzIHNlbnNpdGl2ZSB2YWx1ZXMgaW4gYSBwYXRjaCBmb3IgbG9nZ2luZy9kZWJ1Z2dpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWRhY3RQYXRjaChwYXRjaDogTWVtb3J5UGF0Y2gsIHJlZGFjdGVkU2V0OiBTZXQ8c3RyaW5nPik6IE1lbW9yeVBhdGNoIHtcbiAgY29uc3Qgb3V0ID0gc3RydWN0dXJlZENsb25lKHBhdGNoKTtcbiAgZm9yIChjb25zdCBmbGF0IG9mIHJlZGFjdGVkU2V0KSB7XG4gICAgY29uc3QgcGF0aEFyciA9IGZsYXQuc3BsaXQoREVMSU0pO1xuICAgIGlmIChfaGFzKG91dCwgcGF0aEFycikpIHtcbiAgICAgIGNvbnN0IGN1cnIgPSBfZ2V0KG91dCwgcGF0aEFycik7XG4gICAgICBpZiAodHlwZW9mIGN1cnIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIF9zZXQob3V0LCBwYXRoQXJyLCAnUkVEQUNURUQnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBOb3JtYWxpc2VzIGFuIGFycmF5IHBhdGggaW50byBhIHN0YWJsZSBzdHJpbmcga2V5IHVzaW5nIERFTElNLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXNlUGF0aChwYXRoOiAoc3RyaW5nIHwgbnVtYmVyKVtdKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhdGgubWFwKFN0cmluZykuam9pbihERUxJTSk7XG59XG5cbi8qKlxuICogU3RydWN0dXJhbCBkZWVwIGVxdWFsaXR5IGZvciBjb21taXR0ZWQtc3RhdGUgdmFsdWVzLlxuICpcbiAqIFVzZWQgYnkge0BsaW5rIFRyYW5zYWN0aW9uQnVmZmVyfSB0byBkZWNpZGUgd2hldGhlciBhIHN0YWdlIGFjdHVhbGx5IENIQU5HRURcbiAqIGEgcGF0aCBvciBtZXJlbHkgcmUtd3JvdGUgLyByZXZlcnRlZCBpdCB0byB0aGUgdmFsdWUgaXQgYWxyZWFkeSBoZWxkIChhXG4gKiBcIm5vLW9wIHdyaXRlXCIpLiBDb21taXR0ZWQgc3RhdGUgaXMgSlNPTi1zaGFwZWQg4oCUIGl0IG11c3Qgc3Vydml2ZVxuICogYHN0cnVjdHVyZWRDbG9uZWAg4oCUIHNvIHRoaXMgb25seSBuZWVkcyB0byBoYW5kbGUgdGhlIHNoYXBlcyB0aGF0IGNhbiByZWFjaCBhXG4gKiBjb21taXQ6IHByaW1pdGl2ZXMsIGFycmF5cywgYW5kIHBsYWluIG9iamVjdHMuXG4gKlxuICogU2VtYW50aWNzOlxuICogICAtIHJlZmVyZW5jZSAvIGlkZW50aWNhbC1wcmltaXRpdmUgc2hvcnQtY2lyY3VpdHMgZmlyc3QgKGNoZWFwIGZhc3QgcGF0aClcbiAqICAgLSBgTmFOYCBlcXVhbHMgYE5hTmAgKHByaW1pdGl2ZSBjb21wYXJlIGZhbGxzIGJhY2sgdG8gYE9iamVjdC5pc2ApXG4gKiAgIC0gYXJyYXlzOiBlcXVhbCBsZW5ndGggQU5EIGRlZXAtZXF1YWwgZWxlbWVudC13aXNlIChvcmRlci1zZW5zaXRpdmUpXG4gKiAgIC0gb2JqZWN0czogaWRlbnRpY2FsIG93bi1rZXkgc2V0IEFORCBkZWVwLWVxdWFsIHBlciBrZXlcbiAqICAgLSBtaXNtYXRjaGVkIGtpbmRzIChhcnJheSB2cyBvYmplY3QsIG9iamVjdCB2cyBudWxsKSDihpIgbm90IGVxdWFsXG4gKlxuICogQ29zdCAmIHNhZmV0eTpcbiAqICAgLSBBbGxvY2F0ZXMgTk9USElORyBidXQgdHJhbnNpZW50IGBPYmplY3Qua2V5c2AgYXJyYXlzIOKAlCBubyBjbG9uZXMuIEl0IGlzXG4gKiAgICAgc3RyaWN0bHkgY2hlYXBlciB0aGFuIHRoZSBgc3RydWN0dXJlZENsb25lYCB0aGUgY29tbWl0IGFscmVhZHkgcGVyZm9ybXMuXG4gKiAgIC0gUHJpbWl0aXZlIGNvbXBhcmlzb25zICh0aGUgYnVsayBvZiBzdGF0ZSkgYXJlIE8oMSkgdmlhIHRoZSBgPT09YCAvXG4gKiAgICAgYE9iamVjdC5pc2AgZmFzdCBwYXRoczsgb25seSBuZXN0ZWQgb2JqZWN0cy9hcnJheXMgaW5jdXIgYSB3YWxrLCBib3VuZGVkXG4gKiAgICAgYnkgdGhlIHZhbHVlJ3Mgb3duIHNpemUuXG4gKiAgIC0gVGVybWluYXRlcyBvbiBDWUNMSUMgdmFsdWVzICg5LjE4LjEpOiBhIHN0YXRlIHZhbHVlIG11c3Qgc3Vydml2ZVxuICogICAgIGBzdHJ1Y3R1cmVkQ2xvbmVgLCBhbmQgYHN0cnVjdHVyZWRDbG9uZWAgcHJlc2VydmVzIGN5Y2xlcyDigJQgc28gYVxuICogICAgIHNlbGYtcmVmZXJlbmNpbmcgdmFsdWUgaXMgYSBsZWdhbCB2YWx1ZSwgbm90IGFuIG91dC1vZi1jb250cmFjdCBvbmUuIEFcbiAqICAgICBwYWlyIG9mIG9iamVjdHMgYWxyZWFkeSB1bmRlciBjb21wYXJpc29uIGlzIHRyZWF0ZWQgYXMgZXF1YWwgKHRoZVxuICogICAgIHN0cnVjdHVyYWwgYW5zd2VyLCBsb2Rhc2ggYGlzRXF1YWxgIHNlbWFudGljcyk7IGFjeWNsaWMgaW5wdXRzIHNlZSBub1xuICogICAgIGNoYW5nZS4gRGV2IG1vZGUgc3RpbGwgd2FybnMgYWJvdXQgY3ljbGVzIGF0IHdyaXRlIHRpbWVcbiAqICAgICAoYFNjb3BlRmFjYWRlLnNldFZhbHVlYCkgYmVjYXVzZSB0aGV5IHN1cnByaXNlIG5hcnJhdGl2ZSBhbmQgSlNPTi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZXBFcXVhbChhOiBhbnksIGI6IGFueSk6IGJvb2xlYW4ge1xuICByZXR1cm4gZXF1YWxQYWlycyhhLCBiLCB1bmRlZmluZWQpO1xufVxuXG4vKipcbiAqIE9iamVjdCBwYWlycyBtZXQgc28gZmFyLCBrZXllZCBgYSDihpIgdGhlIGIncyBpdCBoYXMgYmVlbiBwYWlyZWQgd2l0aGAuIENyZWF0ZWRcbiAqIGxhemlseSBieSB0aGUgZmlyc3Qgb2JqZWN0IHBhaXIsIHNvIHByaW1pdGl2ZSBjb21wYXJlcyBhbGxvY2F0ZSBub3RoaW5nLlxuICogTmV2ZXIgcHJ1bmVkOiBldmVyeSBgZmFsc2VgIHJldHVybnMgc3RyYWlnaHQgdXAgdG8gdGhlIGNhbGxlciAoZWFjaCByZWN1cnNpdmVcbiAqIGNhbGwgc2hvcnQtY2lyY3VpdHMgb24gaXQpLCBzbyBub3RoaW5nIGlzIGxvb2tlZCB1cCBhZnRlciBhIG1pc21hdGNoIOKAlCBhXG4gKiBzdG9yZWQgcGFpciBpcyBlaXRoZXIgc3RpbGwgdW5kZXIgY29tcGFyaXNvbiBvciBhbHJlYWR5IGtub3duIGVxdWFsLlxuICovXG50eXBlIFNlZW5QYWlycyA9IFdlYWtNYXA8b2JqZWN0LCBXZWFrU2V0PG9iamVjdD4+O1xuXG5mdW5jdGlvbiBlcXVhbFBhaXJzKGE6IGFueSwgYjogYW55LCBzZWVuOiBTZWVuUGFpcnMgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgaWYgKGEgPT09IGIpIHJldHVybiB0cnVlOyAvLyBzYW1lIHJlZmVyZW5jZSBvciBpZGVudGljYWwgcHJpbWl0aXZlXG4gIGlmICh0eXBlb2YgYSAhPT0gdHlwZW9mIGIpIHJldHVybiBmYWxzZTtcbiAgaWYgKGEgPT09IG51bGwgfHwgYiA9PT0gbnVsbCkgcmV0dXJuIGEgPT09IGI7IC8vIG9uZSBpcyBudWxsLCB0aGUgb3RoZXIgaXNuJ3RcbiAgaWYgKHR5cGVvZiBhICE9PSAnb2JqZWN0JykgcmV0dXJuIE9iamVjdC5pcyhhLCBiKTsgLy8gTmFOLXNhZmUgcHJpbWl0aXZlIGNvbXBhcmVcblxuICBjb25zdCBhSXNBcnJheSA9IEFycmF5LmlzQXJyYXkoYSk7XG4gIGlmIChhSXNBcnJheSAhPT0gQXJyYXkuaXNBcnJheShiKSkgcmV0dXJuIGZhbHNlOyAvLyBhcnJheSB2cyBwbGFpbiBvYmplY3RcblxuICAvLyBDeWNsZSBndWFyZCDigJQgYSBwYWlyIHdlIGFyZSBhbHJlYWR5IGluc2lkZSBpcyBlcXVhbCBieSBhc3N1bXB0aW9uLlxuICBzZWVuID8/PSBuZXcgV2Vha01hcCgpO1xuICBsZXQgcGFydG5lcnMgPSBzZWVuLmdldChhKTtcbiAgaWYgKHBhcnRuZXJzPy5oYXMoYikpIHJldHVybiB0cnVlO1xuICBpZiAoIXBhcnRuZXJzKSBzZWVuLnNldChhLCAocGFydG5lcnMgPSBuZXcgV2Vha1NldCgpKSk7XG4gIHBhcnRuZXJzLmFkZChiKTtcblxuICBpZiAoYUlzQXJyYXkpIHtcbiAgICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIWVxdWFsUGFpcnMoYVtpXSwgYltpXSwgc2VlbikpIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBjb25zdCBhS2V5cyA9IE9iamVjdC5rZXlzKGEpO1xuICBjb25zdCBiS2V5cyA9IE9iamVjdC5rZXlzKGIpO1xuICBpZiAoYUtleXMubGVuZ3RoICE9PSBiS2V5cy5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgZm9yIChjb25zdCBrZXkgb2YgYUtleXMpIHtcbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKCFlcXVhbFBhaXJzKGFba2V5XSwgYltrZXldLCBzZWVuKSkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIERlZXAgdW5pb24gbWVyZ2UgaGVscGVyLlxuICogLSBBcnJheXMgKG5vbi1lbXB0eSk6IHVuaW9uIHdpdGhvdXQgZHVwbGljYXRlcyAoZW5jb3VudGVyIG9yZGVyIHByZXNlcnZlZClcbiAqIC0gQXJyYXlzIChlbXB0eSk6ICAgICByZXBsYWNlIOKAlCBzcmMgYFtdYCBjbGVhcnMgdGhlIGRlc3RpbmF0aW9uIGFycmF5LlxuICogICBSYXRpb25hbGU6IHdyaXRpbmcgYHNjb3BlLnRhZ3MgPSBbXWAgbWVhbnMgXCJjbGVhciB0YWdzXCIsIG5vdCBcImFwcGVuZCBub3RoaW5nXCIuXG4gKiAgIFdpdGhvdXQgdGhpcyBydWxlLCBhbiBlbXB0eS1hcnJheSB3cml0ZSBzaWxlbnRseSBiZWNvbWVzIGEgbm8tb3Agd2hpY2ggaXNcbiAqICAgaW1wb3NzaWJsZSB0byBkaXN0aW5ndWlzaCBmcm9tIGEgYnVnLlxuICogLSBPYmplY3RzOiByZWN1cnNpdmUgbWVyZ2VcbiAqIC0gUHJpbWl0aXZlczogc291cmNlIHdpbnNcbiAqXG4gKiBUZXJtaW5hdGVzIG9uIGEgQ1lDTElDIGBzcmNgICg5LjE4LjEsIHNhbWUgbGF3IGFzIHtAbGluayBkZWVwRXF1YWx9OiBhXG4gKiBzdGF0ZSB2YWx1ZSBzdXJ2aXZlcyBgc3RydWN0dXJlZENsb25lYCwgd2hpY2ggcHJlc2VydmVzIGN5Y2xlcykuIEEgYHNyY2BcbiAqIG9iamVjdCByZS1lbnRlcmVkIHdoaWxlIGl0IGlzIHN0aWxsIGJlaW5nIG1lcmdlZCBoaWdoZXIgdXAgdGhlIHN0YWNrIGhhbmRzXG4gKiBiYWNrIHRoZSBvdXRwdXQgYmVpbmcgYnVpbHQgZm9yIGl0LCBzbyB0aGUgbWVyZ2VkIHZhbHVlIG1pcnJvcnMgdGhlIGN5Y2xlXG4gKiBpbnN0ZWFkIG9mIHVucm9sbGluZyBpdCBmb3JldmVyLiBPbmx5IHRoZSBhbmNlc3RvcnMgb24gdGhlIHN0YWNrIGFyZVxuICogZ3VhcmRlZCDigJQgYSBzaGFyZWQgKGFjeWNsaWMpIGBzcmNgIHJlZmVyZW5jZSBtZXQgYWdhaW4gYXQgYSBkaWZmZXJlbnRcbiAqIGBkc3RgIG1lcmdlcyBhZ2FpbnN0IFRIQVQgYGRzdGAsIGV4YWN0bHkgYXMgYmVmb3JlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVlcFNtYXJ0TWVyZ2UoZHN0OiBhbnksIHNyYzogYW55KTogYW55IHtcbiAgcmV0dXJuIG1lcmdlR3VhcmRlZChkc3QsIHNyYywgdW5kZWZpbmVkKTtcbn1cblxuZnVuY3Rpb24gbWVyZ2VHdWFyZGVkKGRzdDogYW55LCBzcmM6IGFueSwgaW5GbGlnaHQ6IFdlYWtNYXA8b2JqZWN0LCBhbnk+IHwgdW5kZWZpbmVkKTogYW55IHtcbiAgaWYgKHNyYyA9PT0gbnVsbCB8fCB0eXBlb2Ygc3JjICE9PSAnb2JqZWN0JykgcmV0dXJuIHNyYztcblxuICBpZiAoQXJyYXkuaXNBcnJheShzcmMpKSB7XG4gICAgaWYgKHNyYy5sZW5ndGggPT09IDApIHJldHVybiBbXTsgLy8gZW1wdHkgc3JjID0gY2xlYXIsIG5vdCBuby1vcFxuICAgIGlmIChBcnJheS5pc0FycmF5KGRzdCkpIHJldHVybiBbLi4ubmV3IFNldChbLi4uZHN0LCAuLi5zcmNdKV07XG4gICAgcmV0dXJuIFsuLi5zcmNdO1xuICB9XG5cbiAgaWYgKGluRmxpZ2h0Py5oYXMoc3JjKSkgcmV0dXJuIGluRmxpZ2h0LmdldChzcmMpOyAvLyBjeWNsZSDigJQgcmUtZW50ZXIgdGhlIHZhbHVlIGJlaW5nIGJ1aWx0XG5cbiAgY29uc3Qgb3V0OiBhbnkgPSB7IC4uLihkc3QgJiYgdHlwZW9mIGRzdCA9PT0gJ29iamVjdCcgPyBkc3QgOiB7fSkgfTtcbiAgKGluRmxpZ2h0ID8/PSBuZXcgV2Vha01hcCgpKS5zZXQoc3JjLCBvdXQpO1xuICAvLyBPYmplY3Qua2V5cygpIGlzIG93bi1lbnVtZXJhYmxlLW9ubHkgYnkgc3BlYyDigJQgbm8gREVOSUVEIGNoZWNrIG5lZWRlZCBoZXJlLlxuICBmb3IgKGNvbnN0IGsgb2YgT2JqZWN0LmtleXMoc3JjKSkge1xuICAgIG91dFtrXSA9IG1lcmdlR3VhcmRlZChvdXRba10sIHNyY1trXSwgaW5GbGlnaHQpO1xuICB9XG4gIGluRmxpZ2h0LmRlbGV0ZShzcmMpO1xuICByZXR1cm4gb3V0O1xufVxuXG4vKipcbiAqIEFwcGxpZXMgYSBjb21taXQgYnVuZGxlIHRvIGEgYmFzZSBzdGF0ZSBieSByZXBsYXlpbmcgb3BlcmF0aW9ucyBpbiBvcmRlci5cbiAqIEd1YXJhbnRlZXMgXCJsYXN0IHdyaXRlciB3aW5zXCIgc2VtYW50aWNzLlxuICpcbiAqIFRoZSBzaW5nbGUgcmVwbGF5IHByaW1pdGl2ZSDigJQgdGhyZWUgY29uc3VtZXJzIGluaGVyaXQgZXZlcnkgdmVyYiBmcm9tIGl0OlxuICogbGl2ZSBzdGF0ZSAoYFNoYXJlZE1lbW9yeS5hcHBseVBhdGNoYCksIHRpbWUgdHJhdmVsXG4gKiAoYEV2ZW50TG9nLm1hdGVyaWFsaXNlYCksIGFuZCB0aGUgcmVkYWN0ZWQgbWlycm9yXG4gKiAoYFN0YWdlQ29udGV4dC5jb21taXRgJ3Mgc2Vjb25kIGBhcHBseVBhdGNoYCkuXG4gKlxuICogVmVyYiBhcm1zOlxuICogICAtIGAnc2V0J2AgICAg4oCUIG92ZXJ3cml0ZSB3aXRoIGBvdmVyd3JpdGVbcGF0aF1gICh0aGUgZnVsbCBmaW5hbCB2YWx1ZSkuXG4gKiAgIC0gYCdtZXJnZSdgICDigJQgYGRlZXBTbWFydE1lcmdlYCB0aGUgYWNjdW11bGF0ZWQgYHVwZGF0ZXNbcGF0aF1gIGRlbHRhIGluLlxuICogICAtIGAnYXBwZW5kJ2Ag4oCUICgjMTNjLUIgZGVsdGEgbW9kZSkgYG92ZXJ3cml0ZVtwYXRoXWAgaG9sZHMgT05MWSB0aGUgdGFpbDtcbiAqICAgICByZWNvbnN0cnVjdCBieSBjb25jYXRlbmF0aW5nIGl0IG9udG8gdGhlIGN1cnJlbnQgYXJyYXkuIFdoZW4gdGhlXG4gKiAgICAgY3VycmVudCB2YWx1ZSBvciB0aGUgcmVjb3JkZWQgdGFpbCBpcyBub3QgYW4gYXJyYXkgKG91dC1vZi1vcmRlclxuICogICAgIHJlcGxheSBiYXNlLCBvciBhIFJFREFDVEVEIHRhaWwg4oCUIGByZWRhY3RQYXRjaGAgcmVwbGFjZXMgbWF0Y2hlZFxuICogICAgIHBheWxvYWRzIHdpdGggdGhlIGAnUkVEQUNURUQnYCBzdHJpbmcpLCBkZWdyYWRlIHRvIGEgZGlyZWN0IHNldCBvZiB0aGVcbiAqICAgICByZWNvcmRlZCB2YWx1ZSDigJQgdGhlIHNhbWUgdGVybWluYWwgdmFsdWUgYSByZWRhY3RlZC9jb3JydXB0IGAnc2V0J2BcbiAqICAgICBwcm9kdWNlcy5cbiAqICAgLSBgJ2RlbGV0ZSdgIOKAlCAoIzEzYy1CIGRlbHRhIG1vZGUpIHJlbW92ZSB0aGUga2V5IChgbmF0aXZlRGVsZXRlYCxcbiAqICAgICBwcm90b3R5cGUtcG9sbHV0aW9uLXNhZmUpLiBUaGUgcGF0aCBzdGF5cyBlbnVtZXJhdGVkIGluIGBvdmVyd3JpdGVgXG4gKiAgICAgKHZhbHVlIGB1bmRlZmluZWRgKSBmb3Iga2V5LXNldCBjb25zdW1lcnM7IHJlcGxheSBpZ25vcmVzIHRoYXQgdmFsdWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVNtYXJ0TWVyZ2UoYmFzZTogYW55LCB1cGRhdGVzOiBNZW1vcnlQYXRjaCwgb3ZlcndyaXRlOiBNZW1vcnlQYXRjaCwgdHJhY2U6IFRyYWNlRW50cnlbXSk6IGFueSB7XG4gIGNvbnN0IG91dCA9IHN0cnVjdHVyZWRDbG9uZShiYXNlKTtcbiAgZm9yIChjb25zdCB7IHBhdGgsIHZlcmIgfSBvZiB0cmFjZSkge1xuICAgIGNvbnN0IHNlZ3MgPSBwYXRoLnNwbGl0KERFTElNKTtcbiAgICBpZiAodmVyYiA9PT0gJ3NldCcpIHtcbiAgICAgIF9zZXQob3V0LCBzZWdzLCBzdHJ1Y3R1cmVkQ2xvbmUoX2dldChvdmVyd3JpdGUsIHNlZ3MpKSk7XG4gICAgfSBlbHNlIGlmICh2ZXJiID09PSAnYXBwZW5kJykge1xuICAgICAgY29uc3QgdGFpbCA9IHN0cnVjdHVyZWRDbG9uZShfZ2V0KG92ZXJ3cml0ZSwgc2VncykpO1xuICAgICAgY29uc3QgY3VycmVudCA9IF9nZXQob3V0LCBzZWdzKTtcbiAgICAgIF9zZXQob3V0LCBzZWdzLCBBcnJheS5pc0FycmF5KGN1cnJlbnQpICYmIEFycmF5LmlzQXJyYXkodGFpbCkgPyBbLi4uY3VycmVudCwgLi4udGFpbF0gOiB0YWlsKTtcbiAgICB9IGVsc2UgaWYgKHZlcmIgPT09ICdkZWxldGUnKSB7XG4gICAgICBuYXRpdmVEZWxldGUob3V0LCBzZWdzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgY3VycmVudCA9IF9nZXQob3V0LCBzZWdzKSA/PyB7fTtcbiAgICAgIF9zZXQob3V0LCBzZWdzLCBkZWVwU21hcnRNZXJnZShjdXJyZW50LCBfZ2V0KHVwZGF0ZXMsIHNlZ3MpKSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXQ7XG59XG4iXX0=
@@ -0,0 +1,119 @@
1
+ /**
2
+ * axis.ts — the shape of an axis, and the one safe way to narrow it.
3
+ *
4
+ * WHY THIS FILE EXISTS. `commitStops` returns `Stop[]`, and every strategy
5
+ * that COMPOSES it (keep the stages my domain recognises, drop the rest) rests
6
+ * on a shape the type never stated: `[start, …stages, end]` for a non-empty
7
+ * log, empty for an empty one. Each composer therefore wrote its own runtime
8
+ * guard against its own reading of the contract, plus a mocked-substrate test
9
+ * to prove the guard fires. That is one invariant, discovered three times, and
10
+ * the library that owns the invariant should be the one that states it.
11
+ *
12
+ * {@link splitAxis} states it. {@link filterStops} then does the whole
13
+ * composition — check the shape, keep what the caller keeps, RE-PARTITION the
14
+ * log so the dropped stages' commits are still folded somewhere, and mark the
15
+ * `'start'` bookend as carrying a prologue — because getting the
16
+ * re-partitioning right by hand is the other thing every composer had to
17
+ * rediscover.
18
+ */
19
+ import type { AxisSplit, Stop } from './types.js';
20
+ /**
21
+ * Split a strategy's stops into `{ start, stages, end }`, or say why it cannot.
22
+ *
23
+ * THE INVARIANT, stated once: for a non-EMPTY log, `commitStops` returns at
24
+ * least the two bookends, `'start'` first and `'end'` last, with one stop per
25
+ * executed stage in execution order between them. For an EMPTY log it returns
26
+ * `[]` — no bookends around nothing, because a cursor with nowhere to stand
27
+ * should say `reason: 'empty'` rather than offer two positions that are the
28
+ * same position.
29
+ *
30
+ * The two refusals are different facts and must not be collapsed: `'empty'`
31
+ * means the run committed nothing, `'not-bookended'` means a strategy broke
32
+ * the contract. A composer that treats them alike reports a broken strategy as
33
+ * an empty run.
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * import { commitStops, splitAxis } from 'footprintjs/trace';
38
+ *
39
+ * const axis = splitAxis(commitStops(snapshot.commitLog, snapshot.executionTree));
40
+ * if (axis.ok) {
41
+ * axis.start.commitIdx; // -1 — the fold base
42
+ * axis.stages.map((s) => s.label);
43
+ * axis.end.lastCommitIdx; // the last bundle in the log
44
+ * } else {
45
+ * axis.reason; // 'empty' | 'not-bookended'
46
+ * }
47
+ * ```
48
+ */
49
+ export declare function splitAxis<TMeta = unknown>(stops: readonly Stop<TMeta>[]): AxisSplit<TMeta>;
50
+ /**
51
+ * What {@link filterStops} does with one stop: drop it, keep it, or keep it
52
+ * carrying the strategy's own label and vocabulary.
53
+ *
54
+ * `false` / `null` / `undefined` drop. `true` keeps it unchanged. An object
55
+ * keeps it and overrides `label` and/or sets `meta` — the strategy's own
56
+ * classification, travelling ON the stop instead of being re-derived from
57
+ * `runtimeStageId` at every read.
58
+ */
59
+ export type StopFilter<TMeta> = boolean | null | undefined | {
60
+ readonly label?: string;
61
+ readonly meta?: TMeta;
62
+ };
63
+ /**
64
+ * Build a FILTERING strategy's axis out of another strategy's stops.
65
+ *
66
+ * The rule, in one sentence: keep the stages `keep` recognises, and give the
67
+ * survivors the log back.
68
+ *
69
+ * **Meta is the decision's, never inherited.** The input may already be a
70
+ * filtered axis carrying another strategy's `meta`; a `true` (or a meta-less
71
+ * object) keeps the stop and DROPS that meta, so a `Stop<TMeta>` never carries
72
+ * a value of some other type under `TMeta`. The bookends carry none either.
73
+ *
74
+ * **The survivors re-partition the log.** A dropped stage's commits still
75
+ * happened, so they fold into the stop that PRECEDES them: every kept stop's
76
+ * `lastCommitIdx` runs to just before the next kept stop begins. Nothing is
77
+ * orphaned and `stateAt(stop)` stays "the state that existed when the next
78
+ * kept stage started".
79
+ *
80
+ * **What that costs `'start'`, said out loud.** The commits before the first
81
+ * survivor have nowhere else to go, so `'start'` absorbs them: its fold is the
82
+ * run's base PLUS that prologue — the state the first stop READ, not the raw
83
+ * base. The returned start therefore carries `prologue: true` whenever it
84
+ * actually absorbed a stage, and a renderer that means "before anything ran"
85
+ * checks `kind === 'start' && !prologue`. That flag is the whole reason this
86
+ * helper exists rather than a `.filter()` call.
87
+ *
88
+ * **A log with nothing kept** yields the two bookends and nothing between
89
+ * them: `'start'` folds the whole log, `'end'` folds the whole log, and
90
+ * `jumpTo` on any stage id refuses with `reason: 'miss'`. An axis with nowhere
91
+ * meaningful to stand — which is the truthful shape for a run this strategy
92
+ * recognises nothing in, and NOT the `[]` that says the log was empty.
93
+ *
94
+ * @throws when `stops` is non-empty but not bookended — see {@link splitAxis}.
95
+ * Only a strategy can cause that; a run cannot, so it is a contract error
96
+ * and not a condition to fold into the data.
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * import { commitStops, filterStops } from 'footprintjs/trace';
101
+ * import type { Stop, TimeTravelStrategy } from 'footprintjs/trace';
102
+ *
103
+ * type Milestone = { kind: 'llm-turn' | 'tool-call'; label: string };
104
+ * declare function milestoneFor(runtimeStageId: string): Milestone | null;
105
+ *
106
+ * const milestoneStops: TimeTravelStrategy<Milestone> = {
107
+ * stopsFor: (log, tree) =>
108
+ * filterStops<Milestone>(commitStops(log, tree), (stop) => {
109
+ * const m = milestoneFor(stop.runtimeStageId);
110
+ * return m ? { label: m.label, meta: m } : null;
111
+ * }),
112
+ * };
113
+ *
114
+ * const cursor = timeTravel(snapshot, { strategy: milestoneStops });
115
+ * cursor.at()?.meta?.kind; // 'llm-turn' — no re-derivation
116
+ * cursor.stops[0].prologue; // true when stages ran before the first turn
117
+ * ```
118
+ */
119
+ export declare function filterStops<TMeta = unknown>(stops: readonly Stop<unknown>[], keep: (stop: Stop<unknown>) => StopFilter<TMeta>): Stop<TMeta>[];
@@ -0,0 +1,179 @@
1
+ /**
2
+ * axis.ts — the shape of an axis, and the one safe way to narrow it.
3
+ *
4
+ * WHY THIS FILE EXISTS. `commitStops` returns `Stop[]`, and every strategy
5
+ * that COMPOSES it (keep the stages my domain recognises, drop the rest) rests
6
+ * on a shape the type never stated: `[start, …stages, end]` for a non-empty
7
+ * log, empty for an empty one. Each composer therefore wrote its own runtime
8
+ * guard against its own reading of the contract, plus a mocked-substrate test
9
+ * to prove the guard fires. That is one invariant, discovered three times, and
10
+ * the library that owns the invariant should be the one that states it.
11
+ *
12
+ * {@link splitAxis} states it. {@link filterStops} then does the whole
13
+ * composition — check the shape, keep what the caller keeps, RE-PARTITION the
14
+ * log so the dropped stages' commits are still folded somewhere, and mark the
15
+ * `'start'` bookend as carrying a prologue — because getting the
16
+ * re-partitioning right by hand is the other thing every composer had to
17
+ * rediscover.
18
+ */
19
+ /**
20
+ * Split a strategy's stops into `{ start, stages, end }`, or say why it cannot.
21
+ *
22
+ * THE INVARIANT, stated once: for a non-EMPTY log, `commitStops` returns at
23
+ * least the two bookends, `'start'` first and `'end'` last, with one stop per
24
+ * executed stage in execution order between them. For an EMPTY log it returns
25
+ * `[]` — no bookends around nothing, because a cursor with nowhere to stand
26
+ * should say `reason: 'empty'` rather than offer two positions that are the
27
+ * same position.
28
+ *
29
+ * The two refusals are different facts and must not be collapsed: `'empty'`
30
+ * means the run committed nothing, `'not-bookended'` means a strategy broke
31
+ * the contract. A composer that treats them alike reports a broken strategy as
32
+ * an empty run.
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * import { commitStops, splitAxis } from 'footprintjs/trace';
37
+ *
38
+ * const axis = splitAxis(commitStops(snapshot.commitLog, snapshot.executionTree));
39
+ * if (axis.ok) {
40
+ * axis.start.commitIdx; // -1 — the fold base
41
+ * axis.stages.map((s) => s.label);
42
+ * axis.end.lastCommitIdx; // the last bundle in the log
43
+ * } else {
44
+ * axis.reason; // 'empty' | 'not-bookended'
45
+ * }
46
+ * ```
47
+ */
48
+ export function splitAxis(stops) {
49
+ const kinds = Object.freeze(stops.map((stop) => stop.kind));
50
+ if (stops.length === 0)
51
+ return { ok: false, reason: 'empty', kinds };
52
+ const start = stops[0];
53
+ const end = stops[stops.length - 1];
54
+ if (start.kind !== 'start' || end.kind !== 'end' || stops.length < 2) {
55
+ return { ok: false, reason: 'not-bookended', kinds };
56
+ }
57
+ return { ok: true, start, stages: Object.freeze(stops.slice(1, -1)), end };
58
+ }
59
+ /**
60
+ * `stop` retyped to the OUTPUT vocabulary, with any meta it already carried
61
+ * left behind. The input axis may itself be a filtered one (a Beat axis being
62
+ * narrowed into a Tag axis), and a `true` decision keeps the STOP, not the
63
+ * other strategy's classification: a `Stop<Tag>` whose `meta` is a Beat would
64
+ * be a lie the type could not catch. Only the decision may supply a meta.
65
+ */
66
+ function retyped(stop) {
67
+ if (stop.meta === undefined)
68
+ return stop;
69
+ const out = {};
70
+ const fields = stop;
71
+ for (const key of Object.keys(fields))
72
+ if (key !== 'meta')
73
+ out[key] = fields[key];
74
+ return out;
75
+ }
76
+ /**
77
+ * Build a FILTERING strategy's axis out of another strategy's stops.
78
+ *
79
+ * The rule, in one sentence: keep the stages `keep` recognises, and give the
80
+ * survivors the log back.
81
+ *
82
+ * **Meta is the decision's, never inherited.** The input may already be a
83
+ * filtered axis carrying another strategy's `meta`; a `true` (or a meta-less
84
+ * object) keeps the stop and DROPS that meta, so a `Stop<TMeta>` never carries
85
+ * a value of some other type under `TMeta`. The bookends carry none either.
86
+ *
87
+ * **The survivors re-partition the log.** A dropped stage's commits still
88
+ * happened, so they fold into the stop that PRECEDES them: every kept stop's
89
+ * `lastCommitIdx` runs to just before the next kept stop begins. Nothing is
90
+ * orphaned and `stateAt(stop)` stays "the state that existed when the next
91
+ * kept stage started".
92
+ *
93
+ * **What that costs `'start'`, said out loud.** The commits before the first
94
+ * survivor have nowhere else to go, so `'start'` absorbs them: its fold is the
95
+ * run's base PLUS that prologue — the state the first stop READ, not the raw
96
+ * base. The returned start therefore carries `prologue: true` whenever it
97
+ * actually absorbed a stage, and a renderer that means "before anything ran"
98
+ * checks `kind === 'start' && !prologue`. That flag is the whole reason this
99
+ * helper exists rather than a `.filter()` call.
100
+ *
101
+ * **A log with nothing kept** yields the two bookends and nothing between
102
+ * them: `'start'` folds the whole log, `'end'` folds the whole log, and
103
+ * `jumpTo` on any stage id refuses with `reason: 'miss'`. An axis with nowhere
104
+ * meaningful to stand — which is the truthful shape for a run this strategy
105
+ * recognises nothing in, and NOT the `[]` that says the log was empty.
106
+ *
107
+ * @throws when `stops` is non-empty but not bookended — see {@link splitAxis}.
108
+ * Only a strategy can cause that; a run cannot, so it is a contract error
109
+ * and not a condition to fold into the data.
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * import { commitStops, filterStops } from 'footprintjs/trace';
114
+ * import type { Stop, TimeTravelStrategy } from 'footprintjs/trace';
115
+ *
116
+ * type Milestone = { kind: 'llm-turn' | 'tool-call'; label: string };
117
+ * declare function milestoneFor(runtimeStageId: string): Milestone | null;
118
+ *
119
+ * const milestoneStops: TimeTravelStrategy<Milestone> = {
120
+ * stopsFor: (log, tree) =>
121
+ * filterStops<Milestone>(commitStops(log, tree), (stop) => {
122
+ * const m = milestoneFor(stop.runtimeStageId);
123
+ * return m ? { label: m.label, meta: m } : null;
124
+ * }),
125
+ * };
126
+ *
127
+ * const cursor = timeTravel(snapshot, { strategy: milestoneStops });
128
+ * cursor.at()?.meta?.kind; // 'llm-turn' — no re-derivation
129
+ * cursor.stops[0].prologue; // true when stages ran before the first turn
130
+ * ```
131
+ */
132
+ export function filterStops(stops, keep) {
133
+ const axis = splitAxis(stops);
134
+ if (!axis.ok) {
135
+ if (axis.reason === 'empty')
136
+ return [];
137
+ throw new Error('filterStops: expected a bookended axis — [start, …stages, end] — got kinds ' +
138
+ `[${axis.kinds.join(', ')}]. Only a strategy can produce that shape; a run cannot.`);
139
+ }
140
+ const kept = [];
141
+ for (const stop of axis.stages) {
142
+ const decision = keep(stop);
143
+ if (!decision)
144
+ continue;
145
+ if (decision === true)
146
+ kept.push({ stop });
147
+ else
148
+ kept.push({ stop, label: decision.label, meta: decision.meta });
149
+ }
150
+ // The log's last index, taken from the `'end'` bookend rather than a length:
151
+ // `end` is the one stop guaranteed to fold the whole log, and this function
152
+ // is never handed the log itself.
153
+ const lastIdx = axis.end.lastCommitIdx;
154
+ const first = kept[0];
155
+ const out = [
156
+ {
157
+ ...retyped(axis.start),
158
+ step: 0,
159
+ lastCommitIdx: first ? first.stop.commitIdx - 1 : lastIdx,
160
+ // Only when a STAGE was actually absorbed. An axis that kept everything
161
+ // has the same start it always had, and says nothing it need not say.
162
+ ...(first && first.stop.step > 1 ? { prologue: true } : {}),
163
+ ...(!first && axis.stages.length > 0 ? { prologue: true } : {}),
164
+ },
165
+ ];
166
+ for (const [i, row] of kept.entries()) {
167
+ const next = kept[i + 1];
168
+ out.push({
169
+ ...retyped(row.stop),
170
+ step: out.length,
171
+ lastCommitIdx: next ? next.stop.commitIdx - 1 : lastIdx,
172
+ ...(row.label !== undefined ? { label: row.label } : {}),
173
+ ...(row.meta !== undefined ? { meta: row.meta } : {}),
174
+ });
175
+ }
176
+ out.push({ ...retyped(axis.end), step: out.length });
177
+ return out;
178
+ }
179
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXhpcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdGltZS10cmF2ZWwvYXhpcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFJSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTRCRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQWtCLEtBQTZCO0lBQ3RFLE1BQU0sS0FBSyxHQUF3QixNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ2pGLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQztJQUNyRSxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdkIsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDcEMsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLE9BQU8sSUFBSSxHQUFHLENBQUMsSUFBSSxLQUFLLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3JFLE9BQU8sRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDdkQsQ0FBQztJQUNELE9BQU8sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDN0UsQ0FBQztB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LEdBQUcsQ0FBQyxJQUFJLENBQUM7WUFDUCxHQUFHLE9BQU8sQ0FBUSxHQUFHLENBQUMsSUFBSSxDQUFDO1lBQzNCLElBQUksRUFBRSxHQUFHLENBQUMsTUFBTTtZQUNoQixhQUFhLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU87WUFDdkQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUN4RCxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQ3RELENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxPQUFPLENBQVEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUM1RCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGF4aXMudHMg4oCUIHRoZSBzaGFwZSBvZiBhbiBheGlzLCBhbmQgdGhlIG9uZSBzYWZlIHdheSB0byBuYXJyb3cgaXQuXG4gKlxuICogV0hZIFRISVMgRklMRSBFWElTVFMuIGBjb21taXRTdG9wc2AgcmV0dXJucyBgU3RvcFtdYCwgYW5kIGV2ZXJ5IHN0cmF0ZWd5XG4gKiB0aGF0IENPTVBPU0VTIGl0IChrZWVwIHRoZSBzdGFnZXMgbXkgZG9tYWluIHJlY29nbmlzZXMsIGRyb3AgdGhlIHJlc3QpIHJlc3RzXG4gKiBvbiBhIHNoYXBlIHRoZSB0eXBlIG5ldmVyIHN0YXRlZDogYFtzdGFydCwg4oCmc3RhZ2VzLCBlbmRdYCBmb3IgYSBub24tZW1wdHlcbiAqIGxvZywgZW1wdHkgZm9yIGFuIGVtcHR5IG9uZS4gRWFjaCBjb21wb3NlciB0aGVyZWZvcmUgd3JvdGUgaXRzIG93biBydW50aW1lXG4gKiBndWFyZCBhZ2FpbnN0IGl0cyBvd24gcmVhZGluZyBvZiB0aGUgY29udHJhY3QsIHBsdXMgYSBtb2NrZWQtc3Vic3RyYXRlIHRlc3RcbiAqIHRvIHByb3ZlIHRoZSBndWFyZCBmaXJlcy4gVGhhdCBpcyBvbmUgaW52YXJpYW50LCBkaXNjb3ZlcmVkIHRocmVlIHRpbWVzLCBhbmRcbiAqIHRoZSBsaWJyYXJ5IHRoYXQgb3ducyB0aGUgaW52YXJpYW50IHNob3VsZCBiZSB0aGUgb25lIHRoYXQgc3RhdGVzIGl0LlxuICpcbiAqIHtAbGluayBzcGxpdEF4aXN9IHN0YXRlcyBpdC4ge0BsaW5rIGZpbHRlclN0b3BzfSB0aGVuIGRvZXMgdGhlIHdob2xlXG4gKiBjb21wb3NpdGlvbiDigJQgY2hlY2sgdGhlIHNoYXBlLCBrZWVwIHdoYXQgdGhlIGNhbGxlciBrZWVwcywgUkUtUEFSVElUSU9OIHRoZVxuICogbG9nIHNvIHRoZSBkcm9wcGVkIHN0YWdlcycgY29tbWl0cyBhcmUgc3RpbGwgZm9sZGVkIHNvbWV3aGVyZSwgYW5kIG1hcmsgdGhlXG4gKiBgJ3N0YXJ0J2AgYm9va2VuZCBhcyBjYXJyeWluZyBhIHByb2xvZ3VlIOKAlCBiZWNhdXNlIGdldHRpbmcgdGhlXG4gKiByZS1wYXJ0aXRpb25pbmcgcmlnaHQgYnkgaGFuZCBpcyB0aGUgb3RoZXIgdGhpbmcgZXZlcnkgY29tcG9zZXIgaGFkIHRvXG4gKiByZWRpc2NvdmVyLlxuICovXG5cbmltcG9ydCB0eXBlIHsgQXhpc1NwbGl0LCBTdG9wLCBTdG9wS2luZCB9IGZyb20gJy4vdHlwZXMuanMnO1xuXG4vKipcbiAqIFNwbGl0IGEgc3RyYXRlZ3kncyBzdG9wcyBpbnRvIGB7IHN0YXJ0LCBzdGFnZXMsIGVuZCB9YCwgb3Igc2F5IHdoeSBpdCBjYW5ub3QuXG4gKlxuICogVEhFIElOVkFSSUFOVCwgc3RhdGVkIG9uY2U6IGZvciBhIG5vbi1FTVBUWSBsb2csIGBjb21taXRTdG9wc2AgcmV0dXJucyBhdFxuICogbGVhc3QgdGhlIHR3byBib29rZW5kcywgYCdzdGFydCdgIGZpcnN0IGFuZCBgJ2VuZCdgIGxhc3QsIHdpdGggb25lIHN0b3AgcGVyXG4gKiBleGVjdXRlZCBzdGFnZSBpbiBleGVjdXRpb24gb3JkZXIgYmV0d2VlbiB0aGVtLiBGb3IgYW4gRU1QVFkgbG9nIGl0IHJldHVybnNcbiAqIGBbXWAg4oCUIG5vIGJvb2tlbmRzIGFyb3VuZCBub3RoaW5nLCBiZWNhdXNlIGEgY3Vyc29yIHdpdGggbm93aGVyZSB0byBzdGFuZFxuICogc2hvdWxkIHNheSBgcmVhc29uOiAnZW1wdHknYCByYXRoZXIgdGhhbiBvZmZlciB0d28gcG9zaXRpb25zIHRoYXQgYXJlIHRoZVxuICogc2FtZSBwb3NpdGlvbi5cbiAqXG4gKiBUaGUgdHdvIHJlZnVzYWxzIGFyZSBkaWZmZXJlbnQgZmFjdHMgYW5kIG11c3Qgbm90IGJlIGNvbGxhcHNlZDogYCdlbXB0eSdgXG4gKiBtZWFucyB0aGUgcnVuIGNvbW1pdHRlZCBub3RoaW5nLCBgJ25vdC1ib29rZW5kZWQnYCBtZWFucyBhIHN0cmF0ZWd5IGJyb2tlXG4gKiB0aGUgY29udHJhY3QuIEEgY29tcG9zZXIgdGhhdCB0cmVhdHMgdGhlbSBhbGlrZSByZXBvcnRzIGEgYnJva2VuIHN0cmF0ZWd5IGFzXG4gKiBhbiBlbXB0eSBydW4uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IGNvbW1pdFN0b3BzLCBzcGxpdEF4aXMgfSBmcm9tICdmb290cHJpbnRqcy90cmFjZSc7XG4gKlxuICogY29uc3QgYXhpcyA9IHNwbGl0QXhpcyhjb21taXRTdG9wcyhzbmFwc2hvdC5jb21taXRMb2csIHNuYXBzaG90LmV4ZWN1dGlvblRyZWUpKTtcbiAqIGlmIChheGlzLm9rKSB7XG4gKiAgIGF4aXMuc3RhcnQuY29tbWl0SWR4OyAgICAgICAgICAvLyAtMSDigJQgdGhlIGZvbGQgYmFzZVxuICogICBheGlzLnN0YWdlcy5tYXAoKHMpID0+IHMubGFiZWwpO1xuICogICBheGlzLmVuZC5sYXN0Q29tbWl0SWR4OyAgICAgICAgLy8gdGhlIGxhc3QgYnVuZGxlIGluIHRoZSBsb2dcbiAqIH0gZWxzZSB7XG4gKiAgIGF4aXMucmVhc29uOyAgICAgICAgICAgICAgICAgICAvLyAnZW1wdHknIHwgJ25vdC1ib29rZW5kZWQnXG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNwbGl0QXhpczxUTWV0YSA9IHVua25vd24+KHN0b3BzOiByZWFkb25seSBTdG9wPFRNZXRhPltdKTogQXhpc1NwbGl0PFRNZXRhPiB7XG4gIGNvbnN0IGtpbmRzOiByZWFkb25seSBTdG9wS2luZFtdID0gT2JqZWN0LmZyZWV6ZShzdG9wcy5tYXAoKHN0b3ApID0+IHN0b3Aua2luZCkpO1xuICBpZiAoc3RvcHMubGVuZ3RoID09PSAwKSByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ2VtcHR5Jywga2luZHMgfTtcbiAgY29uc3Qgc3RhcnQgPSBzdG9wc1swXTtcbiAgY29uc3QgZW5kID0gc3RvcHNbc3RvcHMubGVuZ3RoIC0gMV07XG4gIGlmIChzdGFydC5raW5kICE9PSAnc3RhcnQnIHx8IGVuZC5raW5kICE9PSAnZW5kJyB8fCBzdG9wcy5sZW5ndGggPCAyKSB7XG4gICAgcmV0dXJuIHsgb2s6IGZhbHNlLCByZWFzb246ICdub3QtYm9va2VuZGVkJywga2luZHMgfTtcbiAgfVxuICByZXR1cm4geyBvazogdHJ1ZSwgc3RhcnQsIHN0YWdlczogT2JqZWN0LmZyZWV6ZShzdG9wcy5zbGljZSgxLCAtMSkpLCBlbmQgfTtcbn1cblxuLyoqXG4gKiBXaGF0IHtAbGluayBmaWx0ZXJTdG9wc30gZG9lcyB3aXRoIG9uZSBzdG9wOiBkcm9wIGl0LCBrZWVwIGl0LCBvciBrZWVwIGl0XG4gKiBjYXJyeWluZyB0aGUgc3RyYXRlZ3kncyBvd24gbGFiZWwgYW5kIHZvY2FidWxhcnkuXG4gKlxuICogYGZhbHNlYCAvIGBudWxsYCAvIGB1bmRlZmluZWRgIGRyb3AuIGB0cnVlYCBrZWVwcyBpdCB1bmNoYW5nZWQuIEFuIG9iamVjdFxuICoga2VlcHMgaXQgYW5kIG92ZXJyaWRlcyBgbGFiZWxgIGFuZC9vciBzZXRzIGBtZXRhYCDigJQgdGhlIHN0cmF0ZWd5J3Mgb3duXG4gKiBjbGFzc2lmaWNhdGlvbiwgdHJhdmVsbGluZyBPTiB0aGUgc3RvcCBpbnN0ZWFkIG9mIGJlaW5nIHJlLWRlcml2ZWQgZnJvbVxuICogYHJ1bnRpbWVTdGFnZUlkYCBhdCBldmVyeSByZWFkLlxuICovXG5leHBvcnQgdHlwZSBTdG9wRmlsdGVyPFRNZXRhPiA9IGJvb2xlYW4gfCBudWxsIHwgdW5kZWZpbmVkIHwgeyByZWFkb25seSBsYWJlbD86IHN0cmluZzsgcmVhZG9ubHkgbWV0YT86IFRNZXRhIH07XG5cbi8qKlxuICogYHN0b3BgIHJldHlwZWQgdG8gdGhlIE9VVFBVVCB2b2NhYnVsYXJ5LCB3aXRoIGFueSBtZXRhIGl0IGFscmVhZHkgY2FycmllZFxuICogbGVmdCBiZWhpbmQuIFRoZSBpbnB1dCBheGlzIG1heSBpdHNlbGYgYmUgYSBmaWx0ZXJlZCBvbmUgKGEgQmVhdCBheGlzIGJlaW5nXG4gKiBuYXJyb3dlZCBpbnRvIGEgVGFnIGF4aXMpLCBhbmQgYSBgdHJ1ZWAgZGVjaXNpb24ga2VlcHMgdGhlIFNUT1AsIG5vdCB0aGVcbiAqIG90aGVyIHN0cmF0ZWd5J3MgY2xhc3NpZmljYXRpb246IGEgYFN0b3A8VGFnPmAgd2hvc2UgYG1ldGFgIGlzIGEgQmVhdCB3b3VsZFxuICogYmUgYSBsaWUgdGhlIHR5cGUgY291bGQgbm90IGNhdGNoLiBPbmx5IHRoZSBkZWNpc2lvbiBtYXkgc3VwcGx5IGEgbWV0YS5cbiAqL1xuZnVuY3Rpb24gcmV0eXBlZDxUTWV0YT4oc3RvcDogU3RvcDx1bmtub3duPik6IFN0b3A8VE1ldGE+IHtcbiAgaWYgKHN0b3AubWV0YSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gc3RvcCBhcyBTdG9wPFRNZXRhPjtcbiAgY29uc3Qgb3V0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuICBjb25zdCBmaWVsZHMgPSBzdG9wIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGZpZWxkcykpIGlmIChrZXkgIT09ICdtZXRhJykgb3V0W2tleV0gPSBmaWVsZHNba2V5XTtcbiAgcmV0dXJuIG91dCBhcyB1bmtub3duIGFzIFN0b3A8VE1ldGE+O1xufVxuXG4vKipcbiAqIEJ1aWxkIGEgRklMVEVSSU5HIHN0cmF0ZWd5J3MgYXhpcyBvdXQgb2YgYW5vdGhlciBzdHJhdGVneSdzIHN0b3BzLlxuICpcbiAqIFRoZSBydWxlLCBpbiBvbmUgc2VudGVuY2U6IGtlZXAgdGhlIHN0YWdlcyBga2VlcGAgcmVjb2duaXNlcywgYW5kIGdpdmUgdGhlXG4gKiBzdXJ2aXZvcnMgdGhlIGxvZyBiYWNrLlxuICpcbiAqICoqTWV0YSBpcyB0aGUgZGVjaXNpb24ncywgbmV2ZXIgaW5oZXJpdGVkLioqIFRoZSBpbnB1dCBtYXkgYWxyZWFkeSBiZSBhXG4gKiBmaWx0ZXJlZCBheGlzIGNhcnJ5aW5nIGFub3RoZXIgc3RyYXRlZ3kncyBgbWV0YWA7IGEgYHRydWVgIChvciBhIG1ldGEtbGVzc1xuICogb2JqZWN0KSBrZWVwcyB0aGUgc3RvcCBhbmQgRFJPUFMgdGhhdCBtZXRhLCBzbyBhIGBTdG9wPFRNZXRhPmAgbmV2ZXIgY2Fycmllc1xuICogYSB2YWx1ZSBvZiBzb21lIG90aGVyIHR5cGUgdW5kZXIgYFRNZXRhYC4gVGhlIGJvb2tlbmRzIGNhcnJ5IG5vbmUgZWl0aGVyLlxuICpcbiAqICoqVGhlIHN1cnZpdm9ycyByZS1wYXJ0aXRpb24gdGhlIGxvZy4qKiBBIGRyb3BwZWQgc3RhZ2UncyBjb21taXRzIHN0aWxsXG4gKiBoYXBwZW5lZCwgc28gdGhleSBmb2xkIGludG8gdGhlIHN0b3AgdGhhdCBQUkVDRURFUyB0aGVtOiBldmVyeSBrZXB0IHN0b3Anc1xuICogYGxhc3RDb21taXRJZHhgIHJ1bnMgdG8ganVzdCBiZWZvcmUgdGhlIG5leHQga2VwdCBzdG9wIGJlZ2lucy4gTm90aGluZyBpc1xuICogb3JwaGFuZWQgYW5kIGBzdGF0ZUF0KHN0b3ApYCBzdGF5cyBcInRoZSBzdGF0ZSB0aGF0IGV4aXN0ZWQgd2hlbiB0aGUgbmV4dFxuICoga2VwdCBzdGFnZSBzdGFydGVkXCIuXG4gKlxuICogKipXaGF0IHRoYXQgY29zdHMgYCdzdGFydCdgLCBzYWlkIG91dCBsb3VkLioqIFRoZSBjb21taXRzIGJlZm9yZSB0aGUgZmlyc3RcbiAqIHN1cnZpdm9yIGhhdmUgbm93aGVyZSBlbHNlIHRvIGdvLCBzbyBgJ3N0YXJ0J2AgYWJzb3JicyB0aGVtOiBpdHMgZm9sZCBpcyB0aGVcbiAqIHJ1bidzIGJhc2UgUExVUyB0aGF0IHByb2xvZ3VlIOKAlCB0aGUgc3RhdGUgdGhlIGZpcnN0IHN0b3AgUkVBRCwgbm90IHRoZSByYXdcbiAqIGJhc2UuIFRoZSByZXR1cm5lZCBzdGFydCB0aGVyZWZvcmUgY2FycmllcyBgcHJvbG9ndWU6IHRydWVgIHdoZW5ldmVyIGl0XG4gKiBhY3R1YWxseSBhYnNvcmJlZCBhIHN0YWdlLCBhbmQgYSByZW5kZXJlciB0aGF0IG1lYW5zIFwiYmVmb3JlIGFueXRoaW5nIHJhblwiXG4gKiBjaGVja3MgYGtpbmQgPT09ICdzdGFydCcgJiYgIXByb2xvZ3VlYC4gVGhhdCBmbGFnIGlzIHRoZSB3aG9sZSByZWFzb24gdGhpc1xuICogaGVscGVyIGV4aXN0cyByYXRoZXIgdGhhbiBhIGAuZmlsdGVyKClgIGNhbGwuXG4gKlxuICogKipBIGxvZyB3aXRoIG5vdGhpbmcga2VwdCoqIHlpZWxkcyB0aGUgdHdvIGJvb2tlbmRzIGFuZCBub3RoaW5nIGJldHdlZW5cbiAqIHRoZW06IGAnc3RhcnQnYCBmb2xkcyB0aGUgd2hvbGUgbG9nLCBgJ2VuZCdgIGZvbGRzIHRoZSB3aG9sZSBsb2csIGFuZFxuICogYGp1bXBUb2Agb24gYW55IHN0YWdlIGlkIHJlZnVzZXMgd2l0aCBgcmVhc29uOiAnbWlzcydgLiBBbiBheGlzIHdpdGggbm93aGVyZVxuICogbWVhbmluZ2Z1bCB0byBzdGFuZCDigJQgd2hpY2ggaXMgdGhlIHRydXRoZnVsIHNoYXBlIGZvciBhIHJ1biB0aGlzIHN0cmF0ZWd5XG4gKiByZWNvZ25pc2VzIG5vdGhpbmcgaW4sIGFuZCBOT1QgdGhlIGBbXWAgdGhhdCBzYXlzIHRoZSBsb2cgd2FzIGVtcHR5LlxuICpcbiAqIEB0aHJvd3Mgd2hlbiBgc3RvcHNgIGlzIG5vbi1lbXB0eSBidXQgbm90IGJvb2tlbmRlZCDigJQgc2VlIHtAbGluayBzcGxpdEF4aXN9LlxuICogICBPbmx5IGEgc3RyYXRlZ3kgY2FuIGNhdXNlIHRoYXQ7IGEgcnVuIGNhbm5vdCwgc28gaXQgaXMgYSBjb250cmFjdCBlcnJvclxuICogICBhbmQgbm90IGEgY29uZGl0aW9uIHRvIGZvbGQgaW50byB0aGUgZGF0YS5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgY29tbWl0U3RvcHMsIGZpbHRlclN0b3BzIH0gZnJvbSAnZm9vdHByaW50anMvdHJhY2UnO1xuICogaW1wb3J0IHR5cGUgeyBTdG9wLCBUaW1lVHJhdmVsU3RyYXRlZ3kgfSBmcm9tICdmb290cHJpbnRqcy90cmFjZSc7XG4gKlxuICogdHlwZSBNaWxlc3RvbmUgPSB7IGtpbmQ6ICdsbG0tdHVybicgfCAndG9vbC1jYWxsJzsgbGFiZWw6IHN0cmluZyB9O1xuICogZGVjbGFyZSBmdW5jdGlvbiBtaWxlc3RvbmVGb3IocnVudGltZVN0YWdlSWQ6IHN0cmluZyk6IE1pbGVzdG9uZSB8IG51bGw7XG4gKlxuICogY29uc3QgbWlsZXN0b25lU3RvcHM6IFRpbWVUcmF2ZWxTdHJhdGVneTxNaWxlc3RvbmU+ID0ge1xuICogICBzdG9wc0ZvcjogKGxvZywgdHJlZSkgPT5cbiAqICAgICBmaWx0ZXJTdG9wczxNaWxlc3RvbmU+KGNvbW1pdFN0b3BzKGxvZywgdHJlZSksIChzdG9wKSA9PiB7XG4gKiAgICAgICBjb25zdCBtID0gbWlsZXN0b25lRm9yKHN0b3AucnVudGltZVN0YWdlSWQpO1xuICogICAgICAgcmV0dXJuIG0gPyB7IGxhYmVsOiBtLmxhYmVsLCBtZXRhOiBtIH0gOiBudWxsO1xuICogICAgIH0pLFxuICogfTtcbiAqXG4gKiBjb25zdCBjdXJzb3IgPSB0aW1lVHJhdmVsKHNuYXBzaG90LCB7IHN0cmF0ZWd5OiBtaWxlc3RvbmVTdG9wcyB9KTtcbiAqIGN1cnNvci5hdCgpPy5tZXRhPy5raW5kOyAgICAgICAgLy8gJ2xsbS10dXJuJyDigJQgbm8gcmUtZGVyaXZhdGlvblxuICogY3Vyc29yLnN0b3BzWzBdLnByb2xvZ3VlOyAgICAgICAvLyB0cnVlIHdoZW4gc3RhZ2VzIHJhbiBiZWZvcmUgdGhlIGZpcnN0IHR1cm5cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyU3RvcHM8VE1ldGEgPSB1bmtub3duPihcbiAgc3RvcHM6IHJlYWRvbmx5IFN0b3A8dW5rbm93bj5bXSxcbiAga2VlcDogKHN0b3A6IFN0b3A8dW5rbm93bj4pID0+IFN0b3BGaWx0ZXI8VE1ldGE+LFxuKTogU3RvcDxUTWV0YT5bXSB7XG4gIGNvbnN0IGF4aXMgPSBzcGxpdEF4aXMoc3RvcHMpO1xuICBpZiAoIWF4aXMub2spIHtcbiAgICBpZiAoYXhpcy5yZWFzb24gPT09ICdlbXB0eScpIHJldHVybiBbXTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnZmlsdGVyU3RvcHM6IGV4cGVjdGVkIGEgYm9va2VuZGVkIGF4aXMg4oCUIFtzdGFydCwg4oCmc3RhZ2VzLCBlbmRdIOKAlCBnb3Qga2luZHMgJyArXG4gICAgICAgIGBbJHtheGlzLmtpbmRzLmpvaW4oJywgJyl9XS4gT25seSBhIHN0cmF0ZWd5IGNhbiBwcm9kdWNlIHRoYXQgc2hhcGU7IGEgcnVuIGNhbm5vdC5gLFxuICAgICk7XG4gIH1cblxuICBjb25zdCBrZXB0OiB7IHN0b3A6IFN0b3A8dW5rbm93bj47IGxhYmVsPzogc3RyaW5nOyBtZXRhPzogVE1ldGEgfVtdID0gW107XG4gIGZvciAoY29uc3Qgc3RvcCBvZiBheGlzLnN0YWdlcykge1xuICAgIGNvbnN0IGRlY2lzaW9uID0ga2VlcChzdG9wKTtcbiAgICBpZiAoIWRlY2lzaW9uKSBjb250aW51ZTtcbiAgICBpZiAoZGVjaXNpb24gPT09IHRydWUpIGtlcHQucHVzaCh7IHN0b3AgfSk7XG4gICAgZWxzZSBrZXB0LnB1c2goeyBzdG9wLCBsYWJlbDogZGVjaXNpb24ubGFiZWwsIG1ldGE6IGRlY2lzaW9uLm1ldGEgfSk7XG4gIH1cblxuICAvLyBUaGUgbG9nJ3MgbGFzdCBpbmRleCwgdGFrZW4gZnJvbSB0aGUgYCdlbmQnYCBib29rZW5kIHJhdGhlciB0aGFuIGEgbGVuZ3RoOlxuICAvLyBgZW5kYCBpcyB0aGUgb25lIHN0b3AgZ3VhcmFudGVlZCB0byBmb2xkIHRoZSB3aG9sZSBsb2csIGFuZCB0aGlzIGZ1bmN0aW9uXG4gIC8vIGlzIG5ldmVyIGhhbmRlZCB0aGUgbG9nIGl0c2VsZi5cbiAgY29uc3QgbGFzdElkeCA9IGF4aXMuZW5kLmxhc3RDb21taXRJZHg7XG4gIGNvbnN0IGZpcnN0ID0ga2VwdFswXTtcbiAgY29uc3Qgb3V0OiBTdG9wPFRNZXRhPltdID0gW1xuICAgIHtcbiAgICAgIC4uLnJldHlwZWQ8VE1ldGE+KGF4aXMuc3RhcnQpLFxuICAgICAgc3RlcDogMCxcbiAgICAgIGxhc3RDb21taXRJZHg6IGZpcnN0ID8gZmlyc3Quc3RvcC5jb21taXRJZHggLSAxIDogbGFzdElkeCxcbiAgICAgIC8vIE9ubHkgd2hlbiBhIFNUQUdFIHdhcyBhY3R1YWxseSBhYnNvcmJlZC4gQW4gYXhpcyB0aGF0IGtlcHQgZXZlcnl0aGluZ1xuICAgICAgLy8gaGFzIHRoZSBzYW1lIHN0YXJ0IGl0IGFsd2F5cyBoYWQsIGFuZCBzYXlzIG5vdGhpbmcgaXQgbmVlZCBub3Qgc2F5LlxuICAgICAgLi4uKGZpcnN0ICYmIGZpcnN0LnN0b3Auc3RlcCA+IDEgPyB7IHByb2xvZ3VlOiB0cnVlIGFzIGNvbnN0IH0gOiB7fSksXG4gICAgICAuLi4oIWZpcnN0ICYmIGF4aXMuc3RhZ2VzLmxlbmd0aCA+IDAgPyB7IHByb2xvZ3VlOiB0cnVlIGFzIGNvbnN0IH0gOiB7fSksXG4gICAgfSxcbiAgXTtcblxuICBmb3IgKGNvbnN0IFtpLCByb3ddIG9mIGtlcHQuZW50cmllcygpKSB7XG4gICAgY29uc3QgbmV4dCA9IGtlcHRbaSArIDFdO1xuICAgIG91dC5wdXNoKHtcbiAgICAgIC4uLnJldHlwZWQ8VE1ldGE+KHJvdy5zdG9wKSxcbiAgICAgIHN0ZXA6IG91dC5sZW5ndGgsXG4gICAgICBsYXN0Q29tbWl0SWR4OiBuZXh0ID8gbmV4dC5zdG9wLmNvbW1pdElkeCAtIDEgOiBsYXN0SWR4LFxuICAgICAgLi4uKHJvdy5sYWJlbCAhPT0gdW5kZWZpbmVkID8geyBsYWJlbDogcm93LmxhYmVsIH0gOiB7fSksXG4gICAgICAuLi4ocm93Lm1ldGEgIT09IHVuZGVmaW5lZCA/IHsgbWV0YTogcm93Lm1ldGEgfSA6IHt9KSxcbiAgICB9KTtcbiAgfVxuXG4gIG91dC5wdXNoKHsgLi4ucmV0eXBlZDxUTWV0YT4oYXhpcy5lbmQpLCBzdGVwOiBvdXQubGVuZ3RoIH0pO1xuICByZXR1cm4gb3V0O1xufVxuIl19