footprintjs 9.48.2 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +12 -10
- package/CLAUDE.md +21 -23
- package/README.md +1 -1
- package/dist/advanced.js +71 -128
- package/dist/esm/advanced.d.ts +24 -58
- package/dist/esm/advanced.js +13 -51
- package/dist/esm/index.d.ts +5 -8
- package/dist/esm/index.js +3 -3
- package/dist/esm/lib/builder/FlowChartBuilder.d.ts +1 -1
- package/dist/esm/lib/builder/FlowChartBuilder.js +3 -3
- package/dist/esm/lib/builder/structure/StructureRecorder.d.ts +1 -1
- package/dist/esm/lib/builder/structure/StructureRecorder.js +1 -1
- package/dist/esm/lib/capture/index.d.ts +0 -1
- package/dist/esm/lib/capture/index.js +1 -2
- package/dist/esm/lib/engine/graph/prefixNodeTree.js +2 -2
- package/dist/esm/lib/engine/handlers/ResumeEntry.d.ts +3 -3
- package/dist/esm/lib/engine/handlers/ResumeEntry.js +4 -4
- package/dist/esm/lib/engine/handlers/SubflowExecutor.d.ts +1 -2
- package/dist/esm/lib/engine/handlers/SubflowExecutor.js +4 -8
- package/dist/esm/lib/engine/index.d.ts +1 -1
- package/dist/esm/lib/engine/index.js +1 -1
- package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +4 -4
- package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +1 -1
- package/dist/esm/lib/engine/narrative/index.d.ts +1 -1
- package/dist/esm/lib/engine/narrative/index.js +1 -1
- package/dist/esm/lib/engine/narrative/narrativeTypes.d.ts +1 -11
- package/dist/esm/lib/engine/narrative/narrativeTypes.js +1 -1
- package/dist/esm/lib/engine/traversal/FlowchartTraverser.d.ts +2 -10
- package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +4 -6
- package/dist/esm/lib/engine/traversalContext.d.ts +1 -1
- package/dist/esm/lib/engine/traversalContext.js +2 -2
- package/dist/esm/lib/engine/types.d.ts +2 -10
- package/dist/esm/lib/engine/types.js +1 -1
- package/dist/esm/lib/engine/walkSubflowSpec.js +2 -2
- package/dist/esm/lib/ids/reservedIds.js +2 -2
- package/dist/esm/lib/memory/DiagnosticCollector.js +2 -2
- package/dist/esm/lib/memory/StageContext.d.ts +2 -4
- package/dist/esm/lib/memory/StageContext.js +2 -2
- package/dist/esm/lib/memory/borrowedMutation.js +2 -2
- package/dist/esm/lib/memory/index.d.ts +6 -21
- package/dist/esm/lib/memory/index.js +4 -22
- package/dist/esm/lib/memory/redaction.d.ts +1 -1
- package/dist/esm/lib/memory/redaction.js +2 -2
- package/dist/esm/lib/memory/runPolicy.d.ts +3 -2
- package/dist/esm/lib/memory/runPolicy.js +1 -1
- package/dist/esm/lib/reactive/createTypedScope.js +2 -2
- package/dist/esm/lib/reactive/writeTraps.js +2 -2
- package/dist/esm/lib/recorder/ControlDepRecorder.d.ts +3 -2
- package/dist/esm/lib/recorder/ControlDepRecorder.js +3 -2
- package/dist/esm/lib/recorder/EmitRecorder.d.ts +1 -1
- package/dist/esm/lib/recorder/EmitRecorder.js +1 -1
- package/dist/esm/lib/recorder/InOutRecorder.js +2 -2
- package/dist/esm/lib/recorder/qualityTrace.d.ts +1 -1
- package/dist/esm/lib/recorder/qualityTrace.js +2 -2
- package/dist/esm/lib/runner/DeferredObserverTier.js +2 -2
- package/dist/esm/lib/runner/ExecutionRuntime.d.ts +4 -5
- package/dist/esm/lib/runner/ExecutionRuntime.js +2 -5
- package/dist/esm/lib/runner/FlowChartExecutor.d.ts +1 -1
- package/dist/esm/lib/runner/FlowChartExecutor.js +1 -1
- package/dist/esm/lib/runner/getSubtreeSnapshot.d.ts +1 -1
- package/dist/esm/lib/runner/getSubtreeSnapshot.js +4 -4
- package/dist/esm/lib/runner/resume.js +2 -2
- package/dist/esm/lib/runner/snapshot.js +3 -2
- package/dist/esm/lib/scope/ScopeFacade.js +2 -2
- package/dist/esm/lib/scope/state/zod/scopeFactory.js +2 -2
- package/dist/esm/recorders.d.ts +2 -3
- package/dist/esm/recorders.js +1 -1
- package/dist/esm/trace.d.ts +11 -57
- package/dist/esm/trace.js +10 -68
- package/dist/index.js +3 -3
- package/dist/lib/builder/FlowChartBuilder.js +5 -5
- package/dist/lib/builder/structure/StructureRecorder.js +1 -1
- package/dist/lib/capture/index.js +2 -4
- package/dist/lib/engine/graph/prefixNodeTree.js +5 -5
- package/dist/lib/engine/handlers/ResumeEntry.js +4 -4
- package/dist/lib/engine/handlers/SubflowExecutor.js +5 -9
- package/dist/lib/engine/index.js +1 -1
- package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +1 -1
- package/dist/lib/engine/narrative/index.js +1 -1
- package/dist/lib/engine/narrative/narrativeTypes.js +1 -1
- package/dist/lib/engine/traversal/FlowchartTraverser.js +8 -10
- package/dist/lib/engine/traversalContext.js +4 -4
- package/dist/lib/engine/types.js +1 -1
- package/dist/lib/engine/walkSubflowSpec.js +3 -3
- package/dist/lib/ids/reservedIds.js +5 -5
- package/dist/lib/memory/DiagnosticCollector.js +3 -3
- package/dist/lib/memory/StageContext.js +3 -3
- package/dist/lib/memory/borrowedMutation.js +3 -3
- package/dist/lib/memory/index.js +7 -42
- package/dist/lib/memory/redaction.js +3 -3
- package/dist/lib/memory/runPolicy.js +1 -1
- package/dist/lib/reactive/createTypedScope.js +3 -3
- package/dist/lib/reactive/writeTraps.js +4 -4
- package/dist/lib/recorder/ControlDepRecorder.js +3 -2
- package/dist/lib/recorder/EmitRecorder.js +1 -1
- package/dist/lib/recorder/InOutRecorder.js +3 -3
- package/dist/lib/recorder/qualityTrace.js +4 -4
- package/dist/lib/runner/DeferredObserverTier.js +3 -3
- package/dist/lib/runner/ExecutionRuntime.js +6 -9
- package/dist/lib/runner/FlowChartExecutor.js +1 -1
- package/dist/lib/runner/getSubtreeSnapshot.js +6 -6
- package/dist/lib/runner/resume.js +3 -3
- package/dist/lib/runner/snapshot.js +6 -5
- package/dist/lib/scope/ScopeFacade.js +3 -3
- package/dist/lib/scope/state/zod/scopeFactory.js +4 -4
- package/dist/recorders.js +1 -1
- package/dist/trace.js +18 -120
- package/dist/types/advanced.d.ts +24 -58
- package/dist/types/index.d.ts +5 -8
- package/dist/types/lib/builder/FlowChartBuilder.d.ts +1 -1
- package/dist/types/lib/builder/structure/StructureRecorder.d.ts +1 -1
- package/dist/types/lib/capture/index.d.ts +0 -1
- package/dist/types/lib/engine/handlers/ResumeEntry.d.ts +3 -3
- package/dist/types/lib/engine/handlers/SubflowExecutor.d.ts +1 -2
- package/dist/types/lib/engine/index.d.ts +1 -1
- package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +4 -4
- package/dist/types/lib/engine/narrative/index.d.ts +1 -1
- package/dist/types/lib/engine/narrative/narrativeTypes.d.ts +1 -11
- package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +2 -10
- package/dist/types/lib/engine/traversalContext.d.ts +1 -1
- package/dist/types/lib/engine/types.d.ts +2 -10
- package/dist/types/lib/memory/StageContext.d.ts +2 -4
- package/dist/types/lib/memory/index.d.ts +6 -21
- package/dist/types/lib/memory/redaction.d.ts +1 -1
- package/dist/types/lib/memory/runPolicy.d.ts +3 -2
- package/dist/types/lib/recorder/ControlDepRecorder.d.ts +3 -2
- package/dist/types/lib/recorder/EmitRecorder.d.ts +1 -1
- package/dist/types/lib/recorder/qualityTrace.d.ts +1 -1
- package/dist/types/lib/runner/ExecutionRuntime.d.ts +4 -5
- package/dist/types/lib/runner/FlowChartExecutor.d.ts +1 -1
- package/dist/types/lib/runner/getSubtreeSnapshot.d.ts +1 -1
- package/dist/types/recorders.d.ts +2 -3
- package/dist/types/trace.d.ts +11 -57
- package/package.json +6 -15
- package/dist/esm/lib/capture/freeze.d.ts +0 -91
- package/dist/esm/lib/capture/freeze.js +0 -314
- package/dist/esm/lib/capture/ownData.d.ts +0 -7
- package/dist/esm/lib/capture/ownData.js +0 -15
- package/dist/esm/lib/capture/valueKinds.d.ts +0 -57
- package/dist/esm/lib/capture/valueKinds.js +0 -142
- package/dist/esm/lib/ids/runtimeStageId.d.ts +0 -173
- package/dist/esm/lib/ids/runtimeStageId.js +0 -194
- package/dist/esm/lib/memory/EventLog.d.ts +0 -105
- package/dist/esm/lib/memory/EventLog.js +0 -148
- package/dist/esm/lib/memory/RecordFrame.d.ts +0 -232
- package/dist/esm/lib/memory/RecordFrame.js +0 -296
- package/dist/esm/lib/memory/SharedMemory.d.ts +0 -46
- package/dist/esm/lib/memory/SharedMemory.js +0 -88
- package/dist/esm/lib/memory/TransactionBuffer.d.ts +0 -521
- package/dist/esm/lib/memory/TransactionBuffer.js +0 -946
- package/dist/esm/lib/memory/admission.d.ts +0 -81
- package/dist/esm/lib/memory/admission.js +0 -153
- package/dist/esm/lib/memory/backtrack.d.ts +0 -286
- package/dist/esm/lib/memory/backtrack.js +0 -457
- package/dist/esm/lib/memory/commitLogUtils.d.ts +0 -217
- package/dist/esm/lib/memory/commitLogUtils.js +0 -384
- package/dist/esm/lib/memory/deltaEncoding.d.ts +0 -66
- package/dist/esm/lib/memory/deltaEncoding.js +0 -122
- package/dist/esm/lib/memory/equality.d.ts +0 -93
- package/dist/esm/lib/memory/equality.js +0 -262
- package/dist/esm/lib/memory/eventPosition.d.ts +0 -18
- package/dist/esm/lib/memory/eventPosition.js +0 -2
- package/dist/esm/lib/memory/honesty.d.ts +0 -93
- package/dist/esm/lib/memory/honesty.js +0 -92
- package/dist/esm/lib/memory/keyPaths.d.ts +0 -125
- package/dist/esm/lib/memory/keyPaths.js +0 -227
- package/dist/esm/lib/memory/logModel.d.ts +0 -76
- package/dist/esm/lib/memory/logModel.js +0 -364
- package/dist/esm/lib/memory/merge.d.ts +0 -26
- package/dist/esm/lib/memory/merge.js +0 -60
- package/dist/esm/lib/memory/pathOps.d.ts +0 -115
- package/dist/esm/lib/memory/pathOps.js +0 -290
- package/dist/esm/lib/memory/paths.d.ts +0 -52
- package/dist/esm/lib/memory/paths.js +0 -57
- package/dist/esm/lib/memory/placeholders.d.ts +0 -39
- package/dist/esm/lib/memory/placeholders.js +0 -40
- package/dist/esm/lib/memory/recordCommit.d.ts +0 -45
- package/dist/esm/lib/memory/recordCommit.js +0 -61
- package/dist/esm/lib/memory/scrub.d.ts +0 -53
- package/dist/esm/lib/memory/scrub.js +0 -74
- package/dist/esm/lib/memory/types.d.ts +0 -209
- package/dist/esm/lib/memory/types.js +0 -10
- package/dist/esm/lib/memory/utils.d.ts +0 -73
- package/dist/esm/lib/memory/utils.js +0 -159
- package/dist/esm/lib/memory/verbs.d.ts +0 -333
- package/dist/esm/lib/memory/verbs.js +0 -427
- package/dist/esm/lib/recorder/CommitRangeIndex.d.ts +0 -147
- package/dist/esm/lib/recorder/CommitRangeIndex.js +0 -207
- package/dist/esm/lib/scope/detectCircular.d.ts +0 -13
- package/dist/esm/lib/scope/detectCircular.js +0 -14
- package/dist/esm/lib/scope/recorders/summarizeValue.d.ts +0 -5
- package/dist/esm/lib/scope/recorders/summarizeValue.js +0 -6
- package/dist/esm/lib/slice/elementProvenance.d.ts +0 -81
- package/dist/esm/lib/slice/elementProvenance.js +0 -190
- package/dist/esm/lib/slice/forwardSliceForKey.d.ts +0 -88
- package/dist/esm/lib/slice/forwardSliceForKey.js +0 -243
- package/dist/esm/lib/slice/index.d.ts +0 -25
- package/dist/esm/lib/slice/index.js +0 -25
- package/dist/esm/lib/slice/keyIndex.d.ts +0 -137
- package/dist/esm/lib/slice/keyIndex.js +0 -293
- package/dist/esm/lib/slice/keyTimeline.d.ts +0 -49
- package/dist/esm/lib/slice/keyTimeline.js +0 -113
- package/dist/esm/lib/slice/keysReadSources.d.ts +0 -51
- package/dist/esm/lib/slice/keysReadSources.js +0 -95
- package/dist/esm/lib/slice/serialize.d.ts +0 -78
- package/dist/esm/lib/slice/serialize.js +0 -278
- package/dist/esm/lib/slice/sliceForKey.d.ts +0 -47
- package/dist/esm/lib/slice/sliceForKey.js +0 -88
- package/dist/esm/lib/slice/types.d.ts +0 -567
- package/dist/esm/lib/slice/types.js +0 -25
- package/dist/esm/lib/time-travel/axis.d.ts +0 -119
- package/dist/esm/lib/time-travel/axis.js +0 -179
- package/dist/esm/lib/time-travel/bundles.d.ts +0 -77
- package/dist/esm/lib/time-travel/bundles.js +0 -136
- package/dist/esm/lib/time-travel/chain.d.ts +0 -93
- package/dist/esm/lib/time-travel/chain.js +0 -188
- package/dist/esm/lib/time-travel/commitStops.d.ts +0 -55
- package/dist/esm/lib/time-travel/commitStops.js +0 -202
- package/dist/esm/lib/time-travel/index.d.ts +0 -22
- package/dist/esm/lib/time-travel/index.js +0 -21
- package/dist/esm/lib/time-travel/stateAt.d.ts +0 -102
- package/dist/esm/lib/time-travel/stateAt.js +0 -153
- package/dist/esm/lib/time-travel/tagStops.d.ts +0 -72
- package/dist/esm/lib/time-travel/tagStops.js +0 -102
- package/dist/esm/lib/time-travel/timeTravel.d.ts +0 -70
- package/dist/esm/lib/time-travel/timeTravel.js +0 -360
- package/dist/esm/lib/time-travel/types.d.ts +0 -470
- package/dist/esm/lib/time-travel/types.js +0 -23
- package/dist/esm/write.d.ts +0 -47
- package/dist/esm/write.js +0 -46
- package/dist/lib/capture/freeze.js +0 -320
- package/dist/lib/capture/ownData.js +0 -19
- package/dist/lib/capture/valueKinds.js +0 -146
- package/dist/lib/ids/runtimeStageId.js +0 -210
- package/dist/lib/memory/EventLog.js +0 -152
- package/dist/lib/memory/RecordFrame.js +0 -300
- package/dist/lib/memory/SharedMemory.js +0 -92
- package/dist/lib/memory/TransactionBuffer.js +0 -950
- package/dist/lib/memory/admission.js +0 -159
- package/dist/lib/memory/backtrack.js +0 -463
- package/dist/lib/memory/commitLogUtils.js +0 -399
- package/dist/lib/memory/deltaEncoding.js +0 -128
- package/dist/lib/memory/equality.js +0 -266
- package/dist/lib/memory/eventPosition.js +0 -3
- package/dist/lib/memory/honesty.js +0 -95
- package/dist/lib/memory/keyPaths.js +0 -243
- package/dist/lib/memory/logModel.js +0 -372
- package/dist/lib/memory/merge.js +0 -64
- package/dist/lib/memory/pathOps.js +0 -306
- package/dist/lib/memory/paths.js +0 -62
- package/dist/lib/memory/placeholders.js +0 -43
- package/dist/lib/memory/recordCommit.js +0 -65
- package/dist/lib/memory/scrub.js +0 -79
- package/dist/lib/memory/types.js +0 -11
- package/dist/lib/memory/utils.js +0 -178
- package/dist/lib/memory/verbs.js +0 -444
- package/dist/lib/recorder/CommitRangeIndex.js +0 -211
- package/dist/lib/scope/detectCircular.js +0 -21
- package/dist/lib/scope/recorders/summarizeValue.js +0 -10
- package/dist/lib/slice/elementProvenance.js +0 -195
- package/dist/lib/slice/forwardSliceForKey.js +0 -247
- package/dist/lib/slice/index.js +0 -42
- package/dist/lib/slice/keyIndex.js +0 -313
- package/dist/lib/slice/keyTimeline.js +0 -117
- package/dist/lib/slice/keysReadSources.js +0 -101
- package/dist/lib/slice/serialize.js +0 -286
- package/dist/lib/slice/sliceForKey.js +0 -93
- package/dist/lib/slice/types.js +0 -26
- package/dist/lib/time-travel/axis.js +0 -184
- package/dist/lib/time-travel/bundles.js +0 -144
- package/dist/lib/time-travel/chain.js +0 -193
- package/dist/lib/time-travel/commitStops.js +0 -206
- package/dist/lib/time-travel/index.js +0 -32
- package/dist/lib/time-travel/stateAt.js +0 -160
- package/dist/lib/time-travel/tagStops.js +0 -106
- package/dist/lib/time-travel/timeTravel.js +0 -364
- package/dist/lib/time-travel/types.js +0 -24
- package/dist/types/lib/capture/freeze.d.ts +0 -91
- package/dist/types/lib/capture/ownData.d.ts +0 -7
- package/dist/types/lib/capture/valueKinds.d.ts +0 -57
- package/dist/types/lib/ids/runtimeStageId.d.ts +0 -173
- package/dist/types/lib/memory/EventLog.d.ts +0 -105
- package/dist/types/lib/memory/RecordFrame.d.ts +0 -232
- package/dist/types/lib/memory/SharedMemory.d.ts +0 -46
- package/dist/types/lib/memory/TransactionBuffer.d.ts +0 -521
- package/dist/types/lib/memory/admission.d.ts +0 -81
- package/dist/types/lib/memory/backtrack.d.ts +0 -286
- package/dist/types/lib/memory/commitLogUtils.d.ts +0 -217
- package/dist/types/lib/memory/deltaEncoding.d.ts +0 -66
- package/dist/types/lib/memory/equality.d.ts +0 -93
- package/dist/types/lib/memory/eventPosition.d.ts +0 -18
- package/dist/types/lib/memory/honesty.d.ts +0 -93
- package/dist/types/lib/memory/keyPaths.d.ts +0 -125
- package/dist/types/lib/memory/logModel.d.ts +0 -76
- package/dist/types/lib/memory/merge.d.ts +0 -26
- package/dist/types/lib/memory/pathOps.d.ts +0 -115
- package/dist/types/lib/memory/paths.d.ts +0 -52
- package/dist/types/lib/memory/placeholders.d.ts +0 -39
- package/dist/types/lib/memory/recordCommit.d.ts +0 -45
- package/dist/types/lib/memory/scrub.d.ts +0 -53
- package/dist/types/lib/memory/types.d.ts +0 -209
- package/dist/types/lib/memory/utils.d.ts +0 -73
- package/dist/types/lib/memory/verbs.d.ts +0 -333
- package/dist/types/lib/recorder/CommitRangeIndex.d.ts +0 -147
- package/dist/types/lib/scope/detectCircular.d.ts +0 -13
- package/dist/types/lib/scope/recorders/summarizeValue.d.ts +0 -5
- package/dist/types/lib/slice/elementProvenance.d.ts +0 -81
- package/dist/types/lib/slice/forwardSliceForKey.d.ts +0 -88
- package/dist/types/lib/slice/index.d.ts +0 -25
- package/dist/types/lib/slice/keyIndex.d.ts +0 -137
- package/dist/types/lib/slice/keyTimeline.d.ts +0 -49
- package/dist/types/lib/slice/keysReadSources.d.ts +0 -51
- package/dist/types/lib/slice/serialize.d.ts +0 -78
- package/dist/types/lib/slice/sliceForKey.d.ts +0 -47
- package/dist/types/lib/slice/types.d.ts +0 -567
- package/dist/types/lib/time-travel/axis.d.ts +0 -119
- package/dist/types/lib/time-travel/bundles.d.ts +0 -77
- package/dist/types/lib/time-travel/chain.d.ts +0 -93
- package/dist/types/lib/time-travel/commitStops.d.ts +0 -55
- package/dist/types/lib/time-travel/index.d.ts +0 -22
- package/dist/types/lib/time-travel/stateAt.d.ts +0 -102
- package/dist/types/lib/time-travel/tagStops.d.ts +0 -72
- package/dist/types/lib/time-travel/timeTravel.d.ts +0 -70
- package/dist/types/lib/time-travel/types.d.ts +0 -470
- package/dist/types/write.d.ts +0 -47
- package/dist/write.js +0 -52
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* honesty.ts — the ONE vocabulary for what a reader cannot see.
|
|
3
|
-
*
|
|
4
|
-
* WHY THIS FILE EXISTS. A recording cannot always answer what it is asked, and the library says
|
|
5
|
-
* so in several places, each in its own words: a slice carries `HonestyNote`s and, when it has no
|
|
6
|
-
* answer, a `missing` reason; a fed edge and an element birth carry a `basis`; a fold carries a
|
|
7
|
-
* `basis` and its `redacted` paths; a stored log reports `LogGap`s; a causal node carries
|
|
8
|
-
* `incompleteSources` and `truncated`. A reader that wants to EXPLAIN any of them to a person (a
|
|
9
|
-
* why-panel, an agent tool) kept its own table of code → sentence, and tables kept apart drift.
|
|
10
|
-
* This file is that table, once.
|
|
11
|
-
*
|
|
12
|
-
* WHAT IT HOLDS.
|
|
13
|
-
* - `HONESTY_CODES` — a frozen, closed registry: code → the ONE sentence that says what the code
|
|
14
|
-
* means. The shape of rustc's `--explain` and LSP's `Diagnostic.code`: the code is the stable
|
|
15
|
-
* key a consumer BRANCHES on; the sentence is for whoever reads the screen. It is not the
|
|
16
|
-
* per-instance `detail` a note carries (that names the key, the budget, the rows).
|
|
17
|
-
* - `HonestyCode` / `RegisteredCode` — what makes the registry the owner and not a suggestion:
|
|
18
|
-
* each public union of these codes (`HonestyNoteCode`, `MissingSliceReason`,
|
|
19
|
-
* `MissingProvenanceReason`, `FedBasis`, `AttributionBasis`, `FoldBasis`, and since 9.33.0 `ValueBasis` /
|
|
20
|
-
* `WriterBasis` — the basis twins of `commitValueAt` / `findLastWriter`) declares its members
|
|
21
|
-
* through `RegisteredCode`, so a member the registry does not hold fails to COMPILE. And
|
|
22
|
-
* `test/architecture/honesty-vocabulary.test.ts` asks the type checker for every exported type
|
|
23
|
-
* alias of `footprintjs/trace` that is a union of string literals: each one is inside the
|
|
24
|
-
* registry or is named, with its reason, as not an honesty vocabulary.
|
|
25
|
-
*
|
|
26
|
-
* NO OBJECT GAINS A FIELD from being registered. Three signals carry no code of their own — a
|
|
27
|
-
* `LogGap` (`'log-gap'`), `CausalNode.incompleteSources` (`'incomplete-sources'`) and
|
|
28
|
-
* `FoldedState.redacted` / `redactedPaths` (`'redacted'`) — and a `truncated: { byDepth, byNodes }`
|
|
29
|
-
* field means `'truncated'`; they are registered so a reader explains them from the same place.
|
|
30
|
-
*
|
|
31
|
-
* NOT HERE: the two strings a redaction leaves where a value was. The engine writes those on every
|
|
32
|
-
* redacted run; the log's lives in its own leaf, `memory/placeholders.ts` (the scope channel's with
|
|
33
|
-
* the verdict, `memory/redaction.ts`), so that an app which only runs charts does not carry these
|
|
34
|
-
* sentences in its bundle (`HONESTY_CODES` is a pure expression, so a bundler drops it wherever
|
|
35
|
-
* nothing reads it).
|
|
36
|
-
*
|
|
37
|
-
* WHY L0. This file imports NOTHING, and `slice/` and `time-travel/` (L3) type their codes through
|
|
38
|
-
* it, so it sits below them — the layer table is `scripts/layering.config.cjs`.
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```typescript
|
|
42
|
-
* import { HONESTY_CODES } from 'footprintjs/trace';
|
|
43
|
-
*
|
|
44
|
-
* for (const { code } of forwardSlice.notes) console.log(code, '→', HONESTY_CODES[code]);
|
|
45
|
-
* // reads-not-recorded → This log carries no recorded read at all (the readTracking: 'off' signature), …
|
|
46
|
-
* HONESTY_CODES[foldedState.basis]; // 'log-only' → No initialState travelled with this log (…), …
|
|
47
|
-
* ```
|
|
48
|
-
*/
|
|
49
|
-
/**
|
|
50
|
-
* Every honesty code the trace readers (`footprintjs/trace`) speak, with the one sentence that says
|
|
51
|
-
* what it means.
|
|
52
|
-
*
|
|
53
|
-
* Frozen and closed: the keys are exactly the codes below, and {@link HonestyCode} is derived from
|
|
54
|
-
* them. A new code is one new line here: a union declared through {@link RegisteredCode} cannot hold
|
|
55
|
-
* a code that is not on it, and `test/architecture/honesty-vocabulary.test.ts` fails on an exported
|
|
56
|
-
* type alias of `footprintjs/trace` that is a union of string literals neither inside the registry
|
|
57
|
-
* nor named there as not an honesty vocabulary. The values are typed `string`, not literal types,
|
|
58
|
-
* on purpose: the sentences are for a screen and may be reworded; a consumer branches on the KEY.
|
|
59
|
-
*/
|
|
60
|
-
export declare const HONESTY_CODES: Readonly<{
|
|
61
|
-
'conservative-fed-edges': string;
|
|
62
|
-
'nested-rows': string;
|
|
63
|
-
'pre-run-origin': string;
|
|
64
|
-
'reads-not-recorded': string;
|
|
65
|
-
'unknown-key': string;
|
|
66
|
-
truncated: string;
|
|
67
|
-
'empty-log': string;
|
|
68
|
-
'never-written': string;
|
|
69
|
-
'not-an-array': string;
|
|
70
|
-
'per-write': string;
|
|
71
|
-
stage: string;
|
|
72
|
-
'append-verb': string;
|
|
73
|
-
'prefix-inference': string;
|
|
74
|
-
'whole-value': string;
|
|
75
|
-
'initial+log': string;
|
|
76
|
-
'log-only': string;
|
|
77
|
-
'log-gap': string;
|
|
78
|
-
'incomplete-sources': string;
|
|
79
|
-
redacted: string;
|
|
80
|
-
deleted: string;
|
|
81
|
-
'from-initial-state': string;
|
|
82
|
-
}>;
|
|
83
|
-
/** Any code in {@link HONESTY_CODES} — the key a reader looks an explanation up by. */
|
|
84
|
-
export type HonestyCode = keyof typeof HONESTY_CODES;
|
|
85
|
-
/**
|
|
86
|
-
* A union of honesty codes a type DECLARES: `T` must be a subset of {@link HonestyCode}, or the
|
|
87
|
-
* declaration fails to compile (TS2344).
|
|
88
|
-
*
|
|
89
|
-
* `RegisteredCode<T>` is `T` — an identity at the type level — so the union keeps exactly the
|
|
90
|
-
* members it was written with and does NOT widen to every code:
|
|
91
|
-
* `type FoldBasis = RegisteredCode<'initial+log' | 'log-only'>`.
|
|
92
|
-
*/
|
|
93
|
-
export type RegisteredCode<T extends HonestyCode> = T;
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* honesty.ts — the ONE vocabulary for what a reader cannot see.
|
|
3
|
-
*
|
|
4
|
-
* WHY THIS FILE EXISTS. A recording cannot always answer what it is asked, and the library says
|
|
5
|
-
* so in several places, each in its own words: a slice carries `HonestyNote`s and, when it has no
|
|
6
|
-
* answer, a `missing` reason; a fed edge and an element birth carry a `basis`; a fold carries a
|
|
7
|
-
* `basis` and its `redacted` paths; a stored log reports `LogGap`s; a causal node carries
|
|
8
|
-
* `incompleteSources` and `truncated`. A reader that wants to EXPLAIN any of them to a person (a
|
|
9
|
-
* why-panel, an agent tool) kept its own table of code → sentence, and tables kept apart drift.
|
|
10
|
-
* This file is that table, once.
|
|
11
|
-
*
|
|
12
|
-
* WHAT IT HOLDS.
|
|
13
|
-
* - `HONESTY_CODES` — a frozen, closed registry: code → the ONE sentence that says what the code
|
|
14
|
-
* means. The shape of rustc's `--explain` and LSP's `Diagnostic.code`: the code is the stable
|
|
15
|
-
* key a consumer BRANCHES on; the sentence is for whoever reads the screen. It is not the
|
|
16
|
-
* per-instance `detail` a note carries (that names the key, the budget, the rows).
|
|
17
|
-
* - `HonestyCode` / `RegisteredCode` — what makes the registry the owner and not a suggestion:
|
|
18
|
-
* each public union of these codes (`HonestyNoteCode`, `MissingSliceReason`,
|
|
19
|
-
* `MissingProvenanceReason`, `FedBasis`, `AttributionBasis`, `FoldBasis`, and since 9.33.0 `ValueBasis` /
|
|
20
|
-
* `WriterBasis` — the basis twins of `commitValueAt` / `findLastWriter`) declares its members
|
|
21
|
-
* through `RegisteredCode`, so a member the registry does not hold fails to COMPILE. And
|
|
22
|
-
* `test/architecture/honesty-vocabulary.test.ts` asks the type checker for every exported type
|
|
23
|
-
* alias of `footprintjs/trace` that is a union of string literals: each one is inside the
|
|
24
|
-
* registry or is named, with its reason, as not an honesty vocabulary.
|
|
25
|
-
*
|
|
26
|
-
* NO OBJECT GAINS A FIELD from being registered. Three signals carry no code of their own — a
|
|
27
|
-
* `LogGap` (`'log-gap'`), `CausalNode.incompleteSources` (`'incomplete-sources'`) and
|
|
28
|
-
* `FoldedState.redacted` / `redactedPaths` (`'redacted'`) — and a `truncated: { byDepth, byNodes }`
|
|
29
|
-
* field means `'truncated'`; they are registered so a reader explains them from the same place.
|
|
30
|
-
*
|
|
31
|
-
* NOT HERE: the two strings a redaction leaves where a value was. The engine writes those on every
|
|
32
|
-
* redacted run; the log's lives in its own leaf, `memory/placeholders.ts` (the scope channel's with
|
|
33
|
-
* the verdict, `memory/redaction.ts`), so that an app which only runs charts does not carry these
|
|
34
|
-
* sentences in its bundle (`HONESTY_CODES` is a pure expression, so a bundler drops it wherever
|
|
35
|
-
* nothing reads it).
|
|
36
|
-
*
|
|
37
|
-
* WHY L0. This file imports NOTHING, and `slice/` and `time-travel/` (L3) type their codes through
|
|
38
|
-
* it, so it sits below them — the layer table is `scripts/layering.config.cjs`.
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```typescript
|
|
42
|
-
* import { HONESTY_CODES } from 'footprintjs/trace';
|
|
43
|
-
*
|
|
44
|
-
* for (const { code } of forwardSlice.notes) console.log(code, '→', HONESTY_CODES[code]);
|
|
45
|
-
* // reads-not-recorded → This log carries no recorded read at all (the readTracking: 'off' signature), …
|
|
46
|
-
* HONESTY_CODES[foldedState.basis]; // 'log-only' → No initialState travelled with this log (…), …
|
|
47
|
-
* ```
|
|
48
|
-
*/
|
|
49
|
-
/**
|
|
50
|
-
* Every honesty code the trace readers (`footprintjs/trace`) speak, with the one sentence that says
|
|
51
|
-
* what it means.
|
|
52
|
-
*
|
|
53
|
-
* Frozen and closed: the keys are exactly the codes below, and {@link HonestyCode} is derived from
|
|
54
|
-
* them. A new code is one new line here: a union declared through {@link RegisteredCode} cannot hold
|
|
55
|
-
* a code that is not on it, and `test/architecture/honesty-vocabulary.test.ts` fails on an exported
|
|
56
|
-
* type alias of `footprintjs/trace` that is a union of string literals neither inside the registry
|
|
57
|
-
* nor named there as not an honesty vocabulary. The values are typed `string`, not literal types,
|
|
58
|
-
* on purpose: the sentences are for a screen and may be reworded; a consumer branches on the KEY.
|
|
59
|
-
*/
|
|
60
|
-
export const HONESTY_CODES = /* @__PURE__ */ Object.freeze({
|
|
61
|
-
// ── a slice's notes — `HonestyNote.code` (slice/) ─────────────────────────
|
|
62
|
-
'conservative-fed-edges': "At least one 'fed' edge is stage-level (conservative): its write carries no per-write read provenance, so the edge may not be real — turn on writeProvenance: 'reads-prefix' for exact edges.",
|
|
63
|
-
'nested-rows': "A write this answer rests on reached the key only through paths inside it (a subflow's input seed, an outputMapper merge-back, a fork child's namespace), so it changed part of the key's value, not the whole: earlier writes may account for the rest, and a reader of the key may not have read the part that write changed.",
|
|
64
|
-
'pre-run-origin': 'The value being followed was absent or already there before the first write this log can see (initial state, frozen run input or a closure), so who put it there is outside the commit log.',
|
|
65
|
-
'reads-not-recorded': "This log carries no recorded read at all (the readTracking: 'off' signature), so 'nothing read this value' is unknowable here, not true.",
|
|
66
|
-
'unknown-key': "This log has no write and no recorded read of the key, which is most likely a typo or the wrong run's log rather than a variable with no history.",
|
|
67
|
-
truncated: 'A budget (maxDepth or maxNodes) cut the walk, so more of the answer exists beyond the horizon it stopped at.',
|
|
68
|
-
// ── why a slice has no answer — `missing` (slice/: MissingSliceReason, MissingProvenanceReason) ─
|
|
69
|
-
'empty-log': 'The commit log holds no commit at all (nothing has executed, or the log handed in is empty), so there is no history to answer from.',
|
|
70
|
-
'never-written': 'No commit in the range asked about wrote the key — not its whole value, not a path inside it, and not a container around it in a way that changed it (a forward slice or a timeline also found no recorded read on, inside or around it) — so there is no write to start from: any value it has came from the initial state, the frozen run input or a closure, none of which the commit log can see.',
|
|
71
|
-
'not-an-array': 'The key was written, but its value at the point asked about is not an array (a scalar or object key, a deleted key, or a merge that degraded it), so element provenance does not apply: sliceForKey is the query for it.',
|
|
72
|
-
// ── how a fed edge was attributed — `ForwardEdge.basis` (slice/: FedBasis) ─
|
|
73
|
-
'per-write': "This fed edge is exact: the downstream write carries per-write read provenance (TraceEntry.readKeys, recorded under writeProvenance: 'reads-prefix') and that list names the key, so the value was read before the write it feeds.",
|
|
74
|
-
stage: 'This fed edge is conservative: the downstream write carries no per-write read provenance (the writeProvenance dial was off, or the log is mixed), so all that is known is that its stage read this key and wrote that path in some order, and the edge may not be real.',
|
|
75
|
-
// ── how an element's birth was attributed — `ElementBirth.basis` (slice/: AttributionBasis) ─
|
|
76
|
-
'append-verb': "The engine recorded the element in an append row's tail (how commitValues: 'delta' records an array's growth), so the commit that added it is known exactly, not inferred.",
|
|
77
|
-
'prefix-inference': 'A whole-value write (a set or a merge) kept the previous array as its prefix, so the new tail is attributed to that commit by inference: a write that replaced the array with one that happens to begin the same way looks identical.',
|
|
78
|
-
'whole-value': "This commit placed the array wholesale (there was no earlier array, or the new one does not begin with it), so every element's birth resets to this commit: exact, but coarse.",
|
|
79
|
-
// ── how a fold was derived — `FoldedState.basis` (time-travel/) ───────────
|
|
80
|
-
'initial+log': 'The fold started from the fold base that travelled with the log (initialState) and replayed the commit log onto it, so nothing seeded before the run is missing; rows it could not read are listed apart, in skipped.',
|
|
81
|
-
'log-only': 'No initialState travelled with this log (a snapshot stored before 9.17, a redacted snapshot or a hand-built log), so the fold started from an empty object: a key seeded before the run is whole only once a commit since wrote its whole value, and until then it holds just what its merges, appends and nested writes added, or nothing.',
|
|
82
|
-
// ── a row of a stored log that is not a commit bundle — `LogGap` ──────────
|
|
83
|
-
'log-gap': 'A row of the stored log could not be read as a commit bundle, so it keeps its index but contributes no state, and any fold that crosses it is missing whatever that row wrote.',
|
|
84
|
-
// ── untracked reads a stage also consumed — `CausalNode.incompleteSources` ─
|
|
85
|
-
'incomplete-sources': 'The stage also consumed read paths that bypass read tracking (args, env or an unshadowed silent read), so a slice through it may be incomplete: those reads produce no read-to-write edge to follow.',
|
|
86
|
-
// ── values scrubbed at write time — `FoldedState.redacted` / `redactedPaths`, a value basis ─
|
|
87
|
-
redacted: "Values at the paths listed in redactedPaths (a fold's, or a commit's in the range a key's value rests on) were scrubbed when they were written (by a redaction policy, or a write marked redacted), so where the answer holds the log's placeholder 'REDACTED', or lost a key under a container the placeholder replaced, it stands in for a value the log never recorded.",
|
|
88
|
-
// ── how one key's value was read off the log — `ValueBasis` (commitValueAtWithBasis) ─
|
|
89
|
-
deleted: "The key's last write in the range asked about left it absent (a delete of the key or of a container around it, or a set of a container that no longer holds it), so the answer is undefined because the record says the key was gone at that point, not because nothing was recorded.",
|
|
90
|
-
'from-initial-state': "No set or delete of the key, or of a container around it, is in the range asked about, so the answer rests on the value the key had before the run: folded from the initialState passed in when there was one, and otherwise only what the log's merges, appends and nested writes added to it (or nothing), which is partial for a key seeded before the run.",
|
|
91
|
-
});
|
|
92
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG9uZXN0eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvbWVtb3J5L2hvbmVzdHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBK0NHO0FBRUg7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUN6RCw2RUFBNkU7SUFDN0Usd0JBQXdCLEVBQ3RCLCtMQUErTDtJQUNqTSxhQUFhLEVBQ1gsaVVBQWlVO0lBQ25VLGdCQUFnQixFQUNkLDZMQUE2TDtJQUMvTCxvQkFBb0IsRUFDbEIsMElBQTBJO0lBQzVJLGFBQWEsRUFDWCxtSkFBbUo7SUFDckosU0FBUyxFQUNQLDhHQUE4RztJQUNoSCxtR0FBbUc7SUFDbkcsV0FBVyxFQUNULHFJQUFxSTtJQUN2SSxlQUFlLEVBQ2IsdVlBQXVZO0lBQ3pZLGNBQWMsRUFDWiwwTkFBME47SUFDNU4sOEVBQThFO0lBQzlFLFdBQVcsRUFDVCxvT0FBb087SUFDdE8sS0FBSyxFQUNILHlRQUF5UTtJQUMzUSwrRkFBK0Y7SUFDL0YsYUFBYSxFQUNYLDRLQUE0SztJQUM5SyxrQkFBa0IsRUFDaEIsdU9BQXVPO0lBQ3pPLGFBQWEsRUFDWCxnTEFBZ0w7SUFDbEwsNkVBQTZFO0lBQzdFLGFBQWEsRUFDWCx1TkFBdU47SUFDek4sVUFBVSxFQUNSLDZVQUE2VTtJQUMvVSw2RUFBNkU7SUFDN0UsU0FBUyxFQUNQLGdMQUFnTDtJQUNsTCw4RUFBOEU7SUFDOUUsb0JBQW9CLEVBQ2xCLHNNQUFzTTtJQUN4TSwrRkFBK0Y7SUFDL0YsUUFBUSxFQUNOLDRXQUE0VztJQUM5Vyx3RkFBd0Y7SUFDeEYsT0FBTyxFQUNMLHVSQUF1UjtJQUN6UixvQkFBb0IsRUFDbEIsZ1dBQWdXO0NBQ2xVLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogaG9uZXN0eS50cyDigJQgdGhlIE9ORSB2b2NhYnVsYXJ5IGZvciB3aGF0IGEgcmVhZGVyIGNhbm5vdCBzZWUuXG4gKlxuICogV0hZIFRISVMgRklMRSBFWElTVFMuIEEgcmVjb3JkaW5nIGNhbm5vdCBhbHdheXMgYW5zd2VyIHdoYXQgaXQgaXMgYXNrZWQsIGFuZCB0aGUgbGlicmFyeSBzYXlzXG4gKiBzbyBpbiBzZXZlcmFsIHBsYWNlcywgZWFjaCBpbiBpdHMgb3duIHdvcmRzOiBhIHNsaWNlIGNhcnJpZXMgYEhvbmVzdHlOb3RlYHMgYW5kLCB3aGVuIGl0IGhhcyBub1xuICogYW5zd2VyLCBhIGBtaXNzaW5nYCByZWFzb247IGEgZmVkIGVkZ2UgYW5kIGFuIGVsZW1lbnQgYmlydGggY2FycnkgYSBgYmFzaXNgOyBhIGZvbGQgY2FycmllcyBhXG4gKiBgYmFzaXNgIGFuZCBpdHMgYHJlZGFjdGVkYCBwYXRoczsgYSBzdG9yZWQgbG9nIHJlcG9ydHMgYExvZ0dhcGBzOyBhIGNhdXNhbCBub2RlIGNhcnJpZXNcbiAqIGBpbmNvbXBsZXRlU291cmNlc2AgYW5kIGB0cnVuY2F0ZWRgLiBBIHJlYWRlciB0aGF0IHdhbnRzIHRvIEVYUExBSU4gYW55IG9mIHRoZW0gdG8gYSBwZXJzb24gKGFcbiAqIHdoeS1wYW5lbCwgYW4gYWdlbnQgdG9vbCkga2VwdCBpdHMgb3duIHRhYmxlIG9mIGNvZGUg4oaSIHNlbnRlbmNlLCBhbmQgdGFibGVzIGtlcHQgYXBhcnQgZHJpZnQuXG4gKiBUaGlzIGZpbGUgaXMgdGhhdCB0YWJsZSwgb25jZS5cbiAqXG4gKiBXSEFUIElUIEhPTERTLlxuICogICAtIGBIT05FU1RZX0NPREVTYCDigJQgYSBmcm96ZW4sIGNsb3NlZCByZWdpc3RyeTogY29kZSDihpIgdGhlIE9ORSBzZW50ZW5jZSB0aGF0IHNheXMgd2hhdCB0aGUgY29kZVxuICogICAgIG1lYW5zLiBUaGUgc2hhcGUgb2YgcnVzdGMncyBgLS1leHBsYWluYCBhbmQgTFNQJ3MgYERpYWdub3N0aWMuY29kZWA6IHRoZSBjb2RlIGlzIHRoZSBzdGFibGVcbiAqICAgICBrZXkgYSBjb25zdW1lciBCUkFOQ0hFUyBvbjsgdGhlIHNlbnRlbmNlIGlzIGZvciB3aG9ldmVyIHJlYWRzIHRoZSBzY3JlZW4uIEl0IGlzIG5vdCB0aGVcbiAqICAgICBwZXItaW5zdGFuY2UgYGRldGFpbGAgYSBub3RlIGNhcnJpZXMgKHRoYXQgbmFtZXMgdGhlIGtleSwgdGhlIGJ1ZGdldCwgdGhlIHJvd3MpLlxuICogICAtIGBIb25lc3R5Q29kZWAgLyBgUmVnaXN0ZXJlZENvZGVgIOKAlCB3aGF0IG1ha2VzIHRoZSByZWdpc3RyeSB0aGUgb3duZXIgYW5kIG5vdCBhIHN1Z2dlc3Rpb246XG4gKiAgICAgZWFjaCBwdWJsaWMgdW5pb24gb2YgdGhlc2UgY29kZXMgKGBIb25lc3R5Tm90ZUNvZGVgLCBgTWlzc2luZ1NsaWNlUmVhc29uYCxcbiAqICAgICBgTWlzc2luZ1Byb3ZlbmFuY2VSZWFzb25gLCBgRmVkQmFzaXNgLCBgQXR0cmlidXRpb25CYXNpc2AsIGBGb2xkQmFzaXNgLCBhbmQgc2luY2UgOS4zMy4wIGBWYWx1ZUJhc2lzYCAvXG4gKiAgICAgYFdyaXRlckJhc2lzYCDigJQgdGhlIGJhc2lzIHR3aW5zIG9mIGBjb21taXRWYWx1ZUF0YCAvIGBmaW5kTGFzdFdyaXRlcmApIGRlY2xhcmVzIGl0cyBtZW1iZXJzXG4gKiAgICAgdGhyb3VnaCBgUmVnaXN0ZXJlZENvZGVgLCBzbyBhIG1lbWJlciB0aGUgcmVnaXN0cnkgZG9lcyBub3QgaG9sZCBmYWlscyB0byBDT01QSUxFLiBBbmRcbiAqICAgICBgdGVzdC9hcmNoaXRlY3R1cmUvaG9uZXN0eS12b2NhYnVsYXJ5LnRlc3QudHNgIGFza3MgdGhlIHR5cGUgY2hlY2tlciBmb3IgZXZlcnkgZXhwb3J0ZWQgdHlwZVxuICogICAgIGFsaWFzIG9mIGBmb290cHJpbnRqcy90cmFjZWAgdGhhdCBpcyBhIHVuaW9uIG9mIHN0cmluZyBsaXRlcmFsczogZWFjaCBvbmUgaXMgaW5zaWRlIHRoZVxuICogICAgIHJlZ2lzdHJ5IG9yIGlzIG5hbWVkLCB3aXRoIGl0cyByZWFzb24sIGFzIG5vdCBhbiBob25lc3R5IHZvY2FidWxhcnkuXG4gKlxuICogTk8gT0JKRUNUIEdBSU5TIEEgRklFTEQgZnJvbSBiZWluZyByZWdpc3RlcmVkLiBUaHJlZSBzaWduYWxzIGNhcnJ5IG5vIGNvZGUgb2YgdGhlaXIgb3duIOKAlCBhXG4gKiBgTG9nR2FwYCAoYCdsb2ctZ2FwJ2ApLCBgQ2F1c2FsTm9kZS5pbmNvbXBsZXRlU291cmNlc2AgKGAnaW5jb21wbGV0ZS1zb3VyY2VzJ2ApIGFuZFxuICogYEZvbGRlZFN0YXRlLnJlZGFjdGVkYCAvIGByZWRhY3RlZFBhdGhzYCAoYCdyZWRhY3RlZCdgKSDigJQgYW5kIGEgYHRydW5jYXRlZDogeyBieURlcHRoLCBieU5vZGVzIH1gXG4gKiBmaWVsZCBtZWFucyBgJ3RydW5jYXRlZCdgOyB0aGV5IGFyZSByZWdpc3RlcmVkIHNvIGEgcmVhZGVyIGV4cGxhaW5zIHRoZW0gZnJvbSB0aGUgc2FtZSBwbGFjZS5cbiAqXG4gKiBOT1QgSEVSRTogdGhlIHR3byBzdHJpbmdzIGEgcmVkYWN0aW9uIGxlYXZlcyB3aGVyZSBhIHZhbHVlIHdhcy4gVGhlIGVuZ2luZSB3cml0ZXMgdGhvc2Ugb24gZXZlcnlcbiAqIHJlZGFjdGVkIHJ1bjsgdGhlIGxvZydzIGxpdmVzIGluIGl0cyBvd24gbGVhZiwgYG1lbW9yeS9wbGFjZWhvbGRlcnMudHNgICh0aGUgc2NvcGUgY2hhbm5lbCdzIHdpdGhcbiAqIHRoZSB2ZXJkaWN0LCBgbWVtb3J5L3JlZGFjdGlvbi50c2ApLCBzbyB0aGF0IGFuIGFwcCB3aGljaCBvbmx5IHJ1bnMgY2hhcnRzIGRvZXMgbm90IGNhcnJ5IHRoZXNlXG4gKiBzZW50ZW5jZXMgaW4gaXRzIGJ1bmRsZSAoYEhPTkVTVFlfQ09ERVNgIGlzIGEgcHVyZSBleHByZXNzaW9uLCBzbyBhIGJ1bmRsZXIgZHJvcHMgaXQgd2hlcmV2ZXJcbiAqIG5vdGhpbmcgcmVhZHMgaXQpLlxuICpcbiAqIFdIWSBMMC4gVGhpcyBmaWxlIGltcG9ydHMgTk9USElORywgYW5kIGBzbGljZS9gIGFuZCBgdGltZS10cmF2ZWwvYCAoTDMpIHR5cGUgdGhlaXIgY29kZXMgdGhyb3VnaFxuICogaXQsIHNvIGl0IHNpdHMgYmVsb3cgdGhlbSDigJQgdGhlIGxheWVyIHRhYmxlIGlzIGBzY3JpcHRzL2xheWVyaW5nLmNvbmZpZy5janNgLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBIT05FU1RZX0NPREVTIH0gZnJvbSAnZm9vdHByaW50anMvdHJhY2UnO1xuICpcbiAqIGZvciAoY29uc3QgeyBjb2RlIH0gb2YgZm9yd2FyZFNsaWNlLm5vdGVzKSBjb25zb2xlLmxvZyhjb2RlLCAn4oaSJywgSE9ORVNUWV9DT0RFU1tjb2RlXSk7XG4gKiAvLyByZWFkcy1ub3QtcmVjb3JkZWQg4oaSIFRoaXMgbG9nIGNhcnJpZXMgbm8gcmVjb3JkZWQgcmVhZCBhdCBhbGwgKHRoZSByZWFkVHJhY2tpbmc6ICdvZmYnIHNpZ25hdHVyZSksIOKAplxuICogSE9ORVNUWV9DT0RFU1tmb2xkZWRTdGF0ZS5iYXNpc107IC8vICdsb2ctb25seScg4oaSIE5vIGluaXRpYWxTdGF0ZSB0cmF2ZWxsZWQgd2l0aCB0aGlzIGxvZyAo4oCmKSwg4oCmXG4gKiBgYGBcbiAqL1xuXG4vKipcbiAqIEV2ZXJ5IGhvbmVzdHkgY29kZSB0aGUgdHJhY2UgcmVhZGVycyAoYGZvb3RwcmludGpzL3RyYWNlYCkgc3BlYWssIHdpdGggdGhlIG9uZSBzZW50ZW5jZSB0aGF0IHNheXNcbiAqIHdoYXQgaXQgbWVhbnMuXG4gKlxuICogRnJvemVuIGFuZCBjbG9zZWQ6IHRoZSBrZXlzIGFyZSBleGFjdGx5IHRoZSBjb2RlcyBiZWxvdywgYW5kIHtAbGluayBIb25lc3R5Q29kZX0gaXMgZGVyaXZlZCBmcm9tXG4gKiB0aGVtLiBBIG5ldyBjb2RlIGlzIG9uZSBuZXcgbGluZSBoZXJlOiBhIHVuaW9uIGRlY2xhcmVkIHRocm91Z2gge0BsaW5rIFJlZ2lzdGVyZWRDb2RlfSBjYW5ub3QgaG9sZFxuICogYSBjb2RlIHRoYXQgaXMgbm90IG9uIGl0LCBhbmQgYHRlc3QvYXJjaGl0ZWN0dXJlL2hvbmVzdHktdm9jYWJ1bGFyeS50ZXN0LnRzYCBmYWlscyBvbiBhbiBleHBvcnRlZFxuICogdHlwZSBhbGlhcyBvZiBgZm9vdHByaW50anMvdHJhY2VgIHRoYXQgaXMgYSB1bmlvbiBvZiBzdHJpbmcgbGl0ZXJhbHMgbmVpdGhlciBpbnNpZGUgdGhlIHJlZ2lzdHJ5XG4gKiBub3IgbmFtZWQgdGhlcmUgYXMgbm90IGFuIGhvbmVzdHkgdm9jYWJ1bGFyeS4gVGhlIHZhbHVlcyBhcmUgdHlwZWQgYHN0cmluZ2AsIG5vdCBsaXRlcmFsIHR5cGVzLFxuICogb24gcHVycG9zZTogdGhlIHNlbnRlbmNlcyBhcmUgZm9yIGEgc2NyZWVuIGFuZCBtYXkgYmUgcmV3b3JkZWQ7IGEgY29uc3VtZXIgYnJhbmNoZXMgb24gdGhlIEtFWS5cbiAqL1xuZXhwb3J0IGNvbnN0IEhPTkVTVFlfQ09ERVMgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmZyZWV6ZSh7XG4gIC8vIOKUgOKUgCBhIHNsaWNlJ3Mgbm90ZXMg4oCUIGBIb25lc3R5Tm90ZS5jb2RlYCAoc2xpY2UvKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgJ2NvbnNlcnZhdGl2ZS1mZWQtZWRnZXMnOlxuICAgIFwiQXQgbGVhc3Qgb25lICdmZWQnIGVkZ2UgaXMgc3RhZ2UtbGV2ZWwgKGNvbnNlcnZhdGl2ZSk6IGl0cyB3cml0ZSBjYXJyaWVzIG5vIHBlci13cml0ZSByZWFkIHByb3ZlbmFuY2UsIHNvIHRoZSBlZGdlIG1heSBub3QgYmUgcmVhbCDigJQgdHVybiBvbiB3cml0ZVByb3ZlbmFuY2U6ICdyZWFkcy1wcmVmaXgnIGZvciBleGFjdCBlZGdlcy5cIixcbiAgJ25lc3RlZC1yb3dzJzpcbiAgICBcIkEgd3JpdGUgdGhpcyBhbnN3ZXIgcmVzdHMgb24gcmVhY2hlZCB0aGUga2V5IG9ubHkgdGhyb3VnaCBwYXRocyBpbnNpZGUgaXQgKGEgc3ViZmxvdydzIGlucHV0IHNlZWQsIGFuIG91dHB1dE1hcHBlciBtZXJnZS1iYWNrLCBhIGZvcmsgY2hpbGQncyBuYW1lc3BhY2UpLCBzbyBpdCBjaGFuZ2VkIHBhcnQgb2YgdGhlIGtleSdzIHZhbHVlLCBub3QgdGhlIHdob2xlOiBlYXJsaWVyIHdyaXRlcyBtYXkgYWNjb3VudCBmb3IgdGhlIHJlc3QsIGFuZCBhIHJlYWRlciBvZiB0aGUga2V5IG1heSBub3QgaGF2ZSByZWFkIHRoZSBwYXJ0IHRoYXQgd3JpdGUgY2hhbmdlZC5cIixcbiAgJ3ByZS1ydW4tb3JpZ2luJzpcbiAgICAnVGhlIHZhbHVlIGJlaW5nIGZvbGxvd2VkIHdhcyBhYnNlbnQgb3IgYWxyZWFkeSB0aGVyZSBiZWZvcmUgdGhlIGZpcnN0IHdyaXRlIHRoaXMgbG9nIGNhbiBzZWUgKGluaXRpYWwgc3RhdGUsIGZyb3plbiBydW4gaW5wdXQgb3IgYSBjbG9zdXJlKSwgc28gd2hvIHB1dCBpdCB0aGVyZSBpcyBvdXRzaWRlIHRoZSBjb21taXQgbG9nLicsXG4gICdyZWFkcy1ub3QtcmVjb3JkZWQnOlxuICAgIFwiVGhpcyBsb2cgY2FycmllcyBubyByZWNvcmRlZCByZWFkIGF0IGFsbCAodGhlIHJlYWRUcmFja2luZzogJ29mZicgc2lnbmF0dXJlKSwgc28gJ25vdGhpbmcgcmVhZCB0aGlzIHZhbHVlJyBpcyB1bmtub3dhYmxlIGhlcmUsIG5vdCB0cnVlLlwiLFxuICAndW5rbm93bi1rZXknOlxuICAgIFwiVGhpcyBsb2cgaGFzIG5vIHdyaXRlIGFuZCBubyByZWNvcmRlZCByZWFkIG9mIHRoZSBrZXksIHdoaWNoIGlzIG1vc3QgbGlrZWx5IGEgdHlwbyBvciB0aGUgd3JvbmcgcnVuJ3MgbG9nIHJhdGhlciB0aGFuIGEgdmFyaWFibGUgd2l0aCBubyBoaXN0b3J5LlwiLFxuICB0cnVuY2F0ZWQ6XG4gICAgJ0EgYnVkZ2V0IChtYXhEZXB0aCBvciBtYXhOb2RlcykgY3V0IHRoZSB3YWxrLCBzbyBtb3JlIG9mIHRoZSBhbnN3ZXIgZXhpc3RzIGJleW9uZCB0aGUgaG9yaXpvbiBpdCBzdG9wcGVkIGF0LicsXG4gIC8vIOKUgOKUgCB3aHkgYSBzbGljZSBoYXMgbm8gYW5zd2VyIOKAlCBgbWlzc2luZ2AgKHNsaWNlLzogTWlzc2luZ1NsaWNlUmVhc29uLCBNaXNzaW5nUHJvdmVuYW5jZVJlYXNvbikg4pSAXG4gICdlbXB0eS1sb2cnOlxuICAgICdUaGUgY29tbWl0IGxvZyBob2xkcyBubyBjb21taXQgYXQgYWxsIChub3RoaW5nIGhhcyBleGVjdXRlZCwgb3IgdGhlIGxvZyBoYW5kZWQgaW4gaXMgZW1wdHkpLCBzbyB0aGVyZSBpcyBubyBoaXN0b3J5IHRvIGFuc3dlciBmcm9tLicsXG4gICduZXZlci13cml0dGVuJzpcbiAgICAnTm8gY29tbWl0IGluIHRoZSByYW5nZSBhc2tlZCBhYm91dCB3cm90ZSB0aGUga2V5IOKAlCBub3QgaXRzIHdob2xlIHZhbHVlLCBub3QgYSBwYXRoIGluc2lkZSBpdCwgYW5kIG5vdCBhIGNvbnRhaW5lciBhcm91bmQgaXQgaW4gYSB3YXkgdGhhdCBjaGFuZ2VkIGl0IChhIGZvcndhcmQgc2xpY2Ugb3IgYSB0aW1lbGluZSBhbHNvIGZvdW5kIG5vIHJlY29yZGVkIHJlYWQgb24sIGluc2lkZSBvciBhcm91bmQgaXQpIOKAlCBzbyB0aGVyZSBpcyBubyB3cml0ZSB0byBzdGFydCBmcm9tOiBhbnkgdmFsdWUgaXQgaGFzIGNhbWUgZnJvbSB0aGUgaW5pdGlhbCBzdGF0ZSwgdGhlIGZyb3plbiBydW4gaW5wdXQgb3IgYSBjbG9zdXJlLCBub25lIG9mIHdoaWNoIHRoZSBjb21taXQgbG9nIGNhbiBzZWUuJyxcbiAgJ25vdC1hbi1hcnJheSc6XG4gICAgJ1RoZSBrZXkgd2FzIHdyaXR0ZW4sIGJ1dCBpdHMgdmFsdWUgYXQgdGhlIHBvaW50IGFza2VkIGFib3V0IGlzIG5vdCBhbiBhcnJheSAoYSBzY2FsYXIgb3Igb2JqZWN0IGtleSwgYSBkZWxldGVkIGtleSwgb3IgYSBtZXJnZSB0aGF0IGRlZ3JhZGVkIGl0KSwgc28gZWxlbWVudCBwcm92ZW5hbmNlIGRvZXMgbm90IGFwcGx5OiBzbGljZUZvcktleSBpcyB0aGUgcXVlcnkgZm9yIGl0LicsXG4gIC8vIOKUgOKUgCBob3cgYSBmZWQgZWRnZSB3YXMgYXR0cmlidXRlZCDigJQgYEZvcndhcmRFZGdlLmJhc2lzYCAoc2xpY2UvOiBGZWRCYXNpcykg4pSAXG4gICdwZXItd3JpdGUnOlxuICAgIFwiVGhpcyBmZWQgZWRnZSBpcyBleGFjdDogdGhlIGRvd25zdHJlYW0gd3JpdGUgY2FycmllcyBwZXItd3JpdGUgcmVhZCBwcm92ZW5hbmNlIChUcmFjZUVudHJ5LnJlYWRLZXlzLCByZWNvcmRlZCB1bmRlciB3cml0ZVByb3ZlbmFuY2U6ICdyZWFkcy1wcmVmaXgnKSBhbmQgdGhhdCBsaXN0IG5hbWVzIHRoZSBrZXksIHNvIHRoZSB2YWx1ZSB3YXMgcmVhZCBiZWZvcmUgdGhlIHdyaXRlIGl0IGZlZWRzLlwiLFxuICBzdGFnZTpcbiAgICAnVGhpcyBmZWQgZWRnZSBpcyBjb25zZXJ2YXRpdmU6IHRoZSBkb3duc3RyZWFtIHdyaXRlIGNhcnJpZXMgbm8gcGVyLXdyaXRlIHJlYWQgcHJvdmVuYW5jZSAodGhlIHdyaXRlUHJvdmVuYW5jZSBkaWFsIHdhcyBvZmYsIG9yIHRoZSBsb2cgaXMgbWl4ZWQpLCBzbyBhbGwgdGhhdCBpcyBrbm93biBpcyB0aGF0IGl0cyBzdGFnZSByZWFkIHRoaXMga2V5IGFuZCB3cm90ZSB0aGF0IHBhdGggaW4gc29tZSBvcmRlciwgYW5kIHRoZSBlZGdlIG1heSBub3QgYmUgcmVhbC4nLFxuICAvLyDilIDilIAgaG93IGFuIGVsZW1lbnQncyBiaXJ0aCB3YXMgYXR0cmlidXRlZCDigJQgYEVsZW1lbnRCaXJ0aC5iYXNpc2AgKHNsaWNlLzogQXR0cmlidXRpb25CYXNpcykg4pSAXG4gICdhcHBlbmQtdmVyYic6XG4gICAgXCJUaGUgZW5naW5lIHJlY29yZGVkIHRoZSBlbGVtZW50IGluIGFuIGFwcGVuZCByb3cncyB0YWlsIChob3cgY29tbWl0VmFsdWVzOiAnZGVsdGEnIHJlY29yZHMgYW4gYXJyYXkncyBncm93dGgpLCBzbyB0aGUgY29tbWl0IHRoYXQgYWRkZWQgaXQgaXMga25vd24gZXhhY3RseSwgbm90IGluZmVycmVkLlwiLFxuICAncHJlZml4LWluZmVyZW5jZSc6XG4gICAgJ0Egd2hvbGUtdmFsdWUgd3JpdGUgKGEgc2V0IG9yIGEgbWVyZ2UpIGtlcHQgdGhlIHByZXZpb3VzIGFycmF5IGFzIGl0cyBwcmVmaXgsIHNvIHRoZSBuZXcgdGFpbCBpcyBhdHRyaWJ1dGVkIHRvIHRoYXQgY29tbWl0IGJ5IGluZmVyZW5jZTogYSB3cml0ZSB0aGF0IHJlcGxhY2VkIHRoZSBhcnJheSB3aXRoIG9uZSB0aGF0IGhhcHBlbnMgdG8gYmVnaW4gdGhlIHNhbWUgd2F5IGxvb2tzIGlkZW50aWNhbC4nLFxuICAnd2hvbGUtdmFsdWUnOlxuICAgIFwiVGhpcyBjb21taXQgcGxhY2VkIHRoZSBhcnJheSB3aG9sZXNhbGUgKHRoZXJlIHdhcyBubyBlYXJsaWVyIGFycmF5LCBvciB0aGUgbmV3IG9uZSBkb2VzIG5vdCBiZWdpbiB3aXRoIGl0KSwgc28gZXZlcnkgZWxlbWVudCdzIGJpcnRoIHJlc2V0cyB0byB0aGlzIGNvbW1pdDogZXhhY3QsIGJ1dCBjb2Fyc2UuXCIsXG4gIC8vIOKUgOKUgCBob3cgYSBmb2xkIHdhcyBkZXJpdmVkIOKAlCBgRm9sZGVkU3RhdGUuYmFzaXNgICh0aW1lLXRyYXZlbC8pIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAnaW5pdGlhbCtsb2cnOlxuICAgICdUaGUgZm9sZCBzdGFydGVkIGZyb20gdGhlIGZvbGQgYmFzZSB0aGF0IHRyYXZlbGxlZCB3aXRoIHRoZSBsb2cgKGluaXRpYWxTdGF0ZSkgYW5kIHJlcGxheWVkIHRoZSBjb21taXQgbG9nIG9udG8gaXQsIHNvIG5vdGhpbmcgc2VlZGVkIGJlZm9yZSB0aGUgcnVuIGlzIG1pc3Npbmc7IHJvd3MgaXQgY291bGQgbm90IHJlYWQgYXJlIGxpc3RlZCBhcGFydCwgaW4gc2tpcHBlZC4nLFxuICAnbG9nLW9ubHknOlxuICAgICdObyBpbml0aWFsU3RhdGUgdHJhdmVsbGVkIHdpdGggdGhpcyBsb2cgKGEgc25hcHNob3Qgc3RvcmVkIGJlZm9yZSA5LjE3LCBhIHJlZGFjdGVkIHNuYXBzaG90IG9yIGEgaGFuZC1idWlsdCBsb2cpLCBzbyB0aGUgZm9sZCBzdGFydGVkIGZyb20gYW4gZW1wdHkgb2JqZWN0OiBhIGtleSBzZWVkZWQgYmVmb3JlIHRoZSBydW4gaXMgd2hvbGUgb25seSBvbmNlIGEgY29tbWl0IHNpbmNlIHdyb3RlIGl0cyB3aG9sZSB2YWx1ZSwgYW5kIHVudGlsIHRoZW4gaXQgaG9sZHMganVzdCB3aGF0IGl0cyBtZXJnZXMsIGFwcGVuZHMgYW5kIG5lc3RlZCB3cml0ZXMgYWRkZWQsIG9yIG5vdGhpbmcuJyxcbiAgLy8g4pSA4pSAIGEgcm93IG9mIGEgc3RvcmVkIGxvZyB0aGF0IGlzIG5vdCBhIGNvbW1pdCBidW5kbGUg4oCUIGBMb2dHYXBgIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAnbG9nLWdhcCc6XG4gICAgJ0Egcm93IG9mIHRoZSBzdG9yZWQgbG9nIGNvdWxkIG5vdCBiZSByZWFkIGFzIGEgY29tbWl0IGJ1bmRsZSwgc28gaXQga2VlcHMgaXRzIGluZGV4IGJ1dCBjb250cmlidXRlcyBubyBzdGF0ZSwgYW5kIGFueSBmb2xkIHRoYXQgY3Jvc3NlcyBpdCBpcyBtaXNzaW5nIHdoYXRldmVyIHRoYXQgcm93IHdyb3RlLicsXG4gIC8vIOKUgOKUgCB1bnRyYWNrZWQgcmVhZHMgYSBzdGFnZSBhbHNvIGNvbnN1bWVkIOKAlCBgQ2F1c2FsTm9kZS5pbmNvbXBsZXRlU291cmNlc2Ag4pSAXG4gICdpbmNvbXBsZXRlLXNvdXJjZXMnOlxuICAgICdUaGUgc3RhZ2UgYWxzbyBjb25zdW1lZCByZWFkIHBhdGhzIHRoYXQgYnlwYXNzIHJlYWQgdHJhY2tpbmcgKGFyZ3MsIGVudiBvciBhbiB1bnNoYWRvd2VkIHNpbGVudCByZWFkKSwgc28gYSBzbGljZSB0aHJvdWdoIGl0IG1heSBiZSBpbmNvbXBsZXRlOiB0aG9zZSByZWFkcyBwcm9kdWNlIG5vIHJlYWQtdG8td3JpdGUgZWRnZSB0byBmb2xsb3cuJyxcbiAgLy8g4pSA4pSAIHZhbHVlcyBzY3J1YmJlZCBhdCB3cml0ZSB0aW1lIOKAlCBgRm9sZGVkU3RhdGUucmVkYWN0ZWRgIC8gYHJlZGFjdGVkUGF0aHNgLCBhIHZhbHVlIGJhc2lzIOKUgFxuICByZWRhY3RlZDpcbiAgICBcIlZhbHVlcyBhdCB0aGUgcGF0aHMgbGlzdGVkIGluIHJlZGFjdGVkUGF0aHMgKGEgZm9sZCdzLCBvciBhIGNvbW1pdCdzIGluIHRoZSByYW5nZSBhIGtleSdzIHZhbHVlIHJlc3RzIG9uKSB3ZXJlIHNjcnViYmVkIHdoZW4gdGhleSB3ZXJlIHdyaXR0ZW4gKGJ5IGEgcmVkYWN0aW9uIHBvbGljeSwgb3IgYSB3cml0ZSBtYXJrZWQgcmVkYWN0ZWQpLCBzbyB3aGVyZSB0aGUgYW5zd2VyIGhvbGRzIHRoZSBsb2cncyBwbGFjZWhvbGRlciAnUkVEQUNURUQnLCBvciBsb3N0IGEga2V5IHVuZGVyIGEgY29udGFpbmVyIHRoZSBwbGFjZWhvbGRlciByZXBsYWNlZCwgaXQgc3RhbmRzIGluIGZvciBhIHZhbHVlIHRoZSBsb2cgbmV2ZXIgcmVjb3JkZWQuXCIsXG4gIC8vIOKUgOKUgCBob3cgb25lIGtleSdzIHZhbHVlIHdhcyByZWFkIG9mZiB0aGUgbG9nIOKAlCBgVmFsdWVCYXNpc2AgKGNvbW1pdFZhbHVlQXRXaXRoQmFzaXMpIOKUgFxuICBkZWxldGVkOlxuICAgIFwiVGhlIGtleSdzIGxhc3Qgd3JpdGUgaW4gdGhlIHJhbmdlIGFza2VkIGFib3V0IGxlZnQgaXQgYWJzZW50IChhIGRlbGV0ZSBvZiB0aGUga2V5IG9yIG9mIGEgY29udGFpbmVyIGFyb3VuZCBpdCwgb3IgYSBzZXQgb2YgYSBjb250YWluZXIgdGhhdCBubyBsb25nZXIgaG9sZHMgaXQpLCBzbyB0aGUgYW5zd2VyIGlzIHVuZGVmaW5lZCBiZWNhdXNlIHRoZSByZWNvcmQgc2F5cyB0aGUga2V5IHdhcyBnb25lIGF0IHRoYXQgcG9pbnQsIG5vdCBiZWNhdXNlIG5vdGhpbmcgd2FzIHJlY29yZGVkLlwiLFxuICAnZnJvbS1pbml0aWFsLXN0YXRlJzpcbiAgICBcIk5vIHNldCBvciBkZWxldGUgb2YgdGhlIGtleSwgb3Igb2YgYSBjb250YWluZXIgYXJvdW5kIGl0LCBpcyBpbiB0aGUgcmFuZ2UgYXNrZWQgYWJvdXQsIHNvIHRoZSBhbnN3ZXIgcmVzdHMgb24gdGhlIHZhbHVlIHRoZSBrZXkgaGFkIGJlZm9yZSB0aGUgcnVuOiBmb2xkZWQgZnJvbSB0aGUgaW5pdGlhbFN0YXRlIHBhc3NlZCBpbiB3aGVuIHRoZXJlIHdhcyBvbmUsIGFuZCBvdGhlcndpc2Ugb25seSB3aGF0IHRoZSBsb2cncyBtZXJnZXMsIGFwcGVuZHMgYW5kIG5lc3RlZCB3cml0ZXMgYWRkZWQgdG8gaXQgKG9yIG5vdGhpbmcpLCB3aGljaCBpcyBwYXJ0aWFsIGZvciBhIGtleSBzZWVkZWQgYmVmb3JlIHRoZSBydW4uXCIsXG59IHNhdGlzZmllcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KTtcblxuLyoqIEFueSBjb2RlIGluIHtAbGluayBIT05FU1RZX0NPREVTfSDigJQgdGhlIGtleSBhIHJlYWRlciBsb29rcyBhbiBleHBsYW5hdGlvbiB1cCBieS4gKi9cbmV4cG9ydCB0eXBlIEhvbmVzdHlDb2RlID0ga2V5b2YgdHlwZW9mIEhPTkVTVFlfQ09ERVM7XG5cbi8qKlxuICogQSB1bmlvbiBvZiBob25lc3R5IGNvZGVzIGEgdHlwZSBERUNMQVJFUzogYFRgIG11c3QgYmUgYSBzdWJzZXQgb2Yge0BsaW5rIEhvbmVzdHlDb2RlfSwgb3IgdGhlXG4gKiBkZWNsYXJhdGlvbiBmYWlscyB0byBjb21waWxlIChUUzIzNDQpLlxuICpcbiAqIGBSZWdpc3RlcmVkQ29kZTxUPmAgaXMgYFRgIOKAlCBhbiBpZGVudGl0eSBhdCB0aGUgdHlwZSBsZXZlbCDigJQgc28gdGhlIHVuaW9uIGtlZXBzIGV4YWN0bHkgdGhlXG4gKiBtZW1iZXJzIGl0IHdhcyB3cml0dGVuIHdpdGggYW5kIGRvZXMgTk9UIHdpZGVuIHRvIGV2ZXJ5IGNvZGU6XG4gKiBgdHlwZSBGb2xkQmFzaXMgPSBSZWdpc3RlcmVkQ29kZTwnaW5pdGlhbCtsb2cnIHwgJ2xvZy1vbmx5Jz5gLlxuICovXG5leHBvcnQgdHlwZSBSZWdpc3RlcmVkQ29kZTxUIGV4dGVuZHMgSG9uZXN0eUNvZGU+ID0gVDtcbiJdfQ==
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* keyPaths.ts — which rows of a commit log touch a state key. ONE answer (F3, 9.33.0).
|
|
3
|
-
*
|
|
4
|
-
* WHY THIS FILE EXISTS. A key query (`commitValueAt`, `findLastWriter`, `causalChain`, the slice
|
|
5
|
-
* layer) asks "which rows wrote `key`?". Each reader used to answer with its own `row.path === key`,
|
|
6
|
-
* so a row written INSIDE the key — `cfg␟b`, which every subflow seed of an object, every
|
|
7
|
-
* outputMapper merge-back and every fork child's namespace produces — was invisible to all of
|
|
8
|
-
* them, while the fold (`stateAt`, the live commit) applied it. The fold said `{a:1,b:2}`; the key
|
|
9
|
-
* queries said "never written". Every reader now asks here.
|
|
10
|
-
*
|
|
11
|
-
* THE PATH HALF (this file, L0 — it imports only the path codec and types):
|
|
12
|
-
* - {@link relation} — how a row's path sits against a key's path. A segment prefix on the
|
|
13
|
-
* DELIM-joined path, the way RFC 6901 prefixes a JSON Pointer: `cfg` is a prefix of `cfg␟a`,
|
|
14
|
-
* never of `cfgX`. A row is `'exact'` (on the key), `'inside'` (below it — it wrote part of the
|
|
15
|
-
* key's value) or `'around'` (above it — it wrote a container that holds the key).
|
|
16
|
-
* - {@link buildWriterIndex} / {@link writerCandidates} — one pass over a log, then the rows that
|
|
17
|
-
* can have written a key, found through its top-level key instead of a scan.
|
|
18
|
-
*
|
|
19
|
-
* THE RULES (defined here; the fold is L1 and the log readers L3, so `commitLogUtils.ts` applies
|
|
20
|
-
* them — `writersOf`, `findLastWriter`, `commitValueAt`):
|
|
21
|
-
* - THE WRITER RULE — commit `c` WRITES key `K` iff `c` has a row `'exact'` or `'inside'` `K`,
|
|
22
|
-
* or a row `'around'` `K` across which the value at `K` differs (compared over the whole commit,
|
|
23
|
-
* not row by row: a value that changes and changes back inside one commit was not written).
|
|
24
|
-
* A top-level key has no `'around'` rows, so for it the rule is the path check alone.
|
|
25
|
-
* Why not every `'around'` row: `$update('cfg', { list: [3] })` is a `merge` row on `cfg`, but
|
|
26
|
-
* it never reaches `cfg␟a` — counting it named the wrong writer of `cfg␟a`.
|
|
27
|
-
* - THE VALUE RULE — the value of `K` at commit `i` is the fold of EVERY row under `K`'s top-level
|
|
28
|
-
* key up to `i`, anchored at that key's last `set`/`delete`, read at `K`: the fold `stateAt`
|
|
29
|
-
* does, restricted to one top-level key. Top-level keys never interact under the step, so the
|
|
30
|
-
* restriction is exact. Folding only the rows that touch `K` is NOT: an array union
|
|
31
|
-
* (`deepSmartMerge`) dedups the whole array, so a sibling element written beside `a␟1` changes
|
|
32
|
-
* where a later merge on `a` leaves `a[1]`.
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* ```typescript
|
|
36
|
-
* relation('cfg\u001Fb', 'cfg'); // 'inside' — the row wrote part of cfg
|
|
37
|
-
* relation('cfg', 'cfg\u001Fa'); // 'around' — the row wrote the container cfg.a lives in
|
|
38
|
-
* relation('cfgX', 'cfg'); // undefined — a different key, not a prefix match
|
|
39
|
-
* ```
|
|
40
|
-
*/
|
|
41
|
-
import type { CommitBundle } from './types.js';
|
|
42
|
-
/**
|
|
43
|
-
* The WORK every key query has done — rows indexed and scanned, fold steps, around-verdicts, trie and
|
|
44
|
-
* ancestor steps, binary searches, a causal walk's own loops — summed across calls. A deterministic cost
|
|
45
|
-
* measure: `test/lib/memory/boundary/key-query-scaling.test.ts` asserts a causal walk's work grows linearly
|
|
46
|
-
* in the log by COUNTING it (a wall-clock ratio failed on a busy machine). Never read by the library; one
|
|
47
|
-
* integer add per unit of work it already does. Here, at L0, so every layer that does that work can count it.
|
|
48
|
-
*/
|
|
49
|
-
export declare const queryWork: {
|
|
50
|
-
units: number;
|
|
51
|
-
};
|
|
52
|
-
/** How a row's path sits against a key's path. `undefined` from {@link relation} means disjoint. */
|
|
53
|
-
export type PathRelation = 'exact' | 'inside' | 'around';
|
|
54
|
-
/**
|
|
55
|
-
* How the row path `rowPath` sits against the key `key` — both DELIM-joined `TraceEntry.path`
|
|
56
|
-
* strings (a top-level key is a one-segment path). `'exact'` when they are equal, `'inside'` when
|
|
57
|
-
* the row is below the key, `'around'` when the row is above it, `undefined` when neither is a
|
|
58
|
-
* segment prefix of the other.
|
|
59
|
-
*/
|
|
60
|
-
export declare function relation(rowPath: string, key: string): PathRelation | undefined;
|
|
61
|
-
/** The top-level key a DELIM-joined path belongs to — its first segment. */
|
|
62
|
-
export declare function rootOf(path: string): string;
|
|
63
|
-
/**
|
|
64
|
-
* One written path in a {@link WriterIndex} — a node of the path TRIE built over a log. A node exists for
|
|
65
|
-
* every written path and every prefix of one.
|
|
66
|
-
*/
|
|
67
|
-
export interface PathNode {
|
|
68
|
-
/** The DELIM-joined path this node stands for. */
|
|
69
|
-
readonly path: string;
|
|
70
|
-
/** ARRAY positions of the commits with a row exactly on this path — ascending, one per commit. */
|
|
71
|
-
readonly positions: number[];
|
|
72
|
-
/** The subset of {@link positions} whose row here is a `set` or a `delete` (it decides the value alone). */
|
|
73
|
-
readonly totals: number[];
|
|
74
|
-
/** Positions of commits whose row with a non-`delete` verb sits on this path (the rest are deletes only). */
|
|
75
|
-
readonly writes: number[];
|
|
76
|
-
/** The next segment → its node. */
|
|
77
|
-
readonly children: Map<string, PathNode>;
|
|
78
|
-
/** Memo of {@link subtreePositions}. */
|
|
79
|
-
subtree?: readonly number[];
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* The positions in a log where each written path was written: a path trie per top-level key. Built in ONE
|
|
83
|
-
* pass (`O(total path segments)`); a key's candidates then cost `O(depth + matches)` — its node, its
|
|
84
|
-
* ancestors, its subtree — never a scan of every path under its top-level key.
|
|
85
|
-
*/
|
|
86
|
-
export interface WriterIndex {
|
|
87
|
-
/** Every top-level key → the root of its trie. */
|
|
88
|
-
readonly roots: ReadonlyMap<string, PathNode>;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* One pass over `commitLog`: the path trie of every written path. Build it ONCE when a reader asks about
|
|
92
|
-
* many keys (a causal walk, a forward slice) — or let `commitLogUtils · logModel` memoise it for a frozen log.
|
|
93
|
-
*/
|
|
94
|
-
export declare function buildWriterIndex(commitLog: readonly CommitBundle[]): WriterIndex;
|
|
95
|
-
/** Every path a row was written on, in trie order. */
|
|
96
|
-
export declare function pathsWritten(index: WriterIndex): string[];
|
|
97
|
-
/** The node for `key`, or undefined when no row was written on it or below it. */
|
|
98
|
-
export declare function nodeAt(index: WriterIndex, key: string): PathNode | undefined;
|
|
99
|
-
/** The nodes of `key`'s PROPER ancestors that exist in the index, top-level key first. */
|
|
100
|
-
export declare function ancestorNodes(index: WriterIndex, key: string): PathNode[];
|
|
101
|
-
/** Every commit with a row on `node`'s path or below it — ascending, memoised on the node. */
|
|
102
|
-
export declare function subtreePositions(node: PathNode): readonly number[];
|
|
103
|
-
/** The first index in an ascending list holding a value >= `value`. */
|
|
104
|
-
export declare function lowerBound(sorted: readonly number[], value: number): number;
|
|
105
|
-
/** The last value in an ascending list that is < `before`, or -1. */
|
|
106
|
-
export declare function lastBefore(sorted: readonly number[], before: number): number;
|
|
107
|
-
/** The values of an ascending list in the OPEN range (`after`, `before`). */
|
|
108
|
-
export declare function between(sorted: readonly number[], after: number, before: number): readonly number[];
|
|
109
|
-
/** The commits that can have written a key, split by what the writer rule still has to ask. */
|
|
110
|
-
export interface WriterCandidates {
|
|
111
|
-
/** Commits with a row `'exact'` or `'inside'` the key — writers by the path alone. Ascending. */
|
|
112
|
-
readonly atOrInside: readonly number[];
|
|
113
|
-
/** Commits with a row `'around'` the key and none at or inside it — writers only if the value at the key changed. Ascending. */
|
|
114
|
-
readonly aroundOnly: readonly number[];
|
|
115
|
-
}
|
|
116
|
-
/** The path half of the writer rule over an index: every commit that can have written `key`. `O(depth + matches)`. */
|
|
117
|
-
export declare function writerCandidates(index: WriterIndex, key: string): WriterCandidates;
|
|
118
|
-
/** The ascending, de-duplicated union of ascending position lists. */
|
|
119
|
-
export declare function ascendingUnion(lists: readonly (readonly number[])[]): number[];
|
|
120
|
-
/**
|
|
121
|
-
* Did this commit reach `key` ONLY through rows inside it — at least one row `'inside'` the key, and no
|
|
122
|
-
* row on it or around it? Such a write changed part of the key's value, not the whole: the one test
|
|
123
|
-
* behind every `'nested-rows'` code (a slice note, a causal edge's `basis`, `findLastWriterWithBasis`).
|
|
124
|
-
*/
|
|
125
|
-
export declare function writesOnlyInside(bundle: CommitBundle, key: string): boolean;
|
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* keyPaths.ts — which rows of a commit log touch a state key. ONE answer (F3, 9.33.0).
|
|
3
|
-
*
|
|
4
|
-
* WHY THIS FILE EXISTS. A key query (`commitValueAt`, `findLastWriter`, `causalChain`, the slice
|
|
5
|
-
* layer) asks "which rows wrote `key`?". Each reader used to answer with its own `row.path === key`,
|
|
6
|
-
* so a row written INSIDE the key — `cfg␟b`, which every subflow seed of an object, every
|
|
7
|
-
* outputMapper merge-back and every fork child's namespace produces — was invisible to all of
|
|
8
|
-
* them, while the fold (`stateAt`, the live commit) applied it. The fold said `{a:1,b:2}`; the key
|
|
9
|
-
* queries said "never written". Every reader now asks here.
|
|
10
|
-
*
|
|
11
|
-
* THE PATH HALF (this file, L0 — it imports only the path codec and types):
|
|
12
|
-
* - {@link relation} — how a row's path sits against a key's path. A segment prefix on the
|
|
13
|
-
* DELIM-joined path, the way RFC 6901 prefixes a JSON Pointer: `cfg` is a prefix of `cfg␟a`,
|
|
14
|
-
* never of `cfgX`. A row is `'exact'` (on the key), `'inside'` (below it — it wrote part of the
|
|
15
|
-
* key's value) or `'around'` (above it — it wrote a container that holds the key).
|
|
16
|
-
* - {@link buildWriterIndex} / {@link writerCandidates} — one pass over a log, then the rows that
|
|
17
|
-
* can have written a key, found through its top-level key instead of a scan.
|
|
18
|
-
*
|
|
19
|
-
* THE RULES (defined here; the fold is L1 and the log readers L3, so `commitLogUtils.ts` applies
|
|
20
|
-
* them — `writersOf`, `findLastWriter`, `commitValueAt`):
|
|
21
|
-
* - THE WRITER RULE — commit `c` WRITES key `K` iff `c` has a row `'exact'` or `'inside'` `K`,
|
|
22
|
-
* or a row `'around'` `K` across which the value at `K` differs (compared over the whole commit,
|
|
23
|
-
* not row by row: a value that changes and changes back inside one commit was not written).
|
|
24
|
-
* A top-level key has no `'around'` rows, so for it the rule is the path check alone.
|
|
25
|
-
* Why not every `'around'` row: `$update('cfg', { list: [3] })` is a `merge` row on `cfg`, but
|
|
26
|
-
* it never reaches `cfg␟a` — counting it named the wrong writer of `cfg␟a`.
|
|
27
|
-
* - THE VALUE RULE — the value of `K` at commit `i` is the fold of EVERY row under `K`'s top-level
|
|
28
|
-
* key up to `i`, anchored at that key's last `set`/`delete`, read at `K`: the fold `stateAt`
|
|
29
|
-
* does, restricted to one top-level key. Top-level keys never interact under the step, so the
|
|
30
|
-
* restriction is exact. Folding only the rows that touch `K` is NOT: an array union
|
|
31
|
-
* (`deepSmartMerge`) dedups the whole array, so a sibling element written beside `a␟1` changes
|
|
32
|
-
* where a later merge on `a` leaves `a[1]`.
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* ```typescript
|
|
36
|
-
* relation('cfg\u001Fb', 'cfg'); // 'inside' — the row wrote part of cfg
|
|
37
|
-
* relation('cfg', 'cfg\u001Fa'); // 'around' — the row wrote the container cfg.a lives in
|
|
38
|
-
* relation('cfgX', 'cfg'); // undefined — a different key, not a prefix match
|
|
39
|
-
* ```
|
|
40
|
-
*/
|
|
41
|
-
import { DELIM } from './paths.js';
|
|
42
|
-
/**
|
|
43
|
-
* The WORK every key query has done — rows indexed and scanned, fold steps, around-verdicts, trie and
|
|
44
|
-
* ancestor steps, binary searches, a causal walk's own loops — summed across calls. A deterministic cost
|
|
45
|
-
* measure: `test/lib/memory/boundary/key-query-scaling.test.ts` asserts a causal walk's work grows linearly
|
|
46
|
-
* in the log by COUNTING it (a wall-clock ratio failed on a busy machine). Never read by the library; one
|
|
47
|
-
* integer add per unit of work it already does. Here, at L0, so every layer that does that work can count it.
|
|
48
|
-
*/
|
|
49
|
-
export const queryWork = { units: 0 };
|
|
50
|
-
const DELIM_CODE = DELIM.charCodeAt(0);
|
|
51
|
-
/**
|
|
52
|
-
* How the row path `rowPath` sits against the key `key` — both DELIM-joined `TraceEntry.path`
|
|
53
|
-
* strings (a top-level key is a one-segment path). `'exact'` when they are equal, `'inside'` when
|
|
54
|
-
* the row is below the key, `'around'` when the row is above it, `undefined` when neither is a
|
|
55
|
-
* segment prefix of the other.
|
|
56
|
-
*/
|
|
57
|
-
export function relation(rowPath, key) {
|
|
58
|
-
if (rowPath === key)
|
|
59
|
-
return 'exact';
|
|
60
|
-
if (rowPath.length > key.length) {
|
|
61
|
-
return rowPath.charCodeAt(key.length) === DELIM_CODE && rowPath.startsWith(key) ? 'inside' : undefined;
|
|
62
|
-
}
|
|
63
|
-
return key.charCodeAt(rowPath.length) === DELIM_CODE && key.startsWith(rowPath) ? 'around' : undefined;
|
|
64
|
-
}
|
|
65
|
-
/** The top-level key a DELIM-joined path belongs to — its first segment. */
|
|
66
|
-
export function rootOf(path) {
|
|
67
|
-
const cut = path.indexOf(DELIM);
|
|
68
|
-
return cut === -1 ? path : path.slice(0, cut);
|
|
69
|
-
}
|
|
70
|
-
function nodeOf(path) {
|
|
71
|
-
return { path, positions: [], totals: [], writes: [], children: new Map() };
|
|
72
|
-
}
|
|
73
|
-
/** Append `i` to an ascending list unless it is already its last element. */
|
|
74
|
-
function pushOnce(list, i) {
|
|
75
|
-
if (list[list.length - 1] !== i)
|
|
76
|
-
list.push(i);
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* One pass over `commitLog`: the path trie of every written path. Build it ONCE when a reader asks about
|
|
80
|
-
* many keys (a causal walk, a forward slice) — or let `commitLogUtils · logModel` memoise it for a frozen log.
|
|
81
|
-
*/
|
|
82
|
-
export function buildWriterIndex(commitLog) {
|
|
83
|
-
const roots = new Map();
|
|
84
|
-
for (let i = 0; i < commitLog.length; i++) {
|
|
85
|
-
const trace = commitLog[i].trace;
|
|
86
|
-
for (let row = 0; row < trace.length; row++) {
|
|
87
|
-
const { path, verb } = trace[row];
|
|
88
|
-
const segs = path.split(DELIM);
|
|
89
|
-
let node = roots.get(segs[0]);
|
|
90
|
-
if (node === undefined) {
|
|
91
|
-
node = nodeOf(segs[0]);
|
|
92
|
-
roots.set(segs[0], node);
|
|
93
|
-
}
|
|
94
|
-
for (let s = 1; s < segs.length; s++) {
|
|
95
|
-
let child = node.children.get(segs[s]);
|
|
96
|
-
if (child === undefined) {
|
|
97
|
-
child = nodeOf(node.path + DELIM + segs[s]);
|
|
98
|
-
node.children.set(segs[s], child);
|
|
99
|
-
}
|
|
100
|
-
node = child;
|
|
101
|
-
}
|
|
102
|
-
pushOnce(node.positions, i);
|
|
103
|
-
if (verb === 'set' || verb === 'delete')
|
|
104
|
-
pushOnce(node.totals, i);
|
|
105
|
-
if (verb !== 'delete')
|
|
106
|
-
pushOnce(node.writes, i);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return { roots };
|
|
110
|
-
}
|
|
111
|
-
/** Every path a row was written on, in trie order. */
|
|
112
|
-
export function pathsWritten(index) {
|
|
113
|
-
const out = [];
|
|
114
|
-
const stack = [...index.roots.values()];
|
|
115
|
-
while (stack.length > 0) {
|
|
116
|
-
const node = stack.pop();
|
|
117
|
-
if (node.positions.length > 0)
|
|
118
|
-
out.push(node.path);
|
|
119
|
-
for (const child of node.children.values())
|
|
120
|
-
stack.push(child);
|
|
121
|
-
}
|
|
122
|
-
return out;
|
|
123
|
-
}
|
|
124
|
-
/** The node for `key`, or undefined when no row was written on it or below it. */
|
|
125
|
-
export function nodeAt(index, key) {
|
|
126
|
-
const segs = key.split(DELIM);
|
|
127
|
-
queryWork.units += segs.length;
|
|
128
|
-
let node = index.roots.get(segs[0]);
|
|
129
|
-
for (let s = 1; node !== undefined && s < segs.length; s++)
|
|
130
|
-
node = node.children.get(segs[s]);
|
|
131
|
-
return node;
|
|
132
|
-
}
|
|
133
|
-
/** The nodes of `key`'s PROPER ancestors that exist in the index, top-level key first. */
|
|
134
|
-
export function ancestorNodes(index, key) {
|
|
135
|
-
const segs = key.split(DELIM);
|
|
136
|
-
const out = [];
|
|
137
|
-
queryWork.units += segs.length;
|
|
138
|
-
let node = index.roots.get(segs[0]);
|
|
139
|
-
for (let s = 1; node !== undefined && s < segs.length; s++) {
|
|
140
|
-
out.push(node);
|
|
141
|
-
node = node.children.get(segs[s]);
|
|
142
|
-
}
|
|
143
|
-
return out;
|
|
144
|
-
}
|
|
145
|
-
/** Every commit with a row on `node`'s path or below it — ascending, memoised on the node. */
|
|
146
|
-
export function subtreePositions(node) {
|
|
147
|
-
queryWork.units += 1;
|
|
148
|
-
if (node.subtree === undefined) {
|
|
149
|
-
if (node.children.size === 0)
|
|
150
|
-
node.subtree = node.positions;
|
|
151
|
-
else {
|
|
152
|
-
const lists = [node.positions];
|
|
153
|
-
for (const child of node.children.values())
|
|
154
|
-
lists.push(subtreePositions(child));
|
|
155
|
-
node.subtree = ascendingUnion(lists);
|
|
156
|
-
queryWork.units += node.subtree.length;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return node.subtree;
|
|
160
|
-
}
|
|
161
|
-
/** The first index in an ascending list holding a value >= `value`. */
|
|
162
|
-
export function lowerBound(sorted, value) {
|
|
163
|
-
queryWork.units += 1;
|
|
164
|
-
let lo = 0;
|
|
165
|
-
let hi = sorted.length;
|
|
166
|
-
while (lo < hi) {
|
|
167
|
-
const mid = (lo + hi) >>> 1;
|
|
168
|
-
if (sorted[mid] < value)
|
|
169
|
-
lo = mid + 1;
|
|
170
|
-
else
|
|
171
|
-
hi = mid;
|
|
172
|
-
}
|
|
173
|
-
return lo;
|
|
174
|
-
}
|
|
175
|
-
/** The last value in an ascending list that is < `before`, or -1. */
|
|
176
|
-
export function lastBefore(sorted, before) {
|
|
177
|
-
const at = lowerBound(sorted, before);
|
|
178
|
-
return at > 0 ? sorted[at - 1] : -1;
|
|
179
|
-
}
|
|
180
|
-
/** The values of an ascending list in the OPEN range (`after`, `before`). */
|
|
181
|
-
export function between(sorted, after, before) {
|
|
182
|
-
const out = sorted.slice(lowerBound(sorted, after + 1), lowerBound(sorted, before));
|
|
183
|
-
queryWork.units += out.length;
|
|
184
|
-
return out;
|
|
185
|
-
}
|
|
186
|
-
/** The path half of the writer rule over an index: every commit that can have written `key`. `O(depth + matches)`. */
|
|
187
|
-
export function writerCandidates(index, key) {
|
|
188
|
-
const node = nodeAt(index, key);
|
|
189
|
-
const written = node === undefined ? [] : subtreePositions(node);
|
|
190
|
-
const ancestors = ancestorNodes(index, key);
|
|
191
|
-
if (ancestors.length === 0)
|
|
192
|
-
return { atOrInside: written, aroundOnly: [] };
|
|
193
|
-
const already = new Set(written);
|
|
194
|
-
return {
|
|
195
|
-
atOrInside: written,
|
|
196
|
-
aroundOnly: ascendingUnion(ancestors.map((a) => a.positions)).filter((i) => !already.has(i)),
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
/** The ascending, de-duplicated union of ascending position lists. */
|
|
200
|
-
export function ascendingUnion(lists) {
|
|
201
|
-
if (lists.length === 0)
|
|
202
|
-
return [];
|
|
203
|
-
if (lists.length === 1)
|
|
204
|
-
return [...lists[0]];
|
|
205
|
-
const all = new Set();
|
|
206
|
-
for (const list of lists)
|
|
207
|
-
for (const i of list)
|
|
208
|
-
all.add(i);
|
|
209
|
-
return [...all].sort((a, b) => a - b);
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Did this commit reach `key` ONLY through rows inside it — at least one row `'inside'` the key, and no
|
|
213
|
-
* row on it or around it? Such a write changed part of the key's value, not the whole: the one test
|
|
214
|
-
* behind every `'nested-rows'` code (a slice note, a causal edge's `basis`, `findLastWriterWithBasis`).
|
|
215
|
-
*/
|
|
216
|
-
export function writesOnlyInside(bundle, key) {
|
|
217
|
-
let inside = false;
|
|
218
|
-
for (const t of bundle.trace) {
|
|
219
|
-
const r = relation(t.path, key);
|
|
220
|
-
if (r === 'exact' || r === 'around')
|
|
221
|
-
return false;
|
|
222
|
-
if (r === 'inside')
|
|
223
|
-
inside = true;
|
|
224
|
-
}
|
|
225
|
-
return inside;
|
|
226
|
-
}
|
|
227
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5UGF0aHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL21lbW9yeS9rZXlQYXRocy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdUNHO0FBRUgsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQztBQUduQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUM7QUFLdEMsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUV2Qzs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQUMsT0FBZSxFQUFFLEdBQVc7SUFDbkQsSUFBSSxPQUFPLEtBQUssR0FBRztRQUFFLE9BQU8sT0FBTyxDQUFDO0lBQ3BDLElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDaEMsT0FBTyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxVQUFVLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDekcsQ0FBQztJQUNELE9BQU8sR0FBRyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssVUFBVSxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ3pHLENBQUM7QUFFRCw0RUFBNEU7QUFDNUUsTUFBTSxVQUFVLE1BQU0sQ0FBQyxJQUFZO0lBQ2pDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEMsT0FBTyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDaEQsQ0FBQztBQStCRCxTQUFTLE1BQU0sQ0FBQyxJQUFZO0lBQzFCLE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksR0FBRyxFQUFFLEVBQUUsQ0FBQztBQUM5RSxDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLFNBQVMsUUFBUSxDQUFDLElBQWMsRUFBRSxDQUFTO0lBQ3pDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEQsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxTQUFrQztJQUNqRSxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsRUFBb0IsQ0FBQztJQUMxQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQzFDLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7UUFDakMsS0FBSyxJQUFJLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQztZQUM1QyxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNsQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQy9CLElBQUksSUFBSSxHQUF5QixLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3BELElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUN2QixJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN2QixLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUMzQixDQUFDO1lBQ0QsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDckMsSUFBSSxLQUFLLEdBQXlCLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM3RCxJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDeEIsS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDNUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUNwQyxDQUFDO2dCQUNELElBQUksR0FBRyxLQUFLLENBQUM7WUFDZixDQUFDO1lBQ0QsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDNUIsSUFBSSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxRQUFRO2dCQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ2xFLElBQUksSUFBSSxLQUFLLFFBQVE7Z0JBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDbEQsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7QUFDbkIsQ0FBQztBQUVELHNEQUFzRDtBQUN0RCxNQUFNLFVBQVUsWUFBWSxDQUFDLEtBQWtCO0lBQzdDLE1BQU0sR0FBRyxHQUFhLEVBQUUsQ0FBQztJQUN6QixNQUFNLEtBQUssR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ3hDLE9BQU8sS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN4QixNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsR0FBRyxFQUFjLENBQUM7UUFDckMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDO1lBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbkQsS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRTtZQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUNELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVELGtGQUFrRjtBQUNsRixNQUFNLFVBQVUsTUFBTSxDQUFDLEtBQWtCLEVBQUUsR0FBVztJQUNwRCxNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlCLFNBQVMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUMvQixJQUFJLElBQUksR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLEtBQUssU0FBUyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRTtRQUFFLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5RixPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRCwwRkFBMEY7QUFDMUYsTUFBTSxVQUFVLGFBQWEsQ0FBQyxLQUFrQixFQUFFLEdBQVc7SUFDM0QsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QixNQUFNLEdBQUcsR0FBZSxFQUFFLENBQUM7SUFDM0IsU0FBUyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQy9CLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksS0FBSyxTQUFTLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUMzRCxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2YsSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFFRCw4RkFBOEY7QUFDOUYsTUFBTSxVQUFVLGdCQUFnQixDQUFDLElBQWM7SUFDN0MsU0FBUyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUM7SUFDckIsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQy9CLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssQ0FBQztZQUFFLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQzthQUN2RCxDQUFDO1lBQ0osTUFBTSxLQUFLLEdBQTBCLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3RELEtBQUssTUFBTSxLQUFLLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUU7Z0JBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQ2hGLElBQUksQ0FBQyxPQUFPLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLFNBQVMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDekMsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7QUFDdEIsQ0FBQztBQUVELHVFQUF1RTtBQUN2RSxNQUFNLFVBQVUsVUFBVSxDQUFDLE1BQXlCLEVBQUUsS0FBYTtJQUNqRSxTQUFTLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQztJQUNyQixJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDWCxJQUFJLEVBQUUsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3ZCLE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDO1FBQ2YsTUFBTSxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzVCLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUs7WUFBRSxFQUFFLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQzs7WUFDakMsRUFBRSxHQUFHLEdBQUcsQ0FBQztJQUNoQixDQUFDO0lBQ0QsT0FBTyxFQUFFLENBQUM7QUFDWixDQUFDO0FBRUQscUVBQXFFO0FBQ3JFLE1BQU0sVUFBVSxVQUFVLENBQUMsTUFBeUIsRUFBRSxNQUFjO0lBQ2xFLE1BQU0sRUFBRSxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDdEMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0QyxDQUFDO0FBRUQsNkVBQTZFO0FBQzdFLE1BQU0sVUFBVSxPQUFPLENBQUMsTUFBeUIsRUFBRSxLQUFhLEVBQUUsTUFBYztJQUM5RSxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxHQUFHLENBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNwRixTQUFTLENBQUMsS0FBSyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUM7SUFDOUIsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBVUQsc0hBQXNIO0FBQ3RILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxLQUFrQixFQUFFLEdBQVc7SUFDOUQsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2pFLE1BQU0sU0FBUyxHQUFHLGFBQWEsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDNUMsSUFBSSxTQUFTLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFDM0UsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDakMsT0FBTztRQUNMLFVBQVUsRUFBRSxPQUFPO1FBQ25CLFVBQVUsRUFBRSxjQUFjLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7S0FDN0YsQ0FBQztBQUNKLENBQUM7QUFFRCxzRUFBc0U7QUFDdEUsTUFBTSxVQUFVLGNBQWMsQ0FBQyxLQUFxQztJQUNsRSxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ2xDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDN0MsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUM5QixLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUs7UUFBRSxLQUFLLE1BQU0sQ0FBQyxJQUFJLElBQUk7WUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzNELE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN4QyxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxNQUFvQixFQUFFLEdBQVc7SUFDaEUsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ25CLEtBQUssTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzdCLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxLQUFLLE9BQU8sSUFBSSxDQUFDLEtBQUssUUFBUTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ2xELElBQUksQ0FBQyxLQUFLLFFBQVE7WUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBQ3BDLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBrZXlQYXRocy50cyDigJQgd2hpY2ggcm93cyBvZiBhIGNvbW1pdCBsb2cgdG91Y2ggYSBzdGF0ZSBrZXkuIE9ORSBhbnN3ZXIgKEYzLCA5LjMzLjApLlxuICpcbiAqIFdIWSBUSElTIEZJTEUgRVhJU1RTLiBBIGtleSBxdWVyeSAoYGNvbW1pdFZhbHVlQXRgLCBgZmluZExhc3RXcml0ZXJgLCBgY2F1c2FsQ2hhaW5gLCB0aGUgc2xpY2VcbiAqIGxheWVyKSBhc2tzIFwid2hpY2ggcm93cyB3cm90ZSBga2V5YD9cIi4gRWFjaCByZWFkZXIgdXNlZCB0byBhbnN3ZXIgd2l0aCBpdHMgb3duIGByb3cucGF0aCA9PT0ga2V5YCxcbiAqIHNvIGEgcm93IHdyaXR0ZW4gSU5TSURFIHRoZSBrZXkg4oCUIGBjZmfikJ9iYCwgd2hpY2ggZXZlcnkgc3ViZmxvdyBzZWVkIG9mIGFuIG9iamVjdCwgZXZlcnlcbiAqIG91dHB1dE1hcHBlciBtZXJnZS1iYWNrIGFuZCBldmVyeSBmb3JrIGNoaWxkJ3MgbmFtZXNwYWNlIHByb2R1Y2VzIOKAlCB3YXMgaW52aXNpYmxlIHRvIGFsbCBvZlxuICogdGhlbSwgd2hpbGUgdGhlIGZvbGQgKGBzdGF0ZUF0YCwgdGhlIGxpdmUgY29tbWl0KSBhcHBsaWVkIGl0LiBUaGUgZm9sZCBzYWlkIGB7YToxLGI6Mn1gOyB0aGUga2V5XG4gKiBxdWVyaWVzIHNhaWQgXCJuZXZlciB3cml0dGVuXCIuIEV2ZXJ5IHJlYWRlciBub3cgYXNrcyBoZXJlLlxuICpcbiAqIFRIRSBQQVRIIEhBTEYgKHRoaXMgZmlsZSwgTDAg4oCUIGl0IGltcG9ydHMgb25seSB0aGUgcGF0aCBjb2RlYyBhbmQgdHlwZXMpOlxuICogICAtIHtAbGluayByZWxhdGlvbn0g4oCUIGhvdyBhIHJvdydzIHBhdGggc2l0cyBhZ2FpbnN0IGEga2V5J3MgcGF0aC4gQSBzZWdtZW50IHByZWZpeCBvbiB0aGVcbiAqICAgICBERUxJTS1qb2luZWQgcGF0aCwgdGhlIHdheSBSRkMgNjkwMSBwcmVmaXhlcyBhIEpTT04gUG9pbnRlcjogYGNmZ2AgaXMgYSBwcmVmaXggb2YgYGNmZ+KQn2FgLFxuICogICAgIG5ldmVyIG9mIGBjZmdYYC4gQSByb3cgaXMgYCdleGFjdCdgIChvbiB0aGUga2V5KSwgYCdpbnNpZGUnYCAoYmVsb3cgaXQg4oCUIGl0IHdyb3RlIHBhcnQgb2YgdGhlXG4gKiAgICAga2V5J3MgdmFsdWUpIG9yIGAnYXJvdW5kJ2AgKGFib3ZlIGl0IOKAlCBpdCB3cm90ZSBhIGNvbnRhaW5lciB0aGF0IGhvbGRzIHRoZSBrZXkpLlxuICogICAtIHtAbGluayBidWlsZFdyaXRlckluZGV4fSAvIHtAbGluayB3cml0ZXJDYW5kaWRhdGVzfSDigJQgb25lIHBhc3Mgb3ZlciBhIGxvZywgdGhlbiB0aGUgcm93cyB0aGF0XG4gKiAgICAgY2FuIGhhdmUgd3JpdHRlbiBhIGtleSwgZm91bmQgdGhyb3VnaCBpdHMgdG9wLWxldmVsIGtleSBpbnN0ZWFkIG9mIGEgc2Nhbi5cbiAqXG4gKiBUSEUgUlVMRVMgKGRlZmluZWQgaGVyZTsgdGhlIGZvbGQgaXMgTDEgYW5kIHRoZSBsb2cgcmVhZGVycyBMMywgc28gYGNvbW1pdExvZ1V0aWxzLnRzYCBhcHBsaWVzXG4gKiB0aGVtIOKAlCBgd3JpdGVyc09mYCwgYGZpbmRMYXN0V3JpdGVyYCwgYGNvbW1pdFZhbHVlQXRgKTpcbiAqICAgLSBUSEUgV1JJVEVSIFJVTEUg4oCUIGNvbW1pdCBgY2AgV1JJVEVTIGtleSBgS2AgaWZmIGBjYCBoYXMgYSByb3cgYCdleGFjdCdgIG9yIGAnaW5zaWRlJ2AgYEtgLFxuICogICAgIG9yIGEgcm93IGAnYXJvdW5kJ2AgYEtgIGFjcm9zcyB3aGljaCB0aGUgdmFsdWUgYXQgYEtgIGRpZmZlcnMgKGNvbXBhcmVkIG92ZXIgdGhlIHdob2xlIGNvbW1pdCxcbiAqICAgICBub3Qgcm93IGJ5IHJvdzogYSB2YWx1ZSB0aGF0IGNoYW5nZXMgYW5kIGNoYW5nZXMgYmFjayBpbnNpZGUgb25lIGNvbW1pdCB3YXMgbm90IHdyaXR0ZW4pLlxuICogICAgIEEgdG9wLWxldmVsIGtleSBoYXMgbm8gYCdhcm91bmQnYCByb3dzLCBzbyBmb3IgaXQgdGhlIHJ1bGUgaXMgdGhlIHBhdGggY2hlY2sgYWxvbmUuXG4gKiAgICAgV2h5IG5vdCBldmVyeSBgJ2Fyb3VuZCdgIHJvdzogYCR1cGRhdGUoJ2NmZycsIHsgbGlzdDogWzNdIH0pYCBpcyBhIGBtZXJnZWAgcm93IG9uIGBjZmdgLCBidXRcbiAqICAgICBpdCBuZXZlciByZWFjaGVzIGBjZmfikJ9hYCDigJQgY291bnRpbmcgaXQgbmFtZWQgdGhlIHdyb25nIHdyaXRlciBvZiBgY2Zn4pCfYWAuXG4gKiAgIC0gVEhFIFZBTFVFIFJVTEUg4oCUIHRoZSB2YWx1ZSBvZiBgS2AgYXQgY29tbWl0IGBpYCBpcyB0aGUgZm9sZCBvZiBFVkVSWSByb3cgdW5kZXIgYEtgJ3MgdG9wLWxldmVsXG4gKiAgICAga2V5IHVwIHRvIGBpYCwgYW5jaG9yZWQgYXQgdGhhdCBrZXkncyBsYXN0IGBzZXRgL2BkZWxldGVgLCByZWFkIGF0IGBLYDogdGhlIGZvbGQgYHN0YXRlQXRgXG4gKiAgICAgZG9lcywgcmVzdHJpY3RlZCB0byBvbmUgdG9wLWxldmVsIGtleS4gVG9wLWxldmVsIGtleXMgbmV2ZXIgaW50ZXJhY3QgdW5kZXIgdGhlIHN0ZXAsIHNvIHRoZVxuICogICAgIHJlc3RyaWN0aW9uIGlzIGV4YWN0LiBGb2xkaW5nIG9ubHkgdGhlIHJvd3MgdGhhdCB0b3VjaCBgS2AgaXMgTk9UOiBhbiBhcnJheSB1bmlvblxuICogICAgIChgZGVlcFNtYXJ0TWVyZ2VgKSBkZWR1cHMgdGhlIHdob2xlIGFycmF5LCBzbyBhIHNpYmxpbmcgZWxlbWVudCB3cml0dGVuIGJlc2lkZSBgYeKQnzFgIGNoYW5nZXNcbiAqICAgICB3aGVyZSBhIGxhdGVyIG1lcmdlIG9uIGBhYCBsZWF2ZXMgYGFbMV1gLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiByZWxhdGlvbignY2ZnXFx1MDAxRmInLCAnY2ZnJyk7IC8vICdpbnNpZGUnIOKAlCB0aGUgcm93IHdyb3RlIHBhcnQgb2YgY2ZnXG4gKiByZWxhdGlvbignY2ZnJywgJ2NmZ1xcdTAwMUZhJyk7IC8vICdhcm91bmQnIOKAlCB0aGUgcm93IHdyb3RlIHRoZSBjb250YWluZXIgY2ZnLmEgbGl2ZXMgaW5cbiAqIHJlbGF0aW9uKCdjZmdYJywgJ2NmZycpOyAgICAgICAvLyB1bmRlZmluZWQg4oCUIGEgZGlmZmVyZW50IGtleSwgbm90IGEgcHJlZml4IG1hdGNoXG4gKiBgYGBcbiAqL1xuXG5pbXBvcnQgeyBERUxJTSB9IGZyb20gJy4vcGF0aHMuanMnO1xuaW1wb3J0IHR5cGUgeyBDb21taXRCdW5kbGUgfSBmcm9tICcuL3R5cGVzLmpzJztcblxuLyoqXG4gKiBUaGUgV09SSyBldmVyeSBrZXkgcXVlcnkgaGFzIGRvbmUg4oCUIHJvd3MgaW5kZXhlZCBhbmQgc2Nhbm5lZCwgZm9sZCBzdGVwcywgYXJvdW5kLXZlcmRpY3RzLCB0cmllIGFuZFxuICogYW5jZXN0b3Igc3RlcHMsIGJpbmFyeSBzZWFyY2hlcywgYSBjYXVzYWwgd2FsaydzIG93biBsb29wcyDigJQgc3VtbWVkIGFjcm9zcyBjYWxscy4gQSBkZXRlcm1pbmlzdGljIGNvc3RcbiAqIG1lYXN1cmU6IGB0ZXN0L2xpYi9tZW1vcnkvYm91bmRhcnkva2V5LXF1ZXJ5LXNjYWxpbmcudGVzdC50c2AgYXNzZXJ0cyBhIGNhdXNhbCB3YWxrJ3Mgd29yayBncm93cyBsaW5lYXJseVxuICogaW4gdGhlIGxvZyBieSBDT1VOVElORyBpdCAoYSB3YWxsLWNsb2NrIHJhdGlvIGZhaWxlZCBvbiBhIGJ1c3kgbWFjaGluZSkuIE5ldmVyIHJlYWQgYnkgdGhlIGxpYnJhcnk7IG9uZVxuICogaW50ZWdlciBhZGQgcGVyIHVuaXQgb2Ygd29yayBpdCBhbHJlYWR5IGRvZXMuIEhlcmUsIGF0IEwwLCBzbyBldmVyeSBsYXllciB0aGF0IGRvZXMgdGhhdCB3b3JrIGNhbiBjb3VudCBpdC5cbiAqL1xuZXhwb3J0IGNvbnN0IHF1ZXJ5V29yayA9IHsgdW5pdHM6IDAgfTtcblxuLyoqIEhvdyBhIHJvdydzIHBhdGggc2l0cyBhZ2FpbnN0IGEga2V5J3MgcGF0aC4gYHVuZGVmaW5lZGAgZnJvbSB7QGxpbmsgcmVsYXRpb259IG1lYW5zIGRpc2pvaW50LiAqL1xuZXhwb3J0IHR5cGUgUGF0aFJlbGF0aW9uID0gJ2V4YWN0JyB8ICdpbnNpZGUnIHwgJ2Fyb3VuZCc7XG5cbmNvbnN0IERFTElNX0NPREUgPSBERUxJTS5jaGFyQ29kZUF0KDApO1xuXG4vKipcbiAqIEhvdyB0aGUgcm93IHBhdGggYHJvd1BhdGhgIHNpdHMgYWdhaW5zdCB0aGUga2V5IGBrZXlgIOKAlCBib3RoIERFTElNLWpvaW5lZCBgVHJhY2VFbnRyeS5wYXRoYFxuICogc3RyaW5ncyAoYSB0b3AtbGV2ZWwga2V5IGlzIGEgb25lLXNlZ21lbnQgcGF0aCkuIGAnZXhhY3QnYCB3aGVuIHRoZXkgYXJlIGVxdWFsLCBgJ2luc2lkZSdgIHdoZW5cbiAqIHRoZSByb3cgaXMgYmVsb3cgdGhlIGtleSwgYCdhcm91bmQnYCB3aGVuIHRoZSByb3cgaXMgYWJvdmUgaXQsIGB1bmRlZmluZWRgIHdoZW4gbmVpdGhlciBpcyBhXG4gKiBzZWdtZW50IHByZWZpeCBvZiB0aGUgb3RoZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWxhdGlvbihyb3dQYXRoOiBzdHJpbmcsIGtleTogc3RyaW5nKTogUGF0aFJlbGF0aW9uIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHJvd1BhdGggPT09IGtleSkgcmV0dXJuICdleGFjdCc7XG4gIGlmIChyb3dQYXRoLmxlbmd0aCA+IGtleS5sZW5ndGgpIHtcbiAgICByZXR1cm4gcm93UGF0aC5jaGFyQ29kZUF0KGtleS5sZW5ndGgpID09PSBERUxJTV9DT0RFICYmIHJvd1BhdGguc3RhcnRzV2l0aChrZXkpID8gJ2luc2lkZScgOiB1bmRlZmluZWQ7XG4gIH1cbiAgcmV0dXJuIGtleS5jaGFyQ29kZUF0KHJvd1BhdGgubGVuZ3RoKSA9PT0gREVMSU1fQ09ERSAmJiBrZXkuc3RhcnRzV2l0aChyb3dQYXRoKSA/ICdhcm91bmQnIDogdW5kZWZpbmVkO1xufVxuXG4vKiogVGhlIHRvcC1sZXZlbCBrZXkgYSBERUxJTS1qb2luZWQgcGF0aCBiZWxvbmdzIHRvIOKAlCBpdHMgZmlyc3Qgc2VnbWVudC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByb290T2YocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgY3V0ID0gcGF0aC5pbmRleE9mKERFTElNKTtcbiAgcmV0dXJuIGN1dCA9PT0gLTEgPyBwYXRoIDogcGF0aC5zbGljZSgwLCBjdXQpO1xufVxuXG4vKipcbiAqIE9uZSB3cml0dGVuIHBhdGggaW4gYSB7QGxpbmsgV3JpdGVySW5kZXh9IOKAlCBhIG5vZGUgb2YgdGhlIHBhdGggVFJJRSBidWlsdCBvdmVyIGEgbG9nLiBBIG5vZGUgZXhpc3RzIGZvclxuICogZXZlcnkgd3JpdHRlbiBwYXRoIGFuZCBldmVyeSBwcmVmaXggb2Ygb25lLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBhdGhOb2RlIHtcbiAgLyoqIFRoZSBERUxJTS1qb2luZWQgcGF0aCB0aGlzIG5vZGUgc3RhbmRzIGZvci4gKi9cbiAgcmVhZG9ubHkgcGF0aDogc3RyaW5nO1xuICAvKiogQVJSQVkgcG9zaXRpb25zIG9mIHRoZSBjb21taXRzIHdpdGggYSByb3cgZXhhY3RseSBvbiB0aGlzIHBhdGgg4oCUIGFzY2VuZGluZywgb25lIHBlciBjb21taXQuICovXG4gIHJlYWRvbmx5IHBvc2l0aW9uczogbnVtYmVyW107XG4gIC8qKiBUaGUgc3Vic2V0IG9mIHtAbGluayBwb3NpdGlvbnN9IHdob3NlIHJvdyBoZXJlIGlzIGEgYHNldGAgb3IgYSBgZGVsZXRlYCAoaXQgZGVjaWRlcyB0aGUgdmFsdWUgYWxvbmUpLiAqL1xuICByZWFkb25seSB0b3RhbHM6IG51bWJlcltdO1xuICAvKiogUG9zaXRpb25zIG9mIGNvbW1pdHMgd2hvc2Ugcm93IHdpdGggYSBub24tYGRlbGV0ZWAgdmVyYiBzaXRzIG9uIHRoaXMgcGF0aCAodGhlIHJlc3QgYXJlIGRlbGV0ZXMgb25seSkuICovXG4gIHJlYWRvbmx5IHdyaXRlczogbnVtYmVyW107XG4gIC8qKiBUaGUgbmV4dCBzZWdtZW50IOKGkiBpdHMgbm9kZS4gKi9cbiAgcmVhZG9ubHkgY2hpbGRyZW46IE1hcDxzdHJpbmcsIFBhdGhOb2RlPjtcbiAgLyoqIE1lbW8gb2Yge0BsaW5rIHN1YnRyZWVQb3NpdGlvbnN9LiAqL1xuICBzdWJ0cmVlPzogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbi8qKlxuICogVGhlIHBvc2l0aW9ucyBpbiBhIGxvZyB3aGVyZSBlYWNoIHdyaXR0ZW4gcGF0aCB3YXMgd3JpdHRlbjogYSBwYXRoIHRyaWUgcGVyIHRvcC1sZXZlbCBrZXkuIEJ1aWx0IGluIE9ORVxuICogcGFzcyAoYE8odG90YWwgcGF0aCBzZWdtZW50cylgKTsgYSBrZXkncyBjYW5kaWRhdGVzIHRoZW4gY29zdCBgTyhkZXB0aCArIG1hdGNoZXMpYCDigJQgaXRzIG5vZGUsIGl0c1xuICogYW5jZXN0b3JzLCBpdHMgc3VidHJlZSDigJQgbmV2ZXIgYSBzY2FuIG9mIGV2ZXJ5IHBhdGggdW5kZXIgaXRzIHRvcC1sZXZlbCBrZXkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV3JpdGVySW5kZXgge1xuICAvKiogRXZlcnkgdG9wLWxldmVsIGtleSDihpIgdGhlIHJvb3Qgb2YgaXRzIHRyaWUuICovXG4gIHJlYWRvbmx5IHJvb3RzOiBSZWFkb25seU1hcDxzdHJpbmcsIFBhdGhOb2RlPjtcbn1cblxuZnVuY3Rpb24gbm9kZU9mKHBhdGg6IHN0cmluZyk6IFBhdGhOb2RlIHtcbiAgcmV0dXJuIHsgcGF0aCwgcG9zaXRpb25zOiBbXSwgdG90YWxzOiBbXSwgd3JpdGVzOiBbXSwgY2hpbGRyZW46IG5ldyBNYXAoKSB9O1xufVxuXG4vKiogQXBwZW5kIGBpYCB0byBhbiBhc2NlbmRpbmcgbGlzdCB1bmxlc3MgaXQgaXMgYWxyZWFkeSBpdHMgbGFzdCBlbGVtZW50LiAqL1xuZnVuY3Rpb24gcHVzaE9uY2UobGlzdDogbnVtYmVyW10sIGk6IG51bWJlcik6IHZvaWQge1xuICBpZiAobGlzdFtsaXN0Lmxlbmd0aCAtIDFdICE9PSBpKSBsaXN0LnB1c2goaSk7XG59XG5cbi8qKlxuICogT25lIHBhc3Mgb3ZlciBgY29tbWl0TG9nYDogdGhlIHBhdGggdHJpZSBvZiBldmVyeSB3cml0dGVuIHBhdGguIEJ1aWxkIGl0IE9OQ0Ugd2hlbiBhIHJlYWRlciBhc2tzIGFib3V0XG4gKiBtYW55IGtleXMgKGEgY2F1c2FsIHdhbGssIGEgZm9yd2FyZCBzbGljZSkg4oCUIG9yIGxldCBgY29tbWl0TG9nVXRpbHMgwrcgbG9nTW9kZWxgIG1lbW9pc2UgaXQgZm9yIGEgZnJvemVuIGxvZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkV3JpdGVySW5kZXgoY29tbWl0TG9nOiByZWFkb25seSBDb21taXRCdW5kbGVbXSk6IFdyaXRlckluZGV4IHtcbiAgY29uc3Qgcm9vdHMgPSBuZXcgTWFwPHN0cmluZywgUGF0aE5vZGU+KCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY29tbWl0TG9nLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgdHJhY2UgPSBjb21taXRMb2dbaV0udHJhY2U7XG4gICAgZm9yIChsZXQgcm93ID0gMDsgcm93IDwgdHJhY2UubGVuZ3RoOyByb3crKykge1xuICAgICAgY29uc3QgeyBwYXRoLCB2ZXJiIH0gPSB0cmFjZVtyb3ddO1xuICAgICAgY29uc3Qgc2VncyA9IHBhdGguc3BsaXQoREVMSU0pO1xuICAgICAgbGV0IG5vZGU6IFBhdGhOb2RlIHwgdW5kZWZpbmVkID0gcm9vdHMuZ2V0KHNlZ3NbMF0pO1xuICAgICAgaWYgKG5vZGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBub2RlID0gbm9kZU9mKHNlZ3NbMF0pO1xuICAgICAgICByb290cy5zZXQoc2Vnc1swXSwgbm9kZSk7XG4gICAgICB9XG4gICAgICBmb3IgKGxldCBzID0gMTsgcyA8IHNlZ3MubGVuZ3RoOyBzKyspIHtcbiAgICAgICAgbGV0IGNoaWxkOiBQYXRoTm9kZSB8IHVuZGVmaW5lZCA9IG5vZGUuY2hpbGRyZW4uZ2V0KHNlZ3Nbc10pO1xuICAgICAgICBpZiAoY2hpbGQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNoaWxkID0gbm9kZU9mKG5vZGUucGF0aCArIERFTElNICsgc2Vnc1tzXSk7XG4gICAgICAgICAgbm9kZS5jaGlsZHJlbi5zZXQoc2Vnc1tzXSwgY2hpbGQpO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUgPSBjaGlsZDtcbiAgICAgIH1cbiAgICAgIHB1c2hPbmNlKG5vZGUucG9zaXRpb25zLCBpKTtcbiAgICAgIGlmICh2ZXJiID09PSAnc2V0JyB8fCB2ZXJiID09PSAnZGVsZXRlJykgcHVzaE9uY2Uobm9kZS50b3RhbHMsIGkpO1xuICAgICAgaWYgKHZlcmIgIT09ICdkZWxldGUnKSBwdXNoT25jZShub2RlLndyaXRlcywgaSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7IHJvb3RzIH07XG59XG5cbi8qKiBFdmVyeSBwYXRoIGEgcm93IHdhcyB3cml0dGVuIG9uLCBpbiB0cmllIG9yZGVyLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhdGhzV3JpdHRlbihpbmRleDogV3JpdGVySW5kZXgpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IG91dDogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgc3RhY2sgPSBbLi4uaW5kZXgucm9vdHMudmFsdWVzKCldO1xuICB3aGlsZSAoc3RhY2subGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IG5vZGUgPSBzdGFjay5wb3AoKSBhcyBQYXRoTm9kZTtcbiAgICBpZiAobm9kZS5wb3NpdGlvbnMubGVuZ3RoID4gMCkgb3V0LnB1c2gobm9kZS5wYXRoKTtcbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIG5vZGUuY2hpbGRyZW4udmFsdWVzKCkpIHN0YWNrLnB1c2goY2hpbGQpO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKiBUaGUgbm9kZSBmb3IgYGtleWAsIG9yIHVuZGVmaW5lZCB3aGVuIG5vIHJvdyB3YXMgd3JpdHRlbiBvbiBpdCBvciBiZWxvdyBpdC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub2RlQXQoaW5kZXg6IFdyaXRlckluZGV4LCBrZXk6IHN0cmluZyk6IFBhdGhOb2RlIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgc2VncyA9IGtleS5zcGxpdChERUxJTSk7XG4gIHF1ZXJ5V29yay51bml0cyArPSBzZWdzLmxlbmd0aDtcbiAgbGV0IG5vZGUgPSBpbmRleC5yb290cy5nZXQoc2Vnc1swXSk7XG4gIGZvciAobGV0IHMgPSAxOyBub2RlICE9PSB1bmRlZmluZWQgJiYgcyA8IHNlZ3MubGVuZ3RoOyBzKyspIG5vZGUgPSBub2RlLmNoaWxkcmVuLmdldChzZWdzW3NdKTtcbiAgcmV0dXJuIG5vZGU7XG59XG5cbi8qKiBUaGUgbm9kZXMgb2YgYGtleWAncyBQUk9QRVIgYW5jZXN0b3JzIHRoYXQgZXhpc3QgaW4gdGhlIGluZGV4LCB0b3AtbGV2ZWwga2V5IGZpcnN0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFuY2VzdG9yTm9kZXMoaW5kZXg6IFdyaXRlckluZGV4LCBrZXk6IHN0cmluZyk6IFBhdGhOb2RlW10ge1xuICBjb25zdCBzZWdzID0ga2V5LnNwbGl0KERFTElNKTtcbiAgY29uc3Qgb3V0OiBQYXRoTm9kZVtdID0gW107XG4gIHF1ZXJ5V29yay51bml0cyArPSBzZWdzLmxlbmd0aDtcbiAgbGV0IG5vZGUgPSBpbmRleC5yb290cy5nZXQoc2Vnc1swXSk7XG4gIGZvciAobGV0IHMgPSAxOyBub2RlICE9PSB1bmRlZmluZWQgJiYgcyA8IHNlZ3MubGVuZ3RoOyBzKyspIHtcbiAgICBvdXQucHVzaChub2RlKTtcbiAgICBub2RlID0gbm9kZS5jaGlsZHJlbi5nZXQoc2Vnc1tzXSk7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cblxuLyoqIEV2ZXJ5IGNvbW1pdCB3aXRoIGEgcm93IG9uIGBub2RlYCdzIHBhdGggb3IgYmVsb3cgaXQg4oCUIGFzY2VuZGluZywgbWVtb2lzZWQgb24gdGhlIG5vZGUuICovXG5leHBvcnQgZnVuY3Rpb24gc3VidHJlZVBvc2l0aW9ucyhub2RlOiBQYXRoTm9kZSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgcXVlcnlXb3JrLnVuaXRzICs9IDE7XG4gIGlmIChub2RlLnN1YnRyZWUgPT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChub2RlLmNoaWxkcmVuLnNpemUgPT09IDApIG5vZGUuc3VidHJlZSA9IG5vZGUucG9zaXRpb25zO1xuICAgIGVsc2Uge1xuICAgICAgY29uc3QgbGlzdHM6IChyZWFkb25seSBudW1iZXJbXSlbXSA9IFtub2RlLnBvc2l0aW9uc107XG4gICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIG5vZGUuY2hpbGRyZW4udmFsdWVzKCkpIGxpc3RzLnB1c2goc3VidHJlZVBvc2l0aW9ucyhjaGlsZCkpO1xuICAgICAgbm9kZS5zdWJ0cmVlID0gYXNjZW5kaW5nVW5pb24obGlzdHMpO1xuICAgICAgcXVlcnlXb3JrLnVuaXRzICs9IG5vZGUuc3VidHJlZS5sZW5ndGg7XG4gICAgfVxuICB9XG4gIHJldHVybiBub2RlLnN1YnRyZWU7XG59XG5cbi8qKiBUaGUgZmlyc3QgaW5kZXggaW4gYW4gYXNjZW5kaW5nIGxpc3QgaG9sZGluZyBhIHZhbHVlID49IGB2YWx1ZWAuICovXG5leHBvcnQgZnVuY3Rpb24gbG93ZXJCb3VuZChzb3J0ZWQ6IHJlYWRvbmx5IG51bWJlcltdLCB2YWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgcXVlcnlXb3JrLnVuaXRzICs9IDE7XG4gIGxldCBsbyA9IDA7XG4gIGxldCBoaSA9IHNvcnRlZC5sZW5ndGg7XG4gIHdoaWxlIChsbyA8IGhpKSB7XG4gICAgY29uc3QgbWlkID0gKGxvICsgaGkpID4+PiAxO1xuICAgIGlmIChzb3J0ZWRbbWlkXSA8IHZhbHVlKSBsbyA9IG1pZCArIDE7XG4gICAgZWxzZSBoaSA9IG1pZDtcbiAgfVxuICByZXR1cm4gbG87XG59XG5cbi8qKiBUaGUgbGFzdCB2YWx1ZSBpbiBhbiBhc2NlbmRpbmcgbGlzdCB0aGF0IGlzIDwgYGJlZm9yZWAsIG9yIC0xLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxhc3RCZWZvcmUoc29ydGVkOiByZWFkb25seSBudW1iZXJbXSwgYmVmb3JlOiBudW1iZXIpOiBudW1iZXIge1xuICBjb25zdCBhdCA9IGxvd2VyQm91bmQoc29ydGVkLCBiZWZvcmUpO1xuICByZXR1cm4gYXQgPiAwID8gc29ydGVkW2F0IC0gMV0gOiAtMTtcbn1cblxuLyoqIFRoZSB2YWx1ZXMgb2YgYW4gYXNjZW5kaW5nIGxpc3QgaW4gdGhlIE9QRU4gcmFuZ2UgKGBhZnRlcmAsIGBiZWZvcmVgKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiZXR3ZWVuKHNvcnRlZDogcmVhZG9ubHkgbnVtYmVyW10sIGFmdGVyOiBudW1iZXIsIGJlZm9yZTogbnVtYmVyKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICBjb25zdCBvdXQgPSBzb3J0ZWQuc2xpY2UobG93ZXJCb3VuZChzb3J0ZWQsIGFmdGVyICsgMSksIGxvd2VyQm91bmQoc29ydGVkLCBiZWZvcmUpKTtcbiAgcXVlcnlXb3JrLnVuaXRzICs9IG91dC5sZW5ndGg7XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKiBUaGUgY29tbWl0cyB0aGF0IGNhbiBoYXZlIHdyaXR0ZW4gYSBrZXksIHNwbGl0IGJ5IHdoYXQgdGhlIHdyaXRlciBydWxlIHN0aWxsIGhhcyB0byBhc2suICovXG5leHBvcnQgaW50ZXJmYWNlIFdyaXRlckNhbmRpZGF0ZXMge1xuICAvKiogQ29tbWl0cyB3aXRoIGEgcm93IGAnZXhhY3QnYCBvciBgJ2luc2lkZSdgIHRoZSBrZXkg4oCUIHdyaXRlcnMgYnkgdGhlIHBhdGggYWxvbmUuIEFzY2VuZGluZy4gKi9cbiAgcmVhZG9ubHkgYXRPckluc2lkZTogcmVhZG9ubHkgbnVtYmVyW107XG4gIC8qKiBDb21taXRzIHdpdGggYSByb3cgYCdhcm91bmQnYCB0aGUga2V5IGFuZCBub25lIGF0IG9yIGluc2lkZSBpdCDigJQgd3JpdGVycyBvbmx5IGlmIHRoZSB2YWx1ZSBhdCB0aGUga2V5IGNoYW5nZWQuIEFzY2VuZGluZy4gKi9cbiAgcmVhZG9ubHkgYXJvdW5kT25seTogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbi8qKiBUaGUgcGF0aCBoYWxmIG9mIHRoZSB3cml0ZXIgcnVsZSBvdmVyIGFuIGluZGV4OiBldmVyeSBjb21taXQgdGhhdCBjYW4gaGF2ZSB3cml0dGVuIGBrZXlgLiBgTyhkZXB0aCArIG1hdGNoZXMpYC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cml0ZXJDYW5kaWRhdGVzKGluZGV4OiBXcml0ZXJJbmRleCwga2V5OiBzdHJpbmcpOiBXcml0ZXJDYW5kaWRhdGVzIHtcbiAgY29uc3Qgbm9kZSA9IG5vZGVBdChpbmRleCwga2V5KTtcbiAgY29uc3Qgd3JpdHRlbiA9IG5vZGUgPT09IHVuZGVmaW5lZCA/IFtdIDogc3VidHJlZVBvc2l0aW9ucyhub2RlKTtcbiAgY29uc3QgYW5jZXN0b3JzID0gYW5jZXN0b3JOb2RlcyhpbmRleCwga2V5KTtcbiAgaWYgKGFuY2VzdG9ycy5sZW5ndGggPT09IDApIHJldHVybiB7IGF0T3JJbnNpZGU6IHdyaXR0ZW4sIGFyb3VuZE9ubHk6IFtdIH07XG4gIGNvbnN0IGFscmVhZHkgPSBuZXcgU2V0KHdyaXR0ZW4pO1xuICByZXR1cm4ge1xuICAgIGF0T3JJbnNpZGU6IHdyaXR0ZW4sXG4gICAgYXJvdW5kT25seTogYXNjZW5kaW5nVW5pb24oYW5jZXN0b3JzLm1hcCgoYSkgPT4gYS5wb3NpdGlvbnMpKS5maWx0ZXIoKGkpID0+ICFhbHJlYWR5LmhhcyhpKSksXG4gIH07XG59XG5cbi8qKiBUaGUgYXNjZW5kaW5nLCBkZS1kdXBsaWNhdGVkIHVuaW9uIG9mIGFzY2VuZGluZyBwb3NpdGlvbiBsaXN0cy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc2NlbmRpbmdVbmlvbihsaXN0czogcmVhZG9ubHkgKHJlYWRvbmx5IG51bWJlcltdKVtdKTogbnVtYmVyW10ge1xuICBpZiAobGlzdHMubGVuZ3RoID09PSAwKSByZXR1cm4gW107XG4gIGlmIChsaXN0cy5sZW5ndGggPT09IDEpIHJldHVybiBbLi4ubGlzdHNbMF1dO1xuICBjb25zdCBhbGwgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgZm9yIChjb25zdCBsaXN0IG9mIGxpc3RzKSBmb3IgKGNvbnN0IGkgb2YgbGlzdCkgYWxsLmFkZChpKTtcbiAgcmV0dXJuIFsuLi5hbGxdLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcbn1cblxuLyoqXG4gKiBEaWQgdGhpcyBjb21taXQgcmVhY2ggYGtleWAgT05MWSB0aHJvdWdoIHJvd3MgaW5zaWRlIGl0IOKAlCBhdCBsZWFzdCBvbmUgcm93IGAnaW5zaWRlJ2AgdGhlIGtleSwgYW5kIG5vXG4gKiByb3cgb24gaXQgb3IgYXJvdW5kIGl0PyBTdWNoIGEgd3JpdGUgY2hhbmdlZCBwYXJ0IG9mIHRoZSBrZXkncyB2YWx1ZSwgbm90IHRoZSB3aG9sZTogdGhlIG9uZSB0ZXN0XG4gKiBiZWhpbmQgZXZlcnkgYCduZXN0ZWQtcm93cydgIGNvZGUgKGEgc2xpY2Ugbm90ZSwgYSBjYXVzYWwgZWRnZSdzIGBiYXNpc2AsIGBmaW5kTGFzdFdyaXRlcldpdGhCYXNpc2ApLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd3JpdGVzT25seUluc2lkZShidW5kbGU6IENvbW1pdEJ1bmRsZSwga2V5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgbGV0IGluc2lkZSA9IGZhbHNlO1xuICBmb3IgKGNvbnN0IHQgb2YgYnVuZGxlLnRyYWNlKSB7XG4gICAgY29uc3QgciA9IHJlbGF0aW9uKHQucGF0aCwga2V5KTtcbiAgICBpZiAociA9PT0gJ2V4YWN0JyB8fCByID09PSAnYXJvdW5kJykgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChyID09PSAnaW5zaWRlJykgaW5zaWRlID0gdHJ1ZTtcbiAgfVxuICByZXR1cm4gaW5zaWRlO1xufVxuIl19
|