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,427 +0,0 @@
1
- /**
2
- * verbs.ts — THE VERB LAW (L1): the one place a commit row becomes a value.
3
- *
4
- * A row of a commit bundle's `trace` carries one of four verbs —
5
- * `set | merge | append | delete` — and ONE step turns it into a value:
6
- * {@link applyVerb}. State is a left fold of that step (the event-sourcing
7
- * reducer): {@link foldRows} folds one bundle's rows into a state, and
8
- * {@link foldKey} folds ONE KEY across a log — every row under the key's
9
- * top-level key, read at the key (the value rule, `keyPaths.ts`). Every reader
10
- * of the log runs one of the two —
11
- *
12
- * - the live commit and the redacted mirror (`nextGeneration`),
13
- * - the public replay (`applySmartMerge`), the read-side folds
14
- * (`applySmartMergeInto` — `EventLog.materialise`, `stateAt`) and the
15
- * admitted record's comparison (`dryFold`): all {@link foldRows},
16
- * - `commitValueAt`, and `arrayProvenance` as an OBSERVER of the same fold:
17
- * {@link foldKey}.
18
- *
19
- * Three questions that used to be answered once per reader are answered here
20
- * once: what a verb does to the value before it ({@link applyVerb}), how the
21
- * result is placed ({@link placeVerb}), and how the log's own values are
22
- * treated on the way in (the clone discipline — a PARAMETER of the fold, see
23
- * {@link Discipline} and {@link RecordedPayload}). A new verb is one new arm of
24
- * `applyVerb` and one row of the traits table; the compiler refuses either
25
- * missing ({@link isTotal}, {@link recordsTail}, {@link VERBS}).
26
- *
27
- * An UNKNOWN verb is refused with {@link UnknownVerbError}, never folded as a
28
- * `merge` (the old silent default). Engine-written logs carry the four, so
29
- * every engine run folds byte-for-byte as before.
30
- */
31
- import { deepSmartMerge } from './merge.js';
32
- import { nativeDelete, nativeGet, nativeSet, own, ownedRootOf, ownSpine } from './pathOps.js';
33
- import { DELIM, pathSegments } from './paths.js';
34
- /**
35
- * The vocabulary: each verb with the two traits readers branch on, in the
36
- * order the contract names them. A `Record` over the union — the compiler
37
- * refuses a table that misses (or invents) a verb, so a verb cannot be added
38
- * without saying what it is.
39
- *
40
- * `total` — the row decides the value ALONE; it reads nothing from what came
41
- * before it ({@link isTotal}).
42
- * `tail` — the row records ONLY what it adds, not the whole value
43
- * ({@link recordsTail}).
44
- */
45
- const TRAITS = {
46
- set: { total: true, tail: false },
47
- merge: { total: false, tail: false },
48
- append: { total: false, tail: true },
49
- delete: { total: true, tail: false },
50
- };
51
- /** The four verbs, in the order the contract names them. */
52
- export const VERBS = Object.freeze(Object.keys(TRAITS));
53
- /** Is `value` one of the four? The question every reader of a foreign log asks first. */
54
- export function isVerb(value) {
55
- return typeof value === 'string' && Object.prototype.hasOwnProperty.call(TRAITS, value);
56
- }
57
- /**
58
- * Does the verb decide the value ALONE — read nothing from what came before
59
- * it? `set` and `delete`. A reader that only needs the final value may start
60
- * at the last such row ({@link foldKey} `anchored`); one that tracks how the
61
- * value grew (provenance) starts at the first. Pinned against
62
- * {@link applyVerb} itself, so a new verb cannot misreport it.
63
- */
64
- export function isTotal(verb) {
65
- return TRAITS[verb].total;
66
- }
67
- /**
68
- * Does the row record ONLY what it adds — a tail — rather than the whole
69
- * value? `append`. What the row added is then known exactly: a reader that
70
- * tracks where array elements came from attributes them to this row without
71
- * comparing arrays, where every other verb has to be inferred from.
72
- */
73
- export function recordsTail(verb) {
74
- return TRAITS[verb].tail;
75
- }
76
- /**
77
- * Thrown by the readers of a commit log — {@link foldRows} (behind
78
- * `applySmartMerge`), `commitValueAt`, `arrayProvenance` — when a row carries a
79
- * verb outside {@link VERBS}: a foreign or corrupted log fails loudly instead
80
- * of being replayed as a `merge`. `verb`, `path`, `row` and `commit` name the
81
- * row (`path` / `row` / `commit` are absent when the caller handed over a
82
- * bare verb); `path` is the trace's own DELIM-joined form — take it apart with
83
- * `pathSegments`. The message quotes `verb` and `path`, so a hostile log cannot
84
- * reshape it.
85
- */
86
- export class UnknownVerbError extends Error {
87
- verb;
88
- path;
89
- row;
90
- commit;
91
- constructor(verb, site) {
92
- const named = typeof verb === 'string' ? JSON.stringify(verb) : verb === undefined ? 'undefined' : `of type ${typeof verb}`;
93
- // The verb and the path come from a log nobody vetted: quoted (JSON), so a
94
- // control character in either cannot reshape the message.
95
- const where = site === undefined
96
- ? ''
97
- : ` on trace row ${site.row} (path ${JSON.stringify(pathSegments(site.path).join(' › '))}${site.commit === undefined ? '' : `, commit ${site.commit}`})`;
98
- const one = VERBS.join(' | ');
99
- super(`unknown verb ${named}${where}: a commit row is one of ${one} — the log is refused, not replayed as a merge`);
100
- this.name = 'UnknownVerbError';
101
- this.verb = verb;
102
- if (site !== undefined) {
103
- this.path = site.path;
104
- this.row = site.row;
105
- if (site.commit !== undefined)
106
- this.commit = site.commit;
107
- }
108
- }
109
- }
110
- function refuseVerb(verb) {
111
- throw new UnknownVerbError(verb);
112
- }
113
- // ─── The step ────────────────────────────────────────────────────────────────
114
- /**
115
- * What a `delete` row leaves behind: the KEY IS GONE — which is not the value
116
- * `undefined` (a root replay removes the key; a per-path fold reads it as
117
- * `undefined`). {@link applyVerb} returns it, {@link placeVerb} acts on it.
118
- */
119
- export const ABSENT = Symbol('footprintjs.verbs.absent');
120
- /**
121
- * One bundle's recorded payload, read by path under a clone discipline — the
122
- * values {@link applyVerb} reads out of the log.
123
- *
124
- * `detach` — `true` for every fold that keeps its result: a `set` value or an
125
- * `append` tail is a clone of what the log holds and the merge delta comes from
126
- * ONE detached copy of `updates`, so the result never aliases the log. `false`
127
- * only for the comparison fold ({@link dryFold}), which places recorded values
128
- * as recorded and drops its result.
129
- *
130
- * The delta is detached ONCE per bundle, lazily — a bundle with no `merge` row
131
- * pays nothing. `deepSmartMerge` dedups an array union BY REFERENCE and two
132
- * `merge` rows of one bundle replay the same accumulated delta, so the rows
133
- * must keep seeing the same objects; a clone per row duplicated their elements
134
- * (the differential caught it in the replay; `commitValueAt` carried the bug
135
- * until it folded through here). `only` narrows the copy to ONE path — a
136
- * per-path fold reads nothing else, and must not pay for the rest of the
137
- * bundle.
138
- */
139
- export class RecordedPayload {
140
- updates;
141
- overwrite;
142
- detach;
143
- only;
144
- deltas;
145
- constructor(updates, overwrite, detach, only) {
146
- this.updates = updates;
147
- this.overwrite = overwrite;
148
- this.detach = detach;
149
- this.only = only;
150
- }
151
- /** What a `set` places and an `append` adds: `overwrite[path]`, cloned when detaching. */
152
- value(segs) {
153
- const recorded = nativeGet(this.overwrite, segs);
154
- return this.detach ? structuredClone(recorded) : recorded;
155
- }
156
- /** The accumulated merge delta at `path`: `updates[path]`, from the bundle's one copy. */
157
- delta(segs) {
158
- if (this.deltas === undefined) {
159
- const source = this.only === undefined ? this.updates : atPath(this.updates, this.only);
160
- this.deltas = this.detach ? structuredClone(source) : source;
161
- }
162
- return nativeGet(this.deltas, segs);
163
- }
164
- }
165
- /** `tree` reduced to ONE path: that sub-tree, by reference, under fresh containers. */
166
- function atPath(tree, segs) {
167
- const leaf = nativeGet(tree, segs);
168
- return leaf === undefined ? {} : nativeSet({}, segs, leaf);
169
- }
170
- /**
171
- * ONE row, ONE step: the value at the row's path AFTER the row, given the
172
- * value BEFORE it and the bundle's recorded payload. THE verb law — no other
173
- * function in the library has an arm per verb.
174
- *
175
- * - `'set'` — the recorded value (`overwrite[path]`, the full final value).
176
- * - `'merge'` — `deepSmartMerge` of the accumulated `updates[path]` delta onto
177
- * the value before.
178
- * - `'append'` — (delta mode) `overwrite[path]` holds ONLY the tail: concatenate
179
- * it onto the value before. When either is not an array (an out-of-order
180
- * replay base, or a REDACTED tail — `scrubPatch` replaces matched payloads
181
- * with the `'REDACTED'` string) the tail BECOMES the value — the same
182
- * terminal value a redacted or corrupt `set` produces.
183
- * - `'delete'` — {@link ABSENT}: the key is removed. The path stays enumerated
184
- * in `overwrite` (value `undefined`) for key-set consumers; the step ignores
185
- * that value.
186
- *
187
- * Pure: it reads the payload and never writes. `verb` must be a {@link Verb}
188
- * (the folds check with {@link isVerb} first and name the row); anything else
189
- * that reaches it is refused with {@link UnknownVerbError}.
190
- */
191
- export function applyVerb(verb, before, at, segs) {
192
- if (verb === 'set')
193
- return at.value(segs);
194
- if (verb === 'append') {
195
- const tail = at.value(segs);
196
- return Array.isArray(before) && Array.isArray(tail) ? [...before, ...tail] : tail;
197
- }
198
- if (verb === 'delete')
199
- return ABSENT;
200
- if (verb === 'merge')
201
- return deepSmartMerge(before, at.delta(segs));
202
- return refuseVerb(verb); // `verb` is `never` here — a fifth verb in the union stops compiling
203
- }
204
- /** Put a step's value at its path in `out` — or remove the key, for {@link ABSENT}. */
205
- export function placeVerb(out, segs, next) {
206
- if (next === ABSENT)
207
- nativeDelete(out, segs);
208
- else
209
- nativeSet(out, segs, next);
210
- }
211
- /**
212
- * Is row `i` a `set` that the NEXT row sets again — same path, same verb — so
213
- * that applying it is work the next row redoes?
214
- *
215
- * The one skip every replay iterator shares (9.22.1). A `set` row writes a
216
- * clone of the recorded value at its path; the next row, a `set` of the same
217
- * path, writes a clone of the SAME recorded value over it (the bundle's patch
218
- * tree is fixed), and nothing runs in between — so the first write is
219
- * unobservable, container creation and key order included. Only CONSECUTIVE
220
- * rows qualify: a row in between (an ancestor `merge`, a sibling `set` that
221
- * creates a container) can see the intermediate value, and a `merge`,
222
- * `append` or `delete` next row depends on what is there. Rows are never
223
- * dropped from the log — the 9.22.0 element-write funnel records N
224
- * whole-array `set` rows on one path, and this is what makes replaying them
225
- * O(N) instead of O(N × rows).
226
- *
227
- * Asked by {@link foldRows} — live state and the redacted mirror through
228
- * {@link nextGeneration}, `EventLog.materialise` and `stateAt` through
229
- * {@link applySmartMergeInto}, the public {@link applySmartMerge}, and the
230
- * admitted record's {@link dryFold}. {@link foldKey} needs no skip: it
231
- * anchors at the top-level key's LAST `set`/`delete`, or (provenance) a
232
- * repeated `set` of the one recorded value changes no birth.
233
- */
234
- export function supersededByNextSet(rows, i) {
235
- const row = rows[i];
236
- if (row.verb !== 'set')
237
- return false;
238
- const next = rows[i + 1];
239
- return next !== undefined && next.verb === 'set' && next.path === row.path;
240
- }
241
- /** Does any row write THROUGH a container (a delimited, nested path)? */
242
- function hasNestedRow(rows) {
243
- for (let i = 0; i < rows.length; i++)
244
- if (rows[i].path.indexOf(DELIM) !== -1)
245
- return true;
246
- return false;
247
- }
248
- /**
249
- * Fold one bundle's rows into `out`, in place: for each row (a `set` the next
250
- * row sets again is skipped — {@link supersededByNextSet}) take the step
251
- * ({@link applyVerb}) and put its value where it belongs ({@link placeVerb}).
252
- * `out` is the caller's — see {@link Discipline} for what it must be.
253
- *
254
- * A row whose verb is not one of {@link VERBS} stops the fold with
255
- * {@link UnknownVerbError} naming the row; the rows before it have been
256
- * applied, to a state the caller discards (every in-tree caller does).
257
- */
258
- export function foldRows(out, updates, overwrite, rows, discipline) {
259
- const detach = discipline !== 'byReference';
260
- const owned = discipline !== 'private' && hasNestedRow(rows) ? new WeakSet() : undefined;
261
- own(out, owned);
262
- const at = new RecordedPayload(updates, overwrite, detach);
263
- for (let i = 0; i < rows.length; i++) {
264
- if (supersededByNextSet(rows, i))
265
- continue;
266
- const { path, verb } = rows[i];
267
- if (!isVerb(verb))
268
- throw new UnknownVerbError(verb, { path, row: i });
269
- const segs = path.split(DELIM);
270
- if (owned !== undefined && segs.length > 1)
271
- ownSpine(out, segs, owned);
272
- // A total verb reads nothing from what came before it (isTotal) — so the
273
- // fold does not look.
274
- const next = applyVerb(verb, isTotal(verb) ? undefined : nativeGet(out, segs), at, segs);
275
- // A value this fold CREATED is its own to edit in place; a recorded value
276
- // placed by reference is the log's.
277
- if (detach || verb === 'merge')
278
- own(next, owned);
279
- placeVerb(out, segs, next);
280
- }
281
- return out;
282
- }
283
- /**
284
- * Applies a commit bundle to a base state by replaying operations in order.
285
- * Guarantees "last writer wins" semantics.
286
- *
287
- * Returns a FULLY DETACHED result: the base is deep-cloned first and every
288
- * value the replay writes is its own (`set` / `append` clone the recorded
289
- * value; the `merge` arm reads a detached copy of `updates`), so the result
290
- * shares no container with `base`, `updates` or `overwrite`. This is the
291
- * public (`footprintjs/trace`; also `/advanced` until 10.0.0) contract, unchanged by copy-on-write
292
- * (9.29.0) — byte-identical to 9.28.0 for every caller. The engine's own
293
- * commit does NOT come here: `SharedMemory.applyPatch` builds the next
294
- * generation with `nextGeneration`, which copies only the written
295
- * paths. Both run the ONE fold, {@link foldRows}; the verbs are
296
- * {@link applyVerb}'s.
297
- *
298
- * Verb arms — see {@link applyVerb}. A row with any other verb throws
299
- * {@link UnknownVerbError}.
300
- *
301
- * Work, not bytes (9.22.1): a `set` row the NEXT row re-sets is skipped
302
- * ({@link supersededByNextSet}) — the rows stay in the log, only the clone
303
- * each would have paid is not. Every consumer inherits the skip from
304
- * `foldRows`; there is no second replay loop to keep in step.
305
- */
306
- export function applySmartMerge(base, updates, overwrite, trace) {
307
- return foldRows(structuredClone(base), updates, overwrite, trace, 'private');
308
- }
309
- /**
310
- * The engine's commit (copy-on-write, 9.29.0 — docs/design/2026-10-copy-on-
311
- * write-commit.md): the NEXT committed generation. A copy of `base`'s ROOT
312
- * plus a copy of every container on each written path; every other subtree
313
- * is SHARED with `base`, which is never edited — committed state is
314
- * immutable-after-swap, so sharing is safe, and a commit costs O(what it
315
- * wrote), not O(state). `SharedMemory.applyPatch` (live state and the
316
- * redacted mirror) is its caller. Internal: the public replay is
317
- * {@link applySmartMerge}.
318
- */
319
- export function nextGeneration(base, updates, overwrite, trace) {
320
- return foldRows(ownedRootOf(base), updates, overwrite, trace, 'pathCopy');
321
- }
322
- /**
323
- * The same replay, INTO `target` — no clone of its own. For a caller that
324
- * already holds a private working copy (the read-side folds: `stateAt` in
325
- * `time-travel/stateAt.ts` and `EventLog.materialise` clone their base ONCE
326
- * and then apply every bundle here), so a fold over N bundles costs N row
327
- * applications, not N clones of the whole state. Never hand it committed
328
- * state: it mutates the ROOT in place. Below the root it follows the live
329
- * commit's law ({@link nextGeneration}) — a container this call did not
330
- * create is copied before a write passes through it — so a fold and the live
331
- * state give the same value at every path, aliased subtrees included.
332
- * The values it writes are its own, so `target` never aliases the log.
333
- */
334
- export function applySmartMergeInto(target, updates, overwrite, trace) {
335
- return foldRows(target, updates, overwrite, trace, 'pathCopy');
336
- }
337
- /**
338
- * The fold, for COMPARISON only (9.30.0 — the admitted record): `base` with
339
- * the bundle replayed by the one verb law, copy-on-write below the root,
340
- * every recorded value placed BY REFERENCE — no clone, so it costs what the
341
- * bundle wrote and nothing more. It aliases the payload and every subtree of
342
- * `base` the bundle did not write, and edits neither. Never hand it out,
343
- * store it or write through it: `TransactionBuffer` builds one to ask whether
344
- * a bundle folds back to what the stage read, then drops it.
345
- */
346
- export function dryFold(base, updates, overwrite, trace) {
347
- return foldRows(ownedRootOf(base), updates, overwrite, trace, 'byReference');
348
- }
349
- /**
350
- * The value of ONE key after `touches` — EVERY row under its top-level key, in
351
- * commit order, each already checked with {@link isVerb} — folded from an absent
352
- * key, read at the key (`segs`, its DELIM segments): the value rule of
353
- * `keyPaths.ts`, the fold `stateAt` does restricted to one top-level key. Top-level
354
- * keys never interact under the step, so the restriction is exact.
355
- *
356
- * The same step ({@link applyVerb}) and the same discipline as {@link foldRows}'s
357
- * `'pathCopy'`: `set` / `append` values are clones, the merge delta is detached
358
- * once per BUNDLE (narrowed to the top-level key), so two `merge` rows of one
359
- * bundle see the same objects, and a row that writes through a container this
360
- * fold did not create copies it first. Returns `undefined` for an absent key.
361
- * O(the rows under the key's top-level key), not O(the log).
362
- */
363
- export function foldKey(touches, segs, options = {}) {
364
- const root = segs[0];
365
- let from = 0;
366
- if (options.anchored === true) {
367
- for (let i = touches.length - 1; i >= 0; i--) {
368
- if (isTotal(touches[i].verb) && touches[i].path === root) {
369
- from = i;
370
- break;
371
- }
372
- }
373
- }
374
- const state = {};
375
- if (options.start !== undefined)
376
- state[root] = options.start;
377
- let owned = new WeakSet();
378
- owned.add(state);
379
- const observe = options.observe;
380
- const generations = options.generations;
381
- let kept = -1;
382
- let keptBefore;
383
- /** Drop ownership of every container: the next write through one copies it, so a kept value stays as it is. */
384
- const release = () => {
385
- owned = new WeakSet();
386
- owned.add(state);
387
- };
388
- let at;
389
- let atCommit = -1;
390
- for (let i = from; i < touches.length; i++) {
391
- const touch = touches[i];
392
- if (at === undefined || touch.commitIdx !== atCommit) {
393
- if (kept !== -1) {
394
- generations.keep(kept, keptBefore, nativeGet(state, segs));
395
- kept = -1;
396
- release();
397
- }
398
- if (generations !== undefined && generations.at(touch.commitIdx, state)) {
399
- release();
400
- kept = touch.commitIdx;
401
- keptBefore = nativeGet(state, segs);
402
- }
403
- at = new RecordedPayload(touch.bundle.updates, touch.bundle.overwrite, true, [root]);
404
- atCommit = touch.commitIdx;
405
- }
406
- const rowSegs = touch.path === root ? [root] : touch.path.split(DELIM);
407
- const watched = observe !== undefined && (touch.relation !== undefined || options.everyRow === true);
408
- let before;
409
- if (watched) {
410
- before = nativeGet(state, segs);
411
- if (touch.relation === 'inside' && Array.isArray(before))
412
- before = before.slice();
413
- }
414
- if (rowSegs.length > 1)
415
- ownSpine(state, rowSegs, owned);
416
- // A total verb reads nothing from what came before it (isTotal).
417
- const next = applyVerb(touch.verb, isTotal(touch.verb) ? undefined : nativeGet(state, rowSegs), at, rowSegs);
418
- own(next, owned);
419
- placeVerb(state, rowSegs, next);
420
- if (watched)
421
- observe(touch, before, nativeGet(state, segs));
422
- }
423
- if (kept !== -1)
424
- generations.keep(kept, keptBefore, nativeGet(state, segs));
425
- return nativeGet(state, segs);
426
- }
427
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyYnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL21lbW9yeS92ZXJicy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2Qkc7QUFJSCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUM5RixPQUFPLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLFlBQVksQ0FBQztBQVFqRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxNQUFNLEdBQXNFO0lBQ2hGLEdBQUcsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRTtJQUNqQyxLQUFLLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUU7SUFDcEMsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFO0lBQ3BDLE1BQU0sRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRTtDQUNyQyxDQUFDO0FBRUYsNERBQTREO0FBQzVELE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBb0IsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBVyxDQUFDLENBQUM7QUFFbkYseUZBQXlGO0FBQ3pGLE1BQU0sVUFBVSxNQUFNLENBQUMsS0FBYztJQUNuQyxPQUFPLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzFGLENBQUM7QUFF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UUFDRCxJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUFFLFFBQVEsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3hELGlFQUFpRTtRQUNqRSxNQUFNLElBQUksR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzdHLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDakIsU0FBUyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDaEMsSUFBSSxPQUFPO1lBQUUsT0FBTyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzlELENBQUM7SUFDRCxJQUFJLElBQUksS0FBSyxDQUFDLENBQUM7UUFBRSxXQUFZLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsU0FBUyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzdFLE9BQU8sU0FBUyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNoQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiB2ZXJicy50cyDigJQgVEhFIFZFUkIgTEFXIChMMSk6IHRoZSBvbmUgcGxhY2UgYSBjb21taXQgcm93IGJlY29tZXMgYSB2YWx1ZS5cbiAqXG4gKiBBIHJvdyBvZiBhIGNvbW1pdCBidW5kbGUncyBgdHJhY2VgIGNhcnJpZXMgb25lIG9mIGZvdXIgdmVyYnMg4oCUXG4gKiBgc2V0IHwgbWVyZ2UgfCBhcHBlbmQgfCBkZWxldGVgIOKAlCBhbmQgT05FIHN0ZXAgdHVybnMgaXQgaW50byBhIHZhbHVlOlxuICoge0BsaW5rIGFwcGx5VmVyYn0uIFN0YXRlIGlzIGEgbGVmdCBmb2xkIG9mIHRoYXQgc3RlcCAodGhlIGV2ZW50LXNvdXJjaW5nXG4gKiByZWR1Y2VyKToge0BsaW5rIGZvbGRSb3dzfSBmb2xkcyBvbmUgYnVuZGxlJ3Mgcm93cyBpbnRvIGEgc3RhdGUsIGFuZFxuICoge0BsaW5rIGZvbGRLZXl9IGZvbGRzIE9ORSBLRVkgYWNyb3NzIGEgbG9nIOKAlCBldmVyeSByb3cgdW5kZXIgdGhlIGtleSdzXG4gKiB0b3AtbGV2ZWwga2V5LCByZWFkIGF0IHRoZSBrZXkgKHRoZSB2YWx1ZSBydWxlLCBga2V5UGF0aHMudHNgKS4gRXZlcnkgcmVhZGVyXG4gKiBvZiB0aGUgbG9nIHJ1bnMgb25lIG9mIHRoZSB0d28g4oCUXG4gKlxuICogICAtIHRoZSBsaXZlIGNvbW1pdCBhbmQgdGhlIHJlZGFjdGVkIG1pcnJvciAoYG5leHRHZW5lcmF0aW9uYCksXG4gKiAgIC0gdGhlIHB1YmxpYyByZXBsYXkgKGBhcHBseVNtYXJ0TWVyZ2VgKSwgdGhlIHJlYWQtc2lkZSBmb2xkc1xuICogICAgIChgYXBwbHlTbWFydE1lcmdlSW50b2Ag4oCUIGBFdmVudExvZy5tYXRlcmlhbGlzZWAsIGBzdGF0ZUF0YCkgYW5kIHRoZVxuICogICAgIGFkbWl0dGVkIHJlY29yZCdzIGNvbXBhcmlzb24gKGBkcnlGb2xkYCk6IGFsbCB7QGxpbmsgZm9sZFJvd3N9LFxuICogICAtIGBjb21taXRWYWx1ZUF0YCwgYW5kIGBhcnJheVByb3ZlbmFuY2VgIGFzIGFuIE9CU0VSVkVSIG9mIHRoZSBzYW1lIGZvbGQ6XG4gKiAgICAge0BsaW5rIGZvbGRLZXl9LlxuICpcbiAqIFRocmVlIHF1ZXN0aW9ucyB0aGF0IHVzZWQgdG8gYmUgYW5zd2VyZWQgb25jZSBwZXIgcmVhZGVyIGFyZSBhbnN3ZXJlZCBoZXJlXG4gKiBvbmNlOiB3aGF0IGEgdmVyYiBkb2VzIHRvIHRoZSB2YWx1ZSBiZWZvcmUgaXQgKHtAbGluayBhcHBseVZlcmJ9KSwgaG93IHRoZVxuICogcmVzdWx0IGlzIHBsYWNlZCAoe0BsaW5rIHBsYWNlVmVyYn0pLCBhbmQgaG93IHRoZSBsb2cncyBvd24gdmFsdWVzIGFyZVxuICogdHJlYXRlZCBvbiB0aGUgd2F5IGluICh0aGUgY2xvbmUgZGlzY2lwbGluZSDigJQgYSBQQVJBTUVURVIgb2YgdGhlIGZvbGQsIHNlZVxuICoge0BsaW5rIERpc2NpcGxpbmV9IGFuZCB7QGxpbmsgUmVjb3JkZWRQYXlsb2FkfSkuIEEgbmV3IHZlcmIgaXMgb25lIG5ldyBhcm0gb2ZcbiAqIGBhcHBseVZlcmJgIGFuZCBvbmUgcm93IG9mIHRoZSB0cmFpdHMgdGFibGU7IHRoZSBjb21waWxlciByZWZ1c2VzIGVpdGhlclxuICogbWlzc2luZyAoe0BsaW5rIGlzVG90YWx9LCB7QGxpbmsgcmVjb3Jkc1RhaWx9LCB7QGxpbmsgVkVSQlN9KS5cbiAqXG4gKiBBbiBVTktOT1dOIHZlcmIgaXMgcmVmdXNlZCB3aXRoIHtAbGluayBVbmtub3duVmVyYkVycm9yfSwgbmV2ZXIgZm9sZGVkIGFzIGFcbiAqIGBtZXJnZWAgKHRoZSBvbGQgc2lsZW50IGRlZmF1bHQpLiBFbmdpbmUtd3JpdHRlbiBsb2dzIGNhcnJ5IHRoZSBmb3VyLCBzb1xuICogZXZlcnkgZW5naW5lIHJ1biBmb2xkcyBieXRlLWZvci1ieXRlIGFzIGJlZm9yZS5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IENvbW1pdElkeCB9IGZyb20gJy4uL2lkcy9ydW50aW1lU3RhZ2VJZC5qcyc7XG5pbXBvcnQgdHlwZSB7IFBhdGhSZWxhdGlvbiB9IGZyb20gJy4va2V5UGF0aHMuanMnO1xuaW1wb3J0IHsgZGVlcFNtYXJ0TWVyZ2UgfSBmcm9tICcuL21lcmdlLmpzJztcbmltcG9ydCB7IG5hdGl2ZURlbGV0ZSwgbmF0aXZlR2V0LCBuYXRpdmVTZXQsIG93biwgb3duZWRSb290T2YsIG93blNwaW5lIH0gZnJvbSAnLi9wYXRoT3BzLmpzJztcbmltcG9ydCB7IERFTElNLCBwYXRoU2VnbWVudHMgfSBmcm9tICcuL3BhdGhzLmpzJztcbmltcG9ydCB0eXBlIHsgQ29tbWl0QnVuZGxlLCBNZW1vcnlQYXRjaCwgVHJhY2VFbnRyeSB9IGZyb20gJy4vdHlwZXMuanMnO1xuXG4vLyDilIDilIDilIAgVGhlIHZvY2FidWxhcnkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbi8qKiBBIGNvbW1pdCByb3cncyB2ZXJiIOKAlCBgVHJhY2VFbnRyeVsndmVyYiddYCwgdGhlIHVuaW9uIHRoZSB0eXBlcyBmaWxlIGRlY2xhcmVzLiAqL1xuZXhwb3J0IHR5cGUgVmVyYiA9IFRyYWNlRW50cnlbJ3ZlcmInXTtcblxuLyoqXG4gKiBUaGUgdm9jYWJ1bGFyeTogZWFjaCB2ZXJiIHdpdGggdGhlIHR3byB0cmFpdHMgcmVhZGVycyBicmFuY2ggb24sIGluIHRoZVxuICogb3JkZXIgdGhlIGNvbnRyYWN0IG5hbWVzIHRoZW0uIEEgYFJlY29yZGAgb3ZlciB0aGUgdW5pb24g4oCUIHRoZSBjb21waWxlclxuICogcmVmdXNlcyBhIHRhYmxlIHRoYXQgbWlzc2VzIChvciBpbnZlbnRzKSBhIHZlcmIsIHNvIGEgdmVyYiBjYW5ub3QgYmUgYWRkZWRcbiAqIHdpdGhvdXQgc2F5aW5nIHdoYXQgaXQgaXMuXG4gKlxuICogICBgdG90YWxgIOKAlCB0aGUgcm93IGRlY2lkZXMgdGhlIHZhbHVlIEFMT05FOyBpdCByZWFkcyBub3RoaW5nIGZyb20gd2hhdCBjYW1lXG4gKiAgICAgYmVmb3JlIGl0ICh7QGxpbmsgaXNUb3RhbH0pLlxuICogICBgdGFpbGAgIOKAlCB0aGUgcm93IHJlY29yZHMgT05MWSB3aGF0IGl0IGFkZHMsIG5vdCB0aGUgd2hvbGUgdmFsdWVcbiAqICAgICAoe0BsaW5rIHJlY29yZHNUYWlsfSkuXG4gKi9cbmNvbnN0IFRSQUlUUzogUmVjb3JkPFZlcmIsIHsgcmVhZG9ubHkgdG90YWw6IGJvb2xlYW47IHJlYWRvbmx5IHRhaWw6IGJvb2xlYW4gfT4gPSB7XG4gIHNldDogeyB0b3RhbDogdHJ1ZSwgdGFpbDogZmFsc2UgfSxcbiAgbWVyZ2U6IHsgdG90YWw6IGZhbHNlLCB0YWlsOiBmYWxzZSB9LFxuICBhcHBlbmQ6IHsgdG90YWw6IGZhbHNlLCB0YWlsOiB0cnVlIH0sXG4gIGRlbGV0ZTogeyB0b3RhbDogdHJ1ZSwgdGFpbDogZmFsc2UgfSxcbn07XG5cbi8qKiBUaGUgZm91ciB2ZXJicywgaW4gdGhlIG9yZGVyIHRoZSBjb250cmFjdCBuYW1lcyB0aGVtLiAqL1xuZXhwb3J0IGNvbnN0IFZFUkJTOiByZWFkb25seSBWZXJiW10gPSBPYmplY3QuZnJlZXplKE9iamVjdC5rZXlzKFRSQUlUUykgYXMgVmVyYltdKTtcblxuLyoqIElzIGB2YWx1ZWAgb25lIG9mIHRoZSBmb3VyPyBUaGUgcXVlc3Rpb24gZXZlcnkgcmVhZGVyIG9mIGEgZm9yZWlnbiBsb2cgYXNrcyBmaXJzdC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZlcmIodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBWZXJiIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKFRSQUlUUywgdmFsdWUpO1xufVxuXG4vKipcbiAqIERvZXMgdGhlIHZlcmIgZGVjaWRlIHRoZSB2YWx1ZSBBTE9ORSDigJQgcmVhZCBub3RoaW5nIGZyb20gd2hhdCBjYW1lIGJlZm9yZVxuICogaXQ/IGBzZXRgIGFuZCBgZGVsZXRlYC4gQSByZWFkZXIgdGhhdCBvbmx5IG5lZWRzIHRoZSBmaW5hbCB2YWx1ZSBtYXkgc3RhcnRcbiAqIGF0IHRoZSBsYXN0IHN1Y2ggcm93ICh7QGxpbmsgZm9sZEtleX0gYGFuY2hvcmVkYCk7IG9uZSB0aGF0IHRyYWNrcyBob3cgdGhlXG4gKiB2YWx1ZSBncmV3IChwcm92ZW5hbmNlKSBzdGFydHMgYXQgdGhlIGZpcnN0LiBQaW5uZWQgYWdhaW5zdFxuICoge0BsaW5rIGFwcGx5VmVyYn0gaXRzZWxmLCBzbyBhIG5ldyB2ZXJiIGNhbm5vdCBtaXNyZXBvcnQgaXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1RvdGFsKHZlcmI6IFZlcmIpOiBib29sZWFuIHtcbiAgcmV0dXJuIFRSQUlUU1t2ZXJiXS50b3RhbDtcbn1cblxuLyoqXG4gKiBEb2VzIHRoZSByb3cgcmVjb3JkIE9OTFkgd2hhdCBpdCBhZGRzIOKAlCBhIHRhaWwg4oCUIHJhdGhlciB0aGFuIHRoZSB3aG9sZVxuICogdmFsdWU/IGBhcHBlbmRgLiBXaGF0IHRoZSByb3cgYWRkZWQgaXMgdGhlbiBrbm93biBleGFjdGx5OiBhIHJlYWRlciB0aGF0XG4gKiB0cmFja3Mgd2hlcmUgYXJyYXkgZWxlbWVudHMgY2FtZSBmcm9tIGF0dHJpYnV0ZXMgdGhlbSB0byB0aGlzIHJvdyB3aXRob3V0XG4gKiBjb21wYXJpbmcgYXJyYXlzLCB3aGVyZSBldmVyeSBvdGhlciB2ZXJiIGhhcyB0byBiZSBpbmZlcnJlZCBmcm9tLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3Jkc1RhaWwodmVyYjogVmVyYik6IGJvb2xlYW4ge1xuICByZXR1cm4gVFJBSVRTW3ZlcmJdLnRhaWw7XG59XG5cbi8qKiBXaGVyZSBpbiBhIGxvZyBhIHJlZnVzZWQgcm93IHNpdHMuICovXG5leHBvcnQgaW50ZXJmYWNlIFJvd1NpdGUge1xuICAvKiogVGhlIHJvdydzIGBwYXRoYCwgREVMSU0tam9pbmVkIGFzIHRoZSB0cmFjZSByZWNvcmRzIGl0LiAqL1xuICByZWFkb25seSBwYXRoOiBzdHJpbmc7XG4gIC8qKiBUaGUgcm93J3MgcG9zaXRpb24gaW4gaXRzIGJ1bmRsZSdzIGB0cmFjZWAuICovXG4gIHJlYWRvbmx5IHJvdzogbnVtYmVyO1xuICAvKiogVGhlIGJ1bmRsZSdzIHBvc2l0aW9uIGluIHRoZSBjb21taXQgbG9nLCB3aGVuIHRoZSByZWFkZXIga25vd3MgaXQuICovXG4gIHJlYWRvbmx5IGNvbW1pdD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBUaHJvd24gYnkgdGhlIHJlYWRlcnMgb2YgYSBjb21taXQgbG9nIOKAlCB7QGxpbmsgZm9sZFJvd3N9IChiZWhpbmRcbiAqIGBhcHBseVNtYXJ0TWVyZ2VgKSwgYGNvbW1pdFZhbHVlQXRgLCBgYXJyYXlQcm92ZW5hbmNlYCDigJQgd2hlbiBhIHJvdyBjYXJyaWVzIGFcbiAqIHZlcmIgb3V0c2lkZSB7QGxpbmsgVkVSQlN9OiBhIGZvcmVpZ24gb3IgY29ycnVwdGVkIGxvZyBmYWlscyBsb3VkbHkgaW5zdGVhZFxuICogb2YgYmVpbmcgcmVwbGF5ZWQgYXMgYSBgbWVyZ2VgLiBgdmVyYmAsIGBwYXRoYCwgYHJvd2AgYW5kIGBjb21taXRgIG5hbWUgdGhlXG4gKiByb3cgKGBwYXRoYCAvIGByb3dgIC8gYGNvbW1pdGAgYXJlIGFic2VudCB3aGVuIHRoZSBjYWxsZXIgaGFuZGVkIG92ZXIgYVxuICogYmFyZSB2ZXJiKTsgYHBhdGhgIGlzIHRoZSB0cmFjZSdzIG93biBERUxJTS1qb2luZWQgZm9ybSDigJQgdGFrZSBpdCBhcGFydCB3aXRoXG4gKiBgcGF0aFNlZ21lbnRzYC4gVGhlIG1lc3NhZ2UgcXVvdGVzIGB2ZXJiYCBhbmQgYHBhdGhgLCBzbyBhIGhvc3RpbGUgbG9nIGNhbm5vdFxuICogcmVzaGFwZSBpdC5cbiAqL1xuZXhwb3J0IGNsYXNzIFVua25vd25WZXJiRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIHJlYWRvbmx5IHZlcmI6IHVua25vd247XG4gIHJlYWRvbmx5IHBhdGg/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHJvdz86IG51bWJlcjtcbiAgcmVhZG9ubHkgY29tbWl0PzogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKHZlcmI6IHVua25vd24sIHNpdGU/OiBSb3dTaXRlKSB7XG4gICAgY29uc3QgbmFtZWQgPVxuICAgICAgdHlwZW9mIHZlcmIgPT09ICdzdHJpbmcnID8gSlNPTi5zdHJpbmdpZnkodmVyYikgOiB2ZXJiID09PSB1bmRlZmluZWQgPyAndW5kZWZpbmVkJyA6IGBvZiB0eXBlICR7dHlwZW9mIHZlcmJ9YDtcbiAgICAvLyBUaGUgdmVyYiBhbmQgdGhlIHBhdGggY29tZSBmcm9tIGEgbG9nIG5vYm9keSB2ZXR0ZWQ6IHF1b3RlZCAoSlNPTiksIHNvIGFcbiAgICAvLyBjb250cm9sIGNoYXJhY3RlciBpbiBlaXRoZXIgY2Fubm90IHJlc2hhcGUgdGhlIG1lc3NhZ2UuXG4gICAgY29uc3Qgd2hlcmUgPVxuICAgICAgc2l0ZSA9PT0gdW5kZWZpbmVkXG4gICAgICAgID8gJydcbiAgICAgICAgOiBgIG9uIHRyYWNlIHJvdyAke3NpdGUucm93fSAocGF0aCAke0pTT04uc3RyaW5naWZ5KHBhdGhTZWdtZW50cyhzaXRlLnBhdGgpLmpvaW4oJyDigLogJykpfSR7XG4gICAgICAgICAgICBzaXRlLmNvbW1pdCA9PT0gdW5kZWZpbmVkID8gJycgOiBgLCBjb21taXQgJHtzaXRlLmNvbW1pdH1gXG4gICAgICAgICAgfSlgO1xuICAgIGNvbnN0IG9uZSA9IFZFUkJTLmpvaW4oJyB8ICcpO1xuICAgIHN1cGVyKGB1bmtub3duIHZlcmIgJHtuYW1lZH0ke3doZXJlfTogYSBjb21taXQgcm93IGlzIG9uZSBvZiAke29uZX0g4oCUIHRoZSBsb2cgaXMgcmVmdXNlZCwgbm90IHJlcGxheWVkIGFzIGEgbWVyZ2VgKTtcbiAgICB0aGlzLm5hbWUgPSAnVW5rbm93blZlcmJFcnJvcic7XG4gICAgdGhpcy52ZXJiID0gdmVyYjtcbiAgICBpZiAoc2l0ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnBhdGggPSBzaXRlLnBhdGg7XG4gICAgICB0aGlzLnJvdyA9IHNpdGUucm93O1xuICAgICAgaWYgKHNpdGUuY29tbWl0ICE9PSB1bmRlZmluZWQpIHRoaXMuY29tbWl0ID0gc2l0ZS5jb21taXQ7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHJlZnVzZVZlcmIodmVyYjogbmV2ZXIpOiBuZXZlciB7XG4gIHRocm93IG5ldyBVbmtub3duVmVyYkVycm9yKHZlcmIpO1xufVxuXG4vLyDilIDilIDilIAgVGhlIHN0ZXAg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbi8qKlxuICogV2hhdCBhIGBkZWxldGVgIHJvdyBsZWF2ZXMgYmVoaW5kOiB0aGUgS0VZIElTIEdPTkUg4oCUIHdoaWNoIGlzIG5vdCB0aGUgdmFsdWVcbiAqIGB1bmRlZmluZWRgIChhIHJvb3QgcmVwbGF5IHJlbW92ZXMgdGhlIGtleTsgYSBwZXItcGF0aCBmb2xkIHJlYWRzIGl0IGFzXG4gKiBgdW5kZWZpbmVkYCkuIHtAbGluayBhcHBseVZlcmJ9IHJldHVybnMgaXQsIHtAbGluayBwbGFjZVZlcmJ9IGFjdHMgb24gaXQuXG4gKi9cbmV4cG9ydCBjb25zdCBBQlNFTlQ6IHVuaXF1ZSBzeW1ib2wgPSBTeW1ib2woJ2Zvb3RwcmludGpzLnZlcmJzLmFic2VudCcpO1xuXG4vKipcbiAqIE9uZSBidW5kbGUncyByZWNvcmRlZCBwYXlsb2FkLCByZWFkIGJ5IHBhdGggdW5kZXIgYSBjbG9uZSBkaXNjaXBsaW5lIOKAlCB0aGVcbiAqIHZhbHVlcyB7QGxpbmsgYXBwbHlWZXJifSByZWFkcyBvdXQgb2YgdGhlIGxvZy5cbiAqXG4gKiBgZGV0YWNoYCDigJQgYHRydWVgIGZvciBldmVyeSBmb2xkIHRoYXQga2VlcHMgaXRzIHJlc3VsdDogYSBgc2V0YCB2YWx1ZSBvciBhblxuICogYGFwcGVuZGAgdGFpbCBpcyBhIGNsb25lIG9mIHdoYXQgdGhlIGxvZyBob2xkcyBhbmQgdGhlIG1lcmdlIGRlbHRhIGNvbWVzIGZyb21cbiAqIE9ORSBkZXRhY2hlZCBjb3B5IG9mIGB1cGRhdGVzYCwgc28gdGhlIHJlc3VsdCBuZXZlciBhbGlhc2VzIHRoZSBsb2cuIGBmYWxzZWBcbiAqIG9ubHkgZm9yIHRoZSBjb21wYXJpc29uIGZvbGQgKHtAbGluayBkcnlGb2xkfSksIHdoaWNoIHBsYWNlcyByZWNvcmRlZCB2YWx1ZXNcbiAqIGFzIHJlY29yZGVkIGFuZCBkcm9wcyBpdHMgcmVzdWx0LlxuICpcbiAqIFRoZSBkZWx0YSBpcyBkZXRhY2hlZCBPTkNFIHBlciBidW5kbGUsIGxhemlseSDigJQgYSBidW5kbGUgd2l0aCBubyBgbWVyZ2VgIHJvd1xuICogcGF5cyBub3RoaW5nLiBgZGVlcFNtYXJ0TWVyZ2VgIGRlZHVwcyBhbiBhcnJheSB1bmlvbiBCWSBSRUZFUkVOQ0UgYW5kIHR3b1xuICogYG1lcmdlYCByb3dzIG9mIG9uZSBidW5kbGUgcmVwbGF5IHRoZSBzYW1lIGFjY3VtdWxhdGVkIGRlbHRhLCBzbyB0aGUgcm93c1xuICogbXVzdCBrZWVwIHNlZWluZyB0aGUgc2FtZSBvYmplY3RzOyBhIGNsb25lIHBlciByb3cgZHVwbGljYXRlZCB0aGVpciBlbGVtZW50c1xuICogKHRoZSBkaWZmZXJlbnRpYWwgY2F1Z2h0IGl0IGluIHRoZSByZXBsYXk7IGBjb21taXRWYWx1ZUF0YCBjYXJyaWVkIHRoZSBidWdcbiAqIHVudGlsIGl0IGZvbGRlZCB0aHJvdWdoIGhlcmUpLiBgb25seWAgbmFycm93cyB0aGUgY29weSB0byBPTkUgcGF0aCDigJQgYVxuICogcGVyLXBhdGggZm9sZCByZWFkcyBub3RoaW5nIGVsc2UsIGFuZCBtdXN0IG5vdCBwYXkgZm9yIHRoZSByZXN0IG9mIHRoZVxuICogYnVuZGxlLlxuICovXG5leHBvcnQgY2xhc3MgUmVjb3JkZWRQYXlsb2FkIHtcbiAgcHJpdmF0ZSBkZWx0YXM6IE1lbW9yeVBhdGNoIHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdXBkYXRlczogTWVtb3J5UGF0Y2gsXG4gICAgcHJpdmF0ZSByZWFkb25seSBvdmVyd3JpdGU6IE1lbW9yeVBhdGNoLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZGV0YWNoOiBib29sZWFuLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgb25seT86IHN0cmluZ1tdLFxuICApIHt9XG5cbiAgLyoqIFdoYXQgYSBgc2V0YCBwbGFjZXMgYW5kIGFuIGBhcHBlbmRgIGFkZHM6IGBvdmVyd3JpdGVbcGF0aF1gLCBjbG9uZWQgd2hlbiBkZXRhY2hpbmcuICovXG4gIHZhbHVlKHNlZ3M6IHN0cmluZ1tdKTogdW5rbm93biB7XG4gICAgY29uc3QgcmVjb3JkZWQgPSBuYXRpdmVHZXQodGhpcy5vdmVyd3JpdGUsIHNlZ3MpO1xuICAgIHJldHVybiB0aGlzLmRldGFjaCA/IHN0cnVjdHVyZWRDbG9uZShyZWNvcmRlZCkgOiByZWNvcmRlZDtcbiAgfVxuXG4gIC8qKiBUaGUgYWNjdW11bGF0ZWQgbWVyZ2UgZGVsdGEgYXQgYHBhdGhgOiBgdXBkYXRlc1twYXRoXWAsIGZyb20gdGhlIGJ1bmRsZSdzIG9uZSBjb3B5LiAqL1xuICBkZWx0YShzZWdzOiBzdHJpbmdbXSk6IHVua25vd24ge1xuICAgIGlmICh0aGlzLmRlbHRhcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSB0aGlzLm9ubHkgPT09IHVuZGVmaW5lZCA/IHRoaXMudXBkYXRlcyA6IGF0UGF0aCh0aGlzLnVwZGF0ZXMsIHRoaXMub25seSk7XG4gICAgICB0aGlzLmRlbHRhcyA9IHRoaXMuZGV0YWNoID8gc3RydWN0dXJlZENsb25lKHNvdXJjZSkgOiBzb3VyY2U7XG4gICAgfVxuICAgIHJldHVybiBuYXRpdmVHZXQodGhpcy5kZWx0YXMsIHNlZ3MpO1xuICB9XG59XG5cbi8qKiBgdHJlZWAgcmVkdWNlZCB0byBPTkUgcGF0aDogdGhhdCBzdWItdHJlZSwgYnkgcmVmZXJlbmNlLCB1bmRlciBmcmVzaCBjb250YWluZXJzLiAqL1xuZnVuY3Rpb24gYXRQYXRoKHRyZWU6IE1lbW9yeVBhdGNoLCBzZWdzOiBzdHJpbmdbXSk6IE1lbW9yeVBhdGNoIHtcbiAgY29uc3QgbGVhZiA9IG5hdGl2ZUdldCh0cmVlLCBzZWdzKTtcbiAgcmV0dXJuIGxlYWYgPT09IHVuZGVmaW5lZCA/IHt9IDogbmF0aXZlU2V0KHt9LCBzZWdzLCBsZWFmKTtcbn1cblxuLyoqXG4gKiBPTkUgcm93LCBPTkUgc3RlcDogdGhlIHZhbHVlIGF0IHRoZSByb3cncyBwYXRoIEFGVEVSIHRoZSByb3csIGdpdmVuIHRoZVxuICogdmFsdWUgQkVGT1JFIGl0IGFuZCB0aGUgYnVuZGxlJ3MgcmVjb3JkZWQgcGF5bG9hZC4gVEhFIHZlcmIgbGF3IOKAlCBubyBvdGhlclxuICogZnVuY3Rpb24gaW4gdGhlIGxpYnJhcnkgaGFzIGFuIGFybSBwZXIgdmVyYi5cbiAqXG4gKiAgIC0gYCdzZXQnYCAgICDigJQgdGhlIHJlY29yZGVkIHZhbHVlIChgb3ZlcndyaXRlW3BhdGhdYCwgdGhlIGZ1bGwgZmluYWwgdmFsdWUpLlxuICogICAtIGAnbWVyZ2UnYCAg4oCUIGBkZWVwU21hcnRNZXJnZWAgb2YgdGhlIGFjY3VtdWxhdGVkIGB1cGRhdGVzW3BhdGhdYCBkZWx0YSBvbnRvXG4gKiAgICAgdGhlIHZhbHVlIGJlZm9yZS5cbiAqICAgLSBgJ2FwcGVuZCdgIOKAlCAoZGVsdGEgbW9kZSkgYG92ZXJ3cml0ZVtwYXRoXWAgaG9sZHMgT05MWSB0aGUgdGFpbDogY29uY2F0ZW5hdGVcbiAqICAgICBpdCBvbnRvIHRoZSB2YWx1ZSBiZWZvcmUuIFdoZW4gZWl0aGVyIGlzIG5vdCBhbiBhcnJheSAoYW4gb3V0LW9mLW9yZGVyXG4gKiAgICAgcmVwbGF5IGJhc2UsIG9yIGEgUkVEQUNURUQgdGFpbCDigJQgYHNjcnViUGF0Y2hgIHJlcGxhY2VzIG1hdGNoZWQgcGF5bG9hZHNcbiAqICAgICB3aXRoIHRoZSBgJ1JFREFDVEVEJ2Agc3RyaW5nKSB0aGUgdGFpbCBCRUNPTUVTIHRoZSB2YWx1ZSDigJQgdGhlIHNhbWVcbiAqICAgICB0ZXJtaW5hbCB2YWx1ZSBhIHJlZGFjdGVkIG9yIGNvcnJ1cHQgYHNldGAgcHJvZHVjZXMuXG4gKiAgIC0gYCdkZWxldGUnYCDigJQge0BsaW5rIEFCU0VOVH06IHRoZSBrZXkgaXMgcmVtb3ZlZC4gVGhlIHBhdGggc3RheXMgZW51bWVyYXRlZFxuICogICAgIGluIGBvdmVyd3JpdGVgICh2YWx1ZSBgdW5kZWZpbmVkYCkgZm9yIGtleS1zZXQgY29uc3VtZXJzOyB0aGUgc3RlcCBpZ25vcmVzXG4gKiAgICAgdGhhdCB2YWx1ZS5cbiAqXG4gKiBQdXJlOiBpdCByZWFkcyB0aGUgcGF5bG9hZCBhbmQgbmV2ZXIgd3JpdGVzLiBgdmVyYmAgbXVzdCBiZSBhIHtAbGluayBWZXJifVxuICogKHRoZSBmb2xkcyBjaGVjayB3aXRoIHtAbGluayBpc1ZlcmJ9IGZpcnN0IGFuZCBuYW1lIHRoZSByb3cpOyBhbnl0aGluZyBlbHNlXG4gKiB0aGF0IHJlYWNoZXMgaXQgaXMgcmVmdXNlZCB3aXRoIHtAbGluayBVbmtub3duVmVyYkVycm9yfS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5VmVyYih2ZXJiOiBWZXJiLCBiZWZvcmU6IHVua25vd24sIGF0OiBSZWNvcmRlZFBheWxvYWQsIHNlZ3M6IHN0cmluZ1tdKTogdW5rbm93biB7XG4gIGlmICh2ZXJiID09PSAnc2V0JykgcmV0dXJuIGF0LnZhbHVlKHNlZ3MpO1xuICBpZiAodmVyYiA9PT0gJ2FwcGVuZCcpIHtcbiAgICBjb25zdCB0YWlsID0gYXQudmFsdWUoc2Vncyk7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYmVmb3JlKSAmJiBBcnJheS5pc0FycmF5KHRhaWwpID8gWy4uLmJlZm9yZSwgLi4udGFpbF0gOiB0YWlsO1xuICB9XG4gIGlmICh2ZXJiID09PSAnZGVsZXRlJykgcmV0dXJuIEFCU0VOVDtcbiAgaWYgKHZlcmIgPT09ICdtZXJnZScpIHJldHVybiBkZWVwU21hcnRNZXJnZShiZWZvcmUsIGF0LmRlbHRhKHNlZ3MpKTtcbiAgcmV0dXJuIHJlZnVzZVZlcmIodmVyYik7IC8vIGB2ZXJiYCBpcyBgbmV2ZXJgIGhlcmUg4oCUIGEgZmlmdGggdmVyYiBpbiB0aGUgdW5pb24gc3RvcHMgY29tcGlsaW5nXG59XG5cbi8qKiBQdXQgYSBzdGVwJ3MgdmFsdWUgYXQgaXRzIHBhdGggaW4gYG91dGAg4oCUIG9yIHJlbW92ZSB0aGUga2V5LCBmb3Ige0BsaW5rIEFCU0VOVH0uICovXG5leHBvcnQgZnVuY3Rpb24gcGxhY2VWZXJiKG91dDogYW55LCBzZWdzOiBzdHJpbmdbXSwgbmV4dDogdW5rbm93bik6IHZvaWQge1xuICBpZiAobmV4dCA9PT0gQUJTRU5UKSBuYXRpdmVEZWxldGUob3V0LCBzZWdzKTtcbiAgZWxzZSBuYXRpdmVTZXQob3V0LCBzZWdzLCBuZXh0KTtcbn1cblxuLyoqXG4gKiBJcyByb3cgYGlgIGEgYHNldGAgdGhhdCB0aGUgTkVYVCByb3cgc2V0cyBhZ2FpbiDigJQgc2FtZSBwYXRoLCBzYW1lIHZlcmIg4oCUIHNvXG4gKiB0aGF0IGFwcGx5aW5nIGl0IGlzIHdvcmsgdGhlIG5leHQgcm93IHJlZG9lcz9cbiAqXG4gKiBUaGUgb25lIHNraXAgZXZlcnkgcmVwbGF5IGl0ZXJhdG9yIHNoYXJlcyAoOS4yMi4xKS4gQSBgc2V0YCByb3cgd3JpdGVzIGFcbiAqIGNsb25lIG9mIHRoZSByZWNvcmRlZCB2YWx1ZSBhdCBpdHMgcGF0aDsgdGhlIG5leHQgcm93LCBhIGBzZXRgIG9mIHRoZSBzYW1lXG4gKiBwYXRoLCB3cml0ZXMgYSBjbG9uZSBvZiB0aGUgU0FNRSByZWNvcmRlZCB2YWx1ZSBvdmVyIGl0ICh0aGUgYnVuZGxlJ3MgcGF0Y2hcbiAqIHRyZWUgaXMgZml4ZWQpLCBhbmQgbm90aGluZyBydW5zIGluIGJldHdlZW4g4oCUIHNvIHRoZSBmaXJzdCB3cml0ZSBpc1xuICogdW5vYnNlcnZhYmxlLCBjb250YWluZXIgY3JlYXRpb24gYW5kIGtleSBvcmRlciBpbmNsdWRlZC4gT25seSBDT05TRUNVVElWRVxuICogcm93cyBxdWFsaWZ5OiBhIHJvdyBpbiBiZXR3ZWVuIChhbiBhbmNlc3RvciBgbWVyZ2VgLCBhIHNpYmxpbmcgYHNldGAgdGhhdFxuICogY3JlYXRlcyBhIGNvbnRhaW5lcikgY2FuIHNlZSB0aGUgaW50ZXJtZWRpYXRlIHZhbHVlLCBhbmQgYSBgbWVyZ2VgLFxuICogYGFwcGVuZGAgb3IgYGRlbGV0ZWAgbmV4dCByb3cgZGVwZW5kcyBvbiB3aGF0IGlzIHRoZXJlLiBSb3dzIGFyZSBuZXZlclxuICogZHJvcHBlZCBmcm9tIHRoZSBsb2cg4oCUIHRoZSA5LjIyLjAgZWxlbWVudC13cml0ZSBmdW5uZWwgcmVjb3JkcyBOXG4gKiB3aG9sZS1hcnJheSBgc2V0YCByb3dzIG9uIG9uZSBwYXRoLCBhbmQgdGhpcyBpcyB3aGF0IG1ha2VzIHJlcGxheWluZyB0aGVtXG4gKiBPKE4pIGluc3RlYWQgb2YgTyhOIMOXIHJvd3MpLlxuICpcbiAqIEFza2VkIGJ5IHtAbGluayBmb2xkUm93c30g4oCUIGxpdmUgc3RhdGUgYW5kIHRoZSByZWRhY3RlZCBtaXJyb3IgdGhyb3VnaFxuICoge0BsaW5rIG5leHRHZW5lcmF0aW9ufSwgYEV2ZW50TG9nLm1hdGVyaWFsaXNlYCBhbmQgYHN0YXRlQXRgIHRocm91Z2hcbiAqIHtAbGluayBhcHBseVNtYXJ0TWVyZ2VJbnRvfSwgdGhlIHB1YmxpYyB7QGxpbmsgYXBwbHlTbWFydE1lcmdlfSwgYW5kIHRoZVxuICogYWRtaXR0ZWQgcmVjb3JkJ3Mge0BsaW5rIGRyeUZvbGR9LiB7QGxpbmsgZm9sZEtleX0gbmVlZHMgbm8gc2tpcDogaXRcbiAqIGFuY2hvcnMgYXQgdGhlIHRvcC1sZXZlbCBrZXkncyBMQVNUIGBzZXRgL2BkZWxldGVgLCBvciAocHJvdmVuYW5jZSkgYVxuICogcmVwZWF0ZWQgYHNldGAgb2YgdGhlIG9uZSByZWNvcmRlZCB2YWx1ZSBjaGFuZ2VzIG5vIGJpcnRoLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3VwZXJzZWRlZEJ5TmV4dFNldChyb3dzOiByZWFkb25seSB7IHBhdGg6IHN0cmluZzsgdmVyYjogc3RyaW5nIH1bXSwgaTogbnVtYmVyKTogYm9vbGVhbiB7XG4gIGNvbnN0IHJvdyA9IHJvd3NbaV07XG4gIGlmIChyb3cudmVyYiAhPT0gJ3NldCcpIHJldHVybiBmYWxzZTtcbiAgY29uc3QgbmV4dCA9IHJvd3NbaSArIDFdO1xuICByZXR1cm4gbmV4dCAhPT0gdW5kZWZpbmVkICYmIG5leHQudmVyYiA9PT0gJ3NldCcgJiYgbmV4dC5wYXRoID09PSByb3cucGF0aDtcbn1cblxuLy8g4pSA4pSA4pSAIFRoZSBmb2xkIG92ZXIgb25lIGJ1bmRsZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuLyoqXG4gKiBIb3cge0BsaW5rIGZvbGRSb3dzfSB0cmVhdHMgdGhlIHN0YXRlIGl0IGVkaXRzIGFuZCB0aGUgdmFsdWVzIGl0IHJlYWRzIG91dCBvZlxuICogdGhlIGxvZyDigJQgdGhlIGNsb25lIGRpc2NpcGxpbmUsIGEgcGFyYW1ldGVyIG9mIHRoZSBPTkUgbG9vcDpcbiAqXG4gKiAgIC0gYCdwcml2YXRlJ2Ag4oCUIGBvdXRgIGlzIGEgcHJpdmF0ZSBkZWVwIGNsb25lLCBlZGl0ZWQgaW4gcGxhY2U7IGV2ZXJ5XG4gKiAgICAgcmVjb3JkZWQgdmFsdWUgaXMgY2xvbmVkIGluLiBUaGUgcHVibGljIHtAbGluayBhcHBseVNtYXJ0TWVyZ2V9LlxuICogICAtIGAncGF0aENvcHknYCDigJQgY29weS1vbi13cml0ZSAoOS4yOS4wKTogYmVmb3JlIGEgcm93IHRoYXQgd3JpdGVzIFRIUk9VR0ggYVxuICogICAgIGNvbnRhaW5lciAoYSBuZXN0ZWQgcGF0aCksIHRoZSBjb250YWluZXJzIG9uIGl0cyBwYXRoIHRoYXQgdGhpcyBmb2xkIGRpZFxuICogICAgIG5vdCBjcmVhdGUgYXJlIGNvcGllZCwgc28gbm8gcm93IGVkaXRzIGEgY29udGFpbmVyIGFub3RoZXIgZ2VuZXJhdGlvblxuICogICAgIChvciB0aGUgbG9nKSBob2xkczsgZWFjaCB2YWx1ZSBhIHJvdyBjcmVhdGVzIGlzIG1hcmtlZCBvd25lZCwgc28gbGF0ZXJcbiAqICAgICByb3dzIG9mIHRoZSBidW5kbGUgd3JpdGUgaW50byBpdCBpbiBwbGFjZS4gRXZlcnkgcmVjb3JkZWQgdmFsdWUgaXMgY2xvbmVkXG4gKiAgICAgaW4uIFRoZSBsaXZlIGNvbW1pdCAoe0BsaW5rIG5leHRHZW5lcmF0aW9ufSkgYW5kIHRoZSByZWFkLXNpZGUgZm9sZHNcbiAqICAgICAoe0BsaW5rIGFwcGx5U21hcnRNZXJnZUludG99KS5cbiAqICAgLSBgJ2J5UmVmZXJlbmNlJ2Ag4oCUIGAncGF0aENvcHknYCwgYnV0IHJlY29yZGVkIHZhbHVlcyBhcmUgcGxhY2VkIEFTXG4gKiAgICAgUkVDT1JERUQgKG5vIGNsb25lKSBhbmQgbmV2ZXIgbWFya2VkIG93bmVkIOKAlCBhIGxhdGVyIHJvdyB0aGF0IHdyaXRlc1xuICogICAgIHRocm91Z2ggb25lIGNvcGllcyBpdCBmaXJzdCwgc28gdGhlIHBheWxvYWQgaXMgbmV2ZXIgZWRpdGVkLiBGb3JcbiAqICAgICBDT01QQVJJU09OIG9ubHkgKHtAbGluayBkcnlGb2xkfSk6IHRoZSByZXN1bHQgYWxpYXNlcyB0aGUgbG9nLlxuICovXG5leHBvcnQgdHlwZSBEaXNjaXBsaW5lID0gJ3ByaXZhdGUnIHwgJ3BhdGhDb3B5JyB8ICdieVJlZmVyZW5jZSc7XG5cbi8qKiBEb2VzIGFueSByb3cgd3JpdGUgVEhST1VHSCBhIGNvbnRhaW5lciAoYSBkZWxpbWl0ZWQsIG5lc3RlZCBwYXRoKT8gKi9cbmZ1bmN0aW9uIGhhc05lc3RlZFJvdyhyb3dzOiByZWFkb25seSBUcmFjZUVudHJ5W10pOiBib29sZWFuIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzLmxlbmd0aDsgaSsrKSBpZiAocm93c1tpXS5wYXRoLmluZGV4T2YoREVMSU0pICE9PSAtMSkgcmV0dXJuIHRydWU7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBGb2xkIG9uZSBidW5kbGUncyByb3dzIGludG8gYG91dGAsIGluIHBsYWNlOiBmb3IgZWFjaCByb3cgKGEgYHNldGAgdGhlIG5leHRcbiAqIHJvdyBzZXRzIGFnYWluIGlzIHNraXBwZWQg4oCUIHtAbGluayBzdXBlcnNlZGVkQnlOZXh0U2V0fSkgdGFrZSB0aGUgc3RlcFxuICogKHtAbGluayBhcHBseVZlcmJ9KSBhbmQgcHV0IGl0cyB2YWx1ZSB3aGVyZSBpdCBiZWxvbmdzICh7QGxpbmsgcGxhY2VWZXJifSkuXG4gKiBgb3V0YCBpcyB0aGUgY2FsbGVyJ3Mg4oCUIHNlZSB7QGxpbmsgRGlzY2lwbGluZX0gZm9yIHdoYXQgaXQgbXVzdCBiZS5cbiAqXG4gKiBBIHJvdyB3aG9zZSB2ZXJiIGlzIG5vdCBvbmUgb2Yge0BsaW5rIFZFUkJTfSBzdG9wcyB0aGUgZm9sZCB3aXRoXG4gKiB7QGxpbmsgVW5rbm93blZlcmJFcnJvcn0gbmFtaW5nIHRoZSByb3c7IHRoZSByb3dzIGJlZm9yZSBpdCBoYXZlIGJlZW5cbiAqIGFwcGxpZWQsIHRvIGEgc3RhdGUgdGhlIGNhbGxlciBkaXNjYXJkcyAoZXZlcnkgaW4tdHJlZSBjYWxsZXIgZG9lcykuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb2xkUm93cyhcbiAgb3V0OiBhbnksXG4gIHVwZGF0ZXM6IE1lbW9yeVBhdGNoLFxuICBvdmVyd3JpdGU6IE1lbW9yeVBhdGNoLFxuICByb3dzOiByZWFkb25seSBUcmFjZUVudHJ5W10sXG4gIGRpc2NpcGxpbmU6IERpc2NpcGxpbmUsXG4pOiBhbnkge1xuICBjb25zdCBkZXRhY2ggPSBkaXNjaXBsaW5lICE9PSAnYnlSZWZlcmVuY2UnO1xuICBjb25zdCBvd25lZCA9IGRpc2NpcGxpbmUgIT09ICdwcml2YXRlJyAmJiBoYXNOZXN0ZWRSb3cocm93cykgPyBuZXcgV2Vha1NldDxvYmplY3Q+KCkgOiB1bmRlZmluZWQ7XG4gIG93bihvdXQsIG93bmVkKTtcbiAgY29uc3QgYXQgPSBuZXcgUmVjb3JkZWRQYXlsb2FkKHVwZGF0ZXMsIG92ZXJ3cml0ZSwgZGV0YWNoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHN1cGVyc2VkZWRCeU5leHRTZXQocm93cywgaSkpIGNvbnRpbnVlO1xuICAgIGNvbnN0IHsgcGF0aCwgdmVyYiB9ID0gcm93c1tpXTtcbiAgICBpZiAoIWlzVmVyYih2ZXJiKSkgdGhyb3cgbmV3IFVua25vd25WZXJiRXJyb3IodmVyYiwgeyBwYXRoLCByb3c6IGkgfSk7XG4gICAgY29uc3Qgc2VncyA9IHBhdGguc3BsaXQoREVMSU0pO1xuICAgIGlmIChvd25lZCAhPT0gdW5kZWZpbmVkICYmIHNlZ3MubGVuZ3RoID4gMSkgb3duU3BpbmUob3V0LCBzZWdzLCBvd25lZCk7XG4gICAgLy8gQSB0b3RhbCB2ZXJiIHJlYWRzIG5vdGhpbmcgZnJvbSB3aGF0IGNhbWUgYmVmb3JlIGl0IChpc1RvdGFsKSDigJQgc28gdGhlXG4gICAgLy8gZm9sZCBkb2VzIG5vdCBsb29rLlxuICAgIGNvbnN0IG5leHQgPSBhcHBseVZlcmIodmVyYiwgaXNUb3RhbCh2ZXJiKSA/IHVuZGVmaW5lZCA6IG5hdGl2ZUdldChvdXQsIHNlZ3MpLCBhdCwgc2Vncyk7XG4gICAgLy8gQSB2YWx1ZSB0aGlzIGZvbGQgQ1JFQVRFRCBpcyBpdHMgb3duIHRvIGVkaXQgaW4gcGxhY2U7IGEgcmVjb3JkZWQgdmFsdWVcbiAgICAvLyBwbGFjZWQgYnkgcmVmZXJlbmNlIGlzIHRoZSBsb2cncy5cbiAgICBpZiAoZGV0YWNoIHx8IHZlcmIgPT09ICdtZXJnZScpIG93bihuZXh0LCBvd25lZCk7XG4gICAgcGxhY2VWZXJiKG91dCwgc2VncywgbmV4dCk7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBBcHBsaWVzIGEgY29tbWl0IGJ1bmRsZSB0byBhIGJhc2Ugc3RhdGUgYnkgcmVwbGF5aW5nIG9wZXJhdGlvbnMgaW4gb3JkZXIuXG4gKiBHdWFyYW50ZWVzIFwibGFzdCB3cml0ZXIgd2luc1wiIHNlbWFudGljcy5cbiAqXG4gKiBSZXR1cm5zIGEgRlVMTFkgREVUQUNIRUQgcmVzdWx0OiB0aGUgYmFzZSBpcyBkZWVwLWNsb25lZCBmaXJzdCBhbmQgZXZlcnlcbiAqIHZhbHVlIHRoZSByZXBsYXkgd3JpdGVzIGlzIGl0cyBvd24gKGBzZXRgIC8gYGFwcGVuZGAgY2xvbmUgdGhlIHJlY29yZGVkXG4gKiB2YWx1ZTsgdGhlIGBtZXJnZWAgYXJtIHJlYWRzIGEgZGV0YWNoZWQgY29weSBvZiBgdXBkYXRlc2ApLCBzbyB0aGUgcmVzdWx0XG4gKiBzaGFyZXMgbm8gY29udGFpbmVyIHdpdGggYGJhc2VgLCBgdXBkYXRlc2Agb3IgYG92ZXJ3cml0ZWAuIFRoaXMgaXMgdGhlXG4gKiBwdWJsaWMgKGBmb290cHJpbnRqcy90cmFjZWA7IGFsc28gYC9hZHZhbmNlZGAgdW50aWwgMTAuMC4wKSBjb250cmFjdCwgdW5jaGFuZ2VkIGJ5IGNvcHktb24td3JpdGVcbiAqICg5LjI5LjApIOKAlCBieXRlLWlkZW50aWNhbCB0byA5LjI4LjAgZm9yIGV2ZXJ5IGNhbGxlci4gVGhlIGVuZ2luZSdzIG93blxuICogY29tbWl0IGRvZXMgTk9UIGNvbWUgaGVyZTogYFNoYXJlZE1lbW9yeS5hcHBseVBhdGNoYCBidWlsZHMgdGhlIG5leHRcbiAqIGdlbmVyYXRpb24gd2l0aCBgbmV4dEdlbmVyYXRpb25gLCB3aGljaCBjb3BpZXMgb25seSB0aGUgd3JpdHRlblxuICogcGF0aHMuIEJvdGggcnVuIHRoZSBPTkUgZm9sZCwge0BsaW5rIGZvbGRSb3dzfTsgdGhlIHZlcmJzIGFyZVxuICoge0BsaW5rIGFwcGx5VmVyYn0ncy5cbiAqXG4gKiBWZXJiIGFybXMg4oCUIHNlZSB7QGxpbmsgYXBwbHlWZXJifS4gQSByb3cgd2l0aCBhbnkgb3RoZXIgdmVyYiB0aHJvd3NcbiAqIHtAbGluayBVbmtub3duVmVyYkVycm9yfS5cbiAqXG4gKiBXb3JrLCBub3QgYnl0ZXMgKDkuMjIuMSk6IGEgYHNldGAgcm93IHRoZSBORVhUIHJvdyByZS1zZXRzIGlzIHNraXBwZWRcbiAqICh7QGxpbmsgc3VwZXJzZWRlZEJ5TmV4dFNldH0pIOKAlCB0aGUgcm93cyBzdGF5IGluIHRoZSBsb2csIG9ubHkgdGhlIGNsb25lXG4gKiBlYWNoIHdvdWxkIGhhdmUgcGFpZCBpcyBub3QuIEV2ZXJ5IGNvbnN1bWVyIGluaGVyaXRzIHRoZSBza2lwIGZyb21cbiAqIGBmb2xkUm93c2A7IHRoZXJlIGlzIG5vIHNlY29uZCByZXBsYXkgbG9vcCB0byBrZWVwIGluIHN0ZXAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVNtYXJ0TWVyZ2UoYmFzZTogYW55LCB1cGRhdGVzOiBNZW1vcnlQYXRjaCwgb3ZlcndyaXRlOiBNZW1vcnlQYXRjaCwgdHJhY2U6IFRyYWNlRW50cnlbXSk6IGFueSB7XG4gIHJldHVybiBmb2xkUm93cyhzdHJ1Y3R1cmVkQ2xvbmUoYmFzZSksIHVwZGF0ZXMsIG92ZXJ3cml0ZSwgdHJhY2UsICdwcml2YXRlJyk7XG59XG5cbi8qKlxuICogVGhlIGVuZ2luZSdzIGNvbW1pdCAoY29weS1vbi13cml0ZSwgOS4yOS4wIOKAlCBkb2NzL2Rlc2lnbi8yMDI2LTEwLWNvcHktb24tXG4gKiB3cml0ZS1jb21taXQubWQpOiB0aGUgTkVYVCBjb21taXR0ZWQgZ2VuZXJhdGlvbi4gQSBjb3B5IG9mIGBiYXNlYCdzIFJPT1RcbiAqIHBsdXMgYSBjb3B5IG9mIGV2ZXJ5IGNvbnRhaW5lciBvbiBlYWNoIHdyaXR0ZW4gcGF0aDsgZXZlcnkgb3RoZXIgc3VidHJlZVxuICogaXMgU0hBUkVEIHdpdGggYGJhc2VgLCB3aGljaCBpcyBuZXZlciBlZGl0ZWQg4oCUIGNvbW1pdHRlZCBzdGF0ZSBpc1xuICogaW1tdXRhYmxlLWFmdGVyLXN3YXAsIHNvIHNoYXJpbmcgaXMgc2FmZSwgYW5kIGEgY29tbWl0IGNvc3RzIE8od2hhdCBpdFxuICogd3JvdGUpLCBub3QgTyhzdGF0ZSkuIGBTaGFyZWRNZW1vcnkuYXBwbHlQYXRjaGAgKGxpdmUgc3RhdGUgYW5kIHRoZVxuICogcmVkYWN0ZWQgbWlycm9yKSBpcyBpdHMgY2FsbGVyLiBJbnRlcm5hbDogdGhlIHB1YmxpYyByZXBsYXkgaXNcbiAqIHtAbGluayBhcHBseVNtYXJ0TWVyZ2V9LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbmV4dEdlbmVyYXRpb24oYmFzZTogYW55LCB1cGRhdGVzOiBNZW1vcnlQYXRjaCwgb3ZlcndyaXRlOiBNZW1vcnlQYXRjaCwgdHJhY2U6IFRyYWNlRW50cnlbXSk6IGFueSB7XG4gIHJldHVybiBmb2xkUm93cyhvd25lZFJvb3RPZihiYXNlKSwgdXBkYXRlcywgb3ZlcndyaXRlLCB0cmFjZSwgJ3BhdGhDb3B5Jyk7XG59XG5cbi8qKlxuICogVGhlIHNhbWUgcmVwbGF5LCBJTlRPIGB0YXJnZXRgIOKAlCBubyBjbG9uZSBvZiBpdHMgb3duLiBGb3IgYSBjYWxsZXIgdGhhdFxuICogYWxyZWFkeSBob2xkcyBhIHByaXZhdGUgd29ya2luZyBjb3B5ICh0aGUgcmVhZC1zaWRlIGZvbGRzOiBgc3RhdGVBdGAgaW5cbiAqIGB0aW1lLXRyYXZlbC9zdGF0ZUF0LnRzYCBhbmQgYEV2ZW50TG9nLm1hdGVyaWFsaXNlYCBjbG9uZSB0aGVpciBiYXNlIE9OQ0VcbiAqIGFuZCB0aGVuIGFwcGx5IGV2ZXJ5IGJ1bmRsZSBoZXJlKSwgc28gYSBmb2xkIG92ZXIgTiBidW5kbGVzIGNvc3RzIE4gcm93XG4gKiBhcHBsaWNhdGlvbnMsIG5vdCBOIGNsb25lcyBvZiB0aGUgd2hvbGUgc3RhdGUuIE5ldmVyIGhhbmQgaXQgY29tbWl0dGVkXG4gKiBzdGF0ZTogaXQgbXV0YXRlcyB0aGUgUk9PVCBpbiBwbGFjZS4gQmVsb3cgdGhlIHJvb3QgaXQgZm9sbG93cyB0aGUgbGl2ZVxuICogY29tbWl0J3MgbGF3ICh7QGxpbmsgbmV4dEdlbmVyYXRpb259KSDigJQgYSBjb250YWluZXIgdGhpcyBjYWxsIGRpZCBub3RcbiAqIGNyZWF0ZSBpcyBjb3BpZWQgYmVmb3JlIGEgd3JpdGUgcGFzc2VzIHRocm91Z2ggaXQg4oCUIHNvIGEgZm9sZCBhbmQgdGhlIGxpdmVcbiAqIHN0YXRlIGdpdmUgdGhlIHNhbWUgdmFsdWUgYXQgZXZlcnkgcGF0aCwgYWxpYXNlZCBzdWJ0cmVlcyBpbmNsdWRlZC5cbiAqIFRoZSB2YWx1ZXMgaXQgd3JpdGVzIGFyZSBpdHMgb3duLCBzbyBgdGFyZ2V0YCBuZXZlciBhbGlhc2VzIHRoZSBsb2cuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVNtYXJ0TWVyZ2VJbnRvKFxuICB0YXJnZXQ6IGFueSxcbiAgdXBkYXRlczogTWVtb3J5UGF0Y2gsXG4gIG92ZXJ3cml0ZTogTWVtb3J5UGF0Y2gsXG4gIHRyYWNlOiBUcmFjZUVudHJ5W10sXG4pOiBhbnkge1xuICByZXR1cm4gZm9sZFJvd3ModGFyZ2V0LCB1cGRhdGVzLCBvdmVyd3JpdGUsIHRyYWNlLCAncGF0aENvcHknKTtcbn1cblxuLyoqXG4gKiBUaGUgZm9sZCwgZm9yIENPTVBBUklTT04gb25seSAoOS4zMC4wIOKAlCB0aGUgYWRtaXR0ZWQgcmVjb3JkKTogYGJhc2VgIHdpdGhcbiAqIHRoZSBidW5kbGUgcmVwbGF5ZWQgYnkgdGhlIG9uZSB2ZXJiIGxhdywgY29weS1vbi13cml0ZSBiZWxvdyB0aGUgcm9vdCxcbiAqIGV2ZXJ5IHJlY29yZGVkIHZhbHVlIHBsYWNlZCBCWSBSRUZFUkVOQ0Ug4oCUIG5vIGNsb25lLCBzbyBpdCBjb3N0cyB3aGF0IHRoZVxuICogYnVuZGxlIHdyb3RlIGFuZCBub3RoaW5nIG1vcmUuIEl0IGFsaWFzZXMgdGhlIHBheWxvYWQgYW5kIGV2ZXJ5IHN1YnRyZWUgb2ZcbiAqIGBiYXNlYCB0aGUgYnVuZGxlIGRpZCBub3Qgd3JpdGUsIGFuZCBlZGl0cyBuZWl0aGVyLiBOZXZlciBoYW5kIGl0IG91dCxcbiAqIHN0b3JlIGl0IG9yIHdyaXRlIHRocm91Z2ggaXQ6IGBUcmFuc2FjdGlvbkJ1ZmZlcmAgYnVpbGRzIG9uZSB0byBhc2sgd2hldGhlclxuICogYSBidW5kbGUgZm9sZHMgYmFjayB0byB3aGF0IHRoZSBzdGFnZSByZWFkLCB0aGVuIGRyb3BzIGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZHJ5Rm9sZChiYXNlOiBhbnksIHVwZGF0ZXM6IE1lbW9yeVBhdGNoLCBvdmVyd3JpdGU6IE1lbW9yeVBhdGNoLCB0cmFjZTogVHJhY2VFbnRyeVtdKTogYW55IHtcbiAgcmV0dXJuIGZvbGRSb3dzKG93bmVkUm9vdE9mKGJhc2UpLCB1cGRhdGVzLCBvdmVyd3JpdGUsIHRyYWNlLCAnYnlSZWZlcmVuY2UnKTtcbn1cblxuLy8g4pSA4pSA4pSAIFRoZSBmb2xkIG92ZXIgb25lIGtleSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuLyoqXG4gKiBPbmUgcm93IG9mIHRoZSBsb2cgdW5kZXIgdGhlIGZvbGRlZCBrZXkncyBUT1AtTEVWRUwga2V5IOKAlCB3aGF0IHtAbGluayBmb2xkS2V5fVxuICogYXBwbGllcywgaW4gY29tbWl0IG9yZGVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRvdWNoIHtcbiAgcmVhZG9ubHkgdmVyYjogVmVyYjtcbiAgcmVhZG9ubHkgYnVuZGxlOiBDb21taXRCdW5kbGU7XG4gIC8qKiBUaGUgYnVuZGxlJ3MgcG9zaXRpb24gaW4gdGhlIGNvbW1pdCBsb2cuICovXG4gIHJlYWRvbmx5IGNvbW1pdElkeDogQ29tbWl0SWR4O1xuICAvKiogVGhlIHJvdydzIG93biBwYXRoIChERUxJTS1qb2luZWQgYFRyYWNlRW50cnkucGF0aGApLiAqL1xuICByZWFkb25seSBwYXRoOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBIb3cgdGhlIHJvdyBzaXRzIGFnYWluc3QgdGhlIGZvbGRlZCBrZXkgKGBrZXlQYXRocyDCtyByZWxhdGlvbmApLiBBQlNFTlQgZm9yIGFcbiAgICogcm93IG9uIGFub3RoZXIgcGF0aCB1bmRlciB0aGUgc2FtZSB0b3AtbGV2ZWwga2V5OiBzdWNoIGEgcm93IGlzIEFQUExJRUQgKGFuXG4gICAqIGFycmF5IHVuaW9uIG9uIGEgY29udGFpbmVyIGFib3ZlIHRoZSBrZXkgZGVkdXBzIHRoZSB3aG9sZSBhcnJheSwgc28gYSBzaWJsaW5nXG4gICAqIGNoYW5nZXMgd2hlcmUgaXQgbGVhdmVzIHRoZSBrZXkpIGJ1dCBuZXZlciBvYnNlcnZlZC5cbiAgICovXG4gIHJlYWRvbmx5IHJlbGF0aW9uPzogUGF0aFJlbGF0aW9uO1xufVxuXG4vKiogV2hhdCBhIHJlYWRlciBhc2tzIG9mIHtAbGluayBmb2xkS2V5fS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgS2V5Rm9sZCB7XG4gIC8qKlxuICAgKiBTdGFydCBhdCB0aGUgTEFTVCByb3cgdGhhdCBzZXRzIG9yIGRlbGV0ZXMgdGhlIHdob2xlIFRPUC1MRVZFTCBrZXkgKHtAbGlua1xuICAgKiBpc1RvdGFsfSwgb24gdGhlIHJvb3QgcGF0aCBpdHNlbGYpIOKAlCByb3dzIGJlZm9yZSBpdCBjYW5ub3QgY2hhbmdlIGFueXRoaW5nXG4gICAqIHVuZGVyIHRoYXQga2V5LCBzbyBhIHJlYWRlciB0aGF0IHdhbnRzIG9ubHkgdGhlIHZhbHVlIHNraXBzIHRoZW0uIEEgYHNldGAgb2ZcbiAgICogYSBwYXRoIGJlbG93IHRoZSByb290IGlzIE5PVCBhbiBhbmNob3I6IGFuIGVhcmxpZXIgc2libGluZyBjYW4gc3RpbGwgbW92ZVxuICAgKiB0aGUga2V5IHRocm91Z2ggYSBsYXRlciB1bmlvbi4gT2ZmIGJ5IGRlZmF1bHQ6IGEgcmVhZGVyIHRoYXQgdHJhY2tzIGhvdyB0aGVcbiAgICogdmFsdWUgR1JFVyBtdXN0IHNlZSBldmVyeSByb3cuXG4gICAqL1xuICByZWFkb25seSBhbmNob3JlZD86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBDYWxsZWQgYWZ0ZXIgZWFjaCBhcHBsaWVkIHJvdyB0aGF0IGhhcyBhIHtAbGluayBUb3VjaC5yZWxhdGlvbn0g4oCUIG9uLCBpbnNpZGVcbiAgICogb3IgYXJvdW5kIHRoZSBrZXkgKGV2ZXJ5IHJvdywgd2l0aCBgZXZlcnlSb3dgKSDigJQgd2l0aCB0aGUgdmFsdWUgQVQgVEhFIEtFWSBiZWZvcmUgaXQgYW5kIGFmdGVyIGl0XG4gICAqIChgdW5kZWZpbmVkYCBmb3IgYW4gYWJzZW50IGtleSkuIFRoZSBzZWFtIGEgcHJvdmVuYW5jZSB0cmFjayBhbmQgdGhlIHdyaXRlclxuICAgKiBydWxlIGhhbmcgb246IHRoZXkgd2F0Y2ggdGhlIGZvbGQsIHRoZXkgbmV2ZXIgaGF2ZSBhIHZlcmIgc3dpdGNoIG9mIHRoZWlyXG4gICAqIG93bi4gRm9yIGEgcm93IElOU0lERSB0aGUga2V5LCBhbiBhcnJheSBgYmVmb3JlYCBpcyBhIHNoYWxsb3cgc25hcHNob3Q6IHRoYXRcbiAgICogcm93IGVkaXRzIHRoZSBmb2xkJ3Mgb3duIGNvcHkgaW4gcGxhY2UuXG4gICAqL1xuICByZWFkb25seSBvYnNlcnZlPzogKHRvdWNoOiBUb3VjaCwgYmVmb3JlOiB1bmtub3duLCBhZnRlcjogdW5rbm93bikgPT4gdm9pZDtcbiAgLyoqXG4gICAqIE9ic2VydmUgRVZFUlkgYXBwbGllZCByb3csIG5vdCBvbmx5IHRoZSBrZXkncyBvd24uIFRoZSB3cml0ZXIgcnVsZSBuZWVkcyBpdDogaXQgY29tcGFyZXMgdGhlIHZhbHVlIGF0IHRoZVxuICAgKiBrZXkgYWNyb3NzIGEgV0hPTEUgY29tbWl0LCBhbmQgYSBzaWJsaW5nIHVuZGVyIHRoZSBzYW1lIHRvcC1sZXZlbCBrZXkgY2FuIG1vdmUgdGhhdCB2YWx1ZSDigJQgYSB3cml0ZVxuICAgKiB0aHJvdWdoIGEgY29udGFpbmVyIHRoYXQgaG9sZHMgYSBwcmltaXRpdmUgcmVwbGFjZXMgdGhlIGNvbnRhaW5lciAoYG5hdGl2ZVNldGApLCBhbmQgd2l0aCBpdCB0aGUga2V5LlxuICAgKi9cbiAgcmVhZG9ubHkgZXZlcnlSb3c/OiBib29sZWFuO1xuICAvKipcbiAgICogS2VlcCBHRU5FUkFUSU9OUyBhdCBjaG9zZW4gY29tbWl0czogYGF0YCBpcyBhc2tlZCBiZWZvcmUgYSBjb21taXQncyBmaXJzdCByb3cgKHdpdGggdGhlIGZvbGQncyBzdGF0ZSBhc1xuICAgKiBpdCBzdGFuZHMpOyBmb3IgYSBjb21taXQgaXQgYWNjZXB0cywgYGtlZXBgIGlzIGhhbmRlZCB0aGUgdmFsdWUgYXQgdGhlIGtleSBiZWZvcmUgdGhlIGNvbW1pdCBhbmQgYWZ0ZXJcbiAgICogaXQg4oCUIGNvcHktb24td3JpdGUgYXJvdW5kIHRoYXQgY29tbWl0ICh0aGUgZm9sZCBkcm9wcyBvd25lcnNoaXAgb2YgZXZlcnkgY29udGFpbmVyIGJlZm9yZSBhbmQgYWZ0ZXIgaXQpLFxuICAgKiBzbyBubyBsYXRlciByb3cgZWRpdHMgZWl0aGVyIHZhbHVlLiBUaGUgd3JpdGVyIHJ1bGUncyBtZW1vaXNlZCByb290IGZvbGQgKGBjb21taXRMb2dVdGlscyDCtyBMb2dNb2RlbGApXG4gICAqIGtlZXBzIHRoZSBjb21taXRzIGEga2V5J3MgdmVyZGljdCBuZWVkcywgb25jZSBwZXIgdG9wLWxldmVsIGtleS5cbiAgICovXG4gIC8qKlxuICAgKiBUaGUgdmFsdWUgdGhlIHRvcC1sZXZlbCBrZXkgaG9sZHMgQkVGT1JFIHRoZSBmaXJzdCByb3cg4oCUIGRlZmF1bHQ6IGFic2VudC4gTmV2ZXIgZWRpdGVkOiB0aGUgZm9sZCBjb3BpZXNcbiAgICogaXQgYmVmb3JlIHdyaXRpbmcgdGhyb3VnaCBpdC4gYGNvbW1pdFZhbHVlQXRgIG9uIGEgbWVtb2lzZWQgbG9nIHN0YXJ0cyBmcm9tIGEga2VwdCBnZW5lcmF0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhcnQ/OiB1bmtub3duO1xuICByZWFkb25seSBnZW5lcmF0aW9ucz86IHtcbiAgICBhdChjb21taXRJZHg6IG51bWJlciwgc3RhdGU6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pik6IGJvb2xlYW47XG4gICAga2VlcChjb21taXRJZHg6IG51bWJlciwgYmVmb3JlOiB1bmtub3duLCBhZnRlcjogdW5rbm93bik6IHZvaWQ7XG4gIH07XG59XG5cbi8qKlxuICogVGhlIHZhbHVlIG9mIE9ORSBrZXkgYWZ0ZXIgYHRvdWNoZXNgIOKAlCBFVkVSWSByb3cgdW5kZXIgaXRzIHRvcC1sZXZlbCBrZXksIGluXG4gKiBjb21taXQgb3JkZXIsIGVhY2ggYWxyZWFkeSBjaGVja2VkIHdpdGgge0BsaW5rIGlzVmVyYn0g4oCUIGZvbGRlZCBmcm9tIGFuIGFic2VudFxuICoga2V5LCByZWFkIGF0IHRoZSBrZXkgKGBzZWdzYCwgaXRzIERFTElNIHNlZ21lbnRzKTogdGhlIHZhbHVlIHJ1bGUgb2ZcbiAqIGBrZXlQYXRocy50c2AsIHRoZSBmb2xkIGBzdGF0ZUF0YCBkb2VzIHJlc3RyaWN0ZWQgdG8gb25lIHRvcC1sZXZlbCBrZXkuIFRvcC1sZXZlbFxuICoga2V5cyBuZXZlciBpbnRlcmFjdCB1bmRlciB0aGUgc3RlcCwgc28gdGhlIHJlc3RyaWN0aW9uIGlzIGV4YWN0LlxuICpcbiAqIFRoZSBzYW1lIHN0ZXAgKHtAbGluayBhcHBseVZlcmJ9KSBhbmQgdGhlIHNhbWUgZGlzY2lwbGluZSBhcyB7QGxpbmsgZm9sZFJvd3N9J3NcbiAqIGAncGF0aENvcHknYDogYHNldGAgLyBgYXBwZW5kYCB2YWx1ZXMgYXJlIGNsb25lcywgdGhlIG1lcmdlIGRlbHRhIGlzIGRldGFjaGVkXG4gKiBvbmNlIHBlciBCVU5ETEUgKG5hcnJvd2VkIHRvIHRoZSB0b3AtbGV2ZWwga2V5KSwgc28gdHdvIGBtZXJnZWAgcm93cyBvZiBvbmVcbiAqIGJ1bmRsZSBzZWUgdGhlIHNhbWUgb2JqZWN0cywgYW5kIGEgcm93IHRoYXQgd3JpdGVzIHRocm91Z2ggYSBjb250YWluZXIgdGhpc1xuICogZm9sZCBkaWQgbm90IGNyZWF0ZSBjb3BpZXMgaXQgZmlyc3QuIFJldHVybnMgYHVuZGVmaW5lZGAgZm9yIGFuIGFic2VudCBrZXkuXG4gKiBPKHRoZSByb3dzIHVuZGVyIHRoZSBrZXkncyB0b3AtbGV2ZWwga2V5KSwgbm90IE8odGhlIGxvZykuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb2xkS2V5KHRvdWNoZXM6IHJlYWRvbmx5IFRvdWNoW10sIHNlZ3M6IHN0cmluZ1tdLCBvcHRpb25zOiBLZXlGb2xkID0ge30pOiB1bmtub3duIHtcbiAgY29uc3Qgcm9vdCA9IHNlZ3NbMF07XG4gIGxldCBmcm9tID0gMDtcbiAgaWYgKG9wdGlvbnMuYW5jaG9yZWQgPT09IHRydWUpIHtcbiAgICBmb3IgKGxldCBpID0gdG91Y2hlcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgaWYgKGlzVG90YWwodG91Y2hlc1tpXS52ZXJiKSAmJiB0b3VjaGVzW2ldLnBhdGggPT09IHJvb3QpIHtcbiAgICAgICAgZnJvbSA9IGk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb25zdCBzdGF0ZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgaWYgKG9wdGlvbnMuc3RhcnQgIT09IHVuZGVmaW5lZCkgc3RhdGVbcm9vdF0gPSBvcHRpb25zLnN0YXJ0O1xuICBsZXQgb3duZWQgPSBuZXcgV2Vha1NldDxvYmplY3Q+KCk7XG4gIG93bmVkLmFkZChzdGF0ZSk7XG4gIGNvbnN0IG9ic2VydmUgPSBvcHRpb25zLm9ic2VydmU7XG4gIGNvbnN0IGdlbmVyYXRpb25zID0gb3B0aW9ucy5nZW5lcmF0aW9ucztcbiAgbGV0IGtlcHQgPSAtMTtcbiAgbGV0IGtlcHRCZWZvcmU6IHVua25vd247XG4gIC8qKiBEcm9wIG93bmVyc2hpcCBvZiBldmVyeSBjb250YWluZXI6IHRoZSBuZXh0IHdyaXRlIHRocm91Z2ggb25lIGNvcGllcyBpdCwgc28gYSBrZXB0IHZhbHVlIHN0YXlzIGFzIGl0IGlzLiAqL1xuICBjb25zdCByZWxlYXNlID0gKCkgPT4ge1xuICAgIG93bmVkID0gbmV3IFdlYWtTZXQ8b2JqZWN0PigpO1xuICAgIG93bmVkLmFkZChzdGF0ZSk7XG4gIH07XG4gIGxldCBhdDogUmVjb3JkZWRQYXlsb2FkIHwgdW5kZWZpbmVkO1xuICBsZXQgYXRDb21taXQgPSAtMTtcbiAgZm9yIChsZXQgaSA9IGZyb207IGkgPCB0b3VjaGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgdG91Y2ggPSB0b3VjaGVzW2ldO1xuICAgIGlmIChhdCA9PT0gdW5kZWZpbmVkIHx8IHRvdWNoLmNvbW1pdElkeCAhPT0gYXRDb21taXQpIHtcbiAgICAgIGlmIChrZXB0ICE9PSAtMSkge1xuICAgICAgICBnZW5lcmF0aW9ucyEua2VlcChrZXB0LCBrZXB0QmVmb3JlLCBuYXRpdmVHZXQoc3RhdGUsIHNlZ3MpKTtcbiAgICAgICAga2VwdCA9IC0xO1xuICAgICAgICByZWxlYXNlKCk7XG4gICAgICB9XG4gICAgICBpZiAoZ2VuZXJhdGlvbnMgIT09IHVuZGVmaW5lZCAmJiBnZW5lcmF0aW9ucy5hdCh0b3VjaC5jb21taXRJZHgsIHN0YXRlKSkge1xuICAgICAgICByZWxlYXNlKCk7XG4gICAgICAgIGtlcHQgPSB0b3VjaC5jb21taXRJZHg7XG4gICAgICAgIGtlcHRCZWZvcmUgPSBuYXRpdmVHZXQoc3RhdGUsIHNlZ3MpO1xuICAgICAgfVxuICAgICAgYXQgPSBuZXcgUmVjb3JkZWRQYXlsb2FkKHRvdWNoLmJ1bmRsZS51cGRhdGVzLCB0b3VjaC5idW5kbGUub3ZlcndyaXRlLCB0cnVlLCBbcm9vdF0pO1xuICAgICAgYXRDb21taXQgPSB0b3VjaC5jb21taXRJZHg7XG4gICAgfVxuICAgIGNvbnN0IHJvd1NlZ3MgPSB0b3VjaC5wYXRoID09PSByb290ID8gW3Jvb3RdIDogdG91Y2gucGF0aC5zcGxpdChERUxJTSk7XG4gICAgY29uc3Qgd2F0Y2hlZCA9IG9ic2VydmUgIT09IHVuZGVmaW5lZCAmJiAodG91Y2gucmVsYXRpb24gIT09IHVuZGVmaW5lZCB8fCBvcHRpb25zLmV2ZXJ5Um93ID09PSB0cnVlKTtcbiAgICBsZXQgYmVmb3JlOiB1bmtub3duO1xuICAgIGlmICh3YXRjaGVkKSB7XG4gICAgICBiZWZvcmUgPSBuYXRpdmVHZXQoc3RhdGUsIHNlZ3MpO1xuICAgICAgaWYgKHRvdWNoLnJlbGF0aW9uID09PSAnaW5zaWRlJyAmJiBBcnJheS5pc0FycmF5KGJlZm9yZSkpIGJlZm9yZSA9IGJlZm9yZS5zbGljZSgpO1xuICAgIH1cbiAgICBpZiAocm93U2Vncy5sZW5ndGggPiAxKSBvd25TcGluZShzdGF0ZSwgcm93U2Vncywgb3duZWQpO1xuICAgIC8vIEEgdG90YWwgdmVyYiByZWFkcyBub3RoaW5nIGZyb20gd2hhdCBjYW1lIGJlZm9yZSBpdCAoaXNUb3RhbCkuXG4gICAgY29uc3QgbmV4dCA9IGFwcGx5VmVyYih0b3VjaC52ZXJiLCBpc1RvdGFsKHRvdWNoLnZlcmIpID8gdW5kZWZpbmVkIDogbmF0aXZlR2V0KHN0YXRlLCByb3dTZWdzKSwgYXQsIHJvd1NlZ3MpO1xuICAgIG93bihuZXh0LCBvd25lZCk7XG4gICAgcGxhY2VWZXJiKHN0YXRlLCByb3dTZWdzLCBuZXh0KTtcbiAgICBpZiAod2F0Y2hlZCkgb2JzZXJ2ZSh0b3VjaCwgYmVmb3JlLCBuYXRpdmVHZXQoc3RhdGUsIHNlZ3MpKTtcbiAgfVxuICBpZiAoa2VwdCAhPT0gLTEpIGdlbmVyYXRpb25zIS5rZWVwKGtlcHQsIGtlcHRCZWZvcmUsIG5hdGl2ZUdldChzdGF0ZSwgc2VncykpO1xuICByZXR1cm4gbmF0aXZlR2V0KHN0YXRlLCBzZWdzKTtcbn1cbiJdfQ==