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.
Files changed (326) hide show
  1. package/AGENTS.md +12 -10
  2. package/CLAUDE.md +21 -23
  3. package/README.md +1 -1
  4. package/dist/advanced.js +71 -128
  5. package/dist/esm/advanced.d.ts +24 -58
  6. package/dist/esm/advanced.js +13 -51
  7. package/dist/esm/index.d.ts +5 -8
  8. package/dist/esm/index.js +3 -3
  9. package/dist/esm/lib/builder/FlowChartBuilder.d.ts +1 -1
  10. package/dist/esm/lib/builder/FlowChartBuilder.js +3 -3
  11. package/dist/esm/lib/builder/structure/StructureRecorder.d.ts +1 -1
  12. package/dist/esm/lib/builder/structure/StructureRecorder.js +1 -1
  13. package/dist/esm/lib/capture/index.d.ts +0 -1
  14. package/dist/esm/lib/capture/index.js +1 -2
  15. package/dist/esm/lib/engine/graph/prefixNodeTree.js +2 -2
  16. package/dist/esm/lib/engine/handlers/ResumeEntry.d.ts +3 -3
  17. package/dist/esm/lib/engine/handlers/ResumeEntry.js +4 -4
  18. package/dist/esm/lib/engine/handlers/SubflowExecutor.d.ts +1 -2
  19. package/dist/esm/lib/engine/handlers/SubflowExecutor.js +4 -8
  20. package/dist/esm/lib/engine/index.d.ts +1 -1
  21. package/dist/esm/lib/engine/index.js +1 -1
  22. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +4 -4
  23. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +1 -1
  24. package/dist/esm/lib/engine/narrative/index.d.ts +1 -1
  25. package/dist/esm/lib/engine/narrative/index.js +1 -1
  26. package/dist/esm/lib/engine/narrative/narrativeTypes.d.ts +1 -11
  27. package/dist/esm/lib/engine/narrative/narrativeTypes.js +1 -1
  28. package/dist/esm/lib/engine/traversal/FlowchartTraverser.d.ts +2 -10
  29. package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +4 -6
  30. package/dist/esm/lib/engine/traversalContext.d.ts +1 -1
  31. package/dist/esm/lib/engine/traversalContext.js +2 -2
  32. package/dist/esm/lib/engine/types.d.ts +2 -10
  33. package/dist/esm/lib/engine/types.js +1 -1
  34. package/dist/esm/lib/engine/walkSubflowSpec.js +2 -2
  35. package/dist/esm/lib/ids/reservedIds.js +2 -2
  36. package/dist/esm/lib/memory/DiagnosticCollector.js +2 -2
  37. package/dist/esm/lib/memory/StageContext.d.ts +2 -4
  38. package/dist/esm/lib/memory/StageContext.js +2 -2
  39. package/dist/esm/lib/memory/borrowedMutation.js +2 -2
  40. package/dist/esm/lib/memory/index.d.ts +6 -21
  41. package/dist/esm/lib/memory/index.js +4 -22
  42. package/dist/esm/lib/memory/redaction.d.ts +1 -1
  43. package/dist/esm/lib/memory/redaction.js +2 -2
  44. package/dist/esm/lib/memory/runPolicy.d.ts +3 -2
  45. package/dist/esm/lib/memory/runPolicy.js +1 -1
  46. package/dist/esm/lib/reactive/createTypedScope.js +2 -2
  47. package/dist/esm/lib/reactive/writeTraps.js +2 -2
  48. package/dist/esm/lib/recorder/ControlDepRecorder.d.ts +3 -2
  49. package/dist/esm/lib/recorder/ControlDepRecorder.js +3 -2
  50. package/dist/esm/lib/recorder/EmitRecorder.d.ts +1 -1
  51. package/dist/esm/lib/recorder/EmitRecorder.js +1 -1
  52. package/dist/esm/lib/recorder/InOutRecorder.js +2 -2
  53. package/dist/esm/lib/recorder/qualityTrace.d.ts +1 -1
  54. package/dist/esm/lib/recorder/qualityTrace.js +2 -2
  55. package/dist/esm/lib/runner/DeferredObserverTier.js +2 -2
  56. package/dist/esm/lib/runner/ExecutionRuntime.d.ts +4 -5
  57. package/dist/esm/lib/runner/ExecutionRuntime.js +2 -5
  58. package/dist/esm/lib/runner/FlowChartExecutor.d.ts +1 -1
  59. package/dist/esm/lib/runner/FlowChartExecutor.js +1 -1
  60. package/dist/esm/lib/runner/getSubtreeSnapshot.d.ts +1 -1
  61. package/dist/esm/lib/runner/getSubtreeSnapshot.js +4 -4
  62. package/dist/esm/lib/runner/resume.js +2 -2
  63. package/dist/esm/lib/runner/snapshot.js +3 -2
  64. package/dist/esm/lib/scope/ScopeFacade.js +2 -2
  65. package/dist/esm/lib/scope/state/zod/scopeFactory.js +2 -2
  66. package/dist/esm/recorders.d.ts +2 -3
  67. package/dist/esm/recorders.js +1 -1
  68. package/dist/esm/trace.d.ts +11 -57
  69. package/dist/esm/trace.js +10 -68
  70. package/dist/index.js +3 -3
  71. package/dist/lib/builder/FlowChartBuilder.js +5 -5
  72. package/dist/lib/builder/structure/StructureRecorder.js +1 -1
  73. package/dist/lib/capture/index.js +2 -4
  74. package/dist/lib/engine/graph/prefixNodeTree.js +5 -5
  75. package/dist/lib/engine/handlers/ResumeEntry.js +4 -4
  76. package/dist/lib/engine/handlers/SubflowExecutor.js +5 -9
  77. package/dist/lib/engine/index.js +1 -1
  78. package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +1 -1
  79. package/dist/lib/engine/narrative/index.js +1 -1
  80. package/dist/lib/engine/narrative/narrativeTypes.js +1 -1
  81. package/dist/lib/engine/traversal/FlowchartTraverser.js +8 -10
  82. package/dist/lib/engine/traversalContext.js +4 -4
  83. package/dist/lib/engine/types.js +1 -1
  84. package/dist/lib/engine/walkSubflowSpec.js +3 -3
  85. package/dist/lib/ids/reservedIds.js +5 -5
  86. package/dist/lib/memory/DiagnosticCollector.js +3 -3
  87. package/dist/lib/memory/StageContext.js +3 -3
  88. package/dist/lib/memory/borrowedMutation.js +3 -3
  89. package/dist/lib/memory/index.js +7 -42
  90. package/dist/lib/memory/redaction.js +3 -3
  91. package/dist/lib/memory/runPolicy.js +1 -1
  92. package/dist/lib/reactive/createTypedScope.js +3 -3
  93. package/dist/lib/reactive/writeTraps.js +4 -4
  94. package/dist/lib/recorder/ControlDepRecorder.js +3 -2
  95. package/dist/lib/recorder/EmitRecorder.js +1 -1
  96. package/dist/lib/recorder/InOutRecorder.js +3 -3
  97. package/dist/lib/recorder/qualityTrace.js +4 -4
  98. package/dist/lib/runner/DeferredObserverTier.js +3 -3
  99. package/dist/lib/runner/ExecutionRuntime.js +6 -9
  100. package/dist/lib/runner/FlowChartExecutor.js +1 -1
  101. package/dist/lib/runner/getSubtreeSnapshot.js +6 -6
  102. package/dist/lib/runner/resume.js +3 -3
  103. package/dist/lib/runner/snapshot.js +6 -5
  104. package/dist/lib/scope/ScopeFacade.js +3 -3
  105. package/dist/lib/scope/state/zod/scopeFactory.js +4 -4
  106. package/dist/recorders.js +1 -1
  107. package/dist/trace.js +18 -120
  108. package/dist/types/advanced.d.ts +24 -58
  109. package/dist/types/index.d.ts +5 -8
  110. package/dist/types/lib/builder/FlowChartBuilder.d.ts +1 -1
  111. package/dist/types/lib/builder/structure/StructureRecorder.d.ts +1 -1
  112. package/dist/types/lib/capture/index.d.ts +0 -1
  113. package/dist/types/lib/engine/handlers/ResumeEntry.d.ts +3 -3
  114. package/dist/types/lib/engine/handlers/SubflowExecutor.d.ts +1 -2
  115. package/dist/types/lib/engine/index.d.ts +1 -1
  116. package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +4 -4
  117. package/dist/types/lib/engine/narrative/index.d.ts +1 -1
  118. package/dist/types/lib/engine/narrative/narrativeTypes.d.ts +1 -11
  119. package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +2 -10
  120. package/dist/types/lib/engine/traversalContext.d.ts +1 -1
  121. package/dist/types/lib/engine/types.d.ts +2 -10
  122. package/dist/types/lib/memory/StageContext.d.ts +2 -4
  123. package/dist/types/lib/memory/index.d.ts +6 -21
  124. package/dist/types/lib/memory/redaction.d.ts +1 -1
  125. package/dist/types/lib/memory/runPolicy.d.ts +3 -2
  126. package/dist/types/lib/recorder/ControlDepRecorder.d.ts +3 -2
  127. package/dist/types/lib/recorder/EmitRecorder.d.ts +1 -1
  128. package/dist/types/lib/recorder/qualityTrace.d.ts +1 -1
  129. package/dist/types/lib/runner/ExecutionRuntime.d.ts +4 -5
  130. package/dist/types/lib/runner/FlowChartExecutor.d.ts +1 -1
  131. package/dist/types/lib/runner/getSubtreeSnapshot.d.ts +1 -1
  132. package/dist/types/recorders.d.ts +2 -3
  133. package/dist/types/trace.d.ts +11 -57
  134. package/package.json +6 -15
  135. package/dist/esm/lib/capture/freeze.d.ts +0 -91
  136. package/dist/esm/lib/capture/freeze.js +0 -314
  137. package/dist/esm/lib/capture/ownData.d.ts +0 -7
  138. package/dist/esm/lib/capture/ownData.js +0 -15
  139. package/dist/esm/lib/capture/valueKinds.d.ts +0 -57
  140. package/dist/esm/lib/capture/valueKinds.js +0 -142
  141. package/dist/esm/lib/ids/runtimeStageId.d.ts +0 -173
  142. package/dist/esm/lib/ids/runtimeStageId.js +0 -194
  143. package/dist/esm/lib/memory/EventLog.d.ts +0 -105
  144. package/dist/esm/lib/memory/EventLog.js +0 -148
  145. package/dist/esm/lib/memory/RecordFrame.d.ts +0 -232
  146. package/dist/esm/lib/memory/RecordFrame.js +0 -296
  147. package/dist/esm/lib/memory/SharedMemory.d.ts +0 -46
  148. package/dist/esm/lib/memory/SharedMemory.js +0 -88
  149. package/dist/esm/lib/memory/TransactionBuffer.d.ts +0 -521
  150. package/dist/esm/lib/memory/TransactionBuffer.js +0 -946
  151. package/dist/esm/lib/memory/admission.d.ts +0 -81
  152. package/dist/esm/lib/memory/admission.js +0 -153
  153. package/dist/esm/lib/memory/backtrack.d.ts +0 -286
  154. package/dist/esm/lib/memory/backtrack.js +0 -457
  155. package/dist/esm/lib/memory/commitLogUtils.d.ts +0 -217
  156. package/dist/esm/lib/memory/commitLogUtils.js +0 -384
  157. package/dist/esm/lib/memory/deltaEncoding.d.ts +0 -66
  158. package/dist/esm/lib/memory/deltaEncoding.js +0 -122
  159. package/dist/esm/lib/memory/equality.d.ts +0 -93
  160. package/dist/esm/lib/memory/equality.js +0 -262
  161. package/dist/esm/lib/memory/eventPosition.d.ts +0 -18
  162. package/dist/esm/lib/memory/eventPosition.js +0 -2
  163. package/dist/esm/lib/memory/honesty.d.ts +0 -93
  164. package/dist/esm/lib/memory/honesty.js +0 -92
  165. package/dist/esm/lib/memory/keyPaths.d.ts +0 -125
  166. package/dist/esm/lib/memory/keyPaths.js +0 -227
  167. package/dist/esm/lib/memory/logModel.d.ts +0 -76
  168. package/dist/esm/lib/memory/logModel.js +0 -364
  169. package/dist/esm/lib/memory/merge.d.ts +0 -26
  170. package/dist/esm/lib/memory/merge.js +0 -60
  171. package/dist/esm/lib/memory/pathOps.d.ts +0 -115
  172. package/dist/esm/lib/memory/pathOps.js +0 -290
  173. package/dist/esm/lib/memory/paths.d.ts +0 -52
  174. package/dist/esm/lib/memory/paths.js +0 -57
  175. package/dist/esm/lib/memory/placeholders.d.ts +0 -39
  176. package/dist/esm/lib/memory/placeholders.js +0 -40
  177. package/dist/esm/lib/memory/recordCommit.d.ts +0 -45
  178. package/dist/esm/lib/memory/recordCommit.js +0 -61
  179. package/dist/esm/lib/memory/scrub.d.ts +0 -53
  180. package/dist/esm/lib/memory/scrub.js +0 -74
  181. package/dist/esm/lib/memory/types.d.ts +0 -209
  182. package/dist/esm/lib/memory/types.js +0 -10
  183. package/dist/esm/lib/memory/utils.d.ts +0 -73
  184. package/dist/esm/lib/memory/utils.js +0 -159
  185. package/dist/esm/lib/memory/verbs.d.ts +0 -333
  186. package/dist/esm/lib/memory/verbs.js +0 -427
  187. package/dist/esm/lib/recorder/CommitRangeIndex.d.ts +0 -147
  188. package/dist/esm/lib/recorder/CommitRangeIndex.js +0 -207
  189. package/dist/esm/lib/scope/detectCircular.d.ts +0 -13
  190. package/dist/esm/lib/scope/detectCircular.js +0 -14
  191. package/dist/esm/lib/scope/recorders/summarizeValue.d.ts +0 -5
  192. package/dist/esm/lib/scope/recorders/summarizeValue.js +0 -6
  193. package/dist/esm/lib/slice/elementProvenance.d.ts +0 -81
  194. package/dist/esm/lib/slice/elementProvenance.js +0 -190
  195. package/dist/esm/lib/slice/forwardSliceForKey.d.ts +0 -88
  196. package/dist/esm/lib/slice/forwardSliceForKey.js +0 -243
  197. package/dist/esm/lib/slice/index.d.ts +0 -25
  198. package/dist/esm/lib/slice/index.js +0 -25
  199. package/dist/esm/lib/slice/keyIndex.d.ts +0 -137
  200. package/dist/esm/lib/slice/keyIndex.js +0 -293
  201. package/dist/esm/lib/slice/keyTimeline.d.ts +0 -49
  202. package/dist/esm/lib/slice/keyTimeline.js +0 -113
  203. package/dist/esm/lib/slice/keysReadSources.d.ts +0 -51
  204. package/dist/esm/lib/slice/keysReadSources.js +0 -95
  205. package/dist/esm/lib/slice/serialize.d.ts +0 -78
  206. package/dist/esm/lib/slice/serialize.js +0 -278
  207. package/dist/esm/lib/slice/sliceForKey.d.ts +0 -47
  208. package/dist/esm/lib/slice/sliceForKey.js +0 -88
  209. package/dist/esm/lib/slice/types.d.ts +0 -567
  210. package/dist/esm/lib/slice/types.js +0 -25
  211. package/dist/esm/lib/time-travel/axis.d.ts +0 -119
  212. package/dist/esm/lib/time-travel/axis.js +0 -179
  213. package/dist/esm/lib/time-travel/bundles.d.ts +0 -77
  214. package/dist/esm/lib/time-travel/bundles.js +0 -136
  215. package/dist/esm/lib/time-travel/chain.d.ts +0 -93
  216. package/dist/esm/lib/time-travel/chain.js +0 -188
  217. package/dist/esm/lib/time-travel/commitStops.d.ts +0 -55
  218. package/dist/esm/lib/time-travel/commitStops.js +0 -202
  219. package/dist/esm/lib/time-travel/index.d.ts +0 -22
  220. package/dist/esm/lib/time-travel/index.js +0 -21
  221. package/dist/esm/lib/time-travel/stateAt.d.ts +0 -102
  222. package/dist/esm/lib/time-travel/stateAt.js +0 -153
  223. package/dist/esm/lib/time-travel/tagStops.d.ts +0 -72
  224. package/dist/esm/lib/time-travel/tagStops.js +0 -102
  225. package/dist/esm/lib/time-travel/timeTravel.d.ts +0 -70
  226. package/dist/esm/lib/time-travel/timeTravel.js +0 -360
  227. package/dist/esm/lib/time-travel/types.d.ts +0 -470
  228. package/dist/esm/lib/time-travel/types.js +0 -23
  229. package/dist/esm/write.d.ts +0 -47
  230. package/dist/esm/write.js +0 -46
  231. package/dist/lib/capture/freeze.js +0 -320
  232. package/dist/lib/capture/ownData.js +0 -19
  233. package/dist/lib/capture/valueKinds.js +0 -146
  234. package/dist/lib/ids/runtimeStageId.js +0 -210
  235. package/dist/lib/memory/EventLog.js +0 -152
  236. package/dist/lib/memory/RecordFrame.js +0 -300
  237. package/dist/lib/memory/SharedMemory.js +0 -92
  238. package/dist/lib/memory/TransactionBuffer.js +0 -950
  239. package/dist/lib/memory/admission.js +0 -159
  240. package/dist/lib/memory/backtrack.js +0 -463
  241. package/dist/lib/memory/commitLogUtils.js +0 -399
  242. package/dist/lib/memory/deltaEncoding.js +0 -128
  243. package/dist/lib/memory/equality.js +0 -266
  244. package/dist/lib/memory/eventPosition.js +0 -3
  245. package/dist/lib/memory/honesty.js +0 -95
  246. package/dist/lib/memory/keyPaths.js +0 -243
  247. package/dist/lib/memory/logModel.js +0 -372
  248. package/dist/lib/memory/merge.js +0 -64
  249. package/dist/lib/memory/pathOps.js +0 -306
  250. package/dist/lib/memory/paths.js +0 -62
  251. package/dist/lib/memory/placeholders.js +0 -43
  252. package/dist/lib/memory/recordCommit.js +0 -65
  253. package/dist/lib/memory/scrub.js +0 -79
  254. package/dist/lib/memory/types.js +0 -11
  255. package/dist/lib/memory/utils.js +0 -178
  256. package/dist/lib/memory/verbs.js +0 -444
  257. package/dist/lib/recorder/CommitRangeIndex.js +0 -211
  258. package/dist/lib/scope/detectCircular.js +0 -21
  259. package/dist/lib/scope/recorders/summarizeValue.js +0 -10
  260. package/dist/lib/slice/elementProvenance.js +0 -195
  261. package/dist/lib/slice/forwardSliceForKey.js +0 -247
  262. package/dist/lib/slice/index.js +0 -42
  263. package/dist/lib/slice/keyIndex.js +0 -313
  264. package/dist/lib/slice/keyTimeline.js +0 -117
  265. package/dist/lib/slice/keysReadSources.js +0 -101
  266. package/dist/lib/slice/serialize.js +0 -286
  267. package/dist/lib/slice/sliceForKey.js +0 -93
  268. package/dist/lib/slice/types.js +0 -26
  269. package/dist/lib/time-travel/axis.js +0 -184
  270. package/dist/lib/time-travel/bundles.js +0 -144
  271. package/dist/lib/time-travel/chain.js +0 -193
  272. package/dist/lib/time-travel/commitStops.js +0 -206
  273. package/dist/lib/time-travel/index.js +0 -32
  274. package/dist/lib/time-travel/stateAt.js +0 -160
  275. package/dist/lib/time-travel/tagStops.js +0 -106
  276. package/dist/lib/time-travel/timeTravel.js +0 -364
  277. package/dist/lib/time-travel/types.js +0 -24
  278. package/dist/types/lib/capture/freeze.d.ts +0 -91
  279. package/dist/types/lib/capture/ownData.d.ts +0 -7
  280. package/dist/types/lib/capture/valueKinds.d.ts +0 -57
  281. package/dist/types/lib/ids/runtimeStageId.d.ts +0 -173
  282. package/dist/types/lib/memory/EventLog.d.ts +0 -105
  283. package/dist/types/lib/memory/RecordFrame.d.ts +0 -232
  284. package/dist/types/lib/memory/SharedMemory.d.ts +0 -46
  285. package/dist/types/lib/memory/TransactionBuffer.d.ts +0 -521
  286. package/dist/types/lib/memory/admission.d.ts +0 -81
  287. package/dist/types/lib/memory/backtrack.d.ts +0 -286
  288. package/dist/types/lib/memory/commitLogUtils.d.ts +0 -217
  289. package/dist/types/lib/memory/deltaEncoding.d.ts +0 -66
  290. package/dist/types/lib/memory/equality.d.ts +0 -93
  291. package/dist/types/lib/memory/eventPosition.d.ts +0 -18
  292. package/dist/types/lib/memory/honesty.d.ts +0 -93
  293. package/dist/types/lib/memory/keyPaths.d.ts +0 -125
  294. package/dist/types/lib/memory/logModel.d.ts +0 -76
  295. package/dist/types/lib/memory/merge.d.ts +0 -26
  296. package/dist/types/lib/memory/pathOps.d.ts +0 -115
  297. package/dist/types/lib/memory/paths.d.ts +0 -52
  298. package/dist/types/lib/memory/placeholders.d.ts +0 -39
  299. package/dist/types/lib/memory/recordCommit.d.ts +0 -45
  300. package/dist/types/lib/memory/scrub.d.ts +0 -53
  301. package/dist/types/lib/memory/types.d.ts +0 -209
  302. package/dist/types/lib/memory/utils.d.ts +0 -73
  303. package/dist/types/lib/memory/verbs.d.ts +0 -333
  304. package/dist/types/lib/recorder/CommitRangeIndex.d.ts +0 -147
  305. package/dist/types/lib/scope/detectCircular.d.ts +0 -13
  306. package/dist/types/lib/scope/recorders/summarizeValue.d.ts +0 -5
  307. package/dist/types/lib/slice/elementProvenance.d.ts +0 -81
  308. package/dist/types/lib/slice/forwardSliceForKey.d.ts +0 -88
  309. package/dist/types/lib/slice/index.d.ts +0 -25
  310. package/dist/types/lib/slice/keyIndex.d.ts +0 -137
  311. package/dist/types/lib/slice/keyTimeline.d.ts +0 -49
  312. package/dist/types/lib/slice/keysReadSources.d.ts +0 -51
  313. package/dist/types/lib/slice/serialize.d.ts +0 -78
  314. package/dist/types/lib/slice/sliceForKey.d.ts +0 -47
  315. package/dist/types/lib/slice/types.d.ts +0 -567
  316. package/dist/types/lib/time-travel/axis.d.ts +0 -119
  317. package/dist/types/lib/time-travel/bundles.d.ts +0 -77
  318. package/dist/types/lib/time-travel/chain.d.ts +0 -93
  319. package/dist/types/lib/time-travel/commitStops.d.ts +0 -55
  320. package/dist/types/lib/time-travel/index.d.ts +0 -22
  321. package/dist/types/lib/time-travel/stateAt.d.ts +0 -102
  322. package/dist/types/lib/time-travel/tagStops.d.ts +0 -72
  323. package/dist/types/lib/time-travel/timeTravel.d.ts +0 -70
  324. package/dist/types/lib/time-travel/types.d.ts +0 -470
  325. package/dist/types/write.d.ts +0 -47
  326. 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5UGF0aHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL21lbW9yeS9rZXlQYXRocy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdUNHO0FBRUgsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQztBQUduQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUM7QUFLdEMsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUV2Qzs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQUMsT0FBZSxFQUFFLEdBQVc7SUFDbkQsSUFBSSxPQUFPLEtBQUssR0FBRztRQUFFLE9BQU8sT0FBTyxDQUFDO0lBQ3BDLElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDaEMsT0FBTyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxVQUFVLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDekcsQ0FBQztJQUNELE9BQU8sR0FBRyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssVUFBVSxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ3pHLENBQUM7QUFFRCw0RUFBNEU7QUFDNUUsTUFBTSxVQUFVLE1BQU0sQ0FBQyxJQUFZO0lBQ2pDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFD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QyxLQUFxQztJQUNsRSxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ2xDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDN0MsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUM5QixLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUs7UUFBRSxLQUFLLE1BQU0sQ0FBQyxJQUFJLElBQUk7WUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzNELE9BQU8sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN4QyxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxNQUFvQixFQUFFLEdBQVc7SUFDaEUsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ25CLEtBQUssTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzdCLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxLQUFLLE9BQU8sSUFBSSxDQUFDLEtBQUssUUFBUTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ2xELElBQUksQ0FBQyxLQUFLLFFBQVE7WUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBQ3BDLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBrZXlQYXRocy50cyDigJQgd2hpY2ggcm93cyBvZiBhIGNvbW1pdCBsb2cgdG91Y2ggYSBzdGF0ZSBrZXkuIE9ORSBhbnN3ZXIgKEYzLCA5LjMzLjApLlxuICpcbiAqIFdIWSBUSElTIEZJTEUgRVhJU1RTLiBBIGtleSBxdWVyeSAoYGNvbW1pdFZhbHVlQXRgLCBgZmluZExhc3RXcml0ZXJgLCBgY2F1c2FsQ2hhaW5gLCB0aGUgc2xpY2VcbiAqIGxheWVyKSBhc2tzIFwid2hpY2ggcm93cyB3cm90ZSBga2V5YD9cIi4gRWFjaCByZWFkZXIgdXNlZCB0byBhbnN3ZXIgd2l0aCBpdHMgb3duIGByb3cucGF0aCA9PT0ga2V5YCxcbiAqIHNvIGEgcm93IHdyaXR0ZW4gSU5TSURFIHRoZSBrZXkg4oCUIGBjZmfikJ9iYCwgd2hpY2ggZXZlcnkgc3ViZmxvdyBzZWVkIG9mIGFuIG9iamVjdCwgZXZlcnlcbiAqIG91dHB1dE1hcHBlciBtZXJnZS1iYWNrIGFuZCBldmVyeSBmb3JrIGNoaWxkJ3MgbmFtZXNwYWNlIHByb2R1Y2VzIOKAlCB3YXMgaW52aXNpYmxlIHRvIGFsbCBvZlxuICogdGhlbSwgd2hpbGUgdGhlIGZvbGQgKGBzdGF0ZUF0YCwgdGhlIGxpdmUgY29tbWl0KSBhcHBsaWVkIGl0LiBUaGUgZm9sZCBzYWlkIGB7YToxLGI6Mn1gOyB0aGUga2V5XG4gKiBxdWVyaWVzIHNhaWQgXCJuZXZlciB3cml0dGVuXCIuIEV2ZXJ5IHJlYWRlciBub3cgYXNrcyBoZXJlLlxuICpcbiAqIFRIRSBQQVRIIEhBTEYgKHRoaXMgZmlsZSwgTDAg4oCUIGl0IGltcG9ydHMgb25seSB0aGUgcGF0aCBjb2RlYyBhbmQgdHlwZXMpOlxuICogICAtIHtAbGluayByZWxhdGlvbn0g4oCUIGhvdyBhIHJvdydzIHBhdGggc2l0cyBhZ2FpbnN0IGEga2V5J3MgcGF0aC4gQSBzZWdtZW50IHByZWZpeCBvbiB0aGVcbiAqICAgICBERUxJTS1qb2luZWQgcGF0aCwgdGhlIHdheSBSRkMgNjkwMSBwcmVmaXhlcyBhIEpTT04gUG9pbnRlcjogYGNmZ2AgaXMgYSBwcmVmaXggb2YgYGNmZ+KQn2FgLFxuICogICAgIG5ldmVyIG9mIGBjZmdYYC4gQSByb3cgaXMgYCdleGFjdCdgIChvbiB0aGUga2V5KSwgYCdpbnNpZGUnYCAoYmVsb3cgaXQg4oCUIGl0IHdyb3RlIHBhcnQgb2YgdGhlXG4gKiAgICAga2V5J3MgdmFsdWUpIG9yIGAnYXJvdW5kJ2AgKGFib3ZlIGl0IOKAlCBpdCB3cm90ZSBhIGNvbnRhaW5lciB0aGF0IGhvbGRzIHRoZSBrZXkpLlxuICogICAtIHtAbGluayBidWlsZFdyaXRlckluZGV4fSAvIHtAbGluayB3cml0ZXJDYW5kaWRhdGVzfSDigJQgb25lIHBhc3Mgb3ZlciBhIGxvZywgdGhlbiB0aGUgcm93cyB0aGF0XG4gKiAgICAgY2FuIGhhdmUgd3JpdHRlbiBhIGtleSwgZm91bmQgdGhyb3VnaCBpdHMgdG9wLWxldmVsIGtleSBpbnN0ZWFkIG9mIGEgc2Nhbi5cbiAqXG4gKiBUSEUgUlVMRVMgKGRlZmluZWQgaGVyZTsgdGhlIGZvbGQgaXMgTDEgYW5kIHRoZSBsb2cgcmVhZGVycyBMMywgc28gYGNvbW1pdExvZ1V0aWxzLnRzYCBhcHBsaWVzXG4gKiB0aGVtIOKAlCBgd3JpdGVyc09mYCwgYGZpbmRMYXN0V3JpdGVyYCwgYGNvbW1pdFZhbHVlQXRgKTpcbiAqICAgLSBUSEUgV1JJVEVSIFJVTEUg4oCUIGNvbW1pdCBgY2AgV1JJVEVTIGtleSBgS2AgaWZmIGBjYCBoYXMgYSByb3cgYCdleGFjdCdgIG9yIGAnaW5zaWRlJ2AgYEtgLFxuICogICAgIG9yIGEgcm93IGAnYXJvdW5kJ2AgYEtgIGFjcm9zcyB3aGljaCB0aGUgdmFsdWUgYXQgYEtgIGRpZmZlcnMgKGNvbXBhcmVkIG92ZXIgdGhlIHdob2xlIGNvbW1pdCxcbiAqICAgICBub3Qgcm93IGJ5IHJvdzogYSB2YWx1ZSB0aGF0IGNoYW5nZXMgYW5kIGNoYW5nZXMgYmFjayBpbnNpZGUgb25lIGNvbW1pdCB3YXMgbm90IHdyaXR0ZW4pLlxuICogICAgIEEgdG9wLWxldmVsIGtleSBoYXMgbm8gYCdhcm91bmQnYCByb3dzLCBzbyBmb3IgaXQgdGhlIHJ1bGUgaXMgdGhlIHBhdGggY2hlY2sgYWxvbmUuXG4gKiAgICAgV2h5IG5vdCBldmVyeSBgJ2Fyb3VuZCdgIHJvdzogYCR1cGRhdGUoJ2NmZycsIHsgbGlzdDogWzNdIH0pYCBpcyBhIGBtZXJnZWAgcm93IG9uIGBjZmdgLCBidXRcbiAqICAgICBpdCBuZXZlciByZWFjaGVzIGBjZmfikJ9hYCDigJQgY291bnRpbmcgaXQgbmFtZWQgdGhlIHdyb25nIHdyaXRlciBvZiBgY2Zn4pCfYWAuXG4gKiAgIC0gVEhFIFZBTFVFIFJVTEUg4oCUIHRoZSB2YWx1ZSBvZiBgS2AgYXQgY29tbWl0IGBpYCBpcyB0aGUgZm9sZCBvZiBFVkVSWSByb3cgdW5kZXIgYEtgJ3MgdG9wLWxldmVsXG4gKiAgICAga2V5IHVwIHRvIGBpYCwgYW5jaG9yZWQgYXQgdGhhdCBrZXkncyBsYXN0IGBzZXRgL2BkZWxldGVgLCByZWFkIGF0IGBLYDogdGhlIGZvbGQgYHN0YXRlQXRgXG4gKiAgICAgZG9lcywgcmVzdHJpY3RlZCB0byBvbmUgdG9wLWxldmVsIGtleS4gVG9wLWxldmVsIGtleXMgbmV2ZXIgaW50ZXJhY3QgdW5kZXIgdGhlIHN0ZXAsIHNvIHRoZVxuICogICAgIHJlc3RyaWN0aW9uIGlzIGV4YWN0LiBGb2xkaW5nIG9ubHkgdGhlIHJvd3MgdGhhdCB0b3VjaCBgS2AgaXMgTk9UOiBhbiBhcnJheSB1bmlvblxuICogICAgIChgZGVlcFNtYXJ0TWVyZ2VgKSBkZWR1cHMgdGhlIHdob2xlIGFycmF5LCBzbyBhIHNpYmxpbmcgZWxlbWVudCB3cml0dGVuIGJlc2lkZSBgYeKQnzFgIGNoYW5nZXNcbiAqICAgICB3aGVyZSBhIGxhdGVyIG1lcmdlIG9uIGBhYCBsZWF2ZXMgYGFbMV1gLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiByZWxhdGlvbignY2ZnXFx1MDAxRmInLCAnY2ZnJyk7IC8vICdpbnNpZGUnIOKAlCB0aGUgcm93IHdyb3RlIHBhcnQgb2YgY2ZnXG4gKiByZWxhdGlvbignY2ZnJywgJ2NmZ1xcdTAwMUZhJyk7IC8vICdhcm91bmQnIOKAlCB0aGUgcm93IHdyb3RlIHRoZSBjb250YWluZXIgY2ZnLmEgbGl2ZXMgaW5cbiAqIHJlbGF0aW9uKCdjZmdYJywgJ2NmZycpOyAgICAgICAvLyB1bmRlZmluZWQg4oCUIGEgZGlmZmVyZW50IGtleSwgbm90IGEgcHJlZml4IG1hdGNoXG4gKiBgYGBcbiAqL1xuXG5pbXBvcnQgeyBERUxJTSB9IGZyb20gJy4vcGF0aHMuanMnO1xuaW1wb3J0IHR5cGUgeyBDb21taXRCdW5kbGUgfSBmcm9tICcuL3R5cGVzLmpzJztcblxuLyoqXG4gKiBUaGUgV09SSyBldmVyeSBrZXkgcXVlcnkgaGFzIGRvbmUg4oCUIHJvd3MgaW5kZXhlZCBhbmQgc2Nhbm5lZCwgZm9sZCBzdGVwcywgYXJvdW5kLXZlcmRpY3RzLCB0cmllIGFuZFxuICogYW5jZXN0b3Igc3RlcHMsIGJpbmFyeSBzZWFyY2hlcywgYSBjYXVzYWwgd2FsaydzIG93biBsb29wcyDigJQgc3VtbWVkIGFjcm9zcyBjYWxscy4gQSBkZXRlcm1pbmlzdGljIGNvc3RcbiAqIG1lYXN1cmU6IGB0ZXN0L2xpYi9tZW1vcnkvYm91bmRhcnkva2V5LXF1ZXJ5LXNjYWxpbmcudGVzdC50c2AgYXNzZXJ0cyBhIGNhdXNhbCB3YWxrJ3Mgd29yayBncm93cyBsaW5lYXJseVxuICogaW4gdGhlIGxvZyBieSBDT1VOVElORyBpdCAoYSB3YWxsLWNsb2NrIHJhdGlvIGZhaWxlZCBvbiBhIGJ1c3kgbWFjaGluZSkuIE5ldmVyIHJlYWQgYnkgdGhlIGxpYnJhcnk7IG9uZVxuICogaW50ZWdlciBhZGQgcGVyIHVuaXQgb2Ygd29yayBpdCBhbHJlYWR5IGRvZXMuIEhlcmUsIGF0IEwwLCBzbyBldmVyeSBsYXllciB0aGF0IGRvZXMgdGhhdCB3b3JrIGNhbiBjb3VudCBpdC5cbiAqL1xuZXhwb3J0IGNvbnN0IHF1ZXJ5V29yayA9IHsgdW5pdHM6IDAgfTtcblxuLyoqIEhvdyBhIHJvdydzIHBhdGggc2l0cyBhZ2FpbnN0IGEga2V5J3MgcGF0aC4gYHVuZGVmaW5lZGAgZnJvbSB7QGxpbmsgcmVsYXRpb259IG1lYW5zIGRpc2pvaW50LiAqL1xuZXhwb3J0IHR5cGUgUGF0aFJlbGF0aW9uID0gJ2V4YWN0JyB8ICdpbnNpZGUnIHwgJ2Fyb3VuZCc7XG5cbmNvbnN0IERFTElNX0NPREUgPSBERUxJTS5jaGFyQ29kZUF0KDApO1xuXG4vKipcbiAqIEhvdyB0aGUgcm93IHBhdGggYHJvd1BhdGhgIHNpdHMgYWdhaW5zdCB0aGUga2V5IGBrZXlgIOKAlCBib3RoIERFTElNLWpvaW5lZCBgVHJhY2VFbnRyeS5wYXRoYFxuICogc3RyaW5ncyAoYSB0b3AtbGV2ZWwga2V5IGlzIGEgb25lLXNlZ21lbnQgcGF0aCkuIGAnZXhhY3QnYCB3aGVuIHRoZXkgYXJlIGVxdWFsLCBgJ2luc2lkZSdgIHdoZW5cbiAqIHRoZSByb3cgaXMgYmVsb3cgdGhlIGtleSwgYCdhcm91bmQnYCB3aGVuIHRoZSByb3cgaXMgYWJvdmUgaXQsIGB1bmRlZmluZWRgIHdoZW4gbmVpdGhlciBpcyBhXG4gKiBzZWdtZW50IHByZWZpeCBvZiB0aGUgb3RoZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWxhdGlvbihyb3dQYXRoOiBzdHJpbmcsIGtleTogc3RyaW5nKTogUGF0aFJlbGF0aW9uIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHJvd1BhdGggPT09IGtleSkgcmV0dXJuICdleGFjdCc7XG4gIGlmIChyb3dQYXRoLmxlbmd0aCA+IGtleS5sZW5ndGgpIHtcbiAgICByZXR1cm4gcm93UGF0aC5jaGFyQ29kZUF0KGtleS5sZW5ndGgpID09PSBERUxJTV9DT0RFICYmIHJvd1BhdGguc3RhcnRzV2l0aChrZXkpID8gJ2luc2lkZScgOiB1bmRlZmluZWQ7XG4gIH1cbiAgcmV0dXJuIGtleS5jaGFyQ29kZUF0KHJvd1BhdGgubGVuZ3RoKSA9PT0gREVMSU1fQ09ERSAmJiBrZXkuc3RhcnRzV2l0aChyb3dQYXRoKSA/ICdhcm91bmQnIDogdW5kZWZpbmVkO1xufVxuXG4vKiogVGhlIHRvcC1sZXZlbCBrZXkgYSBERUxJTS1qb2luZWQgcGF0aCBiZWxvbmdzIHRvIOKAlCBpdHMgZmlyc3Qgc2VnbWVudC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByb290T2YocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgY3V0ID0gcGF0aC5pbmRleE9mKERFTElNKTtcbiAgcmV0dXJuIGN1dCA9PT0gLTEgPyBwYXRoIDogcGF0aC5zbGljZSgwLCBjdXQpO1xufVxuXG4vKipcbiAqIE9uZSB3cml0dGVuIHBhdGggaW4gYSB7QGxpbmsgV3JpdGVySW5kZXh9IOKAlCBhIG5vZGUgb2YgdGhlIHBhdGggVFJJRSBidWlsdCBvdmVyIGEgbG9nLiBBIG5vZGUgZXhpc3RzIGZvclxuICogZXZlcnkgd3JpdHRlbiBwYXRoIGFuZCBldmVyeSBwcmVmaXggb2Ygb25lLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBhdGhOb2RlIHtcbiAgLyoqIFRoZSBERUxJTS1qb2luZWQgcGF0aCB0aGlzIG5vZGUgc3RhbmRzIGZvci4gKi9cbiAgcmVhZG9ubHkgcGF0aDogc3RyaW5nO1xuICAvKiogQVJSQVkgcG9zaXRpb25zIG9mIHRoZSBjb21taXRzIHdpdGggYSByb3cgZXhhY3RseSBvbiB0aGlzIHBhdGgg4oCUIGFzY2VuZGluZywgb25lIHBlciBjb21taXQuICovXG4gIHJlYWRvbmx5IHBvc2l0aW9uczogbnVtYmVyW107XG4gIC8qKiBUaGUgc3Vic2V0IG9mIHtAbGluayBwb3NpdGlvbnN9IHdob3NlIHJvdyBoZXJlIGlzIGEgYHNldGAgb3IgYSBgZGVsZXRlYCAoaXQgZGVjaWRlcyB0aGUgdmFsdWUgYWxvbmUpLiAqL1xuICByZWFkb25seSB0b3RhbHM6IG51bWJlcltdO1xuICAvKiogUG9zaXRpb25zIG9mIGNvbW1pdHMgd2hvc2Ugcm93IHdpdGggYSBub24tYGRlbGV0ZWAgdmVyYiBzaXRzIG9uIHRoaXMgcGF0aCAodGhlIHJlc3QgYXJlIGRlbGV0ZXMgb25seSkuICovXG4gIHJlYWRvbmx5IHdyaXRlczogbnVtYmVyW107XG4gIC8qKiBUaGUgbmV4dCBzZWdtZW50IOKGkiBpdHMgbm9kZS4gKi9cbiAgcmVhZG9ubHkgY2hpbGRyZW46IE1hcDxzdHJpbmcsIFBhdGhOb2RlPjtcbiAgLyoqIE1lbW8gb2Yge0BsaW5rIHN1YnRyZWVQb3NpdGlvbnN9LiAqL1xuICBzdWJ0cmVlPzogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbi8qKlxuICogVGhlIHBvc2l0aW9ucyBpbiBhIGxvZyB3aGVyZSBlYWNoIHdyaXR0ZW4gcGF0aCB3YXMgd3JpdHRlbjogYSBwYXRoIHRyaWUgcGVyIHRvcC1sZXZlbCBrZXkuIEJ1aWx0IGluIE9ORVxuICogcGFzcyAoYE8odG90YWwgcGF0aCBzZWdtZW50cylgKTsgYSBrZXkncyBjYW5kaWRhdGVzIHRoZW4gY29zdCBgTyhkZXB0aCArIG1hdGNoZXMpYCDigJQgaXRzIG5vZGUsIGl0c1xuICogYW5jZXN0b3JzLCBpdHMgc3VidHJlZSDigJQgbmV2ZXIgYSBzY2FuIG9mIGV2ZXJ5IHBhdGggdW5kZXIgaXRzIHRvcC1sZXZlbCBrZXkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV3JpdGVySW5kZXgge1xuICAvKiogRXZlcnkgdG9wLWxldmVsIGtleSDihpIgdGhlIHJvb3Qgb2YgaXRzIHRyaWUuICovXG4gIHJlYWRvbmx5IHJvb3RzOiBSZWFkb25seU1hcDxzdHJpbmcsIFBhdGhOb2RlPjtcbn1cblxuZnVuY3Rpb24gbm9kZU9mKHBhdGg6IHN0cmluZyk6IFBhdGhOb2RlIHtcbiAgcmV0dXJuIHsgcGF0aCwgcG9zaXRpb25zOiBbXSwgdG90YWxzOiBbXSwgd3JpdGVzOiBbXSwgY2hpbGRyZW46IG5ldyBNYXAoKSB9O1xufVxuXG4vKiogQXBwZW5kIGBpYCB0byBhbiBhc2NlbmRpbmcgbGlzdCB1bmxlc3MgaXQgaXMgYWxyZWFkeSBpdHMgbGFzdCBlbGVtZW50LiAqL1xuZnVuY3Rpb24gcHVzaE9uY2UobGlzdDogbnVtYmVyW10sIGk6IG51bWJlcik6IHZvaWQge1xuICBpZiAobGlzdFtsaXN0Lmxlbmd0aCAtIDFdICE9PSBpKSBsaXN0LnB1c2goaSk7XG59XG5cbi8qKlxuICogT25lIHBhc3Mgb3ZlciBgY29tbWl0TG9nYDogdGhlIHBhdGggdHJpZSBvZiBldmVyeSB3cml0dGVuIHBhdGguIEJ1aWxkIGl0IE9OQ0Ugd2hlbiBhIHJlYWRlciBhc2tzIGFib3V0XG4gKiBtYW55IGtleXMgKGEgY2F1c2FsIHdhbGssIGEgZm9yd2FyZCBzbGljZSkg4oCUIG9yIGxldCBgY29tbWl0TG9nVXRpbHMgwrcgbG9nTW9kZWxgIG1lbW9pc2UgaXQgZm9yIGEgZnJvemVuIGxvZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkV3JpdGVySW5kZXgoY29tbWl0TG9nOiByZWFkb25seSBDb21taXRCdW5kbGVbXSk6IFdyaXRlckluZGV4IHtcbiAgY29uc3Qgcm9vdHMgPSBuZXcgTWFwPHN0cmluZywgUGF0aE5vZGU+KCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY29tbWl0TG9nLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgdHJhY2UgPSBjb21taXRMb2dbaV0udHJhY2U7XG4gICAgZm9yIChsZXQgcm93ID0gMDsgcm93IDwgdHJhY2UubGVuZ3RoOyByb3crKykge1xuICAgICAgY29uc3QgeyBwYXRoLCB2ZXJiIH0gPSB0cmFjZVtyb3ddO1xuICAgICAgY29uc3Qgc2VncyA9IHBhdGguc3BsaXQoREVMSU0pO1xuICAgICAgbGV0IG5vZGU6IFBhdGhOb2RlIHwgdW5kZWZpbmVkID0gcm9vdHMuZ2V0KHNlZ3NbMF0pO1xuICAgICAgaWYgKG5vZGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBub2RlID0gbm9kZU9mKHNlZ3NbMF0pO1xuICAgICAgICByb290cy5zZXQoc2Vnc1swXSwgbm9kZSk7XG4gICAgICB9XG4gICAgICBmb3IgKGxldCBzID0gMTsgcyA8IHNlZ3MubGVuZ3RoOyBzKyspIHtcbiAgICAgICAgbGV0IGNoaWxkOiBQYXRoTm9kZSB8IHVuZGVmaW5lZCA9IG5vZGUuY2hpbGRyZW4uZ2V0KHNlZ3Nbc10pO1xuICAgICAgICBpZiAoY2hpbGQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNoaWxkID0gbm9kZU9mKG5vZGUucGF0aCArIERFTElNICsgc2Vnc1tzXSk7XG4gICAgICAgICAgbm9kZS5jaGlsZHJlbi5zZXQoc2Vnc1tzXSwgY2hpbGQpO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUgPSBjaGlsZDtcbiAgICAgIH1cbiAgICAgIHB1c2hPbmNlKG5vZGUucG9zaXRpb25zLCBpKTtcbiAgICAgIGlmICh2ZXJiID09PSAnc2V0JyB8fCB2ZXJiID09PSAnZGVsZXRlJykgcHVzaE9uY2Uobm9kZS50b3RhbHMsIGkpO1xuICAgICAgaWYgKHZlcmIgIT09ICdkZWxldGUnKSBwdXNoT25jZShub2RlLndyaXRlcywgaSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7IHJvb3RzIH07XG59XG5cbi8qKiBFdmVyeSBwYXRoIGEgcm93IHdhcyB3cml0dGVuIG9uLCBpbiB0cmllIG9yZGVyLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhdGhzV3JpdHRlbihpbmRleDogV3JpdGVySW5kZXgpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IG91dDogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgc3RhY2sgPSBbLi4uaW5kZXgucm9vdHMudmFsdWVzKCldO1xuICB3aGlsZSAoc3RhY2subGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IG5vZGUgPSBzdGFjay5wb3AoKSBhcyBQYXRoTm9kZTtcbiAgICBpZiAobm9kZS5wb3NpdGlvbnMubGVuZ3RoID4gMCkgb3V0LnB1c2gobm9kZS5wYXRoKTtcbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIG5vZGUuY2hpbGRyZW4udmFsdWVzKCkpIHN0YWNrLnB1c2goY2hpbGQpO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKiBUaGUgbm9kZSBmb3IgYGtleWAsIG9yIHVuZGVmaW5lZCB3aGVuIG5vIHJvdyB3YXMgd3JpdHRlbiBvbiBpdCBvciBiZWxvdyBpdC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub2RlQXQoaW5kZXg6IFdyaXRlckluZGV4LCBrZXk6IHN0cmluZyk6IFBhdGhOb2RlIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgc2VncyA9IGtleS5zcGxpdChERUxJTSk7XG4gIHF1ZXJ5V29yay51bml0cyArPSBzZWdzLmxlbmd0aDtcbiAgbGV0IG5vZGUgPSBpbmRleC5yb290cy5nZXQoc2Vnc1swXSk7XG4gIGZvciAobGV0IHMgPSAxOyBub2RlICE9PSB1bmRlZmluZWQgJiYgcyA8IHNlZ3MubGVuZ3RoOyBzKyspIG5vZGUgPSBub2RlLmNoaWxkcmVuLmdldChzZWdzW3NdKTtcbiAgcmV0dXJuIG5vZGU7XG59XG5cbi8qKiBUaGUgbm9kZXMgb2YgYGtleWAncyBQUk9QRVIgYW5jZXN0b3JzIHRoYXQgZXhpc3QgaW4gdGhlIGluZGV4LCB0b3AtbGV2ZWwga2V5IGZpcnN0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFuY2VzdG9yTm9kZXMoaW5kZXg6IFdyaXRlckluZGV4LCBrZXk6IHN0cmluZyk6IFBhdGhOb2RlW10ge1xuICBjb25zdCBzZWdzID0ga2V5LnNwbGl0KERFTElNKTtcbiAgY29uc3Qgb3V0OiBQYXRoTm9kZVtdID0gW107XG4gIHF1ZXJ5V29yay51bml0cyArPSBzZWdzLmxlbmd0aDtcbiAgbGV0IG5vZGUgPSBpbmRleC5yb290cy5nZXQoc2Vnc1swXSk7XG4gIGZvciAobGV0IHMgPSAxOyBub2RlICE9PSB1bmRlZmluZWQgJiYgcyA8IHNlZ3MubGVuZ3RoOyBzKyspIHtcbiAgICBvdXQucHVzaChub2RlKTtcbiAgICBub2RlID0gbm9kZS5jaGlsZHJlbi5nZXQoc2Vnc1tzXSk7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cblxuLyoqIEV2ZXJ5IGNvbW1pdCB3aXRoIGEgcm93IG9uIGBub2RlYCdzIHBhdGggb3IgYmVsb3cgaXQg4oCUIGFzY2VuZGluZywgbWVtb2lzZWQgb24gdGhlIG5vZGUuICovXG5leHBvcnQgZnVuY3Rpb24gc3VidHJlZVBvc2l0aW9ucyhub2RlOiBQYXRoTm9kZSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgcXVlcnlXb3JrLnVuaXRzICs9IDE7XG4gIGlmIChub2RlLnN1YnRyZWUgPT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChub2RlLmNoaWxkcmVuLnNpemUgPT09IDApIG5vZGUuc3VidHJlZSA9IG5vZGUucG9zaXRpb25zO1xuICAgIGVsc2Uge1xuICAgICAgY29uc3QgbGlzdHM6IChyZWFkb25seSBudW1iZXJbXSlbXSA9IFtub2RlLnBvc2l0aW9uc107XG4gICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIG5vZGUuY2hpbGRyZW4udmFsdWVzKCkpIGxpc3RzLnB1c2goc3VidHJlZVBvc2l0aW9ucyhjaGlsZCkpO1xuICAgICAgbm9kZS5zdWJ0cmVlID0gYXNjZW5kaW5nVW5pb24obGlzdHMpO1xuICAgICAgcXVlcnlXb3JrLnVuaXRzICs9IG5vZGUuc3VidHJlZS5sZW5ndGg7XG4gICAgfVxuICB9XG4gIHJldHVybiBub2RlLnN1YnRyZWU7XG59XG5cbi8qKiBUaGUgZmlyc3QgaW5kZXggaW4gYW4gYXNjZW5kaW5nIGxpc3QgaG9sZGluZyBhIHZhbHVlID49IGB2YWx1ZWAuICovXG5leHBvcnQgZnVuY3Rpb24gbG93ZXJCb3VuZChzb3J0ZWQ6IHJlYWRvbmx5IG51bWJlcltdLCB2YWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgcXVlcnlXb3JrLnVuaXRzICs9IDE7XG4gIGxldCBsbyA9IDA7XG4gIGxldCBoaSA9IHNvcnRlZC5sZW5ndGg7XG4gIHdoaWxlIChsbyA8IGhpKSB7XG4gICAgY29uc3QgbWlkID0gKGxvICsgaGkpID4+PiAxO1xuICAgIGlmIChzb3J0ZWRbbWlkXSA8IHZhbHVlKSBsbyA9IG1pZCArIDE7XG4gICAgZWxzZSBoaSA9IG1pZDtcbiAgfVxuICByZXR1cm4gbG87XG59XG5cbi8qKiBUaGUgbGFzdCB2YWx1ZSBpbiBhbiBhc2NlbmRpbmcgbGlzdCB0aGF0IGlzIDwgYGJlZm9yZWAsIG9yIC0xLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxhc3RCZWZvcmUoc29ydGVkOiByZWFkb25seSBudW1iZXJbXSwgYmVmb3JlOiBudW1iZXIpOiBudW1iZXIge1xuICBjb25zdCBhdCA9IGxvd2VyQm91bmQoc29ydGVkLCBiZWZvcmUpO1xuICByZXR1cm4gYXQgPiAwID8gc29ydGVkW2F0IC0gMV0gOiAtMTtcbn1cblxuLyoqIFRoZSB2YWx1ZXMgb2YgYW4gYXNjZW5kaW5nIGxpc3QgaW4gdGhlIE9QRU4gcmFuZ2UgKGBhZnRlcmAsIGBiZWZvcmVgKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiZXR3ZWVuKHNvcnRlZDogcmVhZG9ubHkgbnVtYmVyW10sIGFmdGVyOiBudW1iZXIsIGJlZm9yZTogbnVtYmVyKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICBjb25zdCBvdXQgPSBzb3J0ZWQuc2xpY2UobG93ZXJCb3VuZChzb3J0ZWQsIGFmdGVyICsgMSksIGxvd2VyQm91bmQoc29ydGVkLCBiZWZvcmUpKTtcbiAgcXVlcnlXb3JrLnVuaXRzICs9IG91dC5sZW5ndGg7XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKiBUaGUgY29tbWl0cyB0aGF0IGNhbiBoYXZlIHdyaXR0ZW4gYSBrZXksIHNwbGl0IGJ5IHdoYXQgdGhlIHdyaXRlciBydWxlIHN0aWxsIGhhcyB0byBhc2suICovXG5leHBvcnQgaW50ZXJmYWNlIFdyaXRlckNhbmRpZGF0ZXMge1xuICAvKiogQ29tbWl0cyB3aXRoIGEgcm93IGAnZXhhY3QnYCBvciBgJ2luc2lkZSdgIHRoZSBrZXkg4oCUIHdyaXRlcnMgYnkgdGhlIHBhdGggYWxvbmUuIEFzY2VuZGluZy4gKi9cbiAgcmVhZG9ubHkgYXRPckluc2lkZTogcmVhZG9ubHkgbnVtYmVyW107XG4gIC8qKiBDb21taXRzIHdpdGggYSByb3cgYCdhcm91bmQnYCB0aGUga2V5IGFuZCBub25lIGF0IG9yIGluc2lkZSBpdCDigJQgd3JpdGVycyBvbmx5IGlmIHRoZSB2YWx1ZSBhdCB0aGUga2V5IGNoYW5nZWQuIEFzY2VuZGluZy4gKi9cbiAgcmVhZG9ubHkgYXJvdW5kT25seTogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbi8qKiBUaGUgcGF0aCBoYWxmIG9mIHRoZSB3cml0ZXIgcnVsZSBvdmVyIGFuIGluZGV4OiBldmVyeSBjb21taXQgdGhhdCBjYW4gaGF2ZSB3cml0dGVuIGBrZXlgLiBgTyhkZXB0aCArIG1hdGNoZXMpYC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cml0ZXJDYW5kaWRhdGVzKGluZGV4OiBXcml0ZXJJbmRleCwga2V5OiBzdHJpbmcpOiBXcml0ZXJDYW5kaWRhdGVzIHtcbiAgY29uc3Qgbm9kZSA9IG5vZGVBdChpbmRleCwga2V5KTtcbiAgY29uc3Qgd3JpdHRlbiA9IG5vZGUgPT09IHVuZGVmaW5lZCA/IFtdIDogc3VidHJlZVBvc2l0aW9ucyhub2RlKTtcbiAgY29uc3QgYW5jZXN0b3JzID0gYW5jZXN0b3JOb2RlcyhpbmRleCwga2V5KTtcbiAgaWYgKGFuY2VzdG9ycy5sZW5ndGggPT09IDApIHJldHVybiB7IGF0T3JJbnNpZGU6IHdyaXR0ZW4sIGFyb3VuZE9ubHk6IFtdIH07XG4gIGNvbnN0IGFscmVhZHkgPSBuZXcgU2V0KHdyaXR0ZW4pO1xuICByZXR1cm4ge1xuICAgIGF0T3JJbnNpZGU6IHdyaXR0ZW4sXG4gICAgYXJvdW5kT25seTogYXNjZW5kaW5nVW5pb24oYW5jZXN0b3JzLm1hcCgoYSkgPT4gYS5wb3NpdGlvbnMpKS5maWx0ZXIoKGkpID0+ICFhbHJlYWR5LmhhcyhpKSksXG4gIH07XG59XG5cbi8qKiBUaGUgYXNjZW5kaW5nLCBkZS1kdXBsaWNhdGVkIHVuaW9uIG9mIGFzY2VuZGluZyBwb3NpdGlvbiBsaXN0cy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc2NlbmRpbmdVbmlvbihsaXN0czogcmVhZG9ubHkgKHJlYWRvbmx5IG51bWJlcltdKVtdKTogbnVtYmVyW10ge1xuICBpZiAobGlzdHMubGVuZ3RoID09PSAwKSByZXR1cm4gW107XG4gIGlmIChsaXN0cy5sZW5ndGggPT09IDEpIHJldHVybiBbLi4ubGlzdHNbMF1dO1xuICBjb25zdCBhbGwgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgZm9yIChjb25zdCBsaXN0IG9mIGxpc3RzKSBmb3IgKGNvbnN0IGkgb2YgbGlzdCkgYWxsLmFkZChpKTtcbiAgcmV0dXJuIFsuLi5hbGxdLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcbn1cblxuLyoqXG4gKiBEaWQgdGhpcyBjb21taXQgcmVhY2ggYGtleWAgT05MWSB0aHJvdWdoIHJvd3MgaW5zaWRlIGl0IOKAlCBhdCBsZWFzdCBvbmUgcm93IGAnaW5zaWRlJ2AgdGhlIGtleSwgYW5kIG5vXG4gKiByb3cgb24gaXQgb3IgYXJvdW5kIGl0PyBTdWNoIGEgd3JpdGUgY2hhbmdlZCBwYXJ0IG9mIHRoZSBrZXkncyB2YWx1ZSwgbm90IHRoZSB3aG9sZTogdGhlIG9uZSB0ZXN0XG4gKiBiZWhpbmQgZXZlcnkgYCduZXN0ZWQtcm93cydgIGNvZGUgKGEgc2xpY2Ugbm90ZSwgYSBjYXVzYWwgZWRnZSdzIGBiYXNpc2AsIGBmaW5kTGFzdFdyaXRlcldpdGhCYXNpc2ApLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd3JpdGVzT25seUluc2lkZShidW5kbGU6IENvbW1pdEJ1bmRsZSwga2V5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgbGV0IGluc2lkZSA9IGZhbHNlO1xuICBmb3IgKGNvbnN0IHQgb2YgYnVuZGxlLnRyYWNlKSB7XG4gICAgY29uc3QgciA9IHJlbGF0aW9uKHQucGF0aCwga2V5KTtcbiAgICBpZiAociA9PT0gJ2V4YWN0JyB8fCByID09PSAnYXJvdW5kJykgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChyID09PSAnaW5zaWRlJykgaW5zaWRlID0gdHJ1ZTtcbiAgfVxuICByZXR1cm4gaW5zaWRlO1xufVxuIl19