semantifold 0.3.0 → 0.4.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 (297) hide show
  1. package/README.md +58 -15
  2. package/build/index.d.ts +48 -2
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +57 -8
  5. package/build/src/artifact-path.d.ts +23 -1
  6. package/build/src/artifact-path.d.ts.map +1 -1
  7. package/build/src/artifact-path.js +45 -3
  8. package/build/src/artifacts.d.ts.map +1 -1
  9. package/build/src/artifacts.js +66 -1
  10. package/build/src/backends/c-validation.d.ts.map +1 -1
  11. package/build/src/backends/c-validation.js +7 -3
  12. package/build/src/backends/cpp-validation.d.ts.map +1 -1
  13. package/build/src/backends/cpp-validation.js +7 -3
  14. package/build/src/backends/csharp.js +7 -1
  15. package/build/src/backends/dart-runtime.d.ts +2 -0
  16. package/build/src/backends/dart-runtime.d.ts.map +1 -0
  17. package/build/src/backends/dart-runtime.js +41 -0
  18. package/build/src/backends/dart.d.ts +20 -0
  19. package/build/src/backends/dart.d.ts.map +1 -0
  20. package/build/src/backends/dart.js +321 -0
  21. package/build/src/backends/effects.d.ts +60 -0
  22. package/build/src/backends/effects.d.ts.map +1 -0
  23. package/build/src/backends/effects.js +746 -0
  24. package/build/src/backends/go.js +18 -4
  25. package/build/src/backends/identifiers.d.ts +36 -4
  26. package/build/src/backends/identifiers.d.ts.map +1 -1
  27. package/build/src/backends/identifiers.js +154 -10
  28. package/build/src/backends/index.d.ts.map +1 -1
  29. package/build/src/backends/index.js +27 -4
  30. package/build/src/backends/ios.d.ts +68 -0
  31. package/build/src/backends/ios.d.ts.map +1 -0
  32. package/build/src/backends/ios.js +1503 -0
  33. package/build/src/backends/java.d.ts.map +1 -1
  34. package/build/src/backends/java.js +429 -36
  35. package/build/src/backends/javascript.d.ts +6 -0
  36. package/build/src/backends/javascript.d.ts.map +1 -1
  37. package/build/src/backends/javascript.js +380 -24
  38. package/build/src/backends/kotlin-runtime.d.ts +3 -0
  39. package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
  40. package/build/src/backends/kotlin-runtime.js +29 -0
  41. package/build/src/backends/kotlin.d.ts +23 -0
  42. package/build/src/backends/kotlin.d.ts.map +1 -0
  43. package/build/src/backends/kotlin.js +136 -0
  44. package/build/src/backends/native-validation.d.ts +2 -2
  45. package/build/src/backends/native-validation.d.ts.map +1 -1
  46. package/build/src/backends/native-validation.js +2 -2
  47. package/build/src/backends/ordered-expressions.d.ts.map +1 -1
  48. package/build/src/backends/ordered-expressions.js +39 -7
  49. package/build/src/backends/php-stdlib-support.d.ts +19 -0
  50. package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
  51. package/build/src/backends/php-stdlib-support.js +227 -0
  52. package/build/src/backends/php.d.ts.map +1 -1
  53. package/build/src/backends/php.js +448 -33
  54. package/build/src/backends/program.d.ts +81 -0
  55. package/build/src/backends/program.d.ts.map +1 -0
  56. package/build/src/backends/program.js +1308 -0
  57. package/build/src/backends/python.js +7 -1
  58. package/build/src/backends/ruby.d.ts.map +1 -1
  59. package/build/src/backends/ruby.js +310 -24
  60. package/build/src/backends/rust-runtime.d.ts +7 -0
  61. package/build/src/backends/rust-runtime.d.ts.map +1 -0
  62. package/build/src/backends/rust-runtime.js +32 -0
  63. package/build/src/backends/rust-validation.d.ts +9 -0
  64. package/build/src/backends/rust-validation.d.ts.map +1 -0
  65. package/build/src/backends/rust-validation.js +78 -0
  66. package/build/src/backends/rust.d.ts +24 -0
  67. package/build/src/backends/rust.d.ts.map +1 -0
  68. package/build/src/backends/rust.js +344 -0
  69. package/build/src/backends/scalars.d.ts +14 -6
  70. package/build/src/backends/scalars.d.ts.map +1 -1
  71. package/build/src/backends/scalars.js +167 -17
  72. package/build/src/backends/shared.d.ts +23 -4
  73. package/build/src/backends/shared.d.ts.map +1 -1
  74. package/build/src/backends/shared.js +2158 -62
  75. package/build/src/backends/stdlib-support.d.ts +14 -0
  76. package/build/src/backends/stdlib-support.d.ts.map +1 -0
  77. package/build/src/backends/stdlib-support.js +237 -0
  78. package/build/src/backends/swift-runtime.d.ts +3 -0
  79. package/build/src/backends/swift-runtime.d.ts.map +1 -0
  80. package/build/src/backends/swift-runtime.js +14 -0
  81. package/build/src/backends/swift.d.ts +8 -0
  82. package/build/src/backends/swift.d.ts.map +1 -0
  83. package/build/src/backends/swift.js +127 -0
  84. package/build/src/backends/typescript.d.ts.map +1 -1
  85. package/build/src/backends/typescript.js +344 -24
  86. package/build/src/backends/wasm.d.ts +43 -0
  87. package/build/src/backends/wasm.d.ts.map +1 -0
  88. package/build/src/backends/wasm.js +2164 -0
  89. package/build/src/backends/writer.d.ts +235 -4
  90. package/build/src/backends/writer.d.ts.map +1 -1
  91. package/build/src/backends/writer.js +468 -3
  92. package/build/src/diagnostic.d.ts +4 -3
  93. package/build/src/diagnostic.d.ts.map +1 -1
  94. package/build/src/diagnostic.js +5 -3
  95. package/build/src/frontends/c.d.ts.map +1 -1
  96. package/build/src/frontends/c.js +5 -3
  97. package/build/src/frontends/cpp.d.ts.map +1 -1
  98. package/build/src/frontends/cpp.js +5 -3
  99. package/build/src/frontends/csharp.d.ts.map +1 -1
  100. package/build/src/frontends/csharp.js +7 -3
  101. package/build/src/frontends/dart.d.ts +10 -0
  102. package/build/src/frontends/dart.d.ts.map +1 -0
  103. package/build/src/frontends/dart.js +913 -0
  104. package/build/src/frontends/index.d.ts +3 -1
  105. package/build/src/frontends/index.d.ts.map +1 -1
  106. package/build/src/frontends/index.js +15 -5
  107. package/build/src/frontends/java.d.ts +110 -1
  108. package/build/src/frontends/java.d.ts.map +1 -1
  109. package/build/src/frontends/java.js +1725 -70
  110. package/build/src/frontends/javascript-typescript.d.ts +69 -1
  111. package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
  112. package/build/src/frontends/javascript-typescript.js +1825 -93
  113. package/build/src/frontends/kotlin.d.ts +10 -0
  114. package/build/src/frontends/kotlin.d.ts.map +1 -0
  115. package/build/src/frontends/kotlin.js +685 -0
  116. package/build/src/frontends/php.d.ts +118 -1
  117. package/build/src/frontends/php.d.ts.map +1 -1
  118. package/build/src/frontends/php.js +1583 -76
  119. package/build/src/frontends/program.d.ts +74 -0
  120. package/build/src/frontends/program.d.ts.map +1 -0
  121. package/build/src/frontends/program.js +989 -0
  122. package/build/src/frontends/ruby.d.ts +68 -1
  123. package/build/src/frontends/ruby.d.ts.map +1 -1
  124. package/build/src/frontends/ruby.js +1446 -101
  125. package/build/src/frontends/rust-parser.d.ts +11 -0
  126. package/build/src/frontends/rust-parser.d.ts.map +1 -0
  127. package/build/src/frontends/rust-parser.js +15 -0
  128. package/build/src/frontends/rust.d.ts +14 -0
  129. package/build/src/frontends/rust.d.ts.map +1 -0
  130. package/build/src/frontends/rust.js +715 -0
  131. package/build/src/frontends/scalars.d.ts +10 -0
  132. package/build/src/frontends/scalars.d.ts.map +1 -1
  133. package/build/src/frontends/scalars.js +28 -2
  134. package/build/src/frontends/swift.d.ts +10 -0
  135. package/build/src/frontends/swift.d.ts.map +1 -0
  136. package/build/src/frontends/swift.js +860 -0
  137. package/build/src/frontends/types.d.ts +186 -0
  138. package/build/src/frontends/types.d.ts.map +1 -0
  139. package/build/src/frontends/types.js +634 -0
  140. package/build/src/language-registry.d.ts +46 -4
  141. package/build/src/language-registry.d.ts.map +1 -1
  142. package/build/src/language-registry.js +167 -13
  143. package/build/src/mapping.d.ts +2 -2
  144. package/build/src/mapping.d.ts.map +1 -1
  145. package/build/src/mapping.js +31 -10
  146. package/build/src/semantic/capabilities.d.ts +66 -0
  147. package/build/src/semantic/capabilities.d.ts.map +1 -0
  148. package/build/src/semantic/capabilities.js +649 -0
  149. package/build/src/semantic/effects.d.ts +26 -0
  150. package/build/src/semantic/effects.d.ts.map +1 -0
  151. package/build/src/semantic/effects.js +764 -0
  152. package/build/src/semantic/generics.d.ts +23 -0
  153. package/build/src/semantic/generics.d.ts.map +1 -0
  154. package/build/src/semantic/generics.js +61 -0
  155. package/build/src/semantic/lifetime.d.ts +37 -0
  156. package/build/src/semantic/lifetime.d.ts.map +1 -0
  157. package/build/src/semantic/lifetime.js +527 -0
  158. package/build/src/semantic/provenance.d.ts +9 -2
  159. package/build/src/semantic/provenance.d.ts.map +1 -1
  160. package/build/src/semantic/provenance.js +462 -20
  161. package/build/src/semantic/scalars.d.ts +11 -0
  162. package/build/src/semantic/scalars.d.ts.map +1 -1
  163. package/build/src/semantic/scalars.js +16 -1
  164. package/build/src/semantic/stdlib.d.ts +254 -0
  165. package/build/src/semantic/stdlib.d.ts.map +1 -0
  166. package/build/src/semantic/stdlib.js +880 -0
  167. package/build/src/semantic/types.d.ts +2952 -202
  168. package/build/src/semantic/types.d.ts.map +1 -1
  169. package/build/src/semantic/types.js +688 -15
  170. package/build/src/semantic/validate.d.ts +85 -5
  171. package/build/src/semantic/validate.d.ts.map +1 -1
  172. package/build/src/semantic/validate.js +2576 -98
  173. package/build/src/stdlib-facades.d.ts +304 -0
  174. package/build/src/stdlib-facades.d.ts.map +1 -0
  175. package/build/src/stdlib-facades.js +1167 -0
  176. package/build/src/stdlib-negotiation.d.ts +69 -0
  177. package/build/src/stdlib-negotiation.d.ts.map +1 -0
  178. package/build/src/stdlib-negotiation.js +403 -0
  179. package/build/src/stdlib-providers.d.ts +72 -0
  180. package/build/src/stdlib-providers.d.ts.map +1 -0
  181. package/build/src/stdlib-providers.js +339 -0
  182. package/build/src/toolchains.d.ts +55 -1
  183. package/build/src/toolchains.d.ts.map +1 -1
  184. package/build/src/toolchains.js +15 -4
  185. package/docs/architecture.md +45 -13
  186. package/docs/dart.md +60 -0
  187. package/docs/goals.md +3 -3
  188. package/docs/ios.md +121 -0
  189. package/docs/kotlin.md +42 -0
  190. package/docs/language-support.md +231 -26
  191. package/docs/multi-file-modules.md +52 -0
  192. package/docs/parser-qualification.md +121 -8
  193. package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
  194. package/docs/rust.md +88 -0
  195. package/docs/source-maps.md +15 -7
  196. package/docs/standard-library-portability.md +39 -8
  197. package/docs/swift.md +44 -0
  198. package/docs/testing.md +366 -4
  199. package/docs/webassembly.md +52 -0
  200. package/index.js +63 -8
  201. package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
  202. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
  203. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
  204. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
  205. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
  206. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
  207. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
  208. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
  209. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
  210. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
  211. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
  212. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
  213. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
  214. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
  215. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
  216. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
  217. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
  218. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
  219. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
  220. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
  221. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
  222. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
  223. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
  224. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
  225. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
  226. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
  227. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
  228. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
  229. package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
  230. package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
  231. package/package.json +5 -2
  232. package/src/artifact-path.js +47 -2
  233. package/src/artifacts.js +67 -0
  234. package/src/backends/c-validation.js +6 -1
  235. package/src/backends/cpp-validation.js +6 -1
  236. package/src/backends/csharp.js +3 -0
  237. package/src/backends/dart-runtime.js +41 -0
  238. package/src/backends/dart.js +326 -0
  239. package/src/backends/effects.js +705 -0
  240. package/src/backends/go.js +14 -2
  241. package/src/backends/identifiers.js +160 -9
  242. package/src/backends/index.js +27 -2
  243. package/src/backends/ios.js +1612 -0
  244. package/src/backends/java.js +454 -36
  245. package/src/backends/javascript.js +389 -23
  246. package/src/backends/kotlin-runtime.js +29 -0
  247. package/src/backends/kotlin.js +141 -0
  248. package/src/backends/native-validation.js +1 -1
  249. package/src/backends/ordered-expressions.js +40 -6
  250. package/src/backends/php-stdlib-support.js +239 -0
  251. package/src/backends/php.js +469 -32
  252. package/src/backends/program.js +1407 -0
  253. package/src/backends/python.js +3 -0
  254. package/src/backends/ruby.js +326 -23
  255. package/src/backends/rust-runtime.js +34 -0
  256. package/src/backends/rust-validation.js +75 -0
  257. package/src/backends/rust.js +335 -0
  258. package/src/backends/scalars.js +141 -16
  259. package/src/backends/shared.js +2304 -124
  260. package/src/backends/stdlib-support.js +234 -0
  261. package/src/backends/swift-runtime.js +14 -0
  262. package/src/backends/swift.js +132 -0
  263. package/src/backends/typescript.js +349 -23
  264. package/src/backends/wasm.js +2208 -0
  265. package/src/backends/writer.js +520 -2
  266. package/src/diagnostic.js +4 -2
  267. package/src/frontends/c.js +4 -2
  268. package/src/frontends/cpp.js +4 -2
  269. package/src/frontends/csharp.js +4 -2
  270. package/src/frontends/dart.js +963 -0
  271. package/src/frontends/index.js +14 -4
  272. package/src/frontends/java.js +1977 -69
  273. package/src/frontends/javascript-typescript.js +2046 -102
  274. package/src/frontends/kotlin.js +713 -0
  275. package/src/frontends/php.js +1725 -79
  276. package/src/frontends/program.js +1062 -0
  277. package/src/frontends/ruby.js +1624 -98
  278. package/src/frontends/rust-parser.js +18 -0
  279. package/src/frontends/rust.js +714 -0
  280. package/src/frontends/scalars.js +31 -1
  281. package/src/frontends/swift.js +893 -0
  282. package/src/frontends/types.js +750 -0
  283. package/src/language-registry.js +172 -12
  284. package/src/mapping.js +33 -9
  285. package/src/semantic/capabilities.js +671 -0
  286. package/src/semantic/effects.js +737 -0
  287. package/src/semantic/generics.js +58 -0
  288. package/src/semantic/lifetime.js +517 -0
  289. package/src/semantic/provenance.js +412 -19
  290. package/src/semantic/scalars.js +17 -0
  291. package/src/semantic/stdlib.js +921 -0
  292. package/src/semantic/types.js +765 -14
  293. package/src/semantic/validate.js +2934 -209
  294. package/src/stdlib-facades.js +1211 -0
  295. package/src/stdlib-negotiation.js +446 -0
  296. package/src/stdlib-providers.js +377 -0
  297. package/src/toolchains.js +16 -3
@@ -0,0 +1,2164 @@
1
+ // @ts-check
2
+ import { addSegment, GenMapping, maybeAddSegment, setSourceContent, toEncodedMap } from "@jridgewell/gen-mapping";
3
+ import { createByteMapping } from "../binary-mapping.js";
4
+ import { unsupportedCapability } from "../diagnostic.js";
5
+ import { finalizeMapping, toSourceMapV3 } from "../mapping.js";
6
+ import { createGenerationIndex, primaryLocation, semanticEntries } from "../semantic/provenance.js";
7
+ import { validateNativeGraph } from "./native-validation.js";
8
+ import { validateBackendModule } from "./shared.js";
9
+ import { SourceWriter } from "./writer.js";
10
+ /** @typedef {import("../semantic/types.js").SemanticModule} SemanticModule */
11
+ /** @typedef {import("../semantic/types.js").SemanticNode} SemanticNode */
12
+ /** @typedef {import("../semantic/types.js").Expression} Expression */
13
+ /** @typedef {import("../semantic/types.js").SemanticTypeName} Scalar */
14
+ /** @typedef {import("../semantic/types.js").GeneratedByteRange} GeneratedByteRange */
15
+ /** @typedef {import("../semantic/types.js").SemanticNodeProvenance} SemanticNodeProvenance */
16
+ /** @typedef {{type: Scalar, knownBoolean?: boolean, knownInteger?: bigint, knownString?: string, stringLength?: number}} AbstractValue */
17
+ /** @typedef {{allocated: number, env: Map<string, AbstractValue>, returned?: AbstractValue}} AnalysisState */
18
+ /** @typedef {{type: Scalar, indexes: number[]}} LocalBinding */
19
+ const encoder = new TextEncoder();
20
+ const scratchCapacity = 1_048_576;
21
+ const maximumCallDepth = 64;
22
+ const wasmPageSize = 65_536;
23
+ const maximumAnalysisSteps = 100_000;
24
+ const valueTypes = Object.freeze({ i32: 0x7f, i64: 0x7e });
25
+ const helperNames = Object.freeze(["$concat", "$string_equal", "$checked_add", "$checked_subtract", "$checked_multiply", "$checked_negate"]);
26
+ const helperCount = helperNames.length;
27
+ const importCount = 3;
28
+ const concatFunctionIndex = importCount;
29
+ const stringEqualFunctionIndex = concatFunctionIndex + 1;
30
+ const checkedAddFunctionIndex = stringEqualFunctionIndex + 1;
31
+ const checkedSubtractFunctionIndex = checkedAddFunctionIndex + 1;
32
+ const checkedMultiplyFunctionIndex = checkedSubtractFunctionIndex + 1;
33
+ const checkedNegateFunctionIndex = checkedMultiplyFunctionIndex + 1;
34
+ const cursorGlobalIndex = 0;
35
+ const depthGlobalIndex = 1;
36
+ const activeGlobalIndex = 2;
37
+ /**
38
+ * Generates the complete deterministic browser Wasm artifact set.
39
+ * @param {{filename?: string, mapDirective?: unknown, module: SemanticModule, sourceMapFilename?: unknown, sources?: {filename: string, content: string, language?: import("../semantic/types.js").SemanticLanguage}[]}} input - Backend request.
40
+ * @returns {{artifacts: import("../semantic/types.js").GeneratedSetArtifact[], metadata: Readonly<Record<string, unknown>>, target: string}} Candidate artifact set.
41
+ */
42
+ export function generateBrowserWasm({ filename, mapDirective, module, sourceMapFilename, sources }) {
43
+ validateNativeGraph(module, "wasm");
44
+ validateBackendModule(module, "wasm");
45
+ if (filename !== undefined && filename != "program.wasm") {
46
+ unsupportedCapability("wasm", "artifact filename other than program.wasm", module.location);
47
+ }
48
+ if (mapDirective !== undefined)
49
+ unsupportedCapability("wasm", "source-map directive option", module.location);
50
+ if (sourceMapFilename !== undefined)
51
+ unsupportedCapability("wasm", "alternate source-map filename", module.location);
52
+ analyzeScratchUse(module);
53
+ const index = createGenerationIndex(module, sources);
54
+ const literalLayout = collectLiteralLayout(module, index);
55
+ const scratchBase = align(literalLayout.boundary, 16);
56
+ const memoryBytes = checkedSize(scratchBase + scratchCapacity, module, "linear memory size");
57
+ const memoryPages = Math.ceil(memoryBytes / wasmPageSize);
58
+ const encoded = encodeModule(module, index, literalLayout, scratchBase, memoryPages);
59
+ validateEncodedModule(encoded.bytes, module);
60
+ const byteMapping = createByteMapping({ byteLength: encoded.bytes.byteLength, path: "program.wasm", ranges: encoded.ranges });
61
+ const wasmMap = createWasmSourceMap(byteMapping, index.provenance);
62
+ const loader = textArtifact(semantifoldLoader, "semantifold-loader.mjs", "javascript", "loader", module, sources, "Versioned browser Wasm ABI loader and exact scalar bridge.");
63
+ const html = textArtifact(browserHarness, "index.html", "html", "entry", module, sources, "Deterministic local browser acceptance harness.");
64
+ const metadata = /** @type {const} */ ({
65
+ abi: "semantifold.browser.v1",
66
+ exports: ["memory", "run"],
67
+ imports: [
68
+ { module: "semantifold", name: "print_i64", parameters: ["i64"], results: [] },
69
+ { module: "semantifold", name: "print_bool", parameters: ["i32"], results: [] },
70
+ { module: "semantifold", name: "print_string", parameters: ["i32", "i32"], results: [] }
71
+ ],
72
+ maximumCallDepth,
73
+ memory: {
74
+ initialPages: memoryPages,
75
+ literalBoundary: literalLayout.boundary,
76
+ maximumPages: memoryPages,
77
+ scratchBase,
78
+ scratchCapacity
79
+ },
80
+ schema: "SemantifoldBrowserWasmABI",
81
+ version: 1
82
+ });
83
+ return {
84
+ artifacts: [{
85
+ content: encoded.bytes,
86
+ contentKind: "binary",
87
+ mediaType: "application/wasm",
88
+ ownership: "generated",
89
+ path: "program.wasm",
90
+ provenance: { kind: "bytes", mapping: byteMapping },
91
+ role: "resource"
92
+ }, {
93
+ content: `${JSON.stringify(wasmMap)}\n`,
94
+ contentKind: "text",
95
+ mediaType: "application/json",
96
+ ownership: "generated",
97
+ path: "program.wasm.map",
98
+ provenance: {
99
+ kind: "synthetic",
100
+ reason: "Source Map v3 projection of program.wasm byte provenance.",
101
+ relatedOrigins: relatedOrigins(index.recordFor(module, ""))
102
+ },
103
+ role: "mapping"
104
+ }, loader, html],
105
+ metadata,
106
+ target: "wasm"
107
+ };
108
+ }
109
+ /**
110
+ * Independently checks the completed module before any bytes enter an artifact.
111
+ * @param {Uint8Array} bytes - Completed module bytes.
112
+ * @param {SemanticModule} module - Related semantic module.
113
+ * @returns {void}
114
+ */
115
+ function validateEncodedModule(bytes, module) {
116
+ const moduleBytes = new Uint8Array(bytes.byteLength);
117
+ moduleBytes.set(bytes);
118
+ if (!WebAssembly.validate(moduleBytes))
119
+ unsupportedCapability("wasm", "invalid encoded section, index, stack, or control shape", module.location);
120
+ /** @type {WebAssembly.Module} */
121
+ let compiled;
122
+ try {
123
+ compiled = new WebAssembly.Module(moduleBytes);
124
+ }
125
+ catch (_error) {
126
+ unsupportedCapability("wasm", "invalid completed WebAssembly module", module.location);
127
+ }
128
+ const imports = WebAssembly.Module.imports(compiled).map(({ kind, module: namespace, name }) => [namespace, name, kind]);
129
+ const exports = WebAssembly.Module.exports(compiled).map(({ kind, name }) => [name, kind]);
130
+ if (JSON.stringify(imports) != JSON.stringify([
131
+ ["semantifold", "print_i64", "function"],
132
+ ["semantifold", "print_bool", "function"],
133
+ ["semantifold", "print_string", "function"]
134
+ ]) || JSON.stringify(exports) != JSON.stringify([["memory", "memory"], ["run", "function"]])) {
135
+ unsupportedCapability("wasm", "invalid encoded ABI import or export set", module.location);
136
+ }
137
+ }
138
+ /**
139
+ * Encodes one validated semantic module directly to portable core WebAssembly.
140
+ * @param {SemanticModule} module - Validated module.
141
+ * @param {ReturnType<typeof createGenerationIndex>} index - Canonical provenance index.
142
+ * @param {ReturnType<typeof collectLiteralLayout>} literals - Static literal layout.
143
+ * @param {number} scratchBase - Aligned scratch arena base.
144
+ * @param {number} memoryPages - Fixed memory page count.
145
+ * @returns {{bytes: Uint8Array, ranges: GeneratedByteRange[]}} Encoded module and rich byte ranges.
146
+ */
147
+ function encodeModule(module, index, literals, scratchBase, memoryPages) {
148
+ const writer = new BinaryWriter(index);
149
+ const root = { node: module, path: "" };
150
+ writer.synthetic([0x00, 0x61, 0x73, 0x6d], "WebAssembly binary magic", root, "module header");
151
+ writer.synthetic([0x01, 0x00, 0x00, 0x00], "Pinned WebAssembly core binary version 1", root, "module header");
152
+ const types = new TypePool();
153
+ const importTypes = [
154
+ types.add(["i64"], []),
155
+ types.add(["i32"], []),
156
+ types.add(["i32", "i32"], [])
157
+ ];
158
+ const helperTypes = [
159
+ types.add(["i32", "i32", "i32", "i32"], ["i32", "i32"]),
160
+ types.add(["i32", "i32", "i32", "i32"], ["i32"]),
161
+ types.add(["i64", "i64"], ["i64"]),
162
+ types.add(["i64", "i64"], ["i64"]),
163
+ types.add(["i64", "i64"], ["i64"]),
164
+ types.add(["i64"], ["i64"])
165
+ ];
166
+ const semanticTypeIndexes = module.functions.map((declaration) => types.add(declaration.parameters.flatMap(({ type, location }) => wasmTypes(wasmScalarType(type, location))), wasmTypes(wasmReturnType(declaration))));
167
+ const runType = types.add([], []);
168
+ const functionIndexes = new Map(module.functions.map((declaration, offset) => [declaration.name, importCount + helperCount + offset]));
169
+ const runFunctionIndex = importCount + helperCount + module.functions.length;
170
+ appendSection(writer, 1, "type", encodeTypeSection(types, index, root), root);
171
+ appendSection(writer, 2, "import", encodeImportSection(importTypes, index, root), root);
172
+ appendSection(writer, 3, "function", encodeFunctionSection(helperTypes, semanticTypeIndexes, runType, module, index), root);
173
+ appendSection(writer, 5, "memory", encodeMemorySection(memoryPages, index, root), root);
174
+ appendSection(writer, 6, "global", encodeGlobalSection(scratchBase, index, root), root);
175
+ appendSection(writer, 7, "export", encodeExportSection(runFunctionIndex, index, root), root);
176
+ const code = new BinaryWriter(index);
177
+ code.synthetic(u32(helperCount + module.functions.length + 1), "Defined function count", root, "function count");
178
+ appendFunctionBody(code, helperConcat(index, module, scratchBase), ["i32", "i32", "i32", "i32"], root, "$concat");
179
+ appendFunctionBody(code, helperStringEqual(index, module), ["i32"], root, "$string_equal");
180
+ appendFunctionBody(code, helperCheckedAdd(index, module), ["i64"], root, "$checked_add");
181
+ appendFunctionBody(code, helperCheckedSubtract(index, module), ["i64"], root, "$checked_subtract");
182
+ appendFunctionBody(code, helperCheckedMultiply(index, module), ["i64"], root, "$checked_multiply");
183
+ appendFunctionBody(code, helperCheckedNegate(index, module), [], root, "$checked_negate");
184
+ for (let functionOffset = 0; functionOffset < module.functions.length; functionOffset += 1) {
185
+ const declaration = module.functions[functionOffset];
186
+ const path = `/functions/${functionOffset}`;
187
+ const emitter = new FunctionEmitter({ functionIndexes, index, literals: literals.byValue, module, scratchBase });
188
+ emitter.bindParameters(declaration.parameters);
189
+ emitter.block(declaration.body, `${path}/body`);
190
+ emitter.syntheticUnreachable(declaration, path);
191
+ emitter.syntheticEnd(declaration, path);
192
+ appendFunctionBody(code, emitter.writer, emitter.locals, { node: declaration, path }, declaration.name);
193
+ }
194
+ const runEmitter = new FunctionEmitter({ functionIndexes, index, literals: literals.byValue, module, scratchBase });
195
+ runEmitter.run(module.entryPoint, "/entryPoint");
196
+ appendFunctionBody(code, runEmitter.writer, runEmitter.locals, { node: module.entryPoint, path: "/entryPoint" }, "run");
197
+ appendSection(writer, 10, "code", code, root);
198
+ appendSection(writer, 11, "data", encodeDataSection(literals.entries, index, root), root);
199
+ appendCustomSection(writer, "name", encodeNamePayload(module, runFunctionIndex, index), root);
200
+ appendCustomSection(writer, "sourceMappingURL", namedPayload("program.wasm.map", index, root), root);
201
+ return { bytes: writer.finish(), ranges: writer.ranges };
202
+ }
203
+ /** Direct semantic function and entry-point instruction emitter. */
204
+ class FunctionEmitter {
205
+ /**
206
+ * Creates an instruction emitter.
207
+ * @param {object} options - Encoding context.
208
+ * @param {Map<string, number>} options.functionIndexes - Semantic function indexes.
209
+ * @param {ReturnType<typeof createGenerationIndex>} options.index - Provenance index.
210
+ * @param {Map<string, {address: number, bytes: Uint8Array}>} options.literals - Literal addresses.
211
+ * @param {SemanticModule} options.module - Complete module.
212
+ * @param {number} options.scratchBase - Scratch base.
213
+ */
214
+ constructor({ functionIndexes, index, literals, module, scratchBase }) {
215
+ this.functionIndexes = functionIndexes;
216
+ this.functions = new Map(module.functions.map((declaration) => [declaration.name, declaration]));
217
+ this.index = index;
218
+ this.literals = literals;
219
+ this.module = module;
220
+ this.scratchBase = scratchBase;
221
+ this.writer = new BinaryWriter(index);
222
+ /** @type {("i32" | "i64")[]} */
223
+ this.locals = [];
224
+ /** @type {Map<string, LocalBinding>} */
225
+ this.bindings = new Map();
226
+ this.parameterCount = 0;
227
+ }
228
+ /**
229
+ * Binds flattened semantic parameters to Wasm parameter indexes.
230
+ * @param {import("../semantic/types.js").Parameter[]} parameters - Semantic parameters.
231
+ * @returns {void}
232
+ */
233
+ bindParameters(parameters) {
234
+ let index = 0;
235
+ for (const parameter of parameters) {
236
+ const scalar = wasmScalarType(parameter.type, parameter.location);
237
+ const types = wasmTypes(scalar);
238
+ const indexes = types.map(() => index++);
239
+ this.bindings.set(parameter.name, { indexes, type: scalar });
240
+ }
241
+ this.parameterCount = index;
242
+ }
243
+ /**
244
+ * Emits the guarded exported run body.
245
+ * @param {import("../semantic/types.js").EntryPoint} entryPoint - Semantic entry point.
246
+ * @param {string} path - Entry-point path.
247
+ * @returns {void}
248
+ */
249
+ run(entryPoint, path) {
250
+ this.syntheticOp(0x23, entryPoint, path, "active guard read");
251
+ this.syntheticImmediate(u32(activeGlobalIndex), entryPoint, path, "active guard global index");
252
+ this.syntheticOp(0x04, entryPoint, path, "active guard branch");
253
+ this.syntheticImmediate([0x40], entryPoint, path, "empty block type");
254
+ this.syntheticOp(0x00, entryPoint, path, "reentrant invocation trap");
255
+ this.syntheticOp(0x0b, entryPoint, path, "active guard branch end");
256
+ this.syntheticI32(1, entryPoint, path, "mark run active");
257
+ this.syntheticGlobalSet(activeGlobalIndex, entryPoint, path, "active guard");
258
+ this.syntheticI32(this.scratchBase, entryPoint, path, "reset scratch cursor");
259
+ this.syntheticGlobalSet(cursorGlobalIndex, entryPoint, path, "scratch cursor");
260
+ this.syntheticI32(0, entryPoint, path, "reset semantic call depth");
261
+ this.syntheticGlobalSet(depthGlobalIndex, entryPoint, path, "call depth");
262
+ this.block(entryPoint.body, `${path}/body`);
263
+ this.syntheticI32(0, entryPoint, path, "clear semantic call depth");
264
+ this.syntheticGlobalSet(depthGlobalIndex, entryPoint, path, "call depth");
265
+ this.syntheticI32(0, entryPoint, path, "mark run inactive");
266
+ this.syntheticGlobalSet(activeGlobalIndex, entryPoint, path, "active guard");
267
+ this.syntheticEnd(entryPoint, path);
268
+ }
269
+ /**
270
+ * Emits one semantic block.
271
+ * @param {import("../semantic/types.js").Block} block - Semantic block.
272
+ * @param {string} path - Occurrence path.
273
+ * @returns {void}
274
+ */
275
+ block(block, path) {
276
+ for (let index = 0; index < block.statements.length; index += 1) {
277
+ const statement = block.statements[index];
278
+ const statementPath = `${path}/statements/${index}`;
279
+ if (statement.kind == "LocalDeclaration") {
280
+ this.expression(statement.initializer, `${statementPath}/initializer`);
281
+ const binding = this.allocateBinding(wasmScalarType(statement.type, statement.location));
282
+ this.bindings.set(statement.name, binding);
283
+ this.setBinding(binding, statement, statementPath, "name");
284
+ }
285
+ else if (statement.kind == "AssignmentStatement") {
286
+ this.expression(statement.expression, `${statementPath}/expression`);
287
+ const binding = this.bindings.get(statement.target.name);
288
+ if (!binding)
289
+ throw new Error("Validated Wasm assignment omitted its binding.");
290
+ this.setBinding(binding, statement.target, `${statementPath}/target`, "name");
291
+ }
292
+ else if (statement.kind == "PrintStatement") {
293
+ const type = expressionType(statement.expression, this.bindings, this.functions);
294
+ this.expression(statement.expression, `${statementPath}/expression`);
295
+ const importIndex = type == "integer" ? 0 : type == "boolean" ? 1 : 2;
296
+ this.mappedOp(0x10, statement, statementPath, "print instruction");
297
+ this.mappedImmediate(u32(importIndex), statement, statementPath, "print import index");
298
+ }
299
+ else if (statement.kind == "ReturnStatement") {
300
+ if (!statement.expression)
301
+ throw new TypeError("Wasm bare return reached emission.");
302
+ this.expression(statement.expression, `${statementPath}/expression`);
303
+ this.mappedOp(0x0f, statement, statementPath, "return instruction");
304
+ }
305
+ else if (statement.kind == "ExpressionStatement") {
306
+ throw new TypeError("Wasm Task 005 expression statement reached emission.");
307
+ }
308
+ else if (statement.kind == "IfStatement") {
309
+ this.expression(statement.condition, `${statementPath}/condition`);
310
+ this.mappedOp(0x04, statement.condition, `${statementPath}/condition`, "conditional instruction");
311
+ this.syntheticImmediate([0x40], statement, statementPath, "empty conditional block type");
312
+ this.block(statement.consequent, `${statementPath}/consequent`);
313
+ if (statement.alternate) {
314
+ this.mappedOp(0x05, statement, statementPath, "alternate instruction");
315
+ this.block(statement.alternate, `${statementPath}/alternate`);
316
+ }
317
+ this.mappedOp(0x0b, statement, statementPath, "conditional end");
318
+ }
319
+ else {
320
+ throw new TypeError("Unsupported Wasm statement reached emission.");
321
+ }
322
+ }
323
+ }
324
+ /**
325
+ * Emits one expression and leaves its flattened result on the operand stack.
326
+ * @param {Expression} expression - Semantic expression.
327
+ * @param {string} path - Occurrence path.
328
+ * @returns {void}
329
+ */
330
+ expression(expression, path) {
331
+ if (expression.kind == "IdentifierExpression") {
332
+ const binding = this.bindings.get(expression.name);
333
+ if (!binding)
334
+ throw new Error("Validated Wasm identifier omitted its binding.");
335
+ for (const localIndex of binding.indexes) {
336
+ this.mappedOp(0x20, expression, path, "local read", "name");
337
+ this.mappedImmediate(u32(localIndex), expression, path, "local index", "name");
338
+ }
339
+ return;
340
+ }
341
+ if (expression.kind == "IntegerLiteral") {
342
+ this.mappedOp(0x42, expression, path, "i64 constant", "literal");
343
+ this.mappedImmediate(s64(BigInt(expression.value)), expression, path, "i64 immediate", "literal");
344
+ return;
345
+ }
346
+ if (expression.kind == "BooleanLiteral") {
347
+ this.mappedOp(0x41, expression, path, "canonical Boolean constant", "literal");
348
+ this.mappedImmediate(s32(expression.value ? 1 : 0), expression, path, "i32 immediate", "literal");
349
+ return;
350
+ }
351
+ if (expression.kind == "StringLiteral") {
352
+ const literal = this.literals.get(expression.value);
353
+ if (!literal)
354
+ throw new Error("Validated Wasm string literal omitted its static layout.");
355
+ this.mappedOp(0x41, expression, path, "string pointer constant", "literal");
356
+ this.mappedImmediate(s32(literal.address), expression, path, "string pointer immediate", "literal");
357
+ this.mappedOp(0x41, expression, path, "string length constant", "literal");
358
+ this.mappedImmediate(s32(literal.bytes.byteLength), expression, path, "string length immediate", "literal");
359
+ return;
360
+ }
361
+ if (expression.kind == "CallExpression") {
362
+ for (let index = 0; index < expression.arguments.length; index += 1) {
363
+ this.expression(expression.arguments[index], `${path}/arguments/${index}`);
364
+ }
365
+ this.semanticCall(expression, path);
366
+ return;
367
+ }
368
+ if (expression.kind == "UnaryExpression") {
369
+ this.expression(expression.operand, `${path}/operand`);
370
+ if (expression.operation == "BooleanNot")
371
+ this.mappedOp(0x45, expression, path, "Boolean not instruction", "operator");
372
+ else {
373
+ this.mappedOp(0x10, expression, path, "checked integer negate instruction", "operator");
374
+ this.mappedImmediate(u32(checkedNegateFunctionIndex), expression, path, "checked helper index", "operator");
375
+ }
376
+ return;
377
+ }
378
+ if (expression.kind != "BinaryExpression") {
379
+ return unsupportedCapability("wasm", "collection expression reached scalar emission", expression.location);
380
+ }
381
+ if (expression.operation == "BooleanAnd" || expression.operation == "BooleanOr") {
382
+ this.expression(expression.left, `${path}/left`);
383
+ this.mappedOp(0x04, expression, path, "short-circuit conditional", "operator");
384
+ this.syntheticImmediate([valueTypes.i32], expression, path, "Boolean conditional result type");
385
+ if (expression.operation == "BooleanAnd") {
386
+ this.expression(expression.right, `${path}/right`);
387
+ this.mappedOp(0x05, expression, path, "short-circuit alternate", "operator");
388
+ this.syntheticI32(0, expression, path, "canonical false result");
389
+ }
390
+ else {
391
+ this.syntheticI32(1, expression, path, "canonical true result");
392
+ this.mappedOp(0x05, expression, path, "short-circuit alternate", "operator");
393
+ this.expression(expression.right, `${path}/right`);
394
+ }
395
+ this.mappedOp(0x0b, expression, path, "short-circuit end", "operator");
396
+ return;
397
+ }
398
+ this.expression(expression.left, `${path}/left`);
399
+ this.expression(expression.right, `${path}/right`);
400
+ const directOpcode = new Map([
401
+ ["IntegerEqual", 0x51], ["IntegerNotEqual", 0x52], ["IntegerLessThan", 0x53],
402
+ ["IntegerGreaterThan", 0x55], ["IntegerLessThanOrEqual", 0x57], ["IntegerGreaterThanOrEqual", 0x59],
403
+ ["BooleanEqual", 0x46], ["BooleanNotEqual", 0x47]
404
+ ]).get(expression.operation);
405
+ if (directOpcode !== undefined)
406
+ this.mappedOp(directOpcode, expression, path, `${expression.operation} instruction`, "operator");
407
+ else {
408
+ const helperIndex = expression.operation == "StringConcat" ? concatFunctionIndex :
409
+ expression.operation == "StringEqual" || expression.operation == "StringNotEqual" ? stringEqualFunctionIndex :
410
+ expression.operation == "IntegerAdd" ? checkedAddFunctionIndex :
411
+ expression.operation == "IntegerSubtract" ? checkedSubtractFunctionIndex : checkedMultiplyFunctionIndex;
412
+ this.mappedOp(0x10, expression, path, `${expression.operation} helper call`, "operator");
413
+ this.mappedImmediate(u32(helperIndex), expression, path, "helper function index", "operator");
414
+ if (expression.operation == "StringNotEqual")
415
+ this.mappedOp(0x45, expression, path, "String inequality inversion", "operator");
416
+ }
417
+ }
418
+ /**
419
+ * Emits checked semantic-call depth accounting without changing argument order.
420
+ * @param {import("../semantic/types.js").CallExpression} expression - Call expression.
421
+ * @param {string} path - Call occurrence path.
422
+ * @returns {void}
423
+ */
424
+ semanticCall(expression, path) {
425
+ const declaration = this.functions.get(expression.callee);
426
+ const functionIndex = this.functionIndexes.get(expression.callee);
427
+ if (!declaration || functionIndex === undefined)
428
+ throw new Error("Validated Wasm call omitted its declaration.");
429
+ this.syntheticOp(0x23, expression, path, "read semantic call depth");
430
+ this.syntheticImmediate(u32(depthGlobalIndex), expression, path, "call-depth global index");
431
+ this.syntheticI32(maximumCallDepth, expression, path, "maximum semantic call depth");
432
+ this.syntheticOp(0x4f, expression, path, "semantic call-depth limit comparison");
433
+ this.syntheticOp(0x04, expression, path, "semantic call-depth guard");
434
+ this.syntheticImmediate([0x40], expression, path, "empty call-depth guard block type");
435
+ this.syntheticOp(0x00, expression, path, "semantic call-depth trap");
436
+ this.syntheticOp(0x0b, expression, path, "semantic call-depth guard end");
437
+ this.syntheticOp(0x23, expression, path, "read semantic call depth");
438
+ this.syntheticImmediate(u32(depthGlobalIndex), expression, path, "call-depth global index");
439
+ this.syntheticI32(1, expression, path, "semantic call-depth increment");
440
+ this.syntheticOp(0x6a, expression, path, "increment semantic call depth");
441
+ this.syntheticGlobalSet(depthGlobalIndex, expression, path, "call depth");
442
+ this.mappedOp(0x10, expression, path, "semantic call instruction", "callee");
443
+ this.mappedImmediate(u32(functionIndex), expression, path, "semantic callee index", "callee");
444
+ const result = this.allocateBinding(wasmReturnType(declaration));
445
+ this.setBinding(result, expression, path);
446
+ this.syntheticOp(0x23, expression, path, "read semantic call depth");
447
+ this.syntheticImmediate(u32(depthGlobalIndex), expression, path, "call-depth global index");
448
+ this.syntheticI32(1, expression, path, "semantic call-depth decrement");
449
+ this.syntheticOp(0x6b, expression, path, "decrement semantic call depth");
450
+ this.syntheticGlobalSet(depthGlobalIndex, expression, path, "call depth");
451
+ for (const localIndex of result.indexes) {
452
+ this.syntheticOp(0x20, expression, path, "restore semantic call result");
453
+ this.syntheticImmediate(u32(localIndex), expression, path, "result temporary local index");
454
+ }
455
+ }
456
+ /**
457
+ * Allocates flattened Wasm locals for one semantic value.
458
+ * @param {Scalar} type - Semantic type.
459
+ * @returns {LocalBinding} Local binding.
460
+ */
461
+ allocateBinding(type) {
462
+ const indexes = wasmTypes(type).map((wasmType) => {
463
+ const index = this.parameterCount + this.locals.length;
464
+ this.locals.push(wasmType);
465
+ return index;
466
+ });
467
+ return { indexes, type };
468
+ }
469
+ /**
470
+ * Pops a flattened value into its locals.
471
+ * @param {LocalBinding} binding - Destination.
472
+ * @param {SemanticNode} node - Related semantic node.
473
+ * @param {string} path - Occurrence path.
474
+ * @param {string} [sourceRole] - Exact parser-owned token role, when this is a semantic binding.
475
+ * @returns {void}
476
+ */
477
+ setBinding(binding, node, path, sourceRole) {
478
+ for (let index = binding.indexes.length - 1; index >= 0; index -= 1) {
479
+ if (sourceRole) {
480
+ this.mappedOp(0x21, node, path, "local write", sourceRole);
481
+ this.mappedImmediate(u32(binding.indexes[index]), node, path, "local index", sourceRole);
482
+ }
483
+ else {
484
+ this.syntheticOp(0x21, node, path, "store semantic call result");
485
+ this.syntheticImmediate(u32(binding.indexes[index]), node, path, "result temporary local index");
486
+ }
487
+ }
488
+ }
489
+ /**
490
+ * Writes a source-mapped instruction opcode.
491
+ * @param {number} opcode - Wasm opcode.
492
+ * @param {SemanticNode} node - Related semantic node.
493
+ * @param {string} path - Node occurrence path.
494
+ * @param {string} role - Mapping role.
495
+ * @param {string} [sourceRole] - Exact parser-owned token role.
496
+ * @returns {void}
497
+ */
498
+ mappedOp(opcode, node, path, role, sourceRole) { this.writer.mapped([opcode], node, path, role, sourceRole); }
499
+ /**
500
+ * Writes a source-mapped instruction immediate.
501
+ * @param {number[]} bytes - Encoded immediate bytes.
502
+ * @param {SemanticNode} node - Related semantic node.
503
+ * @param {string} path - Node occurrence path.
504
+ * @param {string} role - Mapping role.
505
+ * @param {string} [sourceRole] - Exact parser-owned token role.
506
+ * @returns {void}
507
+ */
508
+ mappedImmediate(bytes, node, path, role, sourceRole) { this.writer.mapped(bytes, node, path, role, sourceRole); }
509
+ /**
510
+ * Writes a synthetic instruction opcode with semantic context.
511
+ * @param {number} opcode - Wasm opcode.
512
+ * @param {SemanticNode} node - Related semantic node.
513
+ * @param {string} path - Node occurrence path.
514
+ * @param {string} reason - Synthetic provenance reason.
515
+ * @returns {void}
516
+ */
517
+ syntheticOp(opcode, node, path, reason) { this.writer.synthetic([opcode], reason, { node, path }, "instruction"); }
518
+ /**
519
+ * Writes a synthetic immediate with semantic context.
520
+ * @param {number[]} bytes - Encoded immediate bytes.
521
+ * @param {SemanticNode} node - Related semantic node.
522
+ * @param {string} path - Node occurrence path.
523
+ * @param {string} reason - Synthetic provenance reason.
524
+ * @returns {void}
525
+ */
526
+ syntheticImmediate(bytes, node, path, reason) { this.writer.synthetic(bytes, reason, { node, path }, "immediate"); }
527
+ /**
528
+ * Writes a synthetic i32 constant instruction.
529
+ * @param {number} value - Constant value.
530
+ * @param {SemanticNode} node - Related semantic node.
531
+ * @param {string} path - Node occurrence path.
532
+ * @param {string} reason - Synthetic provenance reason.
533
+ * @returns {void}
534
+ */
535
+ syntheticI32(value, node, path, reason) {
536
+ this.syntheticOp(0x41, node, path, reason);
537
+ this.syntheticImmediate(s32(value), node, path, `${reason} immediate`);
538
+ }
539
+ /**
540
+ * Writes a synthetic global assignment.
541
+ * @param {number} index - Global index.
542
+ * @param {SemanticNode} node - Related semantic node.
543
+ * @param {string} path - Node occurrence path.
544
+ * @param {string} reason - Synthetic provenance reason.
545
+ * @returns {void}
546
+ */
547
+ syntheticGlobalSet(index, node, path, reason) {
548
+ this.syntheticOp(0x24, node, path, `set ${reason}`);
549
+ this.syntheticImmediate(u32(index), node, path, `${reason} global index`);
550
+ }
551
+ /**
552
+ * Writes a synthetic function-end instruction.
553
+ * @param {SemanticNode} node - Related semantic node.
554
+ * @param {string} path - Node occurrence path.
555
+ * @returns {void}
556
+ */
557
+ syntheticEnd(node, path) { this.syntheticOp(0x0b, node, path, "function end"); }
558
+ /**
559
+ * Writes a synthetic unreachable instruction.
560
+ * @param {SemanticNode} node - Related semantic node.
561
+ * @param {string} path - Node occurrence path.
562
+ * @returns {void}
563
+ */
564
+ syntheticUnreachable(node, path) { this.syntheticOp(0x00, node, path, "validated non-void fallthrough trap"); }
565
+ }
566
+ /** Byte writer that preserves one non-overlapping provenance annotation per write. */
567
+ class BinaryWriter {
568
+ /**
569
+ * Creates an annotated binary writer.
570
+ * @param {ReturnType<typeof createGenerationIndex>} index - Canonical provenance index.
571
+ */
572
+ constructor(index) {
573
+ this.index = index;
574
+ /** @type {number[]} */
575
+ this.bytes = [];
576
+ /** @type {GeneratedByteRange[]} */
577
+ this.ranges = [];
578
+ }
579
+ /**
580
+ * Writes source-backed bytes.
581
+ * @param {number[] | Uint8Array} bytes - Exact bytes.
582
+ * @param {SemanticNode} node - Semantic node.
583
+ * @param {string} path - Occurrence path.
584
+ * @param {string} role - Binary role.
585
+ * @param {string} [sourceRole] - Exact parser-owned token role.
586
+ * @returns {void}
587
+ */
588
+ mapped(bytes, node, path, role, sourceRole) {
589
+ const record = this.index.recordFor(node, path);
590
+ const origin = sourceRole ? originForRole(this.index, record, sourceRole) : record.origin;
591
+ this.write(bytes, { nodeId: record.id, origin, role, symbolId: record.symbolId });
592
+ }
593
+ /**
594
+ * Writes explicit backend scaffolding bytes.
595
+ * @param {number[] | Uint8Array} bytes - Exact bytes.
596
+ * @param {string} reason - Synthetic reason.
597
+ * @param {{node: SemanticNode, path: string}} related - Related occurrence.
598
+ * @param {string} role - Binary role.
599
+ * @returns {void}
600
+ */
601
+ synthetic(bytes, reason, related, role) {
602
+ const record = this.index.recordFor(related.node, related.path);
603
+ this.write(bytes, {
604
+ origin: { kind: "synthetic", reason, relatedOrigins: relatedOrigins(record) },
605
+ role
606
+ });
607
+ }
608
+ /**
609
+ * Appends another annotated writer.
610
+ * @param {BinaryWriter} child - Child bytes.
611
+ * @returns {void}
612
+ */
613
+ append(child) {
614
+ const offset = this.bytes.length;
615
+ for (const byte of child.bytes)
616
+ this.bytes.push(byte);
617
+ for (const range of child.ranges) {
618
+ this.ranges.push({ ...range, generated: { start: range.generated.start + offset, end: range.generated.end + offset } });
619
+ }
620
+ }
621
+ /**
622
+ * Returns detached encoded bytes.
623
+ * @returns {Uint8Array} Detached bytes.
624
+ */
625
+ finish() { return Uint8Array.from(this.bytes); }
626
+ /**
627
+ * Writes one non-empty annotated range.
628
+ * @param {number[] | Uint8Array} bytes - Exact bytes.
629
+ * @param {Omit<GeneratedByteRange, "generated">} annotation - Provenance.
630
+ * @returns {void}
631
+ */
632
+ write(bytes, annotation) {
633
+ if (bytes.length == 0)
634
+ return;
635
+ const start = this.bytes.length;
636
+ for (const byte of bytes) {
637
+ if (!Number.isInteger(byte) || byte < 0 || byte > 255)
638
+ throw new RangeError("Invalid WebAssembly byte.");
639
+ this.bytes.push(byte);
640
+ }
641
+ this.ranges.push({ ...annotation, generated: { start, end: this.bytes.length } });
642
+ }
643
+ }
644
+ /** Deterministic function-type interner. */
645
+ class TypePool {
646
+ constructor() {
647
+ /** @type {{parameters: ("i32" | "i64")[], results: ("i32" | "i64")[]}[]} */
648
+ this.entries = [];
649
+ /** @type {Map<string, number>} */
650
+ this.indexes = new Map();
651
+ }
652
+ /**
653
+ * Interns one function type.
654
+ * @param {("i32" | "i64")[]} parameters - Parameters.
655
+ * @param {("i32" | "i64")[]} results - Results.
656
+ * @returns {number} Type index.
657
+ */
658
+ add(parameters, results) {
659
+ const key = `${parameters.join(",")}->${results.join(",")}`;
660
+ const prior = this.indexes.get(key);
661
+ if (prior !== undefined)
662
+ return prior;
663
+ const index = this.entries.length;
664
+ this.entries.push({ parameters, results });
665
+ this.indexes.set(key, index);
666
+ return index;
667
+ }
668
+ }
669
+ /**
670
+ * Encodes the function-type section payload.
671
+ * @param {TypePool} types - Interned function types.
672
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
673
+ * @param {{node: SemanticNode, path: string}} root - Related module occurrence.
674
+ * @returns {BinaryWriter} Encoded payload.
675
+ */
676
+ function encodeTypeSection(types, index, root) {
677
+ const writer = new BinaryWriter(index);
678
+ writer.synthetic(u32(types.entries.length), "Function type count", root, "type count");
679
+ for (const type of types.entries) {
680
+ writer.synthetic([0x60], "Function type form", root, "type form");
681
+ writer.synthetic(u32(type.parameters.length), "Function parameter count", root, "type parameter count");
682
+ for (const parameter of type.parameters)
683
+ writer.synthetic([valueTypes[parameter]], "Function parameter value type", root, "value type");
684
+ writer.synthetic(u32(type.results.length), "Function result count", root, "type result count");
685
+ for (const result of type.results)
686
+ writer.synthetic([valueTypes[result]], "Function result value type", root, "value type");
687
+ }
688
+ return writer;
689
+ }
690
+ /**
691
+ * Encodes the fixed ABI import section payload.
692
+ * @param {number[]} typeIndexes - Import function type indexes.
693
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
694
+ * @param {{node: SemanticNode, path: string}} root - Related module occurrence.
695
+ * @returns {BinaryWriter} Encoded payload.
696
+ */
697
+ function encodeImportSection(typeIndexes, index, root) {
698
+ const writer = new BinaryWriter(index);
699
+ const names = ["print_i64", "print_bool", "print_string"];
700
+ writer.synthetic(u32(names.length), "ABI import count", root, "import count");
701
+ for (let offset = 0; offset < names.length; offset += 1) {
702
+ writer.synthetic(nameBytes("semantifold"), "ABI import module name", root, "import module");
703
+ writer.synthetic(nameBytes(names[offset]), "ABI import function name", root, "import name");
704
+ writer.synthetic([0x00], "Function import kind", root, "import kind");
705
+ writer.synthetic(u32(typeIndexes[offset]), "ABI import type index", root, "type index");
706
+ }
707
+ return writer;
708
+ }
709
+ /**
710
+ * Encodes defined-function type indexes.
711
+ * @param {number[]} helperTypes - Private helper type indexes.
712
+ * @param {number[]} semanticTypes - Semantic function type indexes.
713
+ * @param {number} runType - Exported run function type index.
714
+ * @param {SemanticModule} module - Semantic module.
715
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
716
+ * @returns {BinaryWriter} Encoded payload.
717
+ */
718
+ function encodeFunctionSection(helperTypes, semanticTypes, runType, module, index) {
719
+ const writer = new BinaryWriter(index);
720
+ const root = { node: module, path: "" };
721
+ writer.synthetic(u32(helperTypes.length + semanticTypes.length + 1), "Defined function count", root, "function count");
722
+ for (const typeIndex of helperTypes)
723
+ writer.synthetic(u32(typeIndex), "Private ABI helper type index", root, "type index");
724
+ for (let offset = 0; offset < semanticTypes.length; offset += 1) {
725
+ const declaration = module.functions[offset];
726
+ writer.synthetic(u32(semanticTypes[offset]), "Semantic function type index", { node: declaration, path: `/functions/${offset}` }, "type index");
727
+ }
728
+ writer.synthetic(u32(runType), "Exported run type index", { node: module.entryPoint, path: "/entryPoint" }, "type index");
729
+ return writer;
730
+ }
731
+ /**
732
+ * Encodes one fixed-memory declaration.
733
+ * @param {number} pages - Equal initial and maximum page count.
734
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
735
+ * @param {{node: SemanticNode, path: string}} root - Related module occurrence.
736
+ * @returns {BinaryWriter} Encoded payload.
737
+ */
738
+ function encodeMemorySection(pages, index, root) {
739
+ const writer = new BinaryWriter(index);
740
+ writer.synthetic(u32(1), "Single fixed linear memory", root, "memory count");
741
+ writer.synthetic([0x01], "Memory limits include equal maximum", root, "memory limits flags");
742
+ writer.synthetic(u32(pages), "Initial memory page count", root, "memory initial pages");
743
+ writer.synthetic(u32(pages), "Maximum memory page count", root, "memory maximum pages");
744
+ return writer;
745
+ }
746
+ /**
747
+ * Encodes private mutable ABI globals.
748
+ * @param {number} scratchBase - Initial scratch cursor.
749
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
750
+ * @param {{node: SemanticNode, path: string}} root - Related module occurrence.
751
+ * @returns {BinaryWriter} Encoded payload.
752
+ */
753
+ function encodeGlobalSection(scratchBase, index, root) {
754
+ const writer = new BinaryWriter(index);
755
+ const globals = [
756
+ { initial: scratchBase, reason: "Private scratch cursor" },
757
+ { initial: 0, reason: "Private semantic call depth" },
758
+ { initial: 0, reason: "Private run active guard" }
759
+ ];
760
+ writer.synthetic(u32(globals.length), "Private mutable global count", root, "global count");
761
+ for (const global of globals) {
762
+ writer.synthetic([valueTypes.i32, 0x01], `${global.reason} type and mutability`, root, "global type");
763
+ writer.synthetic([0x41], `${global.reason} initializer instruction`, root, "instruction");
764
+ writer.synthetic(s32(global.initial), `${global.reason} initializer immediate`, root, "immediate");
765
+ writer.synthetic([0x0b], `${global.reason} initializer end`, root, "instruction");
766
+ }
767
+ return writer;
768
+ }
769
+ /**
770
+ * Encodes exactly the public memory and run exports.
771
+ * @param {number} runIndex - Exported run function index.
772
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
773
+ * @param {{node: SemanticNode, path: string}} root - Related module occurrence.
774
+ * @returns {BinaryWriter} Encoded payload.
775
+ */
776
+ function encodeExportSection(runIndex, index, root) {
777
+ const writer = new BinaryWriter(index);
778
+ writer.synthetic(u32(2), "Exact ABI export count", root, "export count");
779
+ writer.synthetic(nameBytes("memory"), "Exported memory name", root, "export name");
780
+ writer.synthetic([0x02], "Memory export kind", root, "export kind");
781
+ writer.synthetic(u32(0), "Exported memory index", root, "memory index");
782
+ writer.synthetic(nameBytes("run"), "Exported run name", root, "export name");
783
+ writer.synthetic([0x00], "Function export kind", root, "export kind");
784
+ writer.synthetic(u32(runIndex), "Exported run function index", root, "function index");
785
+ return writer;
786
+ }
787
+ /**
788
+ * Encodes immutable UTF-8 literal data segments.
789
+ * @param {ReturnType<typeof collectLiteralLayout>["entries"]} entries - Ordered literal entries.
790
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
791
+ * @param {{node: SemanticNode, path: string}} root - Related module occurrence.
792
+ * @returns {BinaryWriter} Encoded payload.
793
+ */
794
+ function encodeDataSection(entries, index, root) {
795
+ const writer = new BinaryWriter(index);
796
+ const nonempty = entries.filter(({ bytes }) => bytes.byteLength > 0);
797
+ writer.synthetic(u32(nonempty.length), "Immutable literal data segment count", root, "data segment count");
798
+ for (const entry of nonempty) {
799
+ writer.synthetic([0x00, 0x41], "Active literal data segment and offset instruction", root, "data segment header");
800
+ writer.synthetic(s32(entry.address), "Literal data address", root, "data segment offset");
801
+ writer.synthetic([0x0b], "Literal offset expression end", root, "instruction");
802
+ writer.synthetic(u32(entry.bytes.byteLength), "Literal data byte length", root, "data segment length");
803
+ writer.write(entry.bytes, {
804
+ origin: entry.origin,
805
+ role: "immutable UTF-8 literal data"
806
+ });
807
+ }
808
+ return writer;
809
+ }
810
+ /**
811
+ * Encodes deterministic internal and semantic function names.
812
+ * @param {SemanticModule} module - Semantic module.
813
+ * @param {number} runIndex - Exported run function index.
814
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
815
+ * @returns {BinaryWriter} Encoded custom-section payload.
816
+ */
817
+ function encodeNamePayload(module, runIndex, index) {
818
+ const writer = new BinaryWriter(index);
819
+ const root = { node: module, path: "" };
820
+ const subsection = new BinaryWriter(index);
821
+ /** @type {{declaration?: import("../semantic/types.js").FunctionDeclaration, index: number, name: string, path?: string}[]} */
822
+ const names = [
823
+ ...helperNames.map((name, offset) => ({ index: importCount + offset, name })),
824
+ ...module.functions.map((declaration, offset) => ({ declaration, index: importCount + helperCount + offset, name: declaration.name, path: `/functions/${offset}` })),
825
+ { index: runIndex, name: "run" }
826
+ ];
827
+ subsection.synthetic(u32(names.length), "Named function count", root, "name count");
828
+ for (const name of names) {
829
+ subsection.synthetic(u32(name.index), "Named function index", root, "function index");
830
+ if (name.declaration) {
831
+ const bytes = encoder.encode(name.name);
832
+ const related = { node: name.declaration, path: /** @type {string} */ (name.path) };
833
+ subsection.synthetic(u32(bytes.byteLength), "Semantic function name byte length", related, "function name length");
834
+ subsection.mapped(bytes, name.declaration, related.path, "semantic function name", "name");
835
+ }
836
+ else
837
+ subsection.synthetic(nameBytes(name.name), "Private ABI function name", root, "function name");
838
+ }
839
+ writer.synthetic([0x01], "Function names subsection ID", root, "custom subsection id");
840
+ writer.synthetic(u32(subsection.bytes.length), "Function names subsection size", root, "custom subsection size");
841
+ writer.append(subsection);
842
+ return writer;
843
+ }
844
+ /**
845
+ * Encodes one source-map URL custom-section payload.
846
+ * @param {string} content - Relative map URL.
847
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
848
+ * @param {{node: SemanticNode, path: string}} root - Related module occurrence.
849
+ * @returns {BinaryWriter} Encoded payload.
850
+ */
851
+ function namedPayload(content, index, root) {
852
+ const writer = new BinaryWriter(index);
853
+ writer.synthetic(encoder.encode(content), "Relative external Wasm source-map URL", root, "custom section payload");
854
+ return writer;
855
+ }
856
+ /**
857
+ * Appends one sized module section.
858
+ * @param {BinaryWriter} moduleWriter - Complete module writer.
859
+ * @param {number} id - Core section ID.
860
+ * @param {string} name - Diagnostic section name.
861
+ * @param {BinaryWriter} payload - Encoded section payload.
862
+ * @param {{node: SemanticNode, path: string}} root - Related module occurrence.
863
+ * @returns {void}
864
+ */
865
+ function appendSection(moduleWriter, id, name, payload, root) {
866
+ moduleWriter.synthetic([id], `${name} section ID`, root, `${name} section`);
867
+ moduleWriter.synthetic(u32(payload.bytes.length), `${name} section byte length`, root, `${name} section length`);
868
+ moduleWriter.append(payload);
869
+ }
870
+ /**
871
+ * Appends one named custom section.
872
+ * @param {BinaryWriter} writer - Complete module writer.
873
+ * @param {string} name - Custom-section name.
874
+ * @param {BinaryWriter} payload - Custom-section payload.
875
+ * @param {{node: SemanticNode, path: string}} root - Related module occurrence.
876
+ * @returns {void}
877
+ */
878
+ function appendCustomSection(writer, name, payload, root) {
879
+ const complete = new BinaryWriter(writer.index);
880
+ complete.synthetic(nameBytes(name), `Custom section name '${name}'`, root, "custom section name");
881
+ complete.append(payload);
882
+ appendSection(writer, 0, `custom ${name}`, complete, root);
883
+ }
884
+ /**
885
+ * Appends one sized function body and its flattened locals.
886
+ * @param {BinaryWriter} code - Code-section payload writer.
887
+ * @param {BinaryWriter} instructions - Function instructions.
888
+ * @param {("i32" | "i64")[]} locals - Flattened local types.
889
+ * @param {{node: SemanticNode, path: string}} related - Related semantic occurrence.
890
+ * @param {string} name - Function name for provenance.
891
+ * @returns {void}
892
+ */
893
+ function appendFunctionBody(code, instructions, locals, related, name) {
894
+ const body = new BinaryWriter(code.index);
895
+ body.synthetic(u32(locals.length), `Local declaration group count for ${name}`, related, "function locals");
896
+ for (const local of locals) {
897
+ body.synthetic(u32(1), `Local count for ${name}`, related, "local count");
898
+ body.synthetic([valueTypes[local]], `Local value type for ${name}`, related, "local type");
899
+ }
900
+ body.append(instructions);
901
+ code.synthetic(u32(body.bytes.length), `Function body byte length for ${name}`, related, "function body length");
902
+ code.append(body);
903
+ }
904
+ /**
905
+ * Encodes checked scratch allocation and string concatenation.
906
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
907
+ * @param {SemanticModule} module - Semantic module.
908
+ * @param {number} scratchBase - Arena start address.
909
+ * @returns {BinaryWriter} Encoded helper body.
910
+ */
911
+ function helperConcat(index, module, scratchBase) {
912
+ const e = new SyntheticEmitter(index, module, "$concat");
913
+ const total = 4;
914
+ const start = 5;
915
+ const end = 6;
916
+ const cursor = 7;
917
+ e.localGet(1);
918
+ e.localGet(3);
919
+ e.op(0x6a, "add string lengths");
920
+ e.localTee(total);
921
+ e.localGet(1);
922
+ e.op(0x49, "detect unsigned string-length overflow");
923
+ e.trapIf("string-length overflow");
924
+ e.globalGet(cursorGlobalIndex);
925
+ e.localTee(start);
926
+ e.localGet(total);
927
+ e.op(0x6a, "add scratch cursor and allocation length");
928
+ e.localTee(end);
929
+ e.localGet(start);
930
+ e.op(0x49, "detect unsigned scratch-cursor overflow");
931
+ e.trapIf("scratch cursor overflow");
932
+ e.localGet(end);
933
+ e.i32(scratchBase + scratchCapacity);
934
+ e.op(0x4b, "compare allocation end with arena end");
935
+ e.trapIf("scratch capacity exceeded");
936
+ e.i32(0);
937
+ e.localSet(cursor);
938
+ e.copyLoop(cursor, 0, 1, start, undefined);
939
+ e.i32(0);
940
+ e.localSet(cursor);
941
+ e.copyLoop(cursor, 2, 3, start, 1);
942
+ e.localGet(end);
943
+ e.globalSet(cursorGlobalIndex);
944
+ e.localGet(start);
945
+ e.localGet(total);
946
+ e.end();
947
+ return e.writer;
948
+ }
949
+ /**
950
+ * Encodes byte-exact string equality.
951
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
952
+ * @param {SemanticModule} module - Semantic module.
953
+ * @returns {BinaryWriter} Encoded helper body.
954
+ */
955
+ function helperStringEqual(index, module) {
956
+ const e = new SyntheticEmitter(index, module, "$string_equal");
957
+ const cursor = 4;
958
+ e.localGet(1);
959
+ e.localGet(3);
960
+ e.op(0x47, "compare string lengths");
961
+ e.op(0x04, "branch for unequal string lengths");
962
+ e.immediate([0x40], "empty block type");
963
+ e.i32(0);
964
+ e.op(0x0f, "return false for unequal lengths");
965
+ e.op(0x0b, "end length branch");
966
+ e.i32(0);
967
+ e.localSet(cursor);
968
+ e.op(0x02, "string comparison exit block");
969
+ e.immediate([0x40], "empty block type");
970
+ e.op(0x03, "string comparison loop");
971
+ e.immediate([0x40], "empty block type");
972
+ e.localGet(cursor);
973
+ e.localGet(1);
974
+ e.op(0x4f, "compare cursor with string length");
975
+ e.op(0x0d, "exit completed comparison");
976
+ e.immediate(u32(1), "comparison block depth");
977
+ e.localGet(0);
978
+ e.localGet(cursor);
979
+ e.op(0x6a, "left byte address");
980
+ e.load8();
981
+ e.localGet(2);
982
+ e.localGet(cursor);
983
+ e.op(0x6a, "right byte address");
984
+ e.load8();
985
+ e.op(0x47, "compare UTF-8 bytes");
986
+ e.op(0x04, "branch for unequal UTF-8 bytes");
987
+ e.immediate([0x40], "empty block type");
988
+ e.i32(0);
989
+ e.op(0x0f, "return false for unequal bytes");
990
+ e.op(0x0b, "end byte branch");
991
+ e.localGet(cursor);
992
+ e.i32(1);
993
+ e.op(0x6a, "increment comparison cursor");
994
+ e.localSet(cursor);
995
+ e.op(0x0c, "continue string comparison");
996
+ e.immediate(u32(0), "comparison loop depth");
997
+ e.op(0x0b, "end comparison loop");
998
+ e.op(0x0b, "end comparison block");
999
+ e.i32(1);
1000
+ e.end();
1001
+ return e.writer;
1002
+ }
1003
+ /**
1004
+ * Encodes checked signed i64 addition.
1005
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
1006
+ * @param {SemanticModule} module - Semantic module.
1007
+ * @returns {BinaryWriter} Encoded helper body.
1008
+ */
1009
+ function helperCheckedAdd(index, module) {
1010
+ const e = new SyntheticEmitter(index, module, "$checked_add");
1011
+ e.localGet(0);
1012
+ e.localGet(1);
1013
+ e.op(0x7c, "signed i64 addition");
1014
+ e.localSet(2);
1015
+ e.localGet(0);
1016
+ e.localGet(2);
1017
+ e.op(0x85, "addition overflow xor");
1018
+ e.localGet(1);
1019
+ e.localGet(2);
1020
+ e.op(0x85, "addition overflow xor");
1021
+ e.op(0x83, "addition overflow mask");
1022
+ e.i64(0n);
1023
+ e.op(0x53, "addition overflow sign test");
1024
+ e.trapIf("signed i64 addition overflow");
1025
+ e.localGet(2);
1026
+ e.end();
1027
+ return e.writer;
1028
+ }
1029
+ /**
1030
+ * Encodes checked signed i64 subtraction.
1031
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
1032
+ * @param {SemanticModule} module - Semantic module.
1033
+ * @returns {BinaryWriter} Encoded helper body.
1034
+ */
1035
+ function helperCheckedSubtract(index, module) {
1036
+ const e = new SyntheticEmitter(index, module, "$checked_subtract");
1037
+ e.localGet(0);
1038
+ e.localGet(1);
1039
+ e.op(0x7d, "signed i64 subtraction");
1040
+ e.localSet(2);
1041
+ e.localGet(0);
1042
+ e.localGet(1);
1043
+ e.op(0x85, "subtraction overflow xor");
1044
+ e.localGet(0);
1045
+ e.localGet(2);
1046
+ e.op(0x85, "subtraction overflow xor");
1047
+ e.op(0x83, "subtraction overflow mask");
1048
+ e.i64(0n);
1049
+ e.op(0x53, "subtraction overflow sign test");
1050
+ e.trapIf("signed i64 subtraction overflow");
1051
+ e.localGet(2);
1052
+ e.end();
1053
+ return e.writer;
1054
+ }
1055
+ /**
1056
+ * Encodes checked signed i64 multiplication.
1057
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
1058
+ * @param {SemanticModule} module - Semantic module.
1059
+ * @returns {BinaryWriter} Encoded helper body.
1060
+ */
1061
+ function helperCheckedMultiply(index, module) {
1062
+ const e = new SyntheticEmitter(index, module, "$checked_multiply");
1063
+ e.localGet(0);
1064
+ e.op(0x50, "left operand zero test");
1065
+ e.localGet(1);
1066
+ e.op(0x50, "right operand zero test");
1067
+ e.op(0x72, "zero operand combination");
1068
+ e.op(0x04, "zero multiplication branch");
1069
+ e.immediate([valueTypes.i64], "i64 branch result type");
1070
+ e.i64(0n);
1071
+ e.op(0x05, "nonzero multiplication branch");
1072
+ e.localGet(0);
1073
+ e.i64(-1n);
1074
+ e.op(0x51, "left negative-one test");
1075
+ e.localGet(1);
1076
+ e.i64(-9223372036854775808n);
1077
+ e.op(0x51, "right minimum test");
1078
+ e.op(0x71, "first division overflow combination");
1079
+ e.localGet(1);
1080
+ e.i64(-1n);
1081
+ e.op(0x51, "right negative-one test");
1082
+ e.localGet(0);
1083
+ e.i64(-9223372036854775808n);
1084
+ e.op(0x51, "left minimum test");
1085
+ e.op(0x71, "second division overflow combination");
1086
+ e.op(0x72, "division overflow combination");
1087
+ e.trapIf("signed i64 multiplication overflow");
1088
+ e.localGet(0);
1089
+ e.localGet(1);
1090
+ e.op(0x7e, "signed i64 multiplication");
1091
+ e.localSet(2);
1092
+ e.localGet(2);
1093
+ e.localGet(1);
1094
+ e.op(0x7f, "signed i64 division overflow check");
1095
+ e.localGet(0);
1096
+ e.op(0x52, "multiplication quotient mismatch");
1097
+ e.trapIf("signed i64 multiplication overflow");
1098
+ e.localGet(2);
1099
+ e.op(0x0b, "end checked multiplication branch");
1100
+ e.end();
1101
+ return e.writer;
1102
+ }
1103
+ /**
1104
+ * Encodes checked signed i64 negation.
1105
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
1106
+ * @param {SemanticModule} module - Semantic module.
1107
+ * @returns {BinaryWriter} Encoded helper body.
1108
+ */
1109
+ function helperCheckedNegate(index, module) {
1110
+ const e = new SyntheticEmitter(index, module, "$checked_negate");
1111
+ e.localGet(0);
1112
+ e.i64(-9223372036854775808n);
1113
+ e.op(0x51, "minimum i64 negate test");
1114
+ e.trapIf("signed i64 negation overflow");
1115
+ e.i64(0n);
1116
+ e.localGet(0);
1117
+ e.op(0x7d, "signed i64 negation");
1118
+ e.end();
1119
+ return e.writer;
1120
+ }
1121
+ /** Helper instruction emitter with explicit synthetic provenance. */
1122
+ class SyntheticEmitter {
1123
+ /**
1124
+ * Creates a synthetic helper emitter.
1125
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
1126
+ * @param {SemanticModule} module - Related semantic module.
1127
+ * @param {string} name - Helper function name.
1128
+ */
1129
+ constructor(index, module, name) {
1130
+ this.writer = new BinaryWriter(index);
1131
+ this.related = { node: module, path: "" };
1132
+ this.name = name;
1133
+ }
1134
+ /**
1135
+ * Writes an instruction opcode.
1136
+ * @param {number} opcode - Wasm opcode.
1137
+ * @param {string} reason - Synthetic provenance reason.
1138
+ * @returns {void}
1139
+ */
1140
+ op(opcode, reason) { this.writer.synthetic([opcode], `${this.name}: ${reason}`, this.related, "instruction"); }
1141
+ /**
1142
+ * Writes encoded instruction immediates.
1143
+ * @param {number[]} bytes - Immediate bytes.
1144
+ * @param {string} reason - Synthetic provenance reason.
1145
+ * @returns {void}
1146
+ */
1147
+ immediate(bytes, reason) { this.writer.synthetic(bytes, `${this.name}: ${reason}`, this.related, "immediate"); }
1148
+ /**
1149
+ * Reads one local.
1150
+ * @param {number} index - Local index.
1151
+ * @returns {void}
1152
+ */
1153
+ localGet(index) { this.op(0x20, "read local"); this.immediate(u32(index), "local index"); }
1154
+ /**
1155
+ * Writes one local.
1156
+ * @param {number} index - Local index.
1157
+ * @returns {void}
1158
+ */
1159
+ localSet(index) { this.op(0x21, "write local"); this.immediate(u32(index), "local index"); }
1160
+ /**
1161
+ * Writes and retains one local value.
1162
+ * @param {number} index - Local index.
1163
+ * @returns {void}
1164
+ */
1165
+ localTee(index) { this.op(0x22, "tee local"); this.immediate(u32(index), "local index"); }
1166
+ /**
1167
+ * Reads one global.
1168
+ * @param {number} index - Global index.
1169
+ * @returns {void}
1170
+ */
1171
+ globalGet(index) { this.op(0x23, "read global"); this.immediate(u32(index), "global index"); }
1172
+ /**
1173
+ * Writes one global.
1174
+ * @param {number} index - Global index.
1175
+ * @returns {void}
1176
+ */
1177
+ globalSet(index) { this.op(0x24, "write global"); this.immediate(u32(index), "global index"); }
1178
+ /**
1179
+ * Writes one i32 constant.
1180
+ * @param {number} value - Constant value.
1181
+ * @returns {void}
1182
+ */
1183
+ i32(value) { this.op(0x41, "i32 constant"); this.immediate(s32(value), "i32 immediate"); }
1184
+ /**
1185
+ * Writes one i64 constant.
1186
+ * @param {bigint} value - Constant value.
1187
+ * @returns {void}
1188
+ */
1189
+ i64(value) { this.op(0x42, "i64 constant"); this.immediate(s64(value), "i64 immediate"); }
1190
+ /**
1191
+ * Loads one unsigned byte.
1192
+ * @returns {void}
1193
+ */
1194
+ load8() { this.op(0x2d, "load unsigned byte"); this.immediate([0x00, 0x00], "byte-load memory arguments"); }
1195
+ /**
1196
+ * Stores one byte.
1197
+ * @returns {void}
1198
+ */
1199
+ store8() { this.op(0x3a, "store byte"); this.immediate([0x00, 0x00], "byte-store memory arguments"); }
1200
+ /**
1201
+ * Traps when the stack's condition is nonzero.
1202
+ * @param {string} reason - Trap provenance reason.
1203
+ * @returns {void}
1204
+ */
1205
+ trapIf(reason) {
1206
+ this.op(0x04, `${reason} branch`);
1207
+ this.immediate([0x40], "empty block type");
1208
+ this.op(0x00, `${reason} trap`);
1209
+ this.op(0x0b, `${reason} branch end`);
1210
+ }
1211
+ /**
1212
+ * Copies one string operand byte by byte.
1213
+ * @param {number} cursor - Loop cursor local.
1214
+ * @param {number} sourcePointer - Source pointer local.
1215
+ * @param {number} sourceLength - Source length local.
1216
+ * @param {number} destination - Allocation start local.
1217
+ * @param {number | undefined} destinationOffset - Optional left-length local.
1218
+ * @returns {void}
1219
+ */
1220
+ copyLoop(cursor, sourcePointer, sourceLength, destination, destinationOffset) {
1221
+ this.op(0x02, "copy exit block");
1222
+ this.immediate([0x40], "empty block type");
1223
+ this.op(0x03, "copy loop");
1224
+ this.immediate([0x40], "empty block type");
1225
+ this.localGet(cursor);
1226
+ this.localGet(sourceLength);
1227
+ this.op(0x4f, "compare copy cursor with length");
1228
+ this.op(0x0d, "exit completed copy");
1229
+ this.immediate(u32(1), "copy block depth");
1230
+ this.localGet(destination);
1231
+ if (destinationOffset !== undefined) {
1232
+ this.localGet(destinationOffset);
1233
+ this.op(0x6a, "add destination offset");
1234
+ }
1235
+ this.localGet(cursor);
1236
+ this.op(0x6a, "add destination cursor");
1237
+ this.localGet(sourcePointer);
1238
+ this.localGet(cursor);
1239
+ this.op(0x6a, "add source cursor");
1240
+ this.load8();
1241
+ this.store8();
1242
+ this.localGet(cursor);
1243
+ this.i32(1);
1244
+ this.op(0x6a, "increment copy cursor");
1245
+ this.localSet(cursor);
1246
+ this.op(0x0c, "continue copy loop");
1247
+ this.immediate(u32(0), "copy loop depth");
1248
+ this.op(0x0b, "end copy loop");
1249
+ this.op(0x0b, "end copy block");
1250
+ }
1251
+ /**
1252
+ * Ends one helper function.
1253
+ * @returns {void}
1254
+ */
1255
+ end() { this.op(0x0b, "function end"); }
1256
+ }
1257
+ /**
1258
+ * Collects deduplicated literal bytes and their combined semantic origins.
1259
+ * @param {SemanticModule} module - Semantic module.
1260
+ * @param {ReturnType<typeof createGenerationIndex>} index - Provenance index.
1261
+ * @returns {{boundary: number, byValue: Map<string, {address: number, bytes: Uint8Array}>, entries: {address: number, bytes: Uint8Array, origin: import("../semantic/types.js").SemanticOrigin}[]}} Layout.
1262
+ */
1263
+ function collectLiteralLayout(module, index) {
1264
+ /** @type {Map<string, {bytes: Uint8Array, occurrences: ReturnType<typeof index.recordFor>[]}>} */
1265
+ const collected = new Map();
1266
+ for (const { node, path } of semanticEntries(module)) {
1267
+ if (node.kind != "StringLiteral")
1268
+ continue;
1269
+ const existing = collected.get(node.value);
1270
+ if (existing)
1271
+ existing.occurrences.push(index.recordFor(node, path));
1272
+ else
1273
+ collected.set(node.value, { bytes: encoder.encode(node.value), occurrences: [index.recordFor(node, path)] });
1274
+ }
1275
+ let address = 1;
1276
+ /** @type {Map<string, {address: number, bytes: Uint8Array}>} */
1277
+ const byValue = new Map();
1278
+ /** @type {{address: number, bytes: Uint8Array, origin: import("../semantic/types.js").SemanticOrigin}[]} */
1279
+ const entries = [];
1280
+ for (const [value, literal] of collected) {
1281
+ const next = checkedSize(address + literal.bytes.byteLength, module, "immutable literal memory layout");
1282
+ const exactOrigins = literal.occurrences.map((record) => originForRole(index, record, "literal"));
1283
+ const origins = literal.occurrences.flatMap((record, offset) => relatedOrigins(record, exactOrigins[offset]));
1284
+ const origin = literal.occurrences.length == 1 ? exactOrigins[0] : origins.length > 0
1285
+ ? { kind: "derived", origins }
1286
+ : { kind: "synthetic", reason: "Deduplicated immutable UTF-8 literal data without source ranges.", relatedOrigins: [] };
1287
+ entries.push({ address, bytes: literal.bytes, origin: /** @type {import("../semantic/types.js").SemanticOrigin} */ (origin) });
1288
+ byValue.set(value, { address, bytes: literal.bytes });
1289
+ address = next;
1290
+ }
1291
+ return { boundary: address, byValue, entries };
1292
+ }
1293
+ /**
1294
+ * Performs bounded path-sensitive allocation analysis from run.
1295
+ * @param {SemanticModule} module - Validated module.
1296
+ * @returns {number} Worst reachable allocation bytes.
1297
+ */
1298
+ function analyzeScratchUse(module) {
1299
+ const functions = new Map(module.functions.map((declaration) => [declaration.name, declaration]));
1300
+ let steps = 0;
1301
+ const states = block(module.entryPoint.body, [{ allocated: 0, env: new Map() }], 0);
1302
+ return Math.max(0, ...states.map(({ allocated }) => allocated));
1303
+ /**
1304
+ * Analyzes one block from every incoming path state.
1305
+ * @param {import("../semantic/types.js").Block} semanticBlock - Block to analyze.
1306
+ * @param {AnalysisState[]} incoming - Incoming path states.
1307
+ * @param {number} depth - Active semantic call depth.
1308
+ * @returns {AnalysisState[]} Resulting path states.
1309
+ */
1310
+ function block(semanticBlock, incoming, depth) {
1311
+ let states = incoming;
1312
+ for (const statement of semanticBlock.statements) {
1313
+ const next = [];
1314
+ for (const state of states) {
1315
+ if (state.returned) {
1316
+ next.push(state);
1317
+ continue;
1318
+ }
1319
+ if (statement.kind == "LocalDeclaration") {
1320
+ for (const result of expression(statement.initializer, state, depth)) {
1321
+ const env = new Map(result.state.env);
1322
+ env.set(statement.name, result.value);
1323
+ next.push({ ...result.state, env });
1324
+ }
1325
+ }
1326
+ else if (statement.kind == "AssignmentStatement") {
1327
+ for (const result of expression(statement.expression, state, depth)) {
1328
+ const env = new Map(result.state.env);
1329
+ env.set(statement.target.name, result.value);
1330
+ next.push({ ...result.state, env });
1331
+ }
1332
+ }
1333
+ else if (statement.kind == "PrintStatement") {
1334
+ for (const result of expression(statement.expression, state, depth))
1335
+ next.push(result.state);
1336
+ }
1337
+ else if (statement.kind == "ReturnStatement") {
1338
+ if (!statement.expression)
1339
+ throw new TypeError("Wasm bare return reached abstract execution.");
1340
+ for (const result of expression(statement.expression, state, depth))
1341
+ next.push({ ...result.state, returned: result.value });
1342
+ }
1343
+ else if (statement.kind == "ExpressionStatement") {
1344
+ throw new TypeError("Wasm Task 005 expression statement reached abstract execution.");
1345
+ }
1346
+ else if (statement.kind == "IfStatement") {
1347
+ for (const condition of expression(statement.condition, state, depth)) {
1348
+ if (condition.value.knownBoolean !== false) {
1349
+ next.push(...withoutBranchLocals(block(statement.consequent, [cloneState(condition.state)], depth), condition.state.env));
1350
+ }
1351
+ if (condition.value.knownBoolean !== true) {
1352
+ const alternate = statement.alternate
1353
+ ? block(statement.alternate, [cloneState(condition.state)], depth)
1354
+ : [cloneState(condition.state)];
1355
+ next.push(...withoutBranchLocals(alternate, condition.state.env));
1356
+ }
1357
+ }
1358
+ }
1359
+ else {
1360
+ throw new TypeError("Unsupported Wasm statement reached abstract execution.");
1361
+ }
1362
+ }
1363
+ states = boundedStates(next, statement);
1364
+ }
1365
+ return states;
1366
+ }
1367
+ /**
1368
+ * Evaluates abstract values and allocation demand for one expression.
1369
+ * @param {Expression} value - Expression to analyze.
1370
+ * @param {AnalysisState} state - Incoming path state.
1371
+ * @param {number} depth - Active semantic call depth.
1372
+ * @returns {{state: AnalysisState, value: AbstractValue}[]} Possible outcomes.
1373
+ */
1374
+ function expression(value, state, depth) {
1375
+ steps += 1;
1376
+ if (steps > maximumAnalysisSteps)
1377
+ unsupportedCapability("wasm", "unprovable path-sensitive scratch allocation bound", value.location);
1378
+ if (value.kind == "IdentifierExpression") {
1379
+ const found = state.env.get(value.name);
1380
+ if (!found)
1381
+ throw new Error("Validated Wasm analysis omitted an identifier binding.");
1382
+ return [{ state, value: found }];
1383
+ }
1384
+ if (value.kind == "IntegerLiteral")
1385
+ return [{ state, value: { knownInteger: BigInt(value.value), type: "integer" } }];
1386
+ if (value.kind == "BooleanLiteral")
1387
+ return [{ state, value: { knownBoolean: value.value, type: "boolean" } }];
1388
+ if (value.kind == "StringLiteral") {
1389
+ return [{ state, value: { knownString: value.value, stringLength: encoder.encode(value.value).byteLength, type: "string" } }];
1390
+ }
1391
+ if (value.kind == "CallExpression") {
1392
+ let argumentsList = [{ state, values: /** @type {AbstractValue[]} */ ([]) }];
1393
+ for (const argument of value.arguments) {
1394
+ const next = [];
1395
+ for (const current of argumentsList) {
1396
+ for (const result of expression(argument, current.state, depth)) {
1397
+ next.push({ state: result.state, values: [...current.values, result.value] });
1398
+ }
1399
+ }
1400
+ argumentsList = next;
1401
+ }
1402
+ const declaration = functions.get(value.callee);
1403
+ if (!declaration)
1404
+ throw new Error("Validated Wasm analysis omitted a call declaration.");
1405
+ if (depth >= maximumCallDepth)
1406
+ unsupportedCapability("wasm", `semantic call depth above ${maximumCallDepth}`, value.location);
1407
+ /** @type {{state: AnalysisState, value: AbstractValue}[]} */
1408
+ const outcomes = [];
1409
+ for (const argumentSet of argumentsList) {
1410
+ const env = new Map(declaration.parameters.map((parameter, index) => [parameter.name, argumentSet.values[index]]));
1411
+ const called = block(declaration.body, [{ allocated: 0, env }], depth + 1);
1412
+ for (const returned of called) {
1413
+ if (!returned.returned)
1414
+ throw new Error("Validated Wasm function analysis omitted a return value.");
1415
+ outcomes.push({
1416
+ state: { ...argumentSet.state, allocated: addAllocation(argumentSet.state.allocated, returned.allocated, value) },
1417
+ value: returned.returned
1418
+ });
1419
+ }
1420
+ }
1421
+ return outcomes;
1422
+ }
1423
+ if (value.kind == "UnaryExpression") {
1424
+ return expression(value.operand, state, depth).map((operand) => {
1425
+ if (value.operation == "BooleanNot") {
1426
+ return { state: operand.state, value: { type: "boolean", ...(operand.value.knownBoolean === undefined ? {} : { knownBoolean: !operand.value.knownBoolean }) } };
1427
+ }
1428
+ const knownInteger = operand.value.knownInteger === undefined ? undefined : checkedI64(-operand.value.knownInteger, value);
1429
+ return { state: operand.state, value: { type: "integer", ...(knownInteger === undefined ? {} : { knownInteger }) } };
1430
+ });
1431
+ }
1432
+ if (value.kind != "BinaryExpression") {
1433
+ return unsupportedCapability("wasm", "collection expression reached scalar analysis", value.location);
1434
+ }
1435
+ if (value.operation == "BooleanAnd" || value.operation == "BooleanOr") {
1436
+ /** @type {{state: AnalysisState, value: AbstractValue}[]} */
1437
+ const outcomes = [];
1438
+ for (const left of expression(value.left, state, depth)) {
1439
+ const shortCircuits = value.operation == "BooleanAnd" ? left.value.knownBoolean === false : left.value.knownBoolean === true;
1440
+ const mustEvaluate = value.operation == "BooleanAnd" ? left.value.knownBoolean === true : left.value.knownBoolean === false;
1441
+ if (shortCircuits || !mustEvaluate)
1442
+ outcomes.push({ state: left.state, value: { knownBoolean: value.operation == "BooleanOr", type: "boolean" } });
1443
+ if (!shortCircuits)
1444
+ outcomes.push(...expression(value.right, cloneState(left.state), depth));
1445
+ }
1446
+ return outcomes;
1447
+ }
1448
+ const outcomes = [];
1449
+ for (const left of expression(value.left, state, depth)) {
1450
+ for (const right of expression(value.right, left.state, depth)) {
1451
+ outcomes.push(binary(value, left.value, right.value, right.state));
1452
+ }
1453
+ }
1454
+ return outcomes;
1455
+ }
1456
+ /**
1457
+ * Combines abstract operands for one binary operation.
1458
+ * @param {import("../semantic/types.js").BinaryExpression} expressionNode - Binary expression.
1459
+ * @param {AbstractValue} left - Abstract left operand.
1460
+ * @param {AbstractValue} right - Abstract right operand.
1461
+ * @param {AnalysisState} state - State after evaluating both operands.
1462
+ * @returns {{state: AnalysisState, value: AbstractValue}} Combined outcome.
1463
+ */
1464
+ function binary(expressionNode, left, right, state) {
1465
+ const operation = expressionNode.operation;
1466
+ if (operation == "StringConcat") {
1467
+ if (left.stringLength === undefined || right.stringLength === undefined) {
1468
+ unsupportedCapability("wasm", "unprovable StringConcat byte length", expressionNode.location);
1469
+ }
1470
+ const length = addAllocation(left.stringLength, right.stringLength, expressionNode);
1471
+ const allocated = addAllocation(state.allocated, length, expressionNode);
1472
+ const knownString = left.knownString !== undefined && right.knownString !== undefined ? left.knownString + right.knownString : undefined;
1473
+ return { state: { ...state, allocated }, value: { type: "string", stringLength: length, ...(knownString === undefined ? {} : { knownString }) } };
1474
+ }
1475
+ if (["IntegerAdd", "IntegerSubtract", "IntegerMultiply"].includes(operation)) {
1476
+ let knownInteger;
1477
+ if (left.knownInteger !== undefined && right.knownInteger !== undefined) {
1478
+ knownInteger = operation == "IntegerAdd" ? left.knownInteger + right.knownInteger :
1479
+ operation == "IntegerSubtract" ? left.knownInteger - right.knownInteger : left.knownInteger * right.knownInteger;
1480
+ knownInteger = checkedI64(knownInteger, expressionNode);
1481
+ }
1482
+ return { state, value: { type: "integer", ...(knownInteger === undefined ? {} : { knownInteger }) } };
1483
+ }
1484
+ if (operation.startsWith("Integer") && operation != "IntegerEqual" && operation != "IntegerNotEqual") {
1485
+ return { state, value: { knownBoolean: compareKnown(operation, left.knownInteger, right.knownInteger), type: "boolean" } };
1486
+ }
1487
+ if (operation == "IntegerEqual" || operation == "IntegerNotEqual") {
1488
+ return { state, value: { knownBoolean: equalKnown(left.knownInteger, right.knownInteger, operation.endsWith("NotEqual")), type: "boolean" } };
1489
+ }
1490
+ if (operation == "BooleanEqual" || operation == "BooleanNotEqual") {
1491
+ return { state, value: { knownBoolean: equalKnown(left.knownBoolean, right.knownBoolean, operation.endsWith("NotEqual")), type: "boolean" } };
1492
+ }
1493
+ return { state, value: { knownBoolean: equalKnown(left.knownString, right.knownString, operation == "StringNotEqual"), type: "boolean" } };
1494
+ }
1495
+ /**
1496
+ * Rejects path-state growth beyond the deterministic analysis bound.
1497
+ * @param {AnalysisState[]} candidates - Candidate states.
1498
+ * @param {{location: import("../semantic/types.js").SourceLocation}} node - Related semantic node.
1499
+ * @returns {AnalysisState[]} Accepted states.
1500
+ */
1501
+ function boundedStates(candidates, node) {
1502
+ if (candidates.length > maximumAnalysisSteps)
1503
+ unsupportedCapability("wasm", "unprovable path-sensitive scratch allocation state count", node.location);
1504
+ return candidates;
1505
+ }
1506
+ }
1507
+ /**
1508
+ * Compares two known integer operands when available.
1509
+ * @param {string} operation - Semantic comparison operation.
1510
+ * @param {bigint | undefined} left - Known left operand.
1511
+ * @param {bigint | undefined} right - Known right operand.
1512
+ * @returns {boolean | undefined} Known comparison result.
1513
+ */
1514
+ function compareKnown(operation, left, right) {
1515
+ if (left === undefined || right === undefined)
1516
+ return undefined;
1517
+ if (operation == "IntegerLessThan")
1518
+ return left < right;
1519
+ if (operation == "IntegerLessThanOrEqual")
1520
+ return left <= right;
1521
+ if (operation == "IntegerGreaterThan")
1522
+ return left > right;
1523
+ return left >= right;
1524
+ }
1525
+ /**
1526
+ * Compares two known same-type operands when available.
1527
+ * @template T
1528
+ * @param {T | undefined} left - Known left operand.
1529
+ * @param {T | undefined} right - Known right operand.
1530
+ * @param {boolean} invert - Whether to invert equality.
1531
+ * @returns {boolean | undefined} Known equality result.
1532
+ */
1533
+ function equalKnown(left, right, invert) {
1534
+ return left === undefined || right === undefined ? undefined : invert ? left !== right : left === right;
1535
+ }
1536
+ /**
1537
+ * Checks one compile-time integer against signed i64 bounds.
1538
+ * @param {bigint} value - Candidate integer.
1539
+ * @param {{location: import("../semantic/types.js").SourceLocation}} node - Related semantic node.
1540
+ * @returns {bigint} Checked integer.
1541
+ */
1542
+ function checkedI64(value, node) {
1543
+ if (value < -9223372036854775808n || value > 9223372036854775807n) {
1544
+ unsupportedCapability("wasm", "compile-time-known signed i64 overflow", node.location);
1545
+ }
1546
+ return value;
1547
+ }
1548
+ /**
1549
+ * Adds bounded allocation counts without approximation.
1550
+ * @param {number} left - Existing allocation count.
1551
+ * @param {number} right - Additional allocation count.
1552
+ * @param {{location: import("../semantic/types.js").SourceLocation}} node - Related semantic node.
1553
+ * @returns {number} Checked total.
1554
+ */
1555
+ function addAllocation(left, right, node) {
1556
+ const total = left + right;
1557
+ if (!Number.isSafeInteger(total) || total < 0)
1558
+ unsupportedCapability("wasm", "scratch allocation arithmetic overflow", node.location);
1559
+ if (total > scratchCapacity)
1560
+ unsupportedCapability("wasm", `scratch allocation above ${scratchCapacity} bytes`, node.location);
1561
+ return total;
1562
+ }
1563
+ /**
1564
+ * Clones one path state and its lexical environment.
1565
+ * @param {AnalysisState} state - State to clone.
1566
+ * @returns {AnalysisState} Detached state.
1567
+ */
1568
+ function cloneState(state) { return { ...state, env: new Map(state.env) }; }
1569
+ /**
1570
+ * Removes bindings declared only inside a branch.
1571
+ * @param {AnalysisState[]} states - Branch result states.
1572
+ * @param {Map<string, AbstractValue>} parent - Parent lexical environment.
1573
+ * @returns {AnalysisState[]} States restricted to parent bindings.
1574
+ */
1575
+ function withoutBranchLocals(states, parent) {
1576
+ return states.map((state) => {
1577
+ const env = new Map([...state.env].filter(([name]) => parent.has(name)));
1578
+ return { ...state, env };
1579
+ });
1580
+ }
1581
+ /**
1582
+ * Resolves one expression's semantic scalar type.
1583
+ * @param {Expression} expression - Expression to inspect.
1584
+ * @param {Map<string, LocalBinding>} bindings - Lexical local bindings.
1585
+ * @param {Map<string, import("../semantic/types.js").FunctionDeclaration>} functions - Semantic declarations by name.
1586
+ * @returns {Scalar} Expression type.
1587
+ */
1588
+ function expressionType(expression, bindings, functions) {
1589
+ if (expression.kind == "IntegerLiteral")
1590
+ return "integer";
1591
+ if (expression.kind == "BooleanLiteral")
1592
+ return "boolean";
1593
+ if (expression.kind == "StringLiteral")
1594
+ return "string";
1595
+ if (expression.kind == "UnaryExpression" || expression.kind == "BinaryExpression")
1596
+ return expression.type;
1597
+ if (expression.kind == "CallExpression") {
1598
+ const declaration = functions.get(expression.callee);
1599
+ if (!declaration)
1600
+ throw new Error("Validated Wasm expression omitted its call declaration.");
1601
+ return wasmReturnType(declaration);
1602
+ }
1603
+ if (expression.kind != "IdentifierExpression") {
1604
+ return unsupportedCapability("wasm", "collection expression reached scalar type inference", expression.location);
1605
+ }
1606
+ const binding = bindings.get(expression.name);
1607
+ if (!binding)
1608
+ throw new Error("Validated Wasm expression omitted its local binding.");
1609
+ return binding.type;
1610
+ }
1611
+ /**
1612
+ * Narrows a declaration return after the Wasm Task 005 capability preflight.
1613
+ * @param {import("../semantic/types.js").FunctionDeclaration} declaration - Validated declaration.
1614
+ * @returns {Scalar} Supported Wasm scalar return.
1615
+ */
1616
+ function wasmReturnType(declaration) {
1617
+ if (declaration.returnType.kind != "TypeReference" || declaration.returnType.name == "void") {
1618
+ return unsupportedCapability("wasm", "Task 005 void function return", declaration.location);
1619
+ }
1620
+ return declaration.returnType.name;
1621
+ }
1622
+ /**
1623
+ * Narrows one scalar after Wasm collection capability rejection.
1624
+ * @param {import("../semantic/types.js").SemanticValueType} type - Semantic value type.
1625
+ * @param {import("../semantic/types.js").SourceLocation} location - Owning location.
1626
+ * @returns {Scalar} Scalar type.
1627
+ */
1628
+ function wasmScalarType(type, location) {
1629
+ if (type.kind != "TypeReference")
1630
+ return unsupportedCapability("wasm", "Task 006 immutable collection type", location);
1631
+ return type.name;
1632
+ }
1633
+ /**
1634
+ * Flattens one semantic scalar into Wasm value types.
1635
+ * @param {Scalar} type - Semantic scalar type.
1636
+ * @returns {("i32" | "i64")[]} Wasm value types.
1637
+ */
1638
+ function wasmTypes(type) { return type == "integer" ? ["i64"] : type == "boolean" ? ["i32"] : ["i32", "i32"]; }
1639
+ /**
1640
+ * Aligns an unsigned size upward.
1641
+ * @param {number} value - Unaligned value.
1642
+ * @param {number} alignment - Required alignment.
1643
+ * @returns {number} Aligned value.
1644
+ */
1645
+ function align(value, alignment) { return Math.ceil(value / alignment) * alignment; }
1646
+ /**
1647
+ * Checks a computed module size against the portable u32 domain.
1648
+ * @param {number} value - Candidate size.
1649
+ * @param {{location: import("../semantic/types.js").SourceLocation}} node - Related semantic node.
1650
+ * @param {string} capability - Failure capability description.
1651
+ * @returns {number} Checked size.
1652
+ */
1653
+ function checkedSize(value, node, capability) {
1654
+ if (!Number.isSafeInteger(value) || value < 0 || value > 0xffffffff)
1655
+ unsupportedCapability("wasm", capability, node.location);
1656
+ return value;
1657
+ }
1658
+ /**
1659
+ * Encodes an unsigned u32 LEB128 value.
1660
+ * @param {number} value - Unsigned value.
1661
+ * @returns {number[]} Encoded bytes.
1662
+ */
1663
+ function u32(value) {
1664
+ if (!Number.isSafeInteger(value) || value < 0 || value > 0xffffffff)
1665
+ throw new RangeError("Unsigned WebAssembly integer is outside u32.");
1666
+ const bytes = [];
1667
+ let remaining = value;
1668
+ do {
1669
+ let byte = remaining % 128;
1670
+ remaining = Math.floor(remaining / 128);
1671
+ if (remaining != 0)
1672
+ byte |= 0x80;
1673
+ bytes.push(byte);
1674
+ } while (remaining != 0);
1675
+ return bytes;
1676
+ }
1677
+ /**
1678
+ * Encodes a signed i32 LEB128 value.
1679
+ * @param {number} value - Signed value.
1680
+ * @returns {number[]} Encoded bytes.
1681
+ */
1682
+ function s32(value) { return s64(BigInt(value)); }
1683
+ /**
1684
+ * Encodes a signed i64 LEB128 value.
1685
+ * @param {bigint} value - Signed value.
1686
+ * @returns {number[]} Encoded bytes.
1687
+ */
1688
+ function s64(value) {
1689
+ const bytes = [];
1690
+ let remaining = value;
1691
+ let done = false;
1692
+ while (!done) {
1693
+ let byte = Number(remaining & 0x7fn);
1694
+ remaining >>= 7n;
1695
+ const signSet = (byte & 0x40) != 0;
1696
+ done = remaining == 0n && !signSet || remaining == -1n && signSet;
1697
+ if (!done)
1698
+ byte |= 0x80;
1699
+ bytes.push(byte);
1700
+ }
1701
+ return bytes;
1702
+ }
1703
+ /**
1704
+ * Encodes a length-prefixed UTF-8 Wasm name.
1705
+ * @param {string} value - Name value.
1706
+ * @returns {number[]} Encoded bytes.
1707
+ */
1708
+ function nameBytes(value) {
1709
+ const bytes = encoder.encode(value);
1710
+ return [...u32(bytes.byteLength), ...bytes];
1711
+ }
1712
+ /**
1713
+ * Extracts contextual related origins from one semantic record.
1714
+ * @param {SemanticNodeProvenance} record - Semantic provenance record.
1715
+ * @param {import("../semantic/types.js").SemanticOrigin} [origin] - Optional exact semantic origin.
1716
+ * @returns {import("../semantic/types.js").RelatedOrigin[]} Related origins.
1717
+ */
1718
+ function relatedOrigins(record, origin = record.origin) {
1719
+ if (origin.kind == "source") {
1720
+ return [{ location: origin.location, nodeId: record.id, role: "related semantic occurrence", sourceId: origin.sourceId,
1721
+ ...(record.symbolId ? { symbolId: record.symbolId } : {}) }];
1722
+ }
1723
+ const origins = origin.kind == "derived" ? origin.origins : origin.relatedOrigins;
1724
+ return origins.map((origin) => ({ ...origin, nodeId: origin.nodeId ?? record.id, role: origin.role ?? "related semantic occurrence",
1725
+ ...(record.symbolId && !origin.symbolId ? { symbolId: record.symbolId } : {}) }));
1726
+ }
1727
+ /**
1728
+ * Resolves a parser-owned token role to its canonical source identity.
1729
+ * @param {ReturnType<typeof createGenerationIndex>} index - Canonical provenance index.
1730
+ * @param {SemanticNodeProvenance} record - Semantic occurrence record.
1731
+ * @param {string} role - Parser-owned token role.
1732
+ * @returns {import("../semantic/types.js").SemanticOrigin} Exact role origin, or the occurrence origin when unavailable.
1733
+ */
1734
+ function originForRole(index, record, role) {
1735
+ const location = record.ranges[role];
1736
+ if (!location)
1737
+ return record.origin;
1738
+ /** @type {string | undefined} */
1739
+ let fallbackSourceId;
1740
+ if (record.origin.kind == "source" && record.origin.location.filename == location.filename)
1741
+ fallbackSourceId = record.origin.sourceId;
1742
+ else if (record.origin.kind == "derived") {
1743
+ fallbackSourceId = record.origin.origins.find((origin) => origin.location.filename == location.filename)?.sourceId;
1744
+ }
1745
+ else if (record.origin.kind == "synthetic") {
1746
+ fallbackSourceId = record.origin.relatedOrigins.find((origin) => origin.location.filename == location.filename)?.sourceId;
1747
+ }
1748
+ const source = index.provenance.sources.find((candidate) => candidate.id == fallbackSourceId) ??
1749
+ index.provenance.sources.find((candidate) => candidate.filename == location.filename);
1750
+ return source ? { kind: "source", location, sourceId: source.id } : record.origin;
1751
+ }
1752
+ /**
1753
+ * Projects byte provenance to the Wasm Source Map v3 convention.
1754
+ * @param {import("../semantic/types.js").SemantifoldByteMapping} mapping - Authoritative byte mapping.
1755
+ * @param {import("../semantic/types.js").SemanticProvenance} provenance - Source registry.
1756
+ * @returns {import("@jridgewell/gen-mapping").EncodedSourceMap} Source Map v3 projection.
1757
+ */
1758
+ function createWasmSourceMap(mapping, provenance) {
1759
+ const generated = new GenMapping({ file: mapping.generated.path });
1760
+ const sourcesById = new Map(provenance.sources.map((source) => [source.id, source]));
1761
+ const symbolsById = new Map(provenance.symbols.map((symbol) => [symbol.id, symbol]));
1762
+ for (const source of provenance.sources)
1763
+ setSourceContent(generated, source.filename, source.content);
1764
+ for (const range of mapping.ranges) {
1765
+ const location = primaryLocation(range.origin);
1766
+ if (!location || range.origin.kind == "synthetic") {
1767
+ maybeAddSegment(generated, 0, range.generated.start);
1768
+ continue;
1769
+ }
1770
+ const sourceId = range.origin.kind == "source" ? range.origin.sourceId : range.origin.origins[0]?.sourceId;
1771
+ const source = sourceId ? sourcesById.get(sourceId) : undefined;
1772
+ if (!source)
1773
+ throw new Error("Validated Wasm byte origin omitted its registered source.");
1774
+ if (range.symbolId === undefined) {
1775
+ addSegment(generated, 0, range.generated.start, source.filename, location.start.line - 1, location.start.column - 1, null, source.content);
1776
+ }
1777
+ else {
1778
+ const symbol = symbolsById.get(range.symbolId);
1779
+ if (!symbol)
1780
+ throw new Error("Validated Wasm byte range omitted its semantic symbol.");
1781
+ addSegment(generated, 0, range.generated.start, source.filename, location.start.line - 1, location.start.column - 1, symbol.name, source.content);
1782
+ }
1783
+ }
1784
+ return toEncodedMap(generated);
1785
+ }
1786
+ /**
1787
+ * Creates one mapped generated text artifact.
1788
+ * @param {string} content - Complete artifact content.
1789
+ * @param {string} path - Artifact path.
1790
+ * @param {import("../semantic/types.js").GeneratedTextLanguage} language - Generated text syntax.
1791
+ * @param {import("../semantic/types.js").GeneratedArtifactRole} role - Artifact role.
1792
+ * @param {SemanticModule} module - Source semantic module.
1793
+ * @param {{filename: string, content: string, language?: import("../semantic/types.js").SemanticLanguage}[] | undefined} sources - Source overrides.
1794
+ * @param {string} reason - Synthetic mapping reason.
1795
+ * @returns {import("../semantic/types.js").GeneratedSetArtifact} Generated artifact.
1796
+ */
1797
+ function textArtifact(content, path, language, role, module, sources, reason) {
1798
+ const writer = new SourceWriter({ filename: path, language, module, sources });
1799
+ writer.synthetic(content, reason, [module], [""]);
1800
+ const mapping = finalizeMapping(writer.finish());
1801
+ return {
1802
+ content,
1803
+ contentKind: "text",
1804
+ mediaType: path.endsWith(".html") ? "text/html" : "text/javascript",
1805
+ ownership: "generated",
1806
+ path,
1807
+ provenance: { kind: "text", mapping, sourceMap: toSourceMapV3(mapping) },
1808
+ role
1809
+ };
1810
+ }
1811
+ const semantifoldLoader = `const expectedImports = [
1812
+ ["semantifold", "print_i64", ["i64"], []],
1813
+ ["semantifold", "print_bool", ["i32"], []],
1814
+ ["semantifold", "print_string", ["i32", "i32"], []]
1815
+ ]
1816
+
1817
+ export class SemantifoldBrowserError extends Error {
1818
+ constructor(stage, message, cause) {
1819
+ super(message, cause instanceof Error ? {cause} : undefined)
1820
+ this.name = "SemantifoldBrowserError"
1821
+ this.stage = stage
1822
+ }
1823
+ }
1824
+
1825
+ export async function loadSemantifold(url, {fetch: fetchImplementation = globalThis.fetch, sink, timeoutMs = 10000} = {}) {
1826
+ if (typeof fetchImplementation != "function") throw new TypeError("A fetch implementation is required.")
1827
+ if (typeof sink != "function") throw new TypeError("A text sink function is required.")
1828
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2147483647) {
1829
+ throw new TypeError("timeoutMs must be an integer from 1 through 2147483647.")
1830
+ }
1831
+ const controller = new AbortController()
1832
+ let timedOut = false
1833
+ let timeout
1834
+ const deadline = new Promise((resolve, reject) => {
1835
+ const timeoutCause = new Error("Semantifold browser load timed out.")
1836
+
1837
+ timeout = setTimeout(() => {
1838
+ timedOut = true
1839
+ controller.abort(timeoutCause)
1840
+ reject(new SemantifoldBrowserError("timeout", "Wasm loading timed out.", timeoutCause))
1841
+ }, timeoutMs)
1842
+ })
1843
+ const beforeDeadline = (operation) => Promise.race([operation, deadline])
1844
+ const timeoutFailure = (cause) => new SemantifoldBrowserError("timeout", "Wasm loading timed out.",
1845
+ cause instanceof Error ? cause : controller.signal.reason)
1846
+ const bodyFailure = (cause) => {
1847
+ if (cause instanceof SemantifoldBrowserError) return cause
1848
+ if (timedOut) return timeoutFailure(cause)
1849
+ return new SemantifoldBrowserError("fetch/MIME", "Wasm response body could not be read.", cause)
1850
+ }
1851
+ const instantiationFailure = (cause) => {
1852
+ if (cause instanceof SemantifoldBrowserError) return cause
1853
+ if (timedOut) return timeoutFailure(cause)
1854
+ const stage = cause instanceof WebAssembly.CompileError ? "compile" : "instantiate/import"
1855
+
1856
+ return new SemantifoldBrowserError(stage, \`Wasm \${stage} failed.\`, cause)
1857
+ }
1858
+ const readBody = async (body) => {
1859
+ try {
1860
+ return new Uint8Array(await beforeDeadline(body.arrayBuffer()))
1861
+ } catch (cause) {
1862
+ throw bodyFailure(cause)
1863
+ }
1864
+ }
1865
+ const instantiate = async (operation) => {
1866
+ try {
1867
+ return await beforeDeadline(operation())
1868
+ } catch (cause) {
1869
+ throw instantiationFailure(cause)
1870
+ }
1871
+ }
1872
+ let response
1873
+
1874
+ try {
1875
+ response = await beforeDeadline(Promise.resolve().then(() =>
1876
+ fetchImplementation(url, {credentials: "same-origin", redirect: "error", signal: controller.signal})))
1877
+ } catch (cause) {
1878
+ clearTimeout(timeout)
1879
+ if (cause instanceof SemantifoldBrowserError) throw cause
1880
+ const stage = timedOut ? "timeout" : "fetch/MIME"
1881
+ throw new SemantifoldBrowserError(stage, stage == "timeout" ? "Wasm loading timed out." : "Wasm fetch failed.", cause)
1882
+ }
1883
+ if (!response.ok) {
1884
+ clearTimeout(timeout)
1885
+ throw new SemantifoldBrowserError("fetch/MIME", \`Wasm fetch returned HTTP \${response.status}.\`)
1886
+ }
1887
+ const mediaType = response.headers.get("content-type")?.split(";", 1)[0].trim().toLowerCase()
1888
+
1889
+ if (mediaType != "application/wasm") {
1890
+ clearTimeout(timeout)
1891
+ throw new SemantifoldBrowserError("fetch/MIME", "Wasm response requires application/wasm.")
1892
+ }
1893
+
1894
+ let instance
1895
+ let module
1896
+ const decoder = new TextDecoder("utf-8", {fatal: true, ignoreBOM: true})
1897
+ let memory
1898
+ let abiApproved = false
1899
+ const requireApprovedAbi = () => {
1900
+ if (!abiApproved) throw new SemantifoldBrowserError("instantiate/import", "Wasm host imports are locked until ABI inspection succeeds.")
1901
+ }
1902
+ const append = (text) => sink(\`\${text}\\n\`)
1903
+ const imports = {semantifold: {
1904
+ print_i64(value) {
1905
+ requireApprovedAbi()
1906
+ if (typeof value != "bigint") throw new TypeError("print_i64 requires bigint.")
1907
+ append(value.toString(10))
1908
+ },
1909
+ print_bool(value) {
1910
+ requireApprovedAbi()
1911
+ if (value !== 0 && value !== 1) throw new TypeError("print_bool requires canonical 0 or 1.")
1912
+ append(value === 1 ? "true" : "false")
1913
+ },
1914
+ print_string(pointer, length) {
1915
+ requireApprovedAbi()
1916
+ if (!memory || !Number.isInteger(pointer) || pointer < 0 || !Number.isInteger(length) || length < 0) {
1917
+ const cause = new TypeError("print_string requires a non-negative integer pointer and length.")
1918
+
1919
+ throw new SemantifoldBrowserError("memory bounds/UTF-8", cause.message, cause)
1920
+ }
1921
+ const end = pointer + length
1922
+
1923
+ if (!Number.isSafeInteger(end) || end < pointer || end > memory.buffer.byteLength) {
1924
+ const cause = new RangeError("print_string range is outside exported memory.")
1925
+
1926
+ throw new SemantifoldBrowserError("memory bounds/UTF-8", cause.message, cause)
1927
+ }
1928
+ let text
1929
+
1930
+ try {
1931
+ text = decoder.decode(new Uint8Array(memory.buffer, pointer, length))
1932
+ } catch (cause) {
1933
+ throw new SemantifoldBrowserError("memory bounds/UTF-8", "print_string bytes are not valid UTF-8.", cause)
1934
+ }
1935
+ append(text)
1936
+ }
1937
+ }}
1938
+
1939
+ let result
1940
+
1941
+ try {
1942
+ if (typeof WebAssembly.instantiateStreaming == "function") {
1943
+ let body
1944
+
1945
+ try {
1946
+ body = response.clone()
1947
+ } catch (cause) {
1948
+ throw bodyFailure(cause)
1949
+ }
1950
+ const pending = instantiate(() => WebAssembly.instantiateStreaming(response, imports))
1951
+ .then((value) => ({value}), (error) => ({error}))
1952
+ const bytes = await readBody(body)
1953
+
1954
+ inspectAbi(bytes)
1955
+ abiApproved = true
1956
+ const settled = await pending
1957
+
1958
+ if ("error" in settled) throw settled.error
1959
+ result = settled.value
1960
+ } else {
1961
+ const bytes = await readBody(response)
1962
+
1963
+ inspectAbi(bytes)
1964
+ abiApproved = true
1965
+ result = await instantiate(() => WebAssembly.instantiate(bytes, imports))
1966
+ }
1967
+ } catch (error) {
1968
+ clearTimeout(timeout)
1969
+ throw error
1970
+ }
1971
+ clearTimeout(timeout)
1972
+ instance = result.instance
1973
+ module = result.module
1974
+ validateModuleShape(module, instance)
1975
+ memory = instance.exports.memory
1976
+ let active = false
1977
+ let poisoned = false
1978
+
1979
+ return Object.freeze({
1980
+ memory,
1981
+ run() {
1982
+ if (poisoned) throw new SemantifoldBrowserError("invocation/trap", "Wasm instance is poisoned after a trap.")
1983
+ if (active) throw new SemantifoldBrowserError("invocation/trap", "Reentrant run invocation is forbidden.")
1984
+ active = true
1985
+ try {
1986
+ instance.exports.run()
1987
+ } catch (cause) {
1988
+ poisoned = true
1989
+ if (cause instanceof SemantifoldBrowserError) throw cause
1990
+ throw new SemantifoldBrowserError("invocation/trap", "Wasm run trapped.", cause)
1991
+ } finally {
1992
+ active = false
1993
+ }
1994
+ }
1995
+ })
1996
+ }
1997
+
1998
+ function validateModuleShape(module, instance) {
1999
+ const imports = WebAssembly.Module.imports(module)
2000
+ const exports = WebAssembly.Module.exports(module)
2001
+
2002
+ if (JSON.stringify(imports.map(({kind, module, name}) => [module, name, kind])) !=
2003
+ JSON.stringify(expectedImports.map(([module, name]) => [module, name, "function"]))) {
2004
+ throw new SemantifoldBrowserError("instantiate/import", "Wasm imports do not match semantifold.browser.v1.")
2005
+ }
2006
+ if (JSON.stringify(exports.map(({kind, name}) => [name, kind])) != JSON.stringify([["memory", "memory"], ["run", "function"]]) ||
2007
+ !(instance.exports.memory instanceof WebAssembly.Memory) || typeof instance.exports.run != "function" || instance.exports.run.length != 0) {
2008
+ throw new SemantifoldBrowserError("instantiate/import", "Wasm exports do not match semantifold.browser.v1.")
2009
+ }
2010
+ }
2011
+
2012
+ function inspectAbi(bytes) {
2013
+ try {
2014
+ let offset = 8
2015
+ const types = []
2016
+ const importedTypes = []
2017
+ const definedTypes = []
2018
+ const exports = []
2019
+ const memories = []
2020
+
2021
+ if (bytes.length < 8 || bytes[0] != 0 || bytes[1] != 97 || bytes[2] != 115 || bytes[3] != 109 || bytes[4] != 1 ||
2022
+ bytes[5] != 0 || bytes[6] != 0 || bytes[7] != 0) throw new WebAssembly.CompileError("Invalid Wasm header.")
2023
+ while (offset < bytes.length) {
2024
+ const id = bytes[offset++]
2025
+ const sizeValue = readU32(bytes, offset)
2026
+ offset = sizeValue.next
2027
+ const end = offset + sizeValue.value
2028
+
2029
+ if (end > bytes.length) throw new WebAssembly.CompileError("Truncated Wasm section.")
2030
+ if (id == 1) {
2031
+ const count = readU32(bytes, offset); offset = count.next
2032
+ for (let index = 0; index < count.value; index += 1) {
2033
+ if (bytes[offset++] != 0x60) throw new WebAssembly.CompileError("Invalid function type.")
2034
+ const parameters = readTypes(bytes, offset); offset = parameters.next
2035
+ const results = readTypes(bytes, offset); offset = results.next
2036
+ types.push([parameters.values, results.values])
2037
+ }
2038
+ } else if (id == 2) {
2039
+ const count = readU32(bytes, offset); offset = count.next
2040
+ for (let index = 0; index < count.value; index += 1) {
2041
+ const moduleName = readName(bytes, offset); offset = moduleName.next
2042
+ const fieldName = readName(bytes, offset); offset = fieldName.next
2043
+ if (bytes[offset++] != 0) throw new SemantifoldBrowserError("instantiate/import", "Only function imports are allowed.")
2044
+ const type = readU32(bytes, offset); offset = type.next
2045
+ importedTypes.push([moduleName.value, fieldName.value, type.value])
2046
+ }
2047
+ } else if (id == 3) {
2048
+ const count = readU32(bytes, offset); offset = count.next
2049
+ for (let index = 0; index < count.value; index += 1) {
2050
+ const type = readU32(bytes, offset); offset = type.next; definedTypes.push(type.value)
2051
+ }
2052
+ } else if (id == 5) {
2053
+ const count = readU32(bytes, offset); offset = count.next
2054
+ for (let index = 0; index < count.value; index += 1) {
2055
+ const flags = bytes[offset++]
2056
+ const minimum = readU32(bytes, offset); offset = minimum.next
2057
+ let maximum
2058
+ if ((flags & 1) != 0) { maximum = readU32(bytes, offset); offset = maximum.next }
2059
+ memories.push([flags, minimum.value, maximum?.value])
2060
+ }
2061
+ } else if (id == 7) {
2062
+ const count = readU32(bytes, offset); offset = count.next
2063
+ for (let index = 0; index < count.value; index += 1) {
2064
+ const name = readName(bytes, offset); offset = name.next
2065
+ const kind = bytes[offset++]
2066
+ const target = readU32(bytes, offset); offset = target.next
2067
+ exports.push([name.value, kind, target.value])
2068
+ }
2069
+ } else if (id == 8) throw new SemantifoldBrowserError("instantiate/import", "A Wasm start section is forbidden.")
2070
+ offset = end
2071
+ }
2072
+ if (importedTypes.length != expectedImports.length) throw new SemantifoldBrowserError("instantiate/import", "Unexpected Wasm import count.")
2073
+ for (let index = 0; index < expectedImports.length; index += 1) {
2074
+ const expected = expectedImports[index]
2075
+ const actual = importedTypes[index]
2076
+ const type = types[actual?.[2]]
2077
+
2078
+ if (!actual || actual[0] != expected[0] || actual[1] != expected[1] || !type ||
2079
+ JSON.stringify(type) != JSON.stringify([expected[2], expected[3]])) {
2080
+ throw new SemantifoldBrowserError("instantiate/import", "Wasm import signature does not match semantifold.browser.v1.")
2081
+ }
2082
+ }
2083
+ if (memories.length != 1 || memories[0][0] != 1 || memories[0][1] != memories[0][2]) {
2084
+ throw new SemantifoldBrowserError("instantiate/import", "Wasm memory must have equal fixed initial and maximum limits.")
2085
+ }
2086
+ if (exports.length != 2 || exports[0][0] != "memory" || exports[0][1] != 2 || exports[0][2] != 0 ||
2087
+ exports[1][0] != "run" || exports[1][1] != 0) {
2088
+ throw new SemantifoldBrowserError("instantiate/import", "Wasm exports do not match semantifold.browser.v1.")
2089
+ }
2090
+ const runType = types[definedTypes[exports[1][2] - importedTypes.length]]
2091
+
2092
+ if (!runType || runType[0].length != 0 || runType[1].length != 0) {
2093
+ throw new SemantifoldBrowserError("instantiate/import", "Wasm run signature does not match semantifold.browser.v1.")
2094
+ }
2095
+ } catch (cause) {
2096
+ if (cause instanceof SemantifoldBrowserError) throw cause
2097
+ throw new SemantifoldBrowserError("compile", "Wasm binary inspection failed.", cause)
2098
+ }
2099
+ }
2100
+
2101
+ function readTypes(bytes, offset) {
2102
+ const count = readU32(bytes, offset); offset = count.next; const values = []
2103
+ for (let index = 0; index < count.value; index += 1) {
2104
+ const type = bytes[offset++]
2105
+ if (type == 0x7f) values.push("i32")
2106
+ else if (type == 0x7e) values.push("i64")
2107
+ else if (type == 0x7d) values.push("f32")
2108
+ else if (type == 0x7c) values.push("f64")
2109
+ else if (type == 0x7b) values.push("v128")
2110
+ else if (type == 0x70) values.push("funcref")
2111
+ else if (type == 0x6f) values.push("externref")
2112
+ else throw new WebAssembly.CompileError("Unsupported ABI value type.")
2113
+ }
2114
+ return {next: offset, values}
2115
+ }
2116
+
2117
+ function readName(bytes, offset) {
2118
+ const length = readU32(bytes, offset); const end = length.next + length.value
2119
+ if (end > bytes.length) throw new WebAssembly.CompileError("Truncated Wasm name.")
2120
+ return {next: end, value: new TextDecoder("utf-8", {fatal: true}).decode(bytes.subarray(length.next, end))}
2121
+ }
2122
+
2123
+ function readU32(bytes, offset) {
2124
+ let value = 0
2125
+ let shift = 0
2126
+ for (let index = 0; index < 5; index += 1) {
2127
+ if (offset >= bytes.length) throw new WebAssembly.CompileError("Truncated unsigned LEB128.")
2128
+ const byte = bytes[offset++]
2129
+ value += (byte & 0x7f) * 2 ** shift
2130
+ if ((byte & 0x80) == 0) return {next: offset, value}
2131
+ shift += 7
2132
+ }
2133
+ throw new WebAssembly.CompileError("Oversized unsigned LEB128.")
2134
+ }
2135
+
2136
+ async function runBrowserHarness() {
2137
+ const output = document.querySelector("#output")
2138
+
2139
+ try {
2140
+ const program = await loadSemantifold("./program.wasm", {sink: (line) => { output.textContent += line }})
2141
+ program.run()
2142
+ document.documentElement.dataset.semantifoldOutput = [...new TextEncoder().encode(output.textContent)]
2143
+ .map((byte) => byte.toString(16).padStart(2, "0")).join("")
2144
+ document.documentElement.dataset.semantifold = "pass"
2145
+ console.log("SEMANTIFOLD_BROWSER_OK")
2146
+ } catch (error) {
2147
+ document.documentElement.dataset.semantifold = "fail"
2148
+ output.textContent += \`ERROR[\${error.stage ?? "unknown"}]: \${error.message}\\n\`
2149
+ console.error("SEMANTIFOLD_BROWSER_FAILED", error)
2150
+ }
2151
+ }
2152
+
2153
+ if (typeof document != "undefined" && document.documentElement.dataset.semantifold == "pending") void runBrowserHarness()
2154
+ `;
2155
+ const browserHarness = `<!doctype html>
2156
+ <html lang="en" data-semantifold="pending">
2157
+ <meta charset="utf-8">
2158
+ <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self' 'wasm-unsafe-eval'; connect-src 'self'; base-uri 'none'; form-action 'none'">
2159
+ <title>Semantifold Browser Wasm</title>
2160
+ <pre id="output"></pre>
2161
+ <script type="module" src="./semantifold-loader.mjs"></script>
2162
+ </html>
2163
+ `;
2164
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FzbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9iYWNrZW5kcy93YXNtLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsVUFBVSxFQUFFLFVBQVUsRUFBRSxlQUFlLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxFQUFDLE1BQU0seUJBQXlCLENBQUE7QUFDL0csT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sc0JBQXNCLENBQUE7QUFDdEQsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDdEQsT0FBTyxFQUFDLGVBQWUsRUFBRSxhQUFhLEVBQUMsTUFBTSxlQUFlLENBQUE7QUFDNUQsT0FBTyxFQUFDLHFCQUFxQixFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQTtBQUNqRyxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQTtBQUMxRCxPQUFPLEVBQUMscUJBQXFCLEVBQUMsTUFBTSxhQUFhLENBQUE7QUFDakQsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGFBQWEsQ0FBQTtBQUV4Qyw4RUFBOEU7QUFDOUUsMEVBQTBFO0FBQzFFLHNFQUFzRTtBQUN0RSx3RUFBd0U7QUFDeEUsc0ZBQXNGO0FBQ3RGLDhGQUE4RjtBQUM5RiwwSUFBMEk7QUFDMUksOEdBQThHO0FBQzlHLGdFQUFnRTtBQUVoRSxNQUFNLE9BQU8sR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFBO0FBQ2pDLE1BQU0sZUFBZSxHQUFHLFNBQVMsQ0FBQTtBQUNqQyxNQUFNLGdCQUFnQixHQUFHLEVBQUUsQ0FBQTtBQUMzQixNQUFNLFlBQVksR0FBRyxNQUFNLENBQUE7QUFDM0IsTUFBTSxvQkFBb0IsR0FBRyxPQUFPLENBQUE7QUFDcEMsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsR0FBRyxF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QUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQVMsWUFBWSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxXQUFXO0lBQ3JFLE1BQU0sTUFBTSxHQUFHLElBQUksWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ3RDLE1BQU0sSUFBSSxHQUFHLEVBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFDLENBQUE7SUFFckMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLDBCQUEwQixFQUFFLElBQUksRUFBRSxlQUFlLENBQUMsQ0FBQTtJQUM3RixNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsMENBQTBDLEVBQUUsSUFBSSxFQUFFLGVBQWUsQ0FBQyxDQUFBO0lBRTdHLE1BQU0sS0FBSyxHQUFHLElBQUksUUFBUSxFQUFFLENBQUE7SUFDNUIsTUFBTSxXQUFXLEdBQUc7UUFDbEIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUN0QixLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3RCLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDO0tBQzlCLENBQUE7SUFDRCxNQUFNLFdBQVcsR0FBRztRQUNsQixLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkQsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFD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QUMsTUFBTSxFQUFFLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLGFBQWEsQ0FBQyxDQUFBLENBQUMsQ0FBQztJQUU5Rzs7Ozs7T0FLRztJQUNILFNBQVMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLEtBQUssTUFBTSxFQUFFLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQSxDQUFDLENBQUM7SUFFL0c7Ozs7T0FJRztJQUNILFFBQVEsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQSxDQUFDLENBQUM7SUFFMUY7Ozs7T0FJRztJQUNILFFBQVEsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQSxDQUFDLENBQUM7SUFFM0Y7Ozs7T0FJRztJQUNILFFBQVEsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQSxDQUFDLENBQUM7SUFFekY7Ozs7T0FJRztJQUNILFNBQVMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQSxDQUFDLENBQUM7SUFFN0Y7Ozs7T0FJRztJQUNILFNBQVMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQSxDQUFDLENBQUM7SUFFOUY7Ozs7T0FJRztJQUNILEdBQUcsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxlQUFlLENBQUMsQ0FBQSxDQUFDLENBQUM7SUFFekY7Ozs7T0FJRztJQUNILEdBQUcsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxlQUFlLENBQUMsQ0FBQSxDQUFDLENBQUM7SUFFekY7OztPQUdHO0lBQ0gsS0FBSyxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLDRCQUE0QixDQUFDLENBQUEsQ0FBQyxDQUFDO0lBRTNHOzs7T0FHRztJQUNILE1BQU0sS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsNkJBQTZCLENBQUMsQ0FBQSxDQUFDLENBQUM7SUFFckc7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxNQUFNO1FBQ1gsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsR0FBRyxNQUFNLFNBQVMsQ0FBQyxDQUFDO1FBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLGtCQUFrQixDQUFDLENBQUE7UUFDN0UsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsR0FBRyxNQUFNLE9BQU8sQ0FBQyxDQUFDO1FBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsR0FBRyxNQUFNLGFBQWEsQ0FBQyxDQUFBO0lBQ3hFLENBQUM7SUFDRDs7Ozs7Ozs7T0FRRztJQUNILFFBQVEsQ0FBQyxNQUFNLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsaUJBQWlCO1FBQzFFLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLGlCQUFpQixDQUFDLENBQUM7UUFBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsa0JBQWtCLENBQUMsQ0FBQTtRQUM1RSxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQztRQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxrQkFBa0IsQ0FBQyxDQUFBO1FBQ3RFLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7UUFBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsaUNBQWlDLENBQUMsQ0FBQTtRQUNwRyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO1FBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsa0JBQWtCLENBQUMsQ0FBQTtRQUNoRixJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFBO1FBQzFCLElBQUksaUJBQWlCLEtBQUssU0FBUyxFQUFFLENBQUM7WUFBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSx3QkFBd0IsQ0FBQyxDQUFBO1FBQUMsQ0FBQztRQUNsSCxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsd0JBQXdCLENBQUMsQ0FBQTtRQUM5RCxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLG1CQUFtQixDQUFDLENBQUM7UUFBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUE7UUFDcEgsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO1FBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNqRyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO1FBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsaUJBQWlCLENBQUMsQ0FBQTtRQUM5RSxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxlQUFlLENBQUMsQ0FBQztRQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLGdCQUFnQixDQUFDLENBQUE7SUFDakUsQ0FBQztJQUNEOzs7T0FHRztJQUNILEdBQUcsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsQ0FBQSxDQUFDLENBQUM7Q0FDeEM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsb0JBQW9CLENBQUMsTUFBTSxFQUFFLEtBQUs7SUFDekMsa0dBQWtHO0lBQ2xHLE1BQU0sU0FBUyxHQUFHLElBQUksR0FBRyxFQUFFLENBQUE7SUFFM0IsS0FBSyxNQUFNLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBQyxJQUFJLGVBQWUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQ25ELElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxlQUFlO1lBQUUsU0FBUTtRQUMxQyxNQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUUxQyxJQUFJLFFBQVE7WUFBRSxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFBOztZQUMvRCxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBQyxDQUFDLENBQUE7SUFDakgsQ0FBQztJQUVELElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQTtJQUNmLGdFQUFnRTtJQUNoRSxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFBO0lBQ3pCLDRHQUE0RztJQUM1RyxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUE7SUFFbEIsS0FBSyxNQUFNLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQ3pDLE1BQU0sSUFBSSxHQUFHLFdBQVcsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLGlDQUFpQyxDQUFDLENBQUE7UUFDdkcsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUE7UUFDakcsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLEVBQUUsQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDN0csTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUNuRixDQUFDLENBQUMsRUFBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBQztZQUM1QixDQUFDLENBQUMsRUFBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxrRUFBa0UsRUFBRSxjQUFjLEVBQUUsRUFBRSxFQUFDLENBQUE7UUFFdkgsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsNERBQTRELENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBQyxDQUFDLENBQUE7UUFDNUgsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsRUFBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLLEVBQUMsQ0FBQyxDQUFBO1FBQ25ELE9BQU8sR0FBRyxJQUFJLENBQUE7SUFDaEIsQ0FBQztJQUVELE9BQU8sRUFBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUMsQ0FBQTtBQUM5QyxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsaUJBQWlCLENBQUMsTUFBTTtJQUMvQixNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNqRyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUE7SUFFYixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksR0FBRyxFQUFFLEVBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFBO0lBRWpGLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBQyxTQUFTLEVBQUMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQTtJQUU3RDs7Ozs7O09BTUc7SUFDSCxTQUFTLEtBQUssQ0FBQyxhQUFhLEVBQUUsUUFBUSxFQUFFLEtBQUs7UUFDM0MsSUFBSSxNQUFNLEdBQUcsUUFBUSxDQUFBO1FBRXJCLEtBQUssTUFBTSxTQUFTLElBQUksYUFBYSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ2pELE1BQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQTtZQUVmLEtBQUssTUFBTSxLQUFLLElBQUksTUFBTSxFQUFFLENBQUM7Z0JBQzNCLElBQUksS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQUMsU0FBUTtnQkFBQyxDQUFDO2dCQUNsRCxJQUFJLFNBQVMsQ0FBQyxJQUFJLElBQUksa0JBQWtCLEVBQUUsQ0FBQztvQkFDekMsS0FBSyxNQUFNLE1BQU0sSUFBSSxVQUFVLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQzt3QkFDckUsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQTt3QkFFckMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQTt3QkFDckMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUMsQ0FBQyxDQUFBO29CQUNuQyxDQUFDO2dCQUNILENBQUM7cUJBQU0sSUFBSSxTQUFTLENBQUMsSUFBSSxJQUFJLHFCQUFxQixFQUFFLENBQUM7b0JBQ25ELEtBQUssTUFBTSxNQUFNLElBQUksVUFBVSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7d0JBQ3BFLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUE7d0JBRXJDLEdBQUcsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO3dCQUM1QyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUMsR0FBRyxNQUFNLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQyxDQUFDLENBQUE7b0JBQ25DLENBQUM7Z0JBQ0gsQ0FBQztxQkFBTSxJQUFJLFNBQVMsQ0FBQyxJQUFJLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztvQkFDOUMsS0FBSyxNQUFNLE1BQU0sSUFBSSxVQUFVLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDO3dCQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO2dCQUM5RixDQUFDO3FCQUFNLElBQUksU0FBUyxDQUFDLElBQUksSUFBSSxpQkFBaUIsRUFBRSxDQUFDO29CQUMvQyxJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVU7d0JBQUUsTUFBTSxJQUFJLFNBQVMsQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFBO29CQUM5RixLQUFLLE1BQU0sTUFBTSxJQUFJLFVBQVUsQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUM7d0JBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLEtBQUssRUFBQyxDQUFDLENBQUE7Z0JBQzNILENBQUM7cUJBQU0sSUFBSSxTQUFTLENBQUMsSUFBSSxJQUFJLHFCQUFxQixFQUFFLENBQUM7b0JBQ25ELE1BQU0sSUFBSSxTQUFTLENBQUMsZ0VBQWdFLENBQUMsQ0FBQTtnQkFDdkYsQ0FBQztxQkFBTSxJQUFJLFNBQVMsQ0FBQyxJQUFJLElBQUksYUFBYSxFQUFFLENBQUM7b0JBQzNDLEtBQUssTUFBTSxTQUFTLElBQUksVUFBVSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7d0JBQ3RFLElBQUksU0FBUyxDQUFDLEtBQUssQ0FBQyxZQUFZLEtBQUssS0FBSyxFQUFFLENBQUM7NEJBQzNDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsRUFBRSxTQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7d0JBQzNILENBQUM7d0JBQ0QsSUFBSSxTQUFTLENBQUMsS0FBSyxDQUFDLFlBQVksS0FBSyxJQUFJLEVBQUUsQ0FBQzs0QkFDMUMsTUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLFNBQVM7Z0NBQ25DLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUM7Z0NBQ2xFLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQTs0QkFF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Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0F1VnpCLENBQUE7QUFFRCxNQUFNLGNBQWMsR0FBRzs7Ozs7Ozs7Q0FRdEIsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQge2FkZFNlZ21lbnQsIEdlbk1hcHBpbmcsIG1heWJlQWRkU2VnbWVudCwgc2V0U291cmNlQ29udGVudCwgdG9FbmNvZGVkTWFwfSBmcm9tIFwiQGpyaWRnZXdlbGwvZ2VuLW1hcHBpbmdcIlxuaW1wb3J0IHtjcmVhdGVCeXRlTWFwcGluZ30gZnJvbSBcIi4uL2JpbmFyeS1tYXBwaW5nLmpzXCJcbmltcG9ydCB7dW5zdXBwb3J0ZWRDYXBhYmlsaXR5fSBmcm9tIFwiLi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge2ZpbmFsaXplTWFwcGluZywgdG9Tb3VyY2VNYXBWM30gZnJvbSBcIi4uL21hcHBpbmcuanNcIlxuaW1wb3J0IHtjcmVhdGVHZW5lcmF0aW9uSW5kZXgsIHByaW1hcnlMb2NhdGlvbiwgc2VtYW50aWNFbnRyaWVzfSBmcm9tIFwiLi4vc2VtYW50aWMvcHJvdmVuYW5jZS5qc1wiXG5pbXBvcnQge3ZhbGlkYXRlTmF0aXZlR3JhcGh9IGZyb20gXCIuL25hdGl2ZS12YWxpZGF0aW9uLmpzXCJcbmltcG9ydCB7dmFsaWRhdGVCYWNrZW5kTW9kdWxlfSBmcm9tIFwiLi9zaGFyZWQuanNcIlxuaW1wb3J0IHtTb3VyY2VXcml0ZXJ9IGZyb20gXCIuL3dyaXRlci5qc1wiXG5cbi8qKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IFNlbWFudGljTW9kdWxlICovXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTm9kZX0gU2VtYW50aWNOb2RlICovXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IEV4cHJlc3Npb24gKi9cbi8qKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZX0gU2NhbGFyICovXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkdlbmVyYXRlZEJ5dGVSYW5nZX0gR2VuZXJhdGVkQnl0ZVJhbmdlICovXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTm9kZVByb3ZlbmFuY2V9IFNlbWFudGljTm9kZVByb3ZlbmFuY2UgKi9cbi8qKiBAdHlwZWRlZiB7e3R5cGU6IFNjYWxhciwga25vd25Cb29sZWFuPzogYm9vbGVhbiwga25vd25JbnRlZ2VyPzogYmlnaW50LCBrbm93blN0cmluZz86IHN0cmluZywgc3RyaW5nTGVuZ3RoPzogbnVtYmVyfX0gQWJzdHJhY3RWYWx1ZSAqL1xuLyoqIEB0eXBlZGVmIHt7YWxsb2NhdGVkOiBudW1iZXIsIGVudjogTWFwPHN0cmluZywgQWJzdHJhY3RWYWx1ZT4sIHJldHVybmVkPzogQWJzdHJhY3RWYWx1ZX19IEFuYWx5c2lzU3RhdGUgKi9cbi8qKiBAdHlwZWRlZiB7e3R5cGU6IFNjYWxhciwgaW5kZXhlczogbnVtYmVyW119fSBMb2NhbEJpbmRpbmcgKi9cblxuY29uc3QgZW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpXG5jb25zdCBzY3JhdGNoQ2FwYWNpdHkgPSAxXzA0OF81NzZcbmNvbnN0IG1heGltdW1DYWxsRGVwdGggPSA2NFxuY29uc3Qgd2FzbVBhZ2VTaXplID0gNjVfNTM2XG5jb25zdCBtYXhpbXVtQW5hbHlzaXNTdGVwcyA9IDEwMF8wMDBcbmNvbnN0IHZhbHVlVHlwZXMgPSBPYmplY3QuZnJlZXplKHtpMzI6IDB4N2YsIGk2NDogMHg3ZX0pXG5jb25zdCBoZWxwZXJOYW1lcyA9IE9iamVjdC5mcmVlemUoW1wiJGNvbmNhdFwiLCBcIiRzdHJpbmdfZXF1YWxcIiwgXCIkY2hlY2tlZF9hZGRcIiwgXCIkY2hlY2tlZF9zdWJ0cmFjdFwiLCBcIiRjaGVja2VkX211bHRpcGx5XCIsIFwiJGNoZWNrZWRfbmVnYXRlXCJdKVxuY29uc3QgaGVscGVyQ291bnQgPSBoZWxwZXJOYW1lcy5sZW5ndGhcbmNvbnN0IGltcG9ydENvdW50ID0gM1xuY29uc3QgY29uY2F0RnVuY3Rpb25JbmRleCA9IGltcG9ydENvdW50XG5jb25zdCBzdHJpbmdFcXVhbEZ1bmN0aW9uSW5kZXggPSBjb25jYXRGdW5jdGlvbkluZGV4ICsgMVxuY29uc3QgY2hlY2tlZEFkZEZ1bmN0aW9uSW5kZXggPSBzdHJpbmdFcXVhbEZ1bmN0aW9uSW5kZXggKyAxXG5jb25zdCBjaGVja2VkU3VidHJhY3RGdW5jdGlvbkluZGV4ID0gY2hlY2tlZEFkZEZ1bmN0aW9uSW5kZXggKyAxXG5jb25zdCBjaGVja2VkTXVsdGlwbHlGdW5jdGlvbkluZGV4ID0gY2hlY2tlZFN1YnRyYWN0RnVuY3Rpb25JbmRleCArIDFcbmNvbnN0IGNoZWNrZWROZWdhdGVGdW5jdGlvbkluZGV4ID0gY2hlY2tlZE11bHRpcGx5RnVuY3Rpb25JbmRleCArIDFcbmNvbnN0IGN1cnNvckdsb2JhbEluZGV4ID0gMFxuY29uc3QgZGVwdGhHbG9iYWxJbmRleCA9IDFcbmNvbnN0IGFjdGl2ZUdsb2JhbEluZGV4ID0gMlxuXG4vKipcbiAqIEdlbmVyYXRlcyB0aGUgY29tcGxldGUgZGV0ZXJtaW5pc3RpYyBicm93c2VyIFdhc20gYXJ0aWZhY3Qgc2V0LlxuICogQHBhcmFtIHt7ZmlsZW5hbWU/OiBzdHJpbmcsIG1hcERpcmVjdGl2ZT86IHVua25vd24sIG1vZHVsZTogU2VtYW50aWNNb2R1bGUsIHNvdXJjZU1hcEZpbGVuYW1lPzogdW5rbm93biwgc291cmNlcz86IHtmaWxlbmFtZTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcsIGxhbmd1YWdlPzogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX1bXX19IGlucHV0IC0gQmFja2VuZCByZXF1ZXN0LlxuICogQHJldHVybnMge3thcnRpZmFjdHM6IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkdlbmVyYXRlZFNldEFydGlmYWN0W10sIG1ldGFkYXRhOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sIHRhcmdldDogc3RyaW5nfX0gQ2FuZGlkYXRlIGFydGlmYWN0IHNldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlQnJvd3Nlcldhc20oe2ZpbGVuYW1lLCBtYXBEaXJlY3RpdmUsIG1vZHVsZSwgc291cmNlTWFwRmlsZW5hbWUsIHNvdXJjZXN9KSB7XG4gIHZhbGlkYXRlTmF0aXZlR3JhcGgobW9kdWxlLCBcIndhc21cIilcbiAgdmFsaWRhdGVCYWNrZW5kTW9kdWxlKG1vZHVsZSwgXCJ3YXNtXCIpXG4gIGlmIChmaWxlbmFtZSAhPT0gdW5kZWZpbmVkICYmIGZpbGVuYW1lICE9IFwicHJvZ3JhbS53YXNtXCIpIHtcbiAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkoXCJ3YXNtXCIsIFwiYXJ0aWZhY3QgZmlsZW5hbWUgb3RoZXIgdGhhbiBwcm9ncmFtLndhc21cIiwgbW9kdWxlLmxvY2F0aW9uKVxuICB9XG4gIGlmIChtYXBEaXJlY3RpdmUgIT09IHVuZGVmaW5lZCkgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KFwid2FzbVwiLCBcInNvdXJjZS1tYXAgZGlyZWN0aXZlIG9wdGlvblwiLCBtb2R1bGUubG9jYXRpb24pXG4gIGlmIChzb3VyY2VNYXBGaWxlbmFtZSAhPT0gdW5kZWZpbmVkKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkoXCJ3YXNtXCIsIFwiYWx0ZXJuYXRlIHNvdXJjZS1tYXAgZmlsZW5hbWVcIiwgbW9kdWxlLmxvY2F0aW9uKVxuICBhbmFseXplU2NyYXRjaFVzZShtb2R1bGUpXG5cbiAgY29uc3QgaW5kZXggPSBjcmVhdGVHZW5lcmF0aW9uSW5kZXgobW9kdWxlLCBzb3VyY2VzKVxuICBjb25zdCBsaXRlcmFsTGF5b3V0ID0gY29sbGVjdExpdGVyYWxMYXlvdXQobW9kdWxlLCBpbmRleClcbiAgY29uc3Qgc2NyYXRjaEJhc2UgPSBhbGlnbihsaXRlcmFsTGF5b3V0LmJvdW5kYXJ5LCAxNilcbiAgY29uc3QgbWVtb3J5Qnl0ZXMgPSBjaGVja2VkU2l6ZShzY3JhdGNoQmFzZSArIHNjcmF0Y2hDYXBhY2l0eSwgbW9kdWxlLCBcImxpbmVhciBtZW1vcnkgc2l6ZVwiKVxuICBjb25zdCBtZW1vcnlQYWdlcyA9IE1hdGguY2VpbChtZW1vcnlCeXRlcyAvIHdhc21QYWdlU2l6ZSlcbiAgY29uc3QgZW5jb2RlZCA9IGVuY29kZU1vZHVsZShtb2R1bGUsIGluZGV4LCBsaXRlcmFsTGF5b3V0LCBzY3JhdGNoQmFzZSwgbWVtb3J5UGFnZXMpXG5cbiAgdmFsaWRhdGVFbmNvZGVkTW9kdWxlKGVuY29kZWQuYnl0ZXMsIG1vZHVsZSlcbiAgY29uc3QgYnl0ZU1hcHBpbmcgPSBjcmVhdGVCeXRlTWFwcGluZyh7Ynl0ZUxlbmd0aDogZW5jb2RlZC5ieXRlcy5ieXRlTGVuZ3RoLCBwYXRoOiBcInByb2dyYW0ud2FzbVwiLCByYW5nZXM6IGVuY29kZWQucmFuZ2VzfSlcbiAgY29uc3Qgd2FzbU1hcCA9IGNyZWF0ZVdhc21Tb3VyY2VNYXAoYnl0ZU1hcHBpbmcsIGluZGV4LnByb3ZlbmFuY2UpXG4gIGNvbnN0IGxvYWRlciA9IHRleHRBcnRpZmFjdChzZW1hbnRpZm9sZExvYWRlciwgXCJzZW1hbnRpZm9sZC1sb2FkZXIubWpzXCIsIFwiamF2YXNjcmlwdFwiLCBcImxvYWRlclwiLCBtb2R1bGUsIHNvdXJjZXMsXG4gICAgXCJWZXJzaW9uZWQgYnJvd3NlciBXYXNtIEFCSSBsb2FkZXIgYW5kIGV4YWN0IHNjYWxhciBicmlkZ2UuXCIpXG4gIGNvbnN0IGh0bWwgPSB0ZXh0QXJ0aWZhY3QoYnJvd3Nlckhhcm5lc3MsIFwiaW5kZXguaHRtbFwiLCBcImh0bWxcIiwgXCJlbnRyeVwiLCBtb2R1bGUsIHNvdXJjZXMsXG4gICAgXCJEZXRlcm1pbmlzdGljIGxvY2FsIGJyb3dzZXIgYWNjZXB0YW5jZSBoYXJuZXNzLlwiKVxuICBjb25zdCBtZXRhZGF0YSA9IC8qKiBAdHlwZSB7Y29uc3R9ICovICh7XG4gICAgYWJpOiBcInNlbWFudGlmb2xkLmJyb3dzZXIudjFcIixcbiAgICBleHBvcnRzOiBbXCJtZW1vcnlcIiwgXCJydW5cIl0sXG4gICAgaW1wb3J0czogW1xuICAgICAge21vZHVsZTogXCJzZW1hbnRpZm9sZFwiLCBuYW1lOiBcInByaW50X2k2NFwiLCBwYXJhbWV0ZXJzOiBbXCJpNjRcIl0sIHJlc3VsdHM6IFtdfSxcbiAgICAgIHttb2R1bGU6IFwic2VtYW50aWZvbGRcIiwgbmFtZTogXCJwcmludF9ib29sXCIsIHBhcmFtZXRlcnM6IFtcImkzMlwiXSwgcmVzdWx0czogW119LFxuICAgICAge21vZHVsZTogXCJzZW1hbnRpZm9sZFwiLCBuYW1lOiBcInByaW50X3N0cmluZ1wiLCBwYXJhbWV0ZXJzOiBbXCJpMzJcIiwgXCJpMzJcIl0sIHJlc3VsdHM6IFtdfVxuICAgIF0sXG4gICAgbWF4aW11bUNhbGxEZXB0aCxcbiAgICBtZW1vcnk6IHtcbiAgICAgIGluaXRpYWxQYWdlczogbWVtb3J5UGFnZXMsXG4gICAgICBsaXRlcmFsQm91bmRhcnk6IGxpdGVyYWxMYXlvdXQuYm91bmRhcnksXG4gICAgICBtYXhpbXVtUGFnZXM6IG1lbW9yeVBhZ2VzLFxuICAgICAgc2NyYXRjaEJhc2UsXG4gICAgICBzY3JhdGNoQ2FwYWNpdHlcbiAgICB9LFxuICAgIHNjaGVtYTogXCJTZW1hbnRpZm9sZEJyb3dzZXJXYXNtQUJJXCIsXG4gICAgdmVyc2lvbjogMVxuICB9KVxuXG4gIHJldHVybiB7XG4gICAgYXJ0aWZhY3RzOiBbe1xuICAgICAgY29udGVudDogZW5jb2RlZC5ieXRlcyxcbiAgICAgIGNvbnRlbnRLaW5kOiBcImJpbmFyeVwiLFxuICAgICAgbWVkaWFUeXBlOiBcImFwcGxpY2F0aW9uL3dhc21cIixcbiAgICAgIG93bmVyc2hpcDogXCJnZW5lcmF0ZWRcIixcbiAgICAgIHBhdGg6IFwicHJvZ3JhbS53YXNtXCIsXG4gICAgICBwcm92ZW5hbmNlOiB7a2luZDogXCJieXRlc1wiLCBtYXBwaW5nOiBieXRlTWFwcGluZ30sXG4gICAgICByb2xlOiBcInJlc291cmNlXCJcbiAgICB9LCB7XG4gICAgICBjb250ZW50OiBgJHtKU09OLnN0cmluZ2lmeSh3YXNtTWFwKX1cXG5gLFxuICAgICAgY29udGVudEtpbmQ6IFwidGV4dFwiLFxuICAgICAgbWVkaWFUeXBlOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgIG93bmVyc2hpcDogXCJnZW5lcmF0ZWRcIixcbiAgICAgIHBhdGg6IFwicHJvZ3JhbS53YXNtLm1hcFwiLFxuICAgICAgcHJvdmVuYW5jZToge1xuICAgICAgICBraW5kOiBcInN5bnRoZXRpY1wiLFxuICAgICAgICByZWFzb246IFwiU291cmNlIE1hcCB2MyBwcm9qZWN0aW9uIG9mIHByb2dyYW0ud2FzbSBieXRlIHByb3ZlbmFuY2UuXCIsXG4gICAgICAgIHJlbGF0ZWRPcmlnaW5zOiByZWxhdGVkT3JpZ2lucyhpbmRleC5yZWNvcmRGb3IobW9kdWxlLCBcIlwiKSlcbiAgICAgIH0sXG4gICAgICByb2xlOiBcIm1hcHBpbmdcIlxuICAgIH0sIGxvYWRlciwgaHRtbF0sXG4gICAgbWV0YWRhdGEsXG4gICAgdGFyZ2V0OiBcIndhc21cIlxuICB9XG59XG5cbi8qKlxuICogSW5kZXBlbmRlbnRseSBjaGVja3MgdGhlIGNvbXBsZXRlZCBtb2R1bGUgYmVmb3JlIGFueSBieXRlcyBlbnRlciBhbiBhcnRpZmFjdC5cbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnl0ZXMgLSBDb21wbGV0ZWQgbW9kdWxlIGJ5dGVzLlxuICogQHBhcmFtIHtTZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gUmVsYXRlZCBzZW1hbnRpYyBtb2R1bGUuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVFbmNvZGVkTW9kdWxlKGJ5dGVzLCBtb2R1bGUpIHtcbiAgY29uc3QgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShieXRlcy5ieXRlTGVuZ3RoKVxuXG4gIG1vZHVsZUJ5dGVzLnNldChieXRlcylcbiAgaWYgKCFXZWJBc3NlbWJseS52YWxpZGF0ZShtb2R1bGVCeXRlcykpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShcIndhc21cIiwgXCJpbnZhbGlkIGVuY29kZWQgc2VjdGlvbiwgaW5kZXgsIHN0YWNrLCBvciBjb250cm9sIHNoYXBlXCIsIG1vZHVsZS5sb2NhdGlvbilcblxuICAvKiogQHR5cGUge1dlYkFzc2VtYmx5Lk1vZHVsZX0gKi9cbiAgbGV0IGNvbXBpbGVkXG5cbiAgdHJ5IHtcbiAgICBjb21waWxlZCA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUobW9kdWxlQnl0ZXMpXG4gIH0gY2F0Y2ggKF9lcnJvcikge1xuICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShcIndhc21cIiwgXCJpbnZhbGlkIGNvbXBsZXRlZCBXZWJBc3NlbWJseSBtb2R1bGVcIiwgbW9kdWxlLmxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IGltcG9ydHMgPSBXZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyhjb21waWxlZCkubWFwKCh7a2luZCwgbW9kdWxlOiBuYW1lc3BhY2UsIG5hbWV9KSA9PiBbbmFtZXNwYWNlLCBuYW1lLCBraW5kXSlcbiAgY29uc3QgZXhwb3J0cyA9IFdlYkFzc2VtYmx5Lk1vZHVsZS5leHBvcnRzKGNvbXBpbGVkKS5tYXAoKHtraW5kLCBuYW1lfSkgPT4gW25hbWUsIGtpbmRdKVxuXG4gIGlmIChKU09OLnN0cmluZ2lmeShpbXBvcnRzKSAhPSBKU09OLnN0cmluZ2lmeShbXG4gICAgW1wic2VtYW50aWZvbGRcIiwgXCJwcmludF9pNjRcIiwgXCJmdW5jdGlvblwiXSxcbiAgICBbXCJzZW1hbnRpZm9sZFwiLCBcInByaW50X2Jvb2xcIiwgXCJmdW5jdGlvblwiXSxcbiAgICBbXCJzZW1hbnRpZm9sZFwiLCBcInByaW50X3N0cmluZ1wiLCBcImZ1bmN0aW9uXCJdXG4gIF0pIHx8IEpTT04uc3RyaW5naWZ5KGV4cG9ydHMpICE9IEpTT04uc3RyaW5naWZ5KFtbXCJtZW1vcnlcIiwgXCJtZW1vcnlcIl0sIFtcInJ1blwiLCBcImZ1bmN0aW9uXCJdXSkpIHtcbiAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkoXCJ3YXNtXCIsIFwiaW52YWxpZCBlbmNvZGVkIEFCSSBpbXBvcnQgb3IgZXhwb3J0IHNldFwiLCBtb2R1bGUubG9jYXRpb24pXG4gIH1cbn1cblxuLyoqXG4gKiBFbmNvZGVzIG9uZSB2YWxpZGF0ZWQgc2VtYW50aWMgbW9kdWxlIGRpcmVjdGx5IHRvIHBvcnRhYmxlIGNvcmUgV2ViQXNzZW1ibHkuXG4gKiBAcGFyYW0ge1NlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBWYWxpZGF0ZWQgbW9kdWxlLlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVHZW5lcmF0aW9uSW5kZXg+fSBpbmRleCAtIENhbm9uaWNhbCBwcm92ZW5hbmNlIGluZGV4LlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBjb2xsZWN0TGl0ZXJhbExheW91dD59IGxpdGVyYWxzIC0gU3RhdGljIGxpdGVyYWwgbGF5b3V0LlxuICogQHBhcmFtIHtudW1iZXJ9IHNjcmF0Y2hCYXNlIC0gQWxpZ25lZCBzY3JhdGNoIGFyZW5hIGJhc2UuXG4gKiBAcGFyYW0ge251bWJlcn0gbWVtb3J5UGFnZXMgLSBGaXhlZCBtZW1vcnkgcGFnZSBjb3VudC5cbiAqIEByZXR1cm5zIHt7Ynl0ZXM6IFVpbnQ4QXJyYXksIHJhbmdlczogR2VuZXJhdGVkQnl0ZVJhbmdlW119fSBFbmNvZGVkIG1vZHVsZSBhbmQgcmljaCBieXRlIHJhbmdlcy5cbiAqL1xuZnVuY3Rpb24gZW5jb2RlTW9kdWxlKG1vZHVsZSwgaW5kZXgsIGxpdGVyYWxzLCBzY3JhdGNoQmFzZSwgbWVtb3J5UGFnZXMpIHtcbiAgY29uc3Qgd3JpdGVyID0gbmV3IEJpbmFyeVdyaXRlcihpbmRleClcbiAgY29uc3Qgcm9vdCA9IHtub2RlOiBtb2R1bGUsIHBhdGg6IFwiXCJ9XG5cbiAgd3JpdGVyLnN5bnRoZXRpYyhbMHgwMCwgMHg2MSwgMHg3MywgMHg2ZF0sIFwiV2ViQXNzZW1ibHkgYmluYXJ5IG1hZ2ljXCIsIHJvb3QsIFwibW9kdWxlIGhlYWRlclwiKVxuICB3cml0ZXIuc3ludGhldGljKFsweDAxLCAweDAwLCAweDAwLCAweDAwXSwgXCJQaW5uZWQgV2ViQXNzZW1ibHkgY29yZSBiaW5hcnkgdmVyc2lvbiAxXCIsIHJvb3QsIFwibW9kdWxlIGhlYWRlclwiKVxuXG4gIGNvbnN0IHR5cGVzID0gbmV3IFR5cGVQb29sKClcbiAgY29uc3QgaW1wb3J0VHlwZXMgPSBbXG4gICAgdHlwZXMuYWRkKFtcImk2NFwiXSwgW10pLFxuICAgIHR5cGVzLmFkZChbXCJpMzJcIl0sIFtdKSxcbiAgICB0eXBlcy5hZGQoW1wiaTMyXCIsIFwiaTMyXCJdLCBbXSlcbiAgXVxuICBjb25zdCBoZWxwZXJUeXBlcyA9IFtcbiAgICB0eXBlcy5hZGQoW1wiaTMyXCIsIFwiaTMyXCIsIFwiaTMyXCIsIFwiaTMyXCJdLCBbXCJpMzJcIiwgXCJpMzJcIl0pLFxuICAgIHR5cGVzLmFkZChbXCJpMzJcIiwgXCJpMzJcIiwgXCJpMzJcIiwgXCJpMzJcIl0sIFtcImkzMlwiXSksXG4gICAgdHlwZXMuYWRkKFtcImk2NFwiLCBcImk2NFwiXSwgW1wiaTY0XCJdKSxcbiAgICB0eXBlcy5hZGQoW1wiaTY0XCIsIFwiaTY0XCJdLCBbXCJpNjRcIl0pLFxuICAgIHR5cGVzLmFkZChbXCJpNjRcIiwgXCJpNjRcIl0sIFtcImk2NFwiXSksXG4gICAgdHlwZXMuYWRkKFtcImk2NFwiXSwgW1wiaTY0XCJdKVxuICBdXG4gIGNvbnN0IHNlbWFudGljVHlwZUluZGV4ZXMgPSBtb2R1bGUuZnVuY3Rpb25zLm1hcCgoZGVjbGFyYXRpb24pID0+IHR5cGVzLmFkZChcbiAgICBkZWNsYXJhdGlvbi5wYXJhbWV0ZXJzLmZsYXRNYXAoKHt0eXBlLCBsb2NhdGlvbn0pID0+IHdhc21UeXBlcyh3YXNtU2NhbGFyVHlwZSh0eXBlLCBsb2NhdGlvbikpKSxcbiAgICB3YXNtVHlwZXMod2FzbVJldHVyblR5cGUoZGVjbGFyYXRpb24pKVxuICApKVxuICBjb25zdCBydW5UeXBlID0gdHlwZXMuYWRkKFtdLCBbXSlcbiAgY29uc3QgZnVuY3Rpb25JbmRleGVzID0gbmV3IE1hcChtb2R1bGUuZnVuY3Rpb25zLm1hcCgoZGVjbGFyYXRpb24sIG9mZnNldCkgPT4gW2RlY2xhcmF0aW9uLm5hbWUsIGltcG9ydENvdW50ICsgaGVscGVyQ291bnQgKyBvZmZzZXRdKSlcbiAgY29uc3QgcnVuRnVuY3Rpb25JbmRleCA9IGltcG9ydENvdW50ICsgaGVscGVyQ291bnQgKyBtb2R1bGUuZnVuY3Rpb25zLmxlbmd0aFxuXG4gIGFwcGVuZFNlY3Rpb24od3JpdGVyLCAxLCBcInR5cGVcIiwgZW5jb2RlVHlwZVNlY3Rpb24odHlwZXMsIGluZGV4LCByb290KSwgcm9vdClcbiAgYXBwZW5kU2VjdGlvbih3cml0ZXIsIDIsIFwiaW1wb3J0XCIsIGVuY29kZUltcG9ydFNlY3Rpb24oaW1wb3J0VHlwZXMsIGluZGV4LCByb290KSwgcm9vdClcbiAgYXBwZW5kU2VjdGlvbih3cml0ZXIsIDMsIFwiZnVuY3Rpb25cIiwgZW5jb2RlRnVuY3Rpb25TZWN0aW9uKGhlbHBlclR5cGVzLCBzZW1hbnRpY1R5cGVJbmRleGVzLCBydW5UeXBlLCBtb2R1bGUsIGluZGV4KSwgcm9vdClcbiAgYXBwZW5kU2VjdGlvbih3cml0ZXIsIDUsIFwibWVtb3J5XCIsIGVuY29kZU1lbW9yeVNlY3Rpb24obWVtb3J5UGFnZXMsIGluZGV4LCByb290KSwgcm9vdClcbiAgYXBwZW5kU2VjdGlvbih3cml0ZXIsIDYsIFwiZ2xvYmFsXCIsIGVuY29kZUdsb2JhbFNlY3Rpb24oc2NyYXRjaEJhc2UsIGluZGV4LCByb290KSwgcm9vdClcbiAgYXBwZW5kU2VjdGlvbih3cml0ZXIsIDcsIFwiZXhwb3J0XCIsIGVuY29kZUV4cG9ydFNlY3Rpb24ocnVuRnVuY3Rpb25JbmRleCwgaW5kZXgsIHJvb3QpLCByb290KVxuXG4gIGNvbnN0IGNvZGUgPSBuZXcgQmluYXJ5V3JpdGVyKGluZGV4KVxuXG4gIGNvZGUuc3ludGhldGljKHUzMihoZWxwZXJDb3VudCArIG1vZHVsZS5mdW5jdGlvbnMubGVuZ3RoICsgMSksIFwiRGVmaW5lZCBmdW5jdGlvbiBjb3VudFwiLCByb290LCBcImZ1bmN0aW9uIGNvdW50XCIpXG4gIGFwcGVuZEZ1bmN0aW9uQm9keShjb2RlLCBoZWxwZXJDb25jYXQoaW5kZXgsIG1vZHVsZSwgc2NyYXRjaEJhc2UpLCBbXCJpMzJcIiwgXCJpMzJcIiwgXCJpMzJcIiwgXCJpMzJcIl0sIHJvb3QsIFwiJGNvbmNhdFwiKVxuICBhcHBlbmRGdW5jdGlvbkJvZHkoY29kZSwgaGVscGVyU3RyaW5nRXF1YWwoaW5kZXgsIG1vZHVsZSksIFtcImkzMlwiXSwgcm9vdCwgXCIkc3RyaW5nX2VxdWFsXCIpXG4gIGFwcGVuZEZ1bmN0aW9uQm9keShjb2RlLCBoZWxwZXJDaGVja2VkQWRkKGluZGV4LCBtb2R1bGUpLCBbXCJpNjRcIl0sIHJvb3QsIFwiJGNoZWNrZWRfYWRkXCIpXG4gIGFwcGVuZEZ1bmN0aW9uQm9keShjb2RlLCBoZWxwZXJDaGVja2VkU3VidHJhY3QoaW5kZXgsIG1vZHVsZSksIFtcImk2NFwiXSwgcm9vdCwgXCIkY2hlY2tlZF9zdWJ0cmFjdFwiKVxuICBhcHBlbmRGdW5jdGlvbkJvZHkoY29kZSwgaGVscGVyQ2hlY2tlZE11bHRpcGx5KGluZGV4LCBtb2R1bGUpLCBbXCJpNjRcIl0sIHJvb3QsIFwiJGNoZWNrZWRfbXVsdGlwbHlcIilcbiAgYXBwZW5kRnVuY3Rpb25Cb2R5KGNvZGUsIGhlbHBlckNoZWNrZWROZWdhdGUoaW5kZXgsIG1vZHVsZSksIFtdLCByb290LCBcIiRjaGVja2VkX25lZ2F0ZVwiKVxuXG4gIGZvciAobGV0IGZ1bmN0aW9uT2Zmc2V0ID0gMDsgZnVuY3Rpb25PZmZzZXQgPCBtb2R1bGUuZnVuY3Rpb25zLmxlbmd0aDsgZnVuY3Rpb25PZmZzZXQgKz0gMSkge1xuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gbW9kdWxlLmZ1bmN0aW9uc1tmdW5jdGlvbk9mZnNldF1cbiAgICBjb25zdCBwYXRoID0gYC9mdW5jdGlvbnMvJHtmdW5jdGlvbk9mZnNldH1gXG4gICAgY29uc3QgZW1pdHRlciA9IG5ldyBGdW5jdGlvbkVtaXR0ZXIoe2Z1bmN0aW9uSW5kZXhlcywgaW5kZXgsIGxpdGVyYWxzOiBsaXRlcmFscy5ieVZhbHVlLCBtb2R1bGUsIHNjcmF0Y2hCYXNlfSlcblxuICAgIGVtaXR0ZXIuYmluZFBhcmFtZXRlcnMoZGVjbGFyYXRpb24ucGFyYW1ldGVycylcbiAgICBlbWl0dGVyLmJsb2NrKGRlY2xhcmF0aW9uLmJvZHksIGAke3BhdGh9L2JvZHlgKVxuICAgIGVtaXR0ZXIuc3ludGhldGljVW5yZWFjaGFibGUoZGVjbGFyYXRpb24sIHBhdGgpXG4gICAgZW1pdHRlci5zeW50aGV0aWNFbmQoZGVjbGFyYXRpb24sIHBhdGgpXG4gICAgYXBwZW5kRnVuY3Rpb25Cb2R5KGNvZGUsIGVtaXR0ZXIud3JpdGVyLCBlbWl0dGVyLmxvY2Fscywge25vZGU6IGRlY2xhcmF0aW9uLCBwYXRofSwgZGVjbGFyYXRpb24ubmFtZSlcbiAgfVxuXG4gIGNvbnN0IHJ1bkVtaXR0ZXIgPSBuZXcgRnVuY3Rpb25FbWl0dGVyKHtmdW5jdGlvbkluZGV4ZXMsIGluZGV4LCBsaXRlcmFsczogbGl0ZXJhbHMuYnlWYWx1ZSwgbW9kdWxlLCBzY3JhdGNoQmFzZX0pXG5cbiAgcnVuRW1pdHRlci5ydW4obW9kdWxlLmVudHJ5UG9pbnQsIFwiL2VudHJ5UG9pbnRcIilcbiAgYXBwZW5kRnVuY3Rpb25Cb2R5KGNvZGUsIHJ1bkVtaXR0ZXIud3JpdGVyLCBydW5FbWl0dGVyLmxvY2Fscywge25vZGU6IG1vZHVsZS5lbnRyeVBvaW50LCBwYXRoOiBcIi9lbnRyeVBvaW50XCJ9LCBcInJ1blwiKVxuICBhcHBlbmRTZWN0aW9uKHdyaXRlciwgMTAsIFwiY29kZVwiLCBjb2RlLCByb290KVxuICBhcHBlbmRTZWN0aW9uKHdyaXRlciwgMTEsIFwiZGF0YVwiLCBlbmNvZGVEYXRhU2VjdGlvbihsaXRlcmFscy5lbnRyaWVzLCBpbmRleCwgcm9vdCksIHJvb3QpXG4gIGFwcGVuZEN1c3RvbVNlY3Rpb24od3JpdGVyLCBcIm5hbWVcIiwgZW5jb2RlTmFtZVBheWxvYWQobW9kdWxlLCBydW5GdW5jdGlvbkluZGV4LCBpbmRleCksIHJvb3QpXG4gIGFwcGVuZEN1c3RvbVNlY3Rpb24od3JpdGVyLCBcInNvdXJjZU1hcHBpbmdVUkxcIiwgbmFtZWRQYXlsb2FkKFwicHJvZ3JhbS53YXNtLm1hcFwiLCBpbmRleCwgcm9vdCksIHJvb3QpXG5cbiAgcmV0dXJuIHtieXRlczogd3JpdGVyLmZpbmlzaCgpLCByYW5nZXM6IHdyaXRlci5yYW5nZXN9XG59XG5cbi8qKiBEaXJlY3Qgc2VtYW50aWMgZnVuY3Rpb24gYW5kIGVudHJ5LXBvaW50IGluc3RydWN0aW9uIGVtaXR0ZXIuICovXG5jbGFzcyBGdW5jdGlvbkVtaXR0ZXIge1xuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0cnVjdGlvbiBlbWl0dGVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9ucyAtIEVuY29kaW5nIGNvbnRleHQuXG4gICAqIEBwYXJhbSB7TWFwPHN0cmluZywgbnVtYmVyPn0gb3B0aW9ucy5mdW5jdGlvbkluZGV4ZXMgLSBTZW1hbnRpYyBmdW5jdGlvbiBpbmRleGVzLlxuICAgKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIGNyZWF0ZUdlbmVyYXRpb25JbmRleD59IG9wdGlvbnMuaW5kZXggLSBQcm92ZW5hbmNlIGluZGV4LlxuICAgKiBAcGFyYW0ge01hcDxzdHJpbmcsIHthZGRyZXNzOiBudW1iZXIsIGJ5dGVzOiBVaW50OEFycmF5fT59IG9wdGlvbnMubGl0ZXJhbHMgLSBMaXRlcmFsIGFkZHJlc3Nlcy5cbiAgICogQHBhcmFtIHtTZW1hbnRpY01vZHVsZX0gb3B0aW9ucy5tb2R1bGUgLSBDb21wbGV0ZSBtb2R1bGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvcHRpb25zLnNjcmF0Y2hCYXNlIC0gU2NyYXRjaCBiYXNlLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2Z1bmN0aW9uSW5kZXhlcywgaW5kZXgsIGxpdGVyYWxzLCBtb2R1bGUsIHNjcmF0Y2hCYXNlfSkge1xuICAgIHRoaXMuZnVuY3Rpb25JbmRleGVzID0gZnVuY3Rpb25JbmRleGVzXG4gICAgdGhpcy5mdW5jdGlvbnMgPSBuZXcgTWFwKG1vZHVsZS5mdW5jdGlvbnMubWFwKChkZWNsYXJhdGlvbikgPT4gW2RlY2xhcmF0aW9uLm5hbWUsIGRlY2xhcmF0aW9uXSkpXG4gICAgdGhpcy5pbmRleCA9IGluZGV4XG4gICAgdGhpcy5saXRlcmFscyA9IGxpdGVyYWxzXG4gICAgdGhpcy5tb2R1bGUgPSBtb2R1bGVcbiAgICB0aGlzLnNjcmF0Y2hCYXNlID0gc2NyYXRjaEJhc2VcbiAgICB0aGlzLndyaXRlciA9IG5ldyBCaW5hcnlXcml0ZXIoaW5kZXgpXG4gICAgLyoqIEB0eXBlIHsoXCJpMzJcIiB8IFwiaTY0XCIpW119ICovXG4gICAgdGhpcy5sb2NhbHMgPSBbXVxuICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgTG9jYWxCaW5kaW5nPn0gKi9cbiAgICB0aGlzLmJpbmRpbmdzID0gbmV3IE1hcCgpXG4gICAgdGhpcy5wYXJhbWV0ZXJDb3VudCA9IDBcbiAgfVxuXG4gIC8qKlxuICAgKiBCaW5kcyBmbGF0dGVuZWQgc2VtYW50aWMgcGFyYW1ldGVycyB0byBXYXNtIHBhcmFtZXRlciBpbmRleGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlBhcmFtZXRlcltdfSBwYXJhbWV0ZXJzIC0gU2VtYW50aWMgcGFyYW1ldGVycy5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBiaW5kUGFyYW1ldGVycyhwYXJhbWV0ZXJzKSB7XG4gICAgbGV0IGluZGV4ID0gMFxuXG4gICAgZm9yIChjb25zdCBwYXJhbWV0ZXIgb2YgcGFyYW1ldGVycykge1xuICAgICAgY29uc3Qgc2NhbGFyID0gd2FzbVNjYWxhclR5cGUocGFyYW1ldGVyLnR5cGUsIHBhcmFtZXRlci5sb2NhdGlvbilcbiAgICAgIGNvbnN0IHR5cGVzID0gd2FzbVR5cGVzKHNjYWxhcilcbiAgICAgIGNvbnN0IGluZGV4ZXMgPSB0eXBlcy5tYXAoKCkgPT4gaW5kZXgrKylcblxuICAgICAgdGhpcy5iaW5kaW5ncy5zZXQocGFyYW1ldGVyLm5hbWUsIHtpbmRleGVzLCB0eXBlOiBzY2FsYXJ9KVxuICAgIH1cbiAgICB0aGlzLnBhcmFtZXRlckNvdW50ID0gaW5kZXhcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyB0aGUgZ3VhcmRlZCBleHBvcnRlZCBydW4gYm9keS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FbnRyeVBvaW50fSBlbnRyeVBvaW50IC0gU2VtYW50aWMgZW50cnkgcG9pbnQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gRW50cnktcG9pbnQgcGF0aC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBydW4oZW50cnlQb2ludCwgcGF0aCkge1xuICAgIHRoaXMuc3ludGhldGljT3AoMHgyMywgZW50cnlQb2ludCwgcGF0aCwgXCJhY3RpdmUgZ3VhcmQgcmVhZFwiKVxuICAgIHRoaXMuc3ludGhldGljSW1tZWRpYXRlKHUzMihhY3RpdmVHbG9iYWxJbmRleCksIGVudHJ5UG9pbnQsIHBhdGgsIFwiYWN0aXZlIGd1YXJkIGdsb2JhbCBpbmRleFwiKVxuICAgIHRoaXMuc3ludGhldGljT3AoMHgwNCwgZW50cnlQb2ludCwgcGF0aCwgXCJhY3RpdmUgZ3VhcmQgYnJhbmNoXCIpXG4gICAgdGhpcy5zeW50aGV0aWNJbW1lZGlhdGUoWzB4NDBdLCBlbnRyeVBvaW50LCBwYXRoLCBcImVtcHR5IGJsb2NrIHR5cGVcIilcbiAgICB0aGlzLnN5bnRoZXRpY09wKDB4MDAsIGVudHJ5UG9pbnQsIHBhdGgsIFwicmVlbnRyYW50IGludm9jYXRpb24gdHJhcFwiKVxuICAgIHRoaXMuc3ludGhldGljT3AoMHgwYiwgZW50cnlQb2ludCwgcGF0aCwgXCJhY3RpdmUgZ3VhcmQgYnJhbmNoIGVuZFwiKVxuICAgIHRoaXMuc3ludGhldGljSTMyKDEsIGVudHJ5UG9pbnQsIHBhdGgsIFwibWFyayBydW4gYWN0aXZlXCIpXG4gICAgdGhpcy5zeW50aGV0aWNHbG9iYWxTZXQoYWN0aXZlR2xvYmFsSW5kZXgsIGVudHJ5UG9pbnQsIHBhdGgsIFwiYWN0aXZlIGd1YXJkXCIpXG4gICAgdGhpcy5zeW50aGV0aWNJMzIodGhpcy5zY3JhdGNoQmFzZSwgZW50cnlQb2ludCwgcGF0aCwgXCJyZXNldCBzY3JhdGNoIGN1cnNvclwiKVxuICAgIHRoaXMuc3ludGhldGljR2xvYmFsU2V0KGN1cnNvckdsb2JhbEluZGV4LCBlbnRyeVBvaW50LCBwYXRoLCBcInNjcmF0Y2ggY3Vyc29yXCIpXG4gICAgdGhpcy5zeW50aGV0aWNJMzIoMCwgZW50cnlQb2ludCwgcGF0aCwgXCJyZXNldCBzZW1hbnRpYyBjYWxsIGRlcHRoXCIpXG4gICAgdGhpcy5zeW50aGV0aWNHbG9iYWxTZXQoZGVwdGhHbG9iYWxJbmRleCwgZW50cnlQb2ludCwgcGF0aCwgXCJjYWxsIGRlcHRoXCIpXG4gICAgdGhpcy5ibG9jayhlbnRyeVBvaW50LmJvZHksIGAke3BhdGh9L2JvZHlgKVxuICAgIHRoaXMuc3ludGhldGljSTMyKDAsIGVudHJ5UG9pbnQsIHBhdGgsIFwiY2xlYXIgc2VtYW50aWMgY2FsbCBkZXB0aFwiKVxuICAgIHRoaXMuc3ludGhldGljR2xvYmFsU2V0KGRlcHRoR2xvYmFsSW5kZXgsIGVudHJ5UG9pbnQsIHBhdGgsIFwiY2FsbCBkZXB0aFwiKVxuICAgIHRoaXMuc3ludGhldGljSTMyKDAsIGVudHJ5UG9pbnQsIHBhdGgsIFwibWFyayBydW4gaW5hY3RpdmVcIilcbiAgICB0aGlzLnN5bnRoZXRpY0dsb2JhbFNldChhY3RpdmVHbG9iYWxJbmRleCwgZW50cnlQb2ludCwgcGF0aCwgXCJhY3RpdmUgZ3VhcmRcIilcbiAgICB0aGlzLnN5bnRoZXRpY0VuZChlbnRyeVBvaW50LCBwYXRoKVxuICB9XG5cbiAgLyoqXG4gICAqIEVtaXRzIG9uZSBzZW1hbnRpYyBibG9jay5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gYmxvY2sgLSBTZW1hbnRpYyBibG9jay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBPY2N1cnJlbmNlIHBhdGguXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgYmxvY2soYmxvY2ssIHBhdGgpIHtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgYmxvY2suc3RhdGVtZW50cy5sZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgIGNvbnN0IHN0YXRlbWVudCA9IGJsb2NrLnN0YXRlbWVudHNbaW5kZXhdXG4gICAgICBjb25zdCBzdGF0ZW1lbnRQYXRoID0gYCR7cGF0aH0vc3RhdGVtZW50cy8ke2luZGV4fWBcblxuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiTG9jYWxEZWNsYXJhdGlvblwiKSB7XG4gICAgICAgIHRoaXMuZXhwcmVzc2lvbihzdGF0ZW1lbnQuaW5pdGlhbGl6ZXIsIGAke3N0YXRlbWVudFBhdGh9L2luaXRpYWxpemVyYClcbiAgICAgICAgY29uc3QgYmluZGluZyA9IHRoaXMuYWxsb2NhdGVCaW5kaW5nKHdhc21TY2FsYXJUeXBlKHN0YXRlbWVudC50eXBlLCBzdGF0ZW1lbnQubG9jYXRpb24pKVxuXG4gICAgICAgIHRoaXMuYmluZGluZ3Muc2V0KHN0YXRlbWVudC5uYW1lLCBiaW5kaW5nKVxuICAgICAgICB0aGlzLnNldEJpbmRpbmcoYmluZGluZywgc3RhdGVtZW50LCBzdGF0ZW1lbnRQYXRoLCBcIm5hbWVcIilcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJBc3NpZ25tZW50U3RhdGVtZW50XCIpIHtcbiAgICAgICAgdGhpcy5leHByZXNzaW9uKHN0YXRlbWVudC5leHByZXNzaW9uLCBgJHtzdGF0ZW1lbnRQYXRofS9leHByZXNzaW9uYClcbiAgICAgICAgY29uc3QgYmluZGluZyA9IHRoaXMuYmluZGluZ3MuZ2V0KHN0YXRlbWVudC50YXJnZXQubmFtZSlcblxuICAgICAgICBpZiAoIWJpbmRpbmcpIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRlZCBXYXNtIGFzc2lnbm1lbnQgb21pdHRlZCBpdHMgYmluZGluZy5cIilcbiAgICAgICAgdGhpcy5zZXRCaW5kaW5nKGJpbmRpbmcsIHN0YXRlbWVudC50YXJnZXQsIGAke3N0YXRlbWVudFBhdGh9L3RhcmdldGAsIFwibmFtZVwiKVxuICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlByaW50U3RhdGVtZW50XCIpIHtcbiAgICAgICAgY29uc3QgdHlwZSA9IGV4cHJlc3Npb25UeXBlKHN0YXRlbWVudC5leHByZXNzaW9uLCB0aGlzLmJpbmRpbmdzLCB0aGlzLmZ1bmN0aW9ucylcblxuICAgICAgICB0aGlzLmV4cHJlc3Npb24oc3RhdGVtZW50LmV4cHJlc3Npb24sIGAke3N0YXRlbWVudFBhdGh9L2V4cHJlc3Npb25gKVxuICAgICAgICBjb25zdCBpbXBvcnRJbmRleCA9IHR5cGUgPT0gXCJpbnRlZ2VyXCIgPyAwIDogdHlwZSA9PSBcImJvb2xlYW5cIiA/IDEgOiAyXG5cbiAgICAgICAgdGhpcy5tYXBwZWRPcCgweDEwLCBzdGF0ZW1lbnQsIHN0YXRlbWVudFBhdGgsIFwicHJpbnQgaW5zdHJ1Y3Rpb25cIilcbiAgICAgICAgdGhpcy5tYXBwZWRJbW1lZGlhdGUodTMyKGltcG9ydEluZGV4KSwgc3RhdGVtZW50LCBzdGF0ZW1lbnRQYXRoLCBcInByaW50IGltcG9ydCBpbmRleFwiKVxuICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlJldHVyblN0YXRlbWVudFwiKSB7XG4gICAgICAgIGlmICghc3RhdGVtZW50LmV4cHJlc3Npb24pIHRocm93IG5ldyBUeXBlRXJyb3IoXCJXYXNtIGJhcmUgcmV0dXJuIHJlYWNoZWQgZW1pc3Npb24uXCIpXG4gICAgICAgIHRoaXMuZXhwcmVzc2lvbihzdGF0ZW1lbnQuZXhwcmVzc2lvbiwgYCR7c3RhdGVtZW50UGF0aH0vZXhwcmVzc2lvbmApXG4gICAgICAgIHRoaXMubWFwcGVkT3AoMHgwZiwgc3RhdGVtZW50LCBzdGF0ZW1lbnRQYXRoLCBcInJldHVybiBpbnN0cnVjdGlvblwiKVxuICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiV2FzbSBUYXNrIDAwNSBleHByZXNzaW9uIHN0YXRlbWVudCByZWFjaGVkIGVtaXNzaW9uLlwiKVxuICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgICAgdGhpcy5leHByZXNzaW9uKHN0YXRlbWVudC5jb25kaXRpb24sIGAke3N0YXRlbWVudFBhdGh9L2NvbmRpdGlvbmApXG4gICAgICAgIHRoaXMubWFwcGVkT3AoMHgwNCwgc3RhdGVtZW50LmNvbmRpdGlvbiwgYCR7c3RhdGVtZW50UGF0aH0vY29uZGl0aW9uYCwgXCJjb25kaXRpb25hbCBpbnN0cnVjdGlvblwiKVxuICAgICAgICB0aGlzLnN5bnRoZXRpY0ltbWVkaWF0ZShbMHg0MF0sIHN0YXRlbWVudCwgc3RhdGVtZW50UGF0aCwgXCJlbXB0eSBjb25kaXRpb25hbCBibG9jayB0eXBlXCIpXG4gICAgICAgIHRoaXMuYmxvY2soc3RhdGVtZW50LmNvbnNlcXVlbnQsIGAke3N0YXRlbWVudFBhdGh9L2NvbnNlcXVlbnRgKVxuICAgICAgICBpZiAoc3RhdGVtZW50LmFsdGVybmF0ZSkge1xuICAgICAgICAgIHRoaXMubWFwcGVkT3AoMHgwNSwgc3RhdGVtZW50LCBzdGF0ZW1lbnRQYXRoLCBcImFsdGVybmF0ZSBpbnN0cnVjdGlvblwiKVxuICAgICAgICAgIHRoaXMuYmxvY2soc3RhdGVtZW50LmFsdGVybmF0ZSwgYCR7c3RhdGVtZW50UGF0aH0vYWx0ZXJuYXRlYClcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm1hcHBlZE9wKDB4MGIsIHN0YXRlbWVudCwgc3RhdGVtZW50UGF0aCwgXCJjb25kaXRpb25hbCBlbmRcIilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJVbnN1cHBvcnRlZCBXYXNtIHN0YXRlbWVudCByZWFjaGVkIGVtaXNzaW9uLlwiKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyBvbmUgZXhwcmVzc2lvbiBhbmQgbGVhdmVzIGl0cyBmbGF0dGVuZWQgcmVzdWx0IG9uIHRoZSBvcGVyYW5kIHN0YWNrLlxuICAgKiBAcGFyYW0ge0V4cHJlc3Npb259IGV4cHJlc3Npb24gLSBTZW1hbnRpYyBleHByZXNzaW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIE9jY3VycmVuY2UgcGF0aC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBleHByZXNzaW9uKGV4cHJlc3Npb24sIHBhdGgpIHtcbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgYmluZGluZyA9IHRoaXMuYmluZGluZ3MuZ2V0KGV4cHJlc3Npb24ubmFtZSlcblxuICAgICAgaWYgKCFiaW5kaW5nKSB0aHJvdyBuZXcgRXJyb3IoXCJWYWxpZGF0ZWQgV2FzbSBpZGVudGlmaWVyIG9taXR0ZWQgaXRzIGJpbmRpbmcuXCIpXG4gICAgICBmb3IgKGNvbnN0IGxvY2FsSW5kZXggb2YgYmluZGluZy5pbmRleGVzKSB7XG4gICAgICAgIHRoaXMubWFwcGVkT3AoMHgyMCwgZXhwcmVzc2lvbiwgcGF0aCwgXCJsb2NhbCByZWFkXCIsIFwibmFtZVwiKVxuICAgICAgICB0aGlzLm1hcHBlZEltbWVkaWF0ZSh1MzIobG9jYWxJbmRleCksIGV4cHJlc3Npb24sIHBhdGgsIFwibG9jYWwgaW5kZXhcIiwgXCJuYW1lXCIpXG4gICAgICB9XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkludGVnZXJMaXRlcmFsXCIpIHtcbiAgICAgIHRoaXMubWFwcGVkT3AoMHg0MiwgZXhwcmVzc2lvbiwgcGF0aCwgXCJpNjQgY29uc3RhbnRcIiwgXCJsaXRlcmFsXCIpXG4gICAgICB0aGlzLm1hcHBlZEltbWVkaWF0ZShzNjQoQmlnSW50KGV4cHJlc3Npb24udmFsdWUpKSwgZXhwcmVzc2lvbiwgcGF0aCwgXCJpNjQgaW1tZWRpYXRlXCIsIFwibGl0ZXJhbFwiKVxuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCb29sZWFuTGl0ZXJhbFwiKSB7XG4gICAgICB0aGlzLm1hcHBlZE9wKDB4NDEsIGV4cHJlc3Npb24sIHBhdGgsIFwiY2Fub25pY2FsIEJvb2xlYW4gY29uc3RhbnRcIiwgXCJsaXRlcmFsXCIpXG4gICAgICB0aGlzLm1hcHBlZEltbWVkaWF0ZShzMzIoZXhwcmVzc2lvbi52YWx1ZSA/IDEgOiAwKSwgZXhwcmVzc2lvbiwgcGF0aCwgXCJpMzIgaW1tZWRpYXRlXCIsIFwibGl0ZXJhbFwiKVxuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJTdHJpbmdMaXRlcmFsXCIpIHtcbiAgICAgIGNvbnN0IGxpdGVyYWwgPSB0aGlzLmxpdGVyYWxzLmdldChleHByZXNzaW9uLnZhbHVlKVxuXG4gICAgICBpZiAoIWxpdGVyYWwpIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRlZCBXYXNtIHN0cmluZyBsaXRlcmFsIG9taXR0ZWQgaXRzIHN0YXRpYyBsYXlvdXQuXCIpXG4gICAgICB0aGlzLm1hcHBlZE9wKDB4NDEsIGV4cHJlc3Npb24sIHBhdGgsIFwic3RyaW5nIHBvaW50ZXIgY29uc3RhbnRcIiwgXCJsaXRlcmFsXCIpXG4gICAgICB0aGlzLm1hcHBlZEltbWVkaWF0ZShzMzIobGl0ZXJhbC5hZGRyZXNzKSwgZXhwcmVzc2lvbiwgcGF0aCwgXCJzdHJpbmcgcG9pbnRlciBpbW1lZGlhdGVcIiwgXCJsaXRlcmFsXCIpXG4gICAgICB0aGlzLm1hcHBlZE9wKDB4NDEsIGV4cHJlc3Npb24sIHBhdGgsIFwic3RyaW5nIGxlbmd0aCBjb25zdGFudFwiLCBcImxpdGVyYWxcIilcbiAgICAgIHRoaXMubWFwcGVkSW1tZWRpYXRlKHMzMihsaXRlcmFsLmJ5dGVzLmJ5dGVMZW5ndGgpLCBleHByZXNzaW9uLCBwYXRoLCBcInN0cmluZyBsZW5ndGggaW1tZWRpYXRlXCIsIFwibGl0ZXJhbFwiKVxuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJDYWxsRXhwcmVzc2lvblwiKSB7XG4gICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgZXhwcmVzc2lvbi5hcmd1bWVudHMubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgICAgIHRoaXMuZXhwcmVzc2lvbihleHByZXNzaW9uLmFyZ3VtZW50c1tpbmRleF0sIGAke3BhdGh9L2FyZ3VtZW50cy8ke2luZGV4fWApXG4gICAgICB9XG4gICAgICB0aGlzLnNlbWFudGljQ2FsbChleHByZXNzaW9uLCBwYXRoKVxuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJVbmFyeUV4cHJlc3Npb25cIikge1xuICAgICAgdGhpcy5leHByZXNzaW9uKGV4cHJlc3Npb24ub3BlcmFuZCwgYCR7cGF0aH0vb3BlcmFuZGApXG4gICAgICBpZiAoZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJCb29sZWFuTm90XCIpIHRoaXMubWFwcGVkT3AoMHg0NSwgZXhwcmVzc2lvbiwgcGF0aCwgXCJCb29sZWFuIG5vdCBpbnN0cnVjdGlvblwiLCBcIm9wZXJhdG9yXCIpXG4gICAgICBlbHNlIHtcbiAgICAgICAgdGhpcy5tYXBwZWRPcCgweDEwLCBleHByZXNzaW9uLCBwYXRoLCBcImNoZWNrZWQgaW50ZWdlciBuZWdhdGUgaW5zdHJ1Y3Rpb25cIiwgXCJvcGVyYXRvclwiKVxuICAgICAgICB0aGlzLm1hcHBlZEltbWVkaWF0ZSh1MzIoY2hlY2tlZE5lZ2F0ZUZ1bmN0aW9uSW5kZXgpLCBleHByZXNzaW9uLCBwYXRoLCBcImNoZWNrZWQgaGVscGVyIGluZGV4XCIsIFwib3BlcmF0b3JcIilcbiAgICAgIH1cbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kICE9IFwiQmluYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KFwid2FzbVwiLCBcImNvbGxlY3Rpb24gZXhwcmVzc2lvbiByZWFjaGVkIHNjYWxhciBlbWlzc2lvblwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAoZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJCb29sZWFuQW5kXCIgfHwgZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJCb29sZWFuT3JcIikge1xuICAgICAgdGhpcy5leHByZXNzaW9uKGV4cHJlc3Npb24ubGVmdCwgYCR7cGF0aH0vbGVmdGApXG4gICAgICB0aGlzLm1hcHBlZE9wKDB4MDQsIGV4cHJlc3Npb24sIHBhdGgsIFwic2hvcnQtY2lyY3VpdCBjb25kaXRpb25hbFwiLCBcIm9wZXJhdG9yXCIpXG4gICAgICB0aGlzLnN5bnRoZXRpY0ltbWVkaWF0ZShbdmFsdWVUeXBlcy5pMzJdLCBleHByZXNzaW9uLCBwYXRoLCBcIkJvb2xlYW4gY29uZGl0aW9uYWwgcmVzdWx0IHR5cGVcIilcbiAgICAgIGlmIChleHByZXNzaW9uLm9wZXJhdGlvbiA9PSBcIkJvb2xlYW5BbmRcIikge1xuICAgICAgICB0aGlzLmV4cHJlc3Npb24oZXhwcmVzc2lvbi5yaWdodCwgYCR7cGF0aH0vcmlnaHRgKVxuICAgICAgICB0aGlzLm1hcHBlZE9wKDB4MDUsIGV4cHJlc3Npb24sIHBhdGgsIFwic2hvcnQtY2lyY3VpdCBhbHRlcm5hdGVcIiwgXCJvcGVyYXRvclwiKVxuICAgICAgICB0aGlzLnN5bnRoZXRpY0kzMigwLCBleHByZXNzaW9uLCBwYXRoLCBcImNhbm9uaWNhbCBmYWxzZSByZXN1bHRcIilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc3ludGhldGljSTMyKDEsIGV4cHJlc3Npb24sIHBhdGgsIFwiY2Fub25pY2FsIHRydWUgcmVzdWx0XCIpXG4gICAgICAgIHRoaXMubWFwcGVkT3AoMHgwNSwgZXhwcmVzc2lvbiwgcGF0aCwgXCJzaG9ydC1jaXJjdWl0IGFsdGVybmF0ZVwiLCBcIm9wZXJhdG9yXCIpXG4gICAgICAgIHRoaXMuZXhwcmVzc2lvbihleHByZXNzaW9uLnJpZ2h0LCBgJHtwYXRofS9yaWdodGApXG4gICAgICB9XG4gICAgICB0aGlzLm1hcHBlZE9wKDB4MGIsIGV4cHJlc3Npb24sIHBhdGgsIFwic2hvcnQtY2lyY3VpdCBlbmRcIiwgXCJvcGVyYXRvclwiKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5leHByZXNzaW9uKGV4cHJlc3Npb24ubGVmdCwgYCR7cGF0aH0vbGVmdGApXG4gICAgdGhpcy5leHByZXNzaW9uKGV4cHJlc3Npb24ucmlnaHQsIGAke3BhdGh9L3JpZ2h0YClcbiAgICBjb25zdCBkaXJlY3RPcGNvZGUgPSBuZXcgTWFwKFtcbiAgICAgIFtcIkludGVnZXJFcXVhbFwiLCAweDUxXSwgW1wiSW50ZWdlck5vdEVxdWFsXCIsIDB4NTJdLCBbXCJJbnRlZ2VyTGVzc1RoYW5cIiwgMHg1M10sXG4gICAgICBbXCJJbnRlZ2VyR3JlYXRlclRoYW5cIiwgMHg1NV0sIFtcIkludGVnZXJMZXNzVGhhbk9yRXF1YWxcIiwgMHg1N10sIFtcIkludGVnZXJHcmVhdGVyVGhhbk9yRXF1YWxcIiwgMHg1OV0sXG4gICAgICBbXCJCb29sZWFuRXF1YWxcIiwgMHg0Nl0sIFtcIkJvb2xlYW5Ob3RFcXVhbFwiLCAweDQ3XVxuICAgIF0pLmdldChleHByZXNzaW9uLm9wZXJhdGlvbilcblxuICAgIGlmIChkaXJlY3RPcGNvZGUgIT09IHVuZGVmaW5lZCkgdGhpcy5tYXBwZWRPcChkaXJlY3RPcGNvZGUsIGV4cHJlc3Npb24sIHBhdGgsIGAke2V4cHJlc3Npb24ub3BlcmF0aW9ufSBpbnN0cnVjdGlvbmAsIFwib3BlcmF0b3JcIilcbiAgICBlbHNlIHtcbiAgICAgIGNvbnN0IGhlbHBlckluZGV4ID0gZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJTdHJpbmdDb25jYXRcIiA/IGNvbmNhdEZ1bmN0aW9uSW5kZXggOlxuICAgICAgICBleHByZXNzaW9uLm9wZXJhdGlvbiA9PSBcIlN0cmluZ0VxdWFsXCIgfHwgZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJTdHJpbmdOb3RFcXVhbFwiID8gc3RyaW5nRXF1YWxGdW5jdGlvbkluZGV4IDpcbiAgICAgICAgICBleHByZXNzaW9uLm9wZXJhdGlvbiA9PSBcIkludGVnZXJBZGRcIiA/IGNoZWNrZWRBZGRGdW5jdGlvbkluZGV4IDpcbiAgICAgICAgICAgIGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiSW50ZWdlclN1YnRyYWN0XCIgPyBjaGVja2VkU3VidHJhY3RGdW5jdGlvbkluZGV4IDogY2hlY2tlZE11bHRpcGx5RnVuY3Rpb25JbmRleFxuXG4gICAgICB0aGlzLm1hcHBlZE9wKDB4MTAsIGV4cHJlc3Npb24sIHBhdGgsIGAke2V4cHJlc3Npb24ub3BlcmF0aW9ufSBoZWxwZXIgY2FsbGAsIFwib3BlcmF0b3JcIilcbiAgICAgIHRoaXMubWFwcGVkSW1tZWRpYXRlKHUzMihoZWxwZXJJbmRleCksIGV4cHJlc3Npb24sIHBhdGgsIFwiaGVscGVyIGZ1bmN0aW9uIGluZGV4XCIsIFwib3BlcmF0b3JcIilcbiAgICAgIGlmIChleHByZXNzaW9uLm9wZXJhdGlvbiA9PSBcIlN0cmluZ05vdEVxdWFsXCIpIHRoaXMubWFwcGVkT3AoMHg0NSwgZXhwcmVzc2lvbiwgcGF0aCwgXCJTdHJpbmcgaW5lcXVhbGl0eSBpbnZlcnNpb25cIiwgXCJvcGVyYXRvclwiKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyBjaGVja2VkIHNlbWFudGljLWNhbGwgZGVwdGggYWNjb3VudGluZyB3aXRob3V0IGNoYW5naW5nIGFyZ3VtZW50IG9yZGVyLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNhbGxFeHByZXNzaW9ufSBleHByZXNzaW9uIC0gQ2FsbCBleHByZXNzaW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIENhbGwgb2NjdXJyZW5jZSBwYXRoLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHNlbWFudGljQ2FsbChleHByZXNzaW9uLCBwYXRoKSB7XG4gICAgY29uc3QgZGVjbGFyYXRpb24gPSB0aGlzLmZ1bmN0aW9ucy5nZXQoZXhwcmVzc2lvbi5jYWxsZWUpXG4gICAgY29uc3QgZnVuY3Rpb25JbmRleCA9IHRoaXMuZnVuY3Rpb25JbmRleGVzLmdldChleHByZXNzaW9uLmNhbGxlZSlcblxuICAgIGlmICghZGVjbGFyYXRpb24gfHwgZnVuY3Rpb25JbmRleCA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoXCJWYWxpZGF0ZWQgV2FzbSBjYWxsIG9taXR0ZWQgaXRzIGRlY2xhcmF0aW9uLlwiKVxuICAgIHRoaXMuc3ludGhldGljT3AoMHgyMywgZXhwcmVzc2lvbiwgcGF0aCwgXCJyZWFkIHNlbWFudGljIGNhbGwgZGVwdGhcIilcbiAgICB0aGlzLnN5bnRoZXRpY0ltbWVkaWF0ZSh1MzIoZGVwdGhHbG9iYWxJbmRleCksIGV4cHJlc3Npb24sIHBhdGgsIFwiY2FsbC1kZXB0aCBnbG9iYWwgaW5kZXhcIilcbiAgICB0aGlzLnN5bnRoZXRpY0kzMihtYXhpbXVtQ2FsbERlcHRoLCBleHByZXNzaW9uLCBwYXRoLCBcIm1heGltdW0gc2VtYW50aWMgY2FsbCBkZXB0aFwiKVxuICAgIHRoaXMuc3ludGhldGljT3AoMHg0ZiwgZXhwcmVzc2lvbiwgcGF0aCwgXCJzZW1hbnRpYyBjYWxsLWRlcHRoIGxpbWl0IGNvbXBhcmlzb25cIilcbiAgICB0aGlzLnN5bnRoZXRpY09wKDB4MDQsIGV4cHJlc3Npb24sIHBhdGgsIFwic2VtYW50aWMgY2FsbC1kZXB0aCBndWFyZFwiKVxuICAgIHRoaXMuc3ludGhldGljSW1tZWRpYXRlKFsweDQwXSwgZXhwcmVzc2lvbiwgcGF0aCwgXCJlbXB0eSBjYWxsLWRlcHRoIGd1YXJkIGJsb2NrIHR5cGVcIilcbiAgICB0aGlzLnN5bnRoZXRpY09wKDB4MDAsIGV4cHJlc3Npb24sIHBhdGgsIFwic2VtYW50aWMgY2FsbC1kZXB0aCB0cmFwXCIpXG4gICAgdGhpcy5zeW50aGV0aWNPcCgweDBiLCBleHByZXNzaW9uLCBwYXRoLCBcInNlbWFudGljIGNhbGwtZGVwdGggZ3VhcmQgZW5kXCIpXG4gICAgdGhpcy5zeW50aGV0aWNPcCgweDIzLCBleHByZXNzaW9uLCBwYXRoLCBcInJlYWQgc2VtYW50aWMgY2FsbCBkZXB0aFwiKVxuICAgIHRoaXMuc3ludGhldGljSW1tZWRpYXRlKHUzMihkZXB0aEdsb2JhbEluZGV4KSwgZXhwcmVzc2lvbiwgcGF0aCwgXCJjYWxsLWRlcHRoIGdsb2JhbCBpbmRleFwiKVxuICAgIHRoaXMuc3ludGhldGljSTMyKDEsIGV4cHJlc3Npb24sIHBhdGgsIFwic2VtYW50aWMgY2FsbC1kZXB0aCBpbmNyZW1lbnRcIilcbiAgICB0aGlzLnN5bnRoZXRpY09wKDB4NmEsIGV4cHJlc3Npb24sIHBhdGgsIFwiaW5jcmVtZW50IHNlbWFudGljIGNhbGwgZGVwdGhcIilcbiAgICB0aGlzLnN5bnRoZXRpY0dsb2JhbFNldChkZXB0aEdsb2JhbEluZGV4LCBleHByZXNzaW9uLCBwYXRoLCBcImNhbGwgZGVwdGhcIilcbiAgICB0aGlzLm1hcHBlZE9wKDB4MTAsIGV4cHJlc3Npb24sIHBhdGgsIFwic2VtYW50aWMgY2FsbCBpbnN0cnVjdGlvblwiLCBcImNhbGxlZVwiKVxuICAgIHRoaXMubWFwcGVkSW1tZWRpYXRlKHUzMihmdW5jdGlvbkluZGV4KSwgZXhwcmVzc2lvbiwgcGF0aCwgXCJzZW1hbnRpYyBjYWxsZWUgaW5kZXhcIiwgXCJjYWxsZWVcIilcblxuICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuYWxsb2NhdGVCaW5kaW5nKHdhc21SZXR1cm5UeXBlKGRlY2xhcmF0aW9uKSlcblxuICAgIHRoaXMuc2V0QmluZGluZyhyZXN1bHQsIGV4cHJlc3Npb24sIHBhdGgpXG4gICAgdGhpcy5zeW50aGV0aWNPcCgweDIzLCBleHByZXNzaW9uLCBwYXRoLCBcInJlYWQgc2VtYW50aWMgY2FsbCBkZXB0aFwiKVxuICAgIHRoaXMuc3ludGhldGljSW1tZWRpYXRlKHUzMihkZXB0aEdsb2JhbEluZGV4KSwgZXhwcmVzc2lvbiwgcGF0aCwgXCJjYWxsLWRlcHRoIGdsb2JhbCBpbmRleFwiKVxuICAgIHRoaXMuc3ludGhldGljSTMyKDEsIGV4cHJlc3Npb24sIHBhdGgsIFwic2VtYW50aWMgY2FsbC1kZXB0aCBkZWNyZW1lbnRcIilcbiAgICB0aGlzLnN5bnRoZXRpY09wKDB4NmIsIGV4cHJlc3Npb24sIHBhdGgsIFwiZGVjcmVtZW50IHNlbWFudGljIGNhbGwgZGVwdGhcIilcbiAgICB0aGlzLnN5bnRoZXRpY0dsb2JhbFNldChkZXB0aEdsb2JhbEluZGV4LCBleHByZXNzaW9uLCBwYXRoLCBcImNhbGwgZGVwdGhcIilcbiAgICBmb3IgKGNvbnN0IGxvY2FsSW5kZXggb2YgcmVzdWx0LmluZGV4ZXMpIHtcbiAgICAgIHRoaXMuc3ludGhldGljT3AoMHgyMCwgZXhwcmVzc2lvbiwgcGF0aCwgXCJyZXN0b3JlIHNlbWFudGljIGNhbGwgcmVzdWx0XCIpXG4gICAgICB0aGlzLnN5bnRoZXRpY0ltbWVkaWF0ZSh1MzIobG9jYWxJbmRleCksIGV4cHJlc3Npb24sIHBhdGgsIFwicmVzdWx0IHRlbXBvcmFyeSBsb2NhbCBpbmRleFwiKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBbGxvY2F0ZXMgZmxhdHRlbmVkIFdhc20gbG9jYWxzIGZvciBvbmUgc2VtYW50aWMgdmFsdWUuXG4gICAqIEBwYXJhbSB7U2NhbGFyfSB0eXBlIC0gU2VtYW50aWMgdHlwZS5cbiAgICogQHJldHVybnMge0xvY2FsQmluZGluZ30gTG9jYWwgYmluZGluZy5cbiAgICovXG4gIGFsbG9jYXRlQmluZGluZyh0eXBlKSB7XG4gICAgY29uc3QgaW5kZXhlcyA9IHdhc21UeXBlcyh0eXBlKS5tYXAoKHdhc21UeXBlKSA9PiB7XG4gICAgICBjb25zdCBpbmRleCA9IHRoaXMucGFyYW1ldGVyQ291bnQgKyB0aGlzLmxvY2Fscy5sZW5ndGhcblxuICAgICAgdGhpcy5sb2NhbHMucHVzaCh3YXNtVHlwZSlcblxuICAgICAgcmV0dXJuIGluZGV4XG4gICAgfSlcblxuICAgIHJldHVybiB7aW5kZXhlcywgdHlwZX1cbiAgfVxuXG4gIC8qKlxuICAgKiBQb3BzIGEgZmxhdHRlbmVkIHZhbHVlIGludG8gaXRzIGxvY2Fscy5cbiAgICogQHBhcmFtIHtMb2NhbEJpbmRpbmd9IGJpbmRpbmcgLSBEZXN0aW5hdGlvbi5cbiAgICogQHBhcmFtIHtTZW1hbnRpY05vZGV9IG5vZGUgLSBSZWxhdGVkIHNlbWFudGljIG5vZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gT2NjdXJyZW5jZSBwYXRoLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3NvdXJjZVJvbGVdIC0gRXhhY3QgcGFyc2VyLW93bmVkIHRva2VuIHJvbGUsIHdoZW4gdGhpcyBpcyBhIHNlbWFudGljIGJpbmRpbmcuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgc2V0QmluZGluZyhiaW5kaW5nLCBub2RlLCBwYXRoLCBzb3VyY2VSb2xlKSB7XG4gICAgZm9yIChsZXQgaW5kZXggPSBiaW5kaW5nLmluZGV4ZXMubGVuZ3RoIC0gMTsgaW5kZXggPj0gMDsgaW5kZXggLT0gMSkge1xuICAgICAgaWYgKHNvdXJjZVJvbGUpIHtcbiAgICAgICAgdGhpcy5tYXBwZWRPcCgweDIxLCBub2RlLCBwYXRoLCBcImxvY2FsIHdyaXRlXCIsIHNvdXJjZVJvbGUpXG4gICAgICAgIHRoaXMubWFwcGVkSW1tZWRpYXRlKHUzMihiaW5kaW5nLmluZGV4ZXNbaW5kZXhdKSwgbm9kZSwgcGF0aCwgXCJsb2NhbCBpbmRleFwiLCBzb3VyY2VSb2xlKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zeW50aGV0aWNPcCgweDIxLCBub2RlLCBwYXRoLCBcInN0b3JlIHNlbWFudGljIGNhbGwgcmVzdWx0XCIpXG4gICAgICAgIHRoaXMuc3ludGhldGljSW1tZWRpYXRlKHUzMihiaW5kaW5nLmluZGV4ZXNbaW5kZXhdKSwgbm9kZSwgcGF0aCwgXCJyZXN1bHQgdGVtcG9yYXJ5IGxvY2FsIGluZGV4XCIpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFdyaXRlcyBhIHNvdXJjZS1tYXBwZWQgaW5zdHJ1Y3Rpb24gb3Bjb2RlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb3Bjb2RlIC0gV2FzbSBvcGNvZGUuXG4gICAqIEBwYXJhbSB7U2VtYW50aWNOb2RlfSBub2RlIC0gUmVsYXRlZCBzZW1hbnRpYyBub2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIE5vZGUgb2NjdXJyZW5jZSBwYXRoLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcm9sZSAtIE1hcHBpbmcgcm9sZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtzb3VyY2VSb2xlXSAtIEV4YWN0IHBhcnNlci1vd25lZCB0b2tlbiByb2xlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIG1hcHBlZE9wKG9wY29kZSwgbm9kZSwgcGF0aCwgcm9sZSwgc291cmNlUm9sZSkgeyB0aGlzLndyaXRlci5tYXBwZWQoW29wY29kZV0sIG5vZGUsIHBhdGgsIHJvbGUsIHNvdXJjZVJvbGUpIH1cblxuICAvKipcbiAgICogV3JpdGVzIGEgc291cmNlLW1hcHBlZCBpbnN0cnVjdGlvbiBpbW1lZGlhdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyW119IGJ5dGVzIC0gRW5jb2RlZCBpbW1lZGlhdGUgYnl0ZXMuXG4gICAqIEBwYXJhbSB7U2VtYW50aWNOb2RlfSBub2RlIC0gUmVsYXRlZCBzZW1hbnRpYyBub2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIE5vZGUgb2NjdXJyZW5jZSBwYXRoLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcm9sZSAtIE1hcHBpbmcgcm9sZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtzb3VyY2VSb2xlXSAtIEV4YWN0IHBhcnNlci1vd25lZCB0b2tlbiByb2xlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIG1hcHBlZEltbWVkaWF0ZShieXRlcywgbm9kZSwgcGF0aCwgcm9sZSwgc291cmNlUm9sZSkgeyB0aGlzLndyaXRlci5tYXBwZWQoYnl0ZXMsIG5vZGUsIHBhdGgsIHJvbGUsIHNvdXJjZVJvbGUpIH1cblxuICAvKipcbiAgICogV3JpdGVzIGEgc3ludGhldGljIGluc3RydWN0aW9uIG9wY29kZSB3aXRoIHNlbWFudGljIGNvbnRleHQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvcGNvZGUgLSBXYXNtIG9wY29kZS5cbiAgICogQHBhcmFtIHtTZW1hbnRpY05vZGV9IG5vZGUgLSBSZWxhdGVkIHNlbWFudGljIG5vZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gTm9kZSBvY2N1cnJlbmNlIHBhdGguXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb24gLSBTeW50aGV0aWMgcHJvdmVuYW5jZSByZWFzb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgc3ludGhldGljT3Aob3Bjb2RlLCBub2RlLCBwYXRoLCByZWFzb24pIHsgdGhpcy53cml0ZXIuc3ludGhldGljKFtvcGNvZGVdLCByZWFzb24sIHtub2RlLCBwYXRofSwgXCJpbnN0cnVjdGlvblwiKSB9XG5cbiAgLyoqXG4gICAqIFdyaXRlcyBhIHN5bnRoZXRpYyBpbW1lZGlhdGUgd2l0aCBzZW1hbnRpYyBjb250ZXh0LlxuICAgKiBAcGFyYW0ge251bWJlcltdfSBieXRlcyAtIEVuY29kZWQgaW1tZWRpYXRlIGJ5dGVzLlxuICAgKiBAcGFyYW0ge1NlbWFudGljTm9kZX0gbm9kZSAtIFJlbGF0ZWQgc2VtYW50aWMgbm9kZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBOb2RlIG9jY3VycmVuY2UgcGF0aC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHJlYXNvbiAtIFN5bnRoZXRpYyBwcm92ZW5hbmNlIHJlYXNvbi5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBzeW50aGV0aWNJbW1lZGlhdGUoYnl0ZXMsIG5vZGUsIHBhdGgsIHJlYXNvbikgeyB0aGlzLndyaXRlci5zeW50aGV0aWMoYnl0ZXMsIHJlYXNvbiwge25vZGUsIHBhdGh9LCBcImltbWVkaWF0ZVwiKSB9XG5cbiAgLyoqXG4gICAqIFdyaXRlcyBhIHN5bnRoZXRpYyBpMzIgY29uc3RhbnQgaW5zdHJ1Y3Rpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSAtIENvbnN0YW50IHZhbHVlLlxuICAgKiBAcGFyYW0ge1NlbWFudGljTm9kZX0gbm9kZSAtIFJlbGF0ZWQgc2VtYW50aWMgbm9kZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBOb2RlIG9jY3VycmVuY2UgcGF0aC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHJlYXNvbiAtIFN5bnRoZXRpYyBwcm92ZW5hbmNlIHJlYXNvbi5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBzeW50aGV0aWNJMzIodmFsdWUsIG5vZGUsIHBhdGgsIHJlYXNvbikge1xuICAgIHRoaXMuc3ludGhldGljT3AoMHg0MSwgbm9kZSwgcGF0aCwgcmVhc29uKVxuICAgIHRoaXMuc3ludGhldGljSW1tZWRpYXRlKHMzMih2YWx1ZSksIG5vZGUsIHBhdGgsIGAke3JlYXNvbn0gaW1tZWRpYXRlYClcbiAgfVxuXG4gIC8qKlxuICAgKiBXcml0ZXMgYSBzeW50aGV0aWMgZ2xvYmFsIGFzc2lnbm1lbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIEdsb2JhbCBpbmRleC5cbiAgICogQHBhcmFtIHtTZW1hbnRpY05vZGV9IG5vZGUgLSBSZWxhdGVkIHNlbWFudGljIG5vZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gTm9kZSBvY2N1cnJlbmNlIHBhdGguXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb24gLSBTeW50aGV0aWMgcHJvdmVuYW5jZSByZWFzb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgc3ludGhldGljR2xvYmFsU2V0KGluZGV4LCBub2RlLCBwYXRoLCByZWFzb24pIHtcbiAgICB0aGlzLnN5bnRoZXRpY09wKDB4MjQsIG5vZGUsIHBhdGgsIGBzZXQgJHtyZWFzb259YClcbiAgICB0aGlzLnN5bnRoZXRpY0ltbWVkaWF0ZSh1MzIoaW5kZXgpLCBub2RlLCBwYXRoLCBgJHtyZWFzb259IGdsb2JhbCBpbmRleGApXG4gIH1cblxuICAvKipcbiAgICogV3JpdGVzIGEgc3ludGhldGljIGZ1bmN0aW9uLWVuZCBpbnN0cnVjdGlvbi5cbiAgICogQHBhcmFtIHtTZW1hbnRpY05vZGV9IG5vZGUgLSBSZWxhdGVkIHNlbWFudGljIG5vZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gTm9kZSBvY2N1cnJlbmNlIHBhdGguXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgc3ludGhldGljRW5kKG5vZGUsIHBhdGgpIHsgdGhpcy5zeW50aGV0aWNPcCgweDBiLCBub2RlLCBwYXRoLCBcImZ1bmN0aW9uIGVuZFwiKSB9XG5cbiAgLyoqXG4gICAqIFdyaXRlcyBhIHN5bnRoZXRpYyB1bnJlYWNoYWJsZSBpbnN0cnVjdGlvbi5cbiAgICogQHBhcmFtIHtTZW1hbnRpY05vZGV9IG5vZGUgLSBSZWxhdGVkIHNlbWFudGljIG5vZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gTm9kZSBvY2N1cnJlbmNlIHBhdGguXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgc3ludGhldGljVW5yZWFjaGFibGUobm9kZSwgcGF0aCkgeyB0aGlzLnN5bnRoZXRpY09wKDB4MDAsIG5vZGUsIHBhdGgsIFwidmFsaWRhdGVkIG5vbi12b2lkIGZhbGx0aHJvdWdoIHRyYXBcIikgfVxufVxuXG4vKiogQnl0ZSB3cml0ZXIgdGhhdCBwcmVzZXJ2ZXMgb25lIG5vbi1vdmVybGFwcGluZyBwcm92ZW5hbmNlIGFubm90YXRpb24gcGVyIHdyaXRlLiAqL1xuY2xhc3MgQmluYXJ5V3JpdGVyIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gYW5ub3RhdGVkIGJpbmFyeSB3cml0ZXIuXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlR2VuZXJhdGlvbkluZGV4Pn0gaW5kZXggLSBDYW5vbmljYWwgcHJvdmVuYW5jZSBpbmRleC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKGluZGV4KSB7XG4gICAgdGhpcy5pbmRleCA9IGluZGV4XG4gICAgLyoqIEB0eXBlIHtudW1iZXJbXX0gKi9cbiAgICB0aGlzLmJ5dGVzID0gW11cbiAgICAvKiogQHR5cGUge0dlbmVyYXRlZEJ5dGVSYW5nZVtdfSAqL1xuICAgIHRoaXMucmFuZ2VzID0gW11cbiAgfVxuXG4gIC8qKlxuICAgKiBXcml0ZXMgc291cmNlLWJhY2tlZCBieXRlcy5cbiAgICogQHBhcmFtIHtudW1iZXJbXSB8IFVpbnQ4QXJyYXl9IGJ5dGVzIC0gRXhhY3QgYnl0ZXMuXG4gICAqIEBwYXJhbSB7U2VtYW50aWNOb2RlfSBub2RlIC0gU2VtYW50aWMgbm9kZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBPY2N1cnJlbmNlIHBhdGguXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByb2xlIC0gQmluYXJ5IHJvbGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbc291cmNlUm9sZV0gLSBFeGFjdCBwYXJzZXItb3duZWQgdG9rZW4gcm9sZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBtYXBwZWQoYnl0ZXMsIG5vZGUsIHBhdGgsIHJvbGUsIHNvdXJjZVJvbGUpIHtcbiAgICBjb25zdCByZWNvcmQgPSB0aGlzLmluZGV4LnJlY29yZEZvcihub2RlLCBwYXRoKVxuICAgIGNvbnN0IG9yaWdpbiA9IHNvdXJjZVJvbGUgPyBvcmlnaW5Gb3JSb2xlKHRoaXMuaW5kZXgsIHJlY29yZCwgc291cmNlUm9sZSkgOiByZWNvcmQub3JpZ2luXG5cbiAgICB0aGlzLndyaXRlKGJ5dGVzLCB7bm9kZUlkOiByZWNvcmQuaWQsIG9yaWdpbiwgcm9sZSwgc3ltYm9sSWQ6IHJlY29yZC5zeW1ib2xJZH0pXG4gIH1cblxuICAvKipcbiAgICogV3JpdGVzIGV4cGxpY2l0IGJhY2tlbmQgc2NhZmZvbGRpbmcgYnl0ZXMuXG4gICAqIEBwYXJhbSB7bnVtYmVyW10gfCBVaW50OEFycmF5fSBieXRlcyAtIEV4YWN0IGJ5dGVzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVhc29uIC0gU3ludGhldGljIHJlYXNvbi5cbiAgICogQHBhcmFtIHt7bm9kZTogU2VtYW50aWNOb2RlLCBwYXRoOiBzdHJpbmd9fSByZWxhdGVkIC0gUmVsYXRlZCBvY2N1cnJlbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcm9sZSAtIEJpbmFyeSByb2xlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHN5bnRoZXRpYyhieXRlcywgcmVhc29uLCByZWxhdGVkLCByb2xlKSB7XG4gICAgY29uc3QgcmVjb3JkID0gdGhpcy5pbmRleC5yZWNvcmRGb3IocmVsYXRlZC5ub2RlLCByZWxhdGVkLnBhdGgpXG5cbiAgICB0aGlzLndyaXRlKGJ5dGVzLCB7XG4gICAgICBvcmlnaW46IHtraW5kOiBcInN5bnRoZXRpY1wiLCByZWFzb24sIHJlbGF0ZWRPcmlnaW5zOiByZWxhdGVkT3JpZ2lucyhyZWNvcmQpfSxcbiAgICAgIHJvbGVcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGVuZHMgYW5vdGhlciBhbm5vdGF0ZWQgd3JpdGVyLlxuICAgKiBAcGFyYW0ge0JpbmFyeVdyaXRlcn0gY2hpbGQgLSBDaGlsZCBieXRlcy5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBhcHBlbmQoY2hpbGQpIHtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLmJ5dGVzLmxlbmd0aFxuXG4gICAgZm9yIChjb25zdCBieXRlIG9mIGNoaWxkLmJ5dGVzKSB0aGlzLmJ5dGVzLnB1c2goYnl0ZSlcbiAgICBmb3IgKGNvbnN0IHJhbmdlIG9mIGNoaWxkLnJhbmdlcykge1xuICAgICAgdGhpcy5yYW5nZXMucHVzaCh7Li4ucmFuZ2UsIGdlbmVyYXRlZDoge3N0YXJ0OiByYW5nZS5nZW5lcmF0ZWQuc3RhcnQgKyBvZmZzZXQsIGVuZDogcmFuZ2UuZ2VuZXJhdGVkLmVuZCArIG9mZnNldH19KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGRldGFjaGVkIGVuY29kZWQgYnl0ZXMuXG4gICAqIEByZXR1cm5zIHtVaW50OEFycmF5fSBEZXRhY2hlZCBieXRlcy5cbiAgICovXG4gIGZpbmlzaCgpIHsgcmV0dXJuIFVpbnQ4QXJyYXkuZnJvbSh0aGlzLmJ5dGVzKSB9XG5cbiAgLyoqXG4gICAqIFdyaXRlcyBvbmUgbm9uLWVtcHR5IGFubm90YXRlZCByYW5nZS5cbiAgICogQHBhcmFtIHtudW1iZXJbXSB8IFVpbnQ4QXJyYXl9IGJ5dGVzIC0gRXhhY3QgYnl0ZXMuXG4gICAqIEBwYXJhbSB7T21pdDxHZW5lcmF0ZWRCeXRlUmFuZ2UsIFwiZ2VuZXJhdGVkXCI+fSBhbm5vdGF0aW9uIC0gUHJvdmVuYW5jZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICB3cml0ZShieXRlcywgYW5ub3RhdGlvbikge1xuICAgIGlmIChieXRlcy5sZW5ndGggPT0gMCkgcmV0dXJuXG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmJ5dGVzLmxlbmd0aFxuXG4gICAgZm9yIChjb25zdCBieXRlIG9mIGJ5dGVzKSB7XG4gICAgICBpZiAoIU51bWJlci5pc0ludGVnZXIoYnl0ZSkgfHwgYnl0ZSA8IDAgfHwgYnl0ZSA+IDI1NSkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIFdlYkFzc2VtYmx5IGJ5dGUuXCIpXG4gICAgICB0aGlzLmJ5dGVzLnB1c2goYnl0ZSlcbiAgICB9XG4gICAgdGhpcy5yYW5nZXMucHVzaCh7Li4uYW5ub3RhdGlvbiwgZ2VuZXJhdGVkOiB7c3RhcnQsIGVuZDogdGhpcy5ieXRlcy5sZW5ndGh9fSlcbiAgfVxufVxuXG4vKiogRGV0ZXJtaW5pc3RpYyBmdW5jdGlvbi10eXBlIGludGVybmVyLiAqL1xuY2xhc3MgVHlwZVBvb2wge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvKiogQHR5cGUge3twYXJhbWV0ZXJzOiAoXCJpMzJcIiB8IFwiaTY0XCIpW10sIHJlc3VsdHM6IChcImkzMlwiIHwgXCJpNjRcIilbXX1bXX0gKi9cbiAgICB0aGlzLmVudHJpZXMgPSBbXVxuICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgbnVtYmVyPn0gKi9cbiAgICB0aGlzLmluZGV4ZXMgPSBuZXcgTWFwKClcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnRlcm5zIG9uZSBmdW5jdGlvbiB0eXBlLlxuICAgKiBAcGFyYW0geyhcImkzMlwiIHwgXCJpNjRcIilbXX0gcGFyYW1ldGVycyAtIFBhcmFtZXRlcnMuXG4gICAqIEBwYXJhbSB7KFwiaTMyXCIgfCBcImk2NFwiKVtdfSByZXN1bHRzIC0gUmVzdWx0cy5cbiAgICogQHJldHVybnMge251bWJlcn0gVHlwZSBpbmRleC5cbiAgICovXG4gIGFkZChwYXJhbWV0ZXJzLCByZXN1bHRzKSB7XG4gICAgY29uc3Qga2V5ID0gYCR7cGFyYW1ldGVycy5qb2luKFwiLFwiKX0tPiR7cmVzdWx0cy5qb2luKFwiLFwiKX1gXG4gICAgY29uc3QgcHJpb3IgPSB0aGlzLmluZGV4ZXMuZ2V0KGtleSlcblxuICAgIGlmIChwcmlvciAhPT0gdW5kZWZpbmVkKSByZXR1cm4gcHJpb3JcbiAgICBjb25zdCBpbmRleCA9IHRoaXMuZW50cmllcy5sZW5ndGhcblxuICAgIHRoaXMuZW50cmllcy5wdXNoKHtwYXJhbWV0ZXJzLCByZXN1bHRzfSlcbiAgICB0aGlzLmluZGV4ZXMuc2V0KGtleSwgaW5kZXgpXG5cbiAgICByZXR1cm4gaW5kZXhcbiAgfVxufVxuXG4vKipcbiAqIEVuY29kZXMgdGhlIGZ1bmN0aW9uLXR5cGUgc2VjdGlvbiBwYXlsb2FkLlxuICogQHBhcmFtIHtUeXBlUG9vbH0gdHlwZXMgLSBJbnRlcm5lZCBmdW5jdGlvbiB0eXBlcy5cbiAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlR2VuZXJhdGlvbkluZGV4Pn0gaW5kZXggLSBQcm92ZW5hbmNlIGluZGV4LlxuICogQHBhcmFtIHt7bm9kZTogU2VtYW50aWNOb2RlLCBwYXRoOiBzdHJpbmd9fSByb290IC0gUmVsYXRlZCBtb2R1bGUgb2NjdXJyZW5jZS5cbiAqIEByZXR1cm5zIHtCaW5hcnlXcml0ZXJ9IEVuY29kZWQgcGF5bG9hZC5cbiAqL1xuZnVuY3Rpb24gZW5jb2RlVHlwZVNlY3Rpb24odHlwZXMsIGluZGV4LCByb290KSB7XG4gIGNvbnN0IHdyaXRlciA9IG5ldyBCaW5hcnlXcml0ZXIoaW5kZXgpXG5cbiAgd3JpdGVyLnN5bnRoZXRpYyh1MzIodHlwZXMuZW50cmllcy5sZW5ndGgpLCBcIkZ1bmN0aW9uIHR5cGUgY291bnRcIiwgcm9vdCwgXCJ0eXBlIGNvdW50XCIpXG4gIGZvciAoY29uc3QgdHlwZSBvZiB0eXBlcy5lbnRyaWVzKSB7XG4gICAgd3JpdGVyLnN5bnRoZXRpYyhbMHg2MF0sIFwiRnVuY3Rpb24gdHlwZSBmb3JtXCIsIHJvb3QsIFwidHlwZSBmb3JtXCIpXG4gICAgd3JpdGVyLnN5bnRoZXRpYyh1MzIodHlwZS5wYXJhbWV0ZXJzLmxlbmd0aCksIFwiRnVuY3Rpb24gcGFyYW1ldGVyIGNvdW50XCIsIHJvb3QsIFwidHlwZSBwYXJhbWV0ZXIgY291bnRcIilcbiAgICBmb3IgKGNvbnN0IHBhcmFtZXRlciBvZiB0eXBlLnBhcmFtZXRlcnMpIHdyaXRlci5zeW50aGV0aWMoW3ZhbHVlVHlwZXNbcGFyYW1ldGVyXV0sIFwiRnVuY3Rpb24gcGFyYW1ldGVyIHZhbHVlIHR5cGVcIiwgcm9vdCwgXCJ2YWx1ZSB0eXBlXCIpXG4gICAgd3JpdGVyLnN5bnRoZXRpYyh1MzIodHlwZS5yZXN1bHRzLmxlbmd0aCksIFwiRnVuY3Rpb24gcmVzdWx0IGNvdW50XCIsIHJvb3QsIFwidHlwZSByZXN1bHQgY291bnRcIilcbiAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiB0eXBlLnJlc3VsdHMpIHdyaXRlci5zeW50aGV0aWMoW3ZhbHVlVHlwZXNbcmVzdWx0XV0sIFwiRnVuY3Rpb24gcmVzdWx0IHZhbHVlIHR5cGVcIiwgcm9vdCwgXCJ2YWx1ZSB0eXBlXCIpXG4gIH1cblxuICByZXR1cm4gd3JpdGVyXG59XG5cbi8qKlxuICogRW5jb2RlcyB0aGUgZml4ZWQgQUJJIGltcG9ydCBzZWN0aW9uIHBheWxvYWQuXG4gKiBAcGFyYW0ge251bWJlcltdfSB0eXBlSW5kZXhlcyAtIEltcG9ydCBmdW5jdGlvbiB0eXBlIGluZGV4ZXMuXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIGNyZWF0ZUdlbmVyYXRpb25JbmRleD59IGluZGV4IC0gUHJvdmVuYW5jZSBpbmRleC5cbiAqIEBwYXJhbSB7e25vZGU6IFNlbWFudGljTm9kZSwgcGF0aDogc3RyaW5nfX0gcm9vdCAtIFJlbGF0ZWQgbW9kdWxlIG9jY3VycmVuY2UuXG4gKiBAcmV0dXJucyB7QmluYXJ5V3JpdGVyfSBFbmNvZGVkIHBheWxvYWQuXG4gKi9cbmZ1bmN0aW9uIGVuY29kZUltcG9ydFNlY3Rpb24odHlwZUluZGV4ZXMsIGluZGV4LCByb290KSB7XG4gIGNvbnN0IHdyaXRlciA9IG5ldyBCaW5hcnlXcml0ZXIoaW5kZXgpXG4gIGNvbnN0IG5hbWVzID0gW1wicHJpbnRfaTY0XCIsIFwicHJpbnRfYm9vbFwiLCBcInByaW50X3N0cmluZ1wiXVxuXG4gIHdyaXRlci5zeW50aGV0aWModTMyKG5hbWVzLmxlbmd0aCksIFwiQUJJIGltcG9ydCBjb3VudFwiLCByb290LCBcImltcG9ydCBjb3VudFwiKVxuICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBuYW1lcy5sZW5ndGg7IG9mZnNldCArPSAxKSB7XG4gICAgd3JpdGVyLnN5bnRoZXRpYyhuYW1lQnl0ZXMoXCJzZW1hbnRpZm9sZFwiKSwgXCJBQkkgaW1wb3J0IG1vZHVsZSBuYW1lXCIsIHJvb3QsIFwiaW1wb3J0IG1vZHVsZVwiKVxuICAgIHdyaXRlci5zeW50aGV0aWMobmFtZUJ5dGVzKG5hbWVzW29mZnNldF0pLCBcIkFCSSBpbXBvcnQgZnVuY3Rpb24gbmFtZVwiLCByb290LCBcImltcG9ydCBuYW1lXCIpXG4gICAgd3JpdGVyLnN5bnRoZXRpYyhbMHgwMF0sIFwiRnVuY3Rpb24gaW1wb3J0IGtpbmRcIiwgcm9vdCwgXCJpbXBvcnQga2luZFwiKVxuICAgIHdyaXRlci5zeW50aGV0aWModTMyKHR5cGVJbmRleGVzW29mZnNldF0pLCBcIkFCSSBpbXBvcnQgdHlwZSBpbmRleFwiLCByb290LCBcInR5cGUgaW5kZXhcIilcbiAgfVxuXG4gIHJldHVybiB3cml0ZXJcbn1cblxuLyoqXG4gKiBFbmNvZGVzIGRlZmluZWQtZnVuY3Rpb24gdHlwZSBpbmRleGVzLlxuICogQHBhcmFtIHtudW1iZXJbXX0gaGVscGVyVHlwZXMgLSBQcml2YXRlIGhlbHBlciB0eXBlIGluZGV4ZXMuXG4gKiBAcGFyYW0ge251bWJlcltdfSBzZW1hbnRpY1R5cGVzIC0gU2VtYW50aWMgZnVuY3Rpb24gdHlwZSBpbmRleGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IHJ1blR5cGUgLSBFeHBvcnRlZCBydW4gZnVuY3Rpb24gdHlwZSBpbmRleC5cbiAqIEBwYXJhbSB7U2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFNlbWFudGljIG1vZHVsZS5cbiAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlR2VuZXJhdGlvbkluZGV4Pn0gaW5kZXggLSBQcm92ZW5hbmNlIGluZGV4LlxuICogQHJldHVybnMge0JpbmFyeVdyaXRlcn0gRW5jb2RlZCBwYXlsb2FkLlxuICovXG5mdW5jdGlvbiBlbmNvZGVGdW5jdGlvblNlY3Rpb24oaGVscGVyVHlwZXMsIHNlbWFudGljVHlwZXMsIHJ1blR5cGUsIG1vZHVsZSwgaW5kZXgpIHtcbiAgY29uc3Qgd3JpdGVyID0gbmV3IEJpbmFyeVdyaXRlcihpbmRleClcbiAgY29uc3Qgcm9vdCA9IHtub2RlOiBtb2R1bGUsIHBhdGg6IFwiXCJ9XG5cbiAgd3JpdGVyLnN5bnRoZXRpYyh1MzIoaGVscGVyVHlwZXMubGVuZ3RoICsgc2VtYW50aWNUeXBlcy5sZW5ndGggKyAxKSwgXCJEZWZpbmVkIGZ1bmN0aW9uIGNvdW50XCIsIHJvb3QsIFwiZnVuY3Rpb24gY291bnRcIilcbiAgZm9yIChjb25zdCB0eXBlSW5kZXggb2YgaGVscGVyVHlwZXMpIHdyaXRlci5zeW50aGV0aWModTMyKHR5cGVJbmRleCksIFwiUHJpdmF0ZSBBQkkgaGVscGVyIHR5cGUgaW5kZXhcIiwgcm9vdCwgXCJ0eXBlIGluZGV4XCIpXG4gIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IHNlbWFudGljVHlwZXMubGVuZ3RoOyBvZmZzZXQgKz0gMSkge1xuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gbW9kdWxlLmZ1bmN0aW9uc1tvZmZzZXRdXG5cbiAgICB3cml0ZXIuc3ludGhldGljKHUzMihzZW1hbnRpY1R5cGVzW29mZnNldF0pLCBcIlNlbWFudGljIGZ1bmN0aW9uIHR5cGUgaW5kZXhcIiwge25vZGU6IGRlY2xhcmF0aW9uLCBwYXRoOiBgL2Z1bmN0aW9ucy8ke29mZnNldH1gfSwgXCJ0eXBlIGluZGV4XCIpXG4gIH1cbiAgd3JpdGVyLnN5bnRoZXRpYyh1MzIocnVuVHlwZSksIFwiRXhwb3J0ZWQgcnVuIHR5cGUgaW5kZXhcIiwge25vZGU6IG1vZHVsZS5lbnRyeVBvaW50LCBwYXRoOiBcIi9lbnRyeVBvaW50XCJ9LCBcInR5cGUgaW5kZXhcIilcblxuICByZXR1cm4gd3JpdGVyXG59XG5cbi8qKlxuICogRW5jb2RlcyBvbmUgZml4ZWQtbWVtb3J5IGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IHBhZ2VzIC0gRXF1YWwgaW5pdGlhbCBhbmQgbWF4aW11bSBwYWdlIGNvdW50LlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVHZW5lcmF0aW9uSW5kZXg+fSBpbmRleCAtIFByb3ZlbmFuY2UgaW5kZXguXG4gKiBAcGFyYW0ge3tub2RlOiBTZW1hbnRpY05vZGUsIHBhdGg6IHN0cmluZ319IHJvb3QgLSBSZWxhdGVkIG1vZHVsZSBvY2N1cnJlbmNlLlxuICogQHJldHVybnMge0JpbmFyeVdyaXRlcn0gRW5jb2RlZCBwYXlsb2FkLlxuICovXG5mdW5jdGlvbiBlbmNvZGVNZW1vcnlTZWN0aW9uKHBhZ2VzLCBpbmRleCwgcm9vdCkge1xuICBjb25zdCB3cml0ZXIgPSBuZXcgQmluYXJ5V3JpdGVyKGluZGV4KVxuXG4gIHdyaXRlci5zeW50aGV0aWModTMyKDEpLCBcIlNpbmdsZSBmaXhlZCBsaW5lYXIgbWVtb3J5XCIsIHJvb3QsIFwibWVtb3J5IGNvdW50XCIpXG4gIHdyaXRlci5zeW50aGV0aWMoWzB4MDFdLCBcIk1lbW9yeSBsaW1pdHMgaW5jbHVkZSBlcXVhbCBtYXhpbXVtXCIsIHJvb3QsIFwibWVtb3J5IGxpbWl0cyBmbGFnc1wiKVxuICB3cml0ZXIuc3ludGhldGljKHUzMihwYWdlcyksIFwiSW5pdGlhbCBtZW1vcnkgcGFnZSBjb3VudFwiLCByb290LCBcIm1lbW9yeSBpbml0aWFsIHBhZ2VzXCIpXG4gIHdyaXRlci5zeW50aGV0aWModTMyKHBhZ2VzKSwgXCJNYXhpbXVtIG1lbW9yeSBwYWdlIGNvdW50XCIsIHJvb3QsIFwibWVtb3J5IG1heGltdW0gcGFnZXNcIilcblxuICByZXR1cm4gd3JpdGVyXG59XG5cbi8qKlxuICogRW5jb2RlcyBwcml2YXRlIG11dGFibGUgQUJJIGdsb2JhbHMuXG4gKiBAcGFyYW0ge251bWJlcn0gc2NyYXRjaEJhc2UgLSBJbml0aWFsIHNjcmF0Y2ggY3Vyc29yLlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVHZW5lcmF0aW9uSW5kZXg+fSBpbmRleCAtIFByb3ZlbmFuY2UgaW5kZXguXG4gKiBAcGFyYW0ge3tub2RlOiBTZW1hbnRpY05vZGUsIHBhdGg6IHN0cmluZ319IHJvb3QgLSBSZWxhdGVkIG1vZHVsZSBvY2N1cnJlbmNlLlxuICogQHJldHVybnMge0JpbmFyeVdyaXRlcn0gRW5jb2RlZCBwYXlsb2FkLlxuICovXG5mdW5jdGlvbiBlbmNvZGVHbG9iYWxTZWN0aW9uKHNjcmF0Y2hCYXNlLCBpbmRleCwgcm9vdCkge1xuICBjb25zdCB3cml0ZXIgPSBuZXcgQmluYXJ5V3JpdGVyKGluZGV4KVxuICBjb25zdCBnbG9iYWxzID0gW1xuICAgIHtpbml0aWFsOiBzY3JhdGNoQmFzZSwgcmVhc29uOiBcIlByaXZhdGUgc2NyYXRjaCBjdXJzb3JcIn0sXG4gICAge2luaXRpYWw6IDAsIHJlYXNvbjogXCJQcml2YXRlIHNlbWFudGljIGNhbGwgZGVwdGhcIn0sXG4gICAge2luaXRpYWw6IDAsIHJlYXNvbjogXCJQcml2YXRlIHJ1biBhY3RpdmUgZ3VhcmRcIn1cbiAgXVxuXG4gIHdyaXRlci5zeW50aGV0aWModTMyKGdsb2JhbHMubGVuZ3RoKSwgXCJQcml2YXRlIG11dGFibGUgZ2xvYmFsIGNvdW50XCIsIHJvb3QsIFwiZ2xvYmFsIGNvdW50XCIpXG4gIGZvciAoY29uc3QgZ2xvYmFsIG9mIGdsb2JhbHMpIHtcbiAgICB3cml0ZXIuc3ludGhldGljKFt2YWx1ZVR5cGVzLmkzMiwgMHgwMV0sIGAke2dsb2JhbC5yZWFzb259IHR5cGUgYW5kIG11dGFiaWxpdHlgLCByb290LCBcImdsb2JhbCB0eXBlXCIpXG4gICAgd3JpdGVyLnN5bnRoZXRpYyhbMHg0MV0sIGAke2dsb2JhbC5yZWFzb259IGluaXRpYWxpemVyIGluc3RydWN0aW9uYCwgcm9vdCwgXCJpbnN0cnVjdGlvblwiKVxuICAgIHdyaXRlci5zeW50aGV0aWMoczMyKGdsb2JhbC5pbml0aWFsKSwgYCR7Z2xvYmFsLnJlYXNvbn0gaW5pdGlhbGl6ZXIgaW1tZWRpYXRlYCwgcm9vdCwgXCJpbW1lZGlhdGVcIilcbiAgICB3cml0ZXIuc3ludGhldGljKFsweDBiXSwgYCR7Z2xvYmFsLnJlYXNvbn0gaW5pdGlhbGl6ZXIgZW5kYCwgcm9vdCwgXCJpbnN0cnVjdGlvblwiKVxuICB9XG5cbiAgcmV0dXJuIHdyaXRlclxufVxuXG4vKipcbiAqIEVuY29kZXMgZXhhY3RseSB0aGUgcHVibGljIG1lbW9yeSBhbmQgcnVuIGV4cG9ydHMuXG4gKiBAcGFyYW0ge251bWJlcn0gcnVuSW5kZXggLSBFeHBvcnRlZCBydW4gZnVuY3Rpb24gaW5kZXguXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIGNyZWF0ZUdlbmVyYXRpb25JbmRleD59IGluZGV4IC0gUHJvdmVuYW5jZSBpbmRleC5cbiAqIEBwYXJhbSB7e25vZGU6IFNlbWFudGljTm9kZSwgcGF0aDogc3RyaW5nfX0gcm9vdCAtIFJlbGF0ZWQgbW9kdWxlIG9jY3VycmVuY2UuXG4gKiBAcmV0dXJucyB7QmluYXJ5V3JpdGVyfSBFbmNvZGVkIHBheWxvYWQuXG4gKi9cbmZ1bmN0aW9uIGVuY29kZUV4cG9ydFNlY3Rpb24ocnVuSW5kZXgsIGluZGV4LCByb290KSB7XG4gIGNvbnN0IHdyaXRlciA9IG5ldyBCaW5hcnlXcml0ZXIoaW5kZXgpXG5cbiAgd3JpdGVyLnN5bnRoZXRpYyh1MzIoMiksIFwiRXhhY3QgQUJJIGV4cG9ydCBjb3VudFwiLCByb290LCBcImV4cG9ydCBjb3VudFwiKVxuICB3cml0ZXIuc3ludGhldGljKG5hbWVCeXRlcyhcIm1lbW9yeVwiKSwgXCJFeHBvcnRlZCBtZW1vcnkgbmFtZVwiLCByb290LCBcImV4cG9ydCBuYW1lXCIpXG4gIHdyaXRlci5zeW50aGV0aWMoWzB4MDJdLCBcIk1lbW9yeSBleHBvcnQga2luZFwiLCByb290LCBcImV4cG9ydCBraW5kXCIpXG4gIHdyaXRlci5zeW50aGV0aWModTMyKDApLCBcIkV4cG9ydGVkIG1lbW9yeSBpbmRleFwiLCByb290LCBcIm1lbW9yeSBpbmRleFwiKVxuICB3cml0ZXIuc3ludGhldGljKG5hbWVCeXRlcyhcInJ1blwiKSwgXCJFeHBvcnRlZCBydW4gbmFtZVwiLCByb290LCBcImV4cG9ydCBuYW1lXCIpXG4gIHdyaXRlci5zeW50aGV0aWMoWzB4MDBdLCBcIkZ1bmN0aW9uIGV4cG9ydCBraW5kXCIsIHJvb3QsIFwiZXhwb3J0IGtpbmRcIilcbiAgd3JpdGVyLnN5bnRoZXRpYyh1MzIocnVuSW5kZXgpLCBcIkV4cG9ydGVkIHJ1biBmdW5jdGlvbiBpbmRleFwiLCByb290LCBcImZ1bmN0aW9uIGluZGV4XCIpXG5cbiAgcmV0dXJuIHdyaXRlclxufVxuXG4vKipcbiAqIEVuY29kZXMgaW1tdXRhYmxlIFVURi04IGxpdGVyYWwgZGF0YSBzZWdtZW50cy5cbiAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgY29sbGVjdExpdGVyYWxMYXlvdXQ+W1wiZW50cmllc1wiXX0gZW50cmllcyAtIE9yZGVyZWQgbGl0ZXJhbCBlbnRyaWVzLlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVHZW5lcmF0aW9uSW5kZXg+fSBpbmRleCAtIFByb3ZlbmFuY2UgaW5kZXguXG4gKiBAcGFyYW0ge3tub2RlOiBTZW1hbnRpY05vZGUsIHBhdGg6IHN0cmluZ319IHJvb3QgLSBSZWxhdGVkIG1vZHVsZSBvY2N1cnJlbmNlLlxuICogQHJldHVybnMge0JpbmFyeVdyaXRlcn0gRW5jb2RlZCBwYXlsb2FkLlxuICovXG5mdW5jdGlvbiBlbmNvZGVEYXRhU2VjdGlvbihlbnRyaWVzLCBpbmRleCwgcm9vdCkge1xuICBjb25zdCB3cml0ZXIgPSBuZXcgQmluYXJ5V3JpdGVyKGluZGV4KVxuICBjb25zdCBub25lbXB0eSA9IGVudHJpZXMuZmlsdGVyKCh7Ynl0ZXN9KSA9PiBieXRlcy5ieXRlTGVuZ3RoID4gMClcblxuICB3cml0ZXIuc3ludGhldGljKHUzMihub25lbXB0eS5sZW5ndGgpLCBcIkltbXV0YWJsZSBsaXRlcmFsIGRhdGEgc2VnbWVudCBjb3VudFwiLCByb290LCBcImRhdGEgc2VnbWVudCBjb3VudFwiKVxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIG5vbmVtcHR5KSB7XG4gICAgd3JpdGVyLnN5bnRoZXRpYyhbMHgwMCwgMHg0MV0sIFwiQWN0aXZlIGxpdGVyYWwgZGF0YSBzZWdtZW50IGFuZCBvZmZzZXQgaW5zdHJ1Y3Rpb25cIiwgcm9vdCwgXCJkYXRhIHNlZ21lbnQgaGVhZGVyXCIpXG4gICAgd3JpdGVyLnN5bnRoZXRpYyhzMzIoZW50cnkuYWRkcmVzcyksIFwiTGl0ZXJhbCBkYXRhIGFkZHJlc3NcIiwgcm9vdCwgXCJkYXRhIHNlZ21lbnQgb2Zmc2V0XCIpXG4gICAgd3JpdGVyLnN5bnRoZXRpYyhbMHgwYl0sIFwiTGl0ZXJhbCBvZmZzZXQgZXhwcmVzc2lvbiBlbmRcIiwgcm9vdCwgXCJpbnN0cnVjdGlvblwiKVxuICAgIHdyaXRlci5zeW50aGV0aWModTMyKGVudHJ5LmJ5dGVzLmJ5dGVMZW5ndGgpLCBcIkxpdGVyYWwgZGF0YSBieXRlIGxlbmd0aFwiLCByb290LCBcImRhdGEgc2VnbWVudCBsZW5ndGhcIilcbiAgICB3cml0ZXIud3JpdGUoZW50cnkuYnl0ZXMsIHtcbiAgICAgIG9yaWdpbjogZW50cnkub3JpZ2luLFxuICAgICAgcm9sZTogXCJpbW11dGFibGUgVVRGLTggbGl0ZXJhbCBkYXRhXCJcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIHdyaXRlclxufVxuXG4vKipcbiAqIEVuY29kZXMgZGV0ZXJtaW5pc3RpYyBpbnRlcm5hbCBhbmQgc2VtYW50aWMgZnVuY3Rpb24gbmFtZXMuXG4gKiBAcGFyYW0ge1NlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBTZW1hbnRpYyBtb2R1bGUuXG4gKiBAcGFyYW0ge251bWJlcn0gcnVuSW5kZXggLSBFeHBvcnRlZCBydW4gZnVuY3Rpb24gaW5kZXguXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIGNyZWF0ZUdlbmVyYXRpb25JbmRleD59IGluZGV4IC0gUHJvdmVuYW5jZSBpbmRleC5cbiAqIEByZXR1cm5zIHtCaW5hcnlXcml0ZXJ9IEVuY29kZWQgY3VzdG9tLXNlY3Rpb24gcGF5bG9hZC5cbiAqL1xuZnVuY3Rpb24gZW5jb2RlTmFtZVBheWxvYWQobW9kdWxlLCBydW5JbmRleCwgaW5kZXgpIHtcbiAgY29uc3Qgd3JpdGVyID0gbmV3IEJpbmFyeVdyaXRlcihpbmRleClcbiAgY29uc3Qgcm9vdCA9IHtub2RlOiBtb2R1bGUsIHBhdGg6IFwiXCJ9XG4gIGNvbnN0IHN1YnNlY3Rpb24gPSBuZXcgQmluYXJ5V3JpdGVyKGluZGV4KVxuICAvKiogQHR5cGUge3tkZWNsYXJhdGlvbj86IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb24sIGluZGV4OiBudW1iZXIsIG5hbWU6IHN0cmluZywgcGF0aD86IHN0cmluZ31bXX0gKi9cbiAgY29uc3QgbmFtZXMgPSBbXG4gICAgLi4uaGVscGVyTmFtZXMubWFwKChuYW1lLCBvZmZzZXQpID0+ICh7aW5kZXg6IGltcG9ydENvdW50ICsgb2Zmc2V0LCBuYW1lfSkpLFxuICAgIC4uLm1vZHVsZS5mdW5jdGlvbnMubWFwKChkZWNsYXJhdGlvbiwgb2Zmc2V0KSA9PiAoe2RlY2xhcmF0aW9uLCBpbmRleDogaW1wb3J0Q291bnQgKyBoZWxwZXJDb3VudCArIG9mZnNldCwgbmFtZTogZGVjbGFyYXRpb24ubmFtZSwgcGF0aDogYC9mdW5jdGlvbnMvJHtvZmZzZXR9YH0pKSxcbiAgICB7aW5kZXg6IHJ1bkluZGV4LCBuYW1lOiBcInJ1blwifVxuICBdXG5cbiAgc3Vic2VjdGlvbi5zeW50aGV0aWModTMyKG5hbWVzLmxlbmd0aCksIFwiTmFtZWQgZnVuY3Rpb24gY291bnRcIiwgcm9vdCwgXCJuYW1lIGNvdW50XCIpXG4gIGZvciAoY29uc3QgbmFtZSBvZiBuYW1lcykge1xuICAgIHN1YnNlY3Rpb24uc3ludGhldGljKHUzMihuYW1lLmluZGV4KSwgXCJOYW1lZCBmdW5jdGlvbiBpbmRleFwiLCByb290LCBcImZ1bmN0aW9uIGluZGV4XCIpXG4gICAgaWYgKG5hbWUuZGVjbGFyYXRpb24pIHtcbiAgICAgIGNvbnN0IGJ5dGVzID0gZW5jb2Rlci5lbmNvZGUobmFtZS5uYW1lKVxuICAgICAgY29uc3QgcmVsYXRlZCA9IHtub2RlOiBuYW1lLmRlY2xhcmF0aW9uLCBwYXRoOiAvKiogQHR5cGUge3N0cmluZ30gKi8gKG5hbWUucGF0aCl9XG5cbiAgICAgIHN1YnNlY3Rpb24uc3ludGhldGljKHUzMihieXRlcy5ieXRlTGVuZ3RoKSwgXCJTZW1hbnRpYyBmdW5jdGlvbiBuYW1lIGJ5dGUgbGVuZ3RoXCIsIHJlbGF0ZWQsIFwiZnVuY3Rpb24gbmFtZSBsZW5ndGhcIilcbiAgICAgIHN1YnNlY3Rpb24ubWFwcGVkKGJ5dGVzLCBuYW1lLmRlY2xhcmF0aW9uLCByZWxhdGVkLnBhdGgsIFwic2VtYW50aWMgZnVuY3Rpb24gbmFtZVwiLCBcIm5hbWVcIilcbiAgICB9IGVsc2Ugc3Vic2VjdGlvbi5zeW50aGV0aWMobmFtZUJ5dGVzKG5hbWUubmFtZSksIFwiUHJpdmF0ZSBBQkkgZnVuY3Rpb24gbmFtZVwiLCByb290LCBcImZ1bmN0aW9uIG5hbWVcIilcbiAgfVxuICB3cml0ZXIuc3ludGhldGljKFsweDAxXSwgXCJGdW5jdGlvbiBuYW1lcyBzdWJzZWN0aW9uIElEXCIsIHJvb3QsIFwiY3VzdG9tIHN1YnNlY3Rpb24gaWRcIilcbiAgd3JpdGVyLnN5bnRoZXRpYyh1MzIoc3Vic2VjdGlvbi5ieXRlcy5sZW5ndGgpLCBcIkZ1bmN0aW9uIG5hbWVzIHN1YnNlY3Rpb24gc2l6ZVwiLCByb290LCBcImN1c3RvbSBzdWJzZWN0aW9uIHNpemVcIilcbiAgd3JpdGVyLmFwcGVuZChzdWJzZWN0aW9uKVxuXG4gIHJldHVybiB3cml0ZXJcbn1cblxuLyoqXG4gKiBFbmNvZGVzIG9uZSBzb3VyY2UtbWFwIFVSTCBjdXN0b20tc2VjdGlvbiBwYXlsb2FkLlxuICogQHBhcmFtIHtzdHJpbmd9IGNvbnRlbnQgLSBSZWxhdGl2ZSBtYXAgVVJMLlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVHZW5lcmF0aW9uSW5kZXg+fSBpbmRleCAtIFByb3ZlbmFuY2UgaW5kZXguXG4gKiBAcGFyYW0ge3tub2RlOiBTZW1hbnRpY05vZGUsIHBhdGg6IHN0cmluZ319IHJvb3QgLSBSZWxhdGVkIG1vZHVsZSBvY2N1cnJlbmNlLlxuICogQHJldHVybnMge0JpbmFyeVdyaXRlcn0gRW5jb2RlZCBwYXlsb2FkLlxuICovXG5mdW5jdGlvbiBuYW1lZFBheWxvYWQoY29udGVudCwgaW5kZXgsIHJvb3QpIHtcbiAgY29uc3Qgd3JpdGVyID0gbmV3IEJpbmFyeVdyaXRlcihpbmRleClcblxuICB3cml0ZXIuc3ludGhldGljKGVuY29kZXIuZW5jb2RlKGNvbnRlbnQpLCBcIlJlbGF0aXZlIGV4dGVybmFsIFdhc20gc291cmNlLW1hcCBVUkxcIiwgcm9vdCwgXCJjdXN0b20gc2VjdGlvbiBwYXlsb2FkXCIpXG5cbiAgcmV0dXJuIHdyaXRlclxufVxuXG4vKipcbiAqIEFwcGVuZHMgb25lIHNpemVkIG1vZHVsZSBzZWN0aW9uLlxuICogQHBhcmFtIHtCaW5hcnlXcml0ZXJ9IG1vZHVsZVdyaXRlciAtIENvbXBsZXRlIG1vZHVsZSB3cml0ZXIuXG4gKiBAcGFyYW0ge251bWJlcn0gaWQgLSBDb3JlIHNlY3Rpb24gSUQuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIERpYWdub3N0aWMgc2VjdGlvbiBuYW1lLlxuICogQHBhcmFtIHtCaW5hcnlXcml0ZXJ9IHBheWxvYWQgLSBFbmNvZGVkIHNlY3Rpb24gcGF5bG9hZC5cbiAqIEBwYXJhbSB7e25vZGU6IFNlbWFudGljTm9kZSwgcGF0aDogc3RyaW5nfX0gcm9vdCAtIFJlbGF0ZWQgbW9kdWxlIG9jY3VycmVuY2UuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gYXBwZW5kU2VjdGlvbihtb2R1bGVXcml0ZXIsIGlkLCBuYW1lLCBwYXlsb2FkLCByb290KSB7XG4gIG1vZHVsZVdyaXRlci5zeW50aGV0aWMoW2lkXSwgYCR7bmFtZX0gc2VjdGlvbiBJRGAsIHJvb3QsIGAke25hbWV9IHNlY3Rpb25gKVxuICBtb2R1bGVXcml0ZXIuc3ludGhldGljKHUzMihwYXlsb2FkLmJ5dGVzLmxlbmd0aCksIGAke25hbWV9IHNlY3Rpb24gYnl0ZSBsZW5ndGhgLCByb290LCBgJHtuYW1lfSBzZWN0aW9uIGxlbmd0aGApXG4gIG1vZHVsZVdyaXRlci5hcHBlbmQocGF5bG9hZClcbn1cblxuLyoqXG4gKiBBcHBlbmRzIG9uZSBuYW1lZCBjdXN0b20gc2VjdGlvbi5cbiAqIEBwYXJhbSB7QmluYXJ5V3JpdGVyfSB3cml0ZXIgLSBDb21wbGV0ZSBtb2R1bGUgd3JpdGVyLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBDdXN0b20tc2VjdGlvbiBuYW1lLlxuICogQHBhcmFtIHtCaW5hcnlXcml0ZXJ9IHBheWxvYWQgLSBDdXN0b20tc2VjdGlvbiBwYXlsb2FkLlxuICogQHBhcmFtIHt7bm9kZTogU2VtYW50aWNOb2RlLCBwYXRoOiBzdHJpbmd9fSByb290IC0gUmVsYXRlZCBtb2R1bGUgb2NjdXJyZW5jZS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiBhcHBlbmRDdXN0b21TZWN0aW9uKHdyaXRlciwgbmFtZSwgcGF5bG9hZCwgcm9vdCkge1xuICBjb25zdCBjb21wbGV0ZSA9IG5ldyBCaW5hcnlXcml0ZXIod3JpdGVyLmluZGV4KVxuXG4gIGNvbXBsZXRlLnN5bnRoZXRpYyhuYW1lQnl0ZXMobmFtZSksIGBDdXN0b20gc2VjdGlvbiBuYW1lICcke25hbWV9J2AsIHJvb3QsIFwiY3VzdG9tIHNlY3Rpb24gbmFtZVwiKVxuICBjb21wbGV0ZS5hcHBlbmQocGF5bG9hZClcbiAgYXBwZW5kU2VjdGlvbih3cml0ZXIsIDAsIGBjdXN0b20gJHtuYW1lfWAsIGNvbXBsZXRlLCByb290KVxufVxuXG4vKipcbiAqIEFwcGVuZHMgb25lIHNpemVkIGZ1bmN0aW9uIGJvZHkgYW5kIGl0cyBmbGF0dGVuZWQgbG9jYWxzLlxuICogQHBhcmFtIHtCaW5hcnlXcml0ZXJ9IGNvZGUgLSBDb2RlLXNlY3Rpb24gcGF5bG9hZCB3cml0ZXIuXG4gKiBAcGFyYW0ge0JpbmFyeVdyaXRlcn0gaW5zdHJ1Y3Rpb25zIC0gRnVuY3Rpb24gaW5zdHJ1Y3Rpb25zLlxuICogQHBhcmFtIHsoXCJpMzJcIiB8IFwiaTY0XCIpW119IGxvY2FscyAtIEZsYXR0ZW5lZCBsb2NhbCB0eXBlcy5cbiAqIEBwYXJhbSB7e25vZGU6IFNlbWFudGljTm9kZSwgcGF0aDogc3RyaW5nfX0gcmVsYXRlZCAtIFJlbGF0ZWQgc2VtYW50aWMgb2NjdXJyZW5jZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gRnVuY3Rpb24gbmFtZSBmb3IgcHJvdmVuYW5jZS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiBhcHBlbmRGdW5jdGlvbkJvZHkoY29kZSwgaW5zdHJ1Y3Rpb25zLCBsb2NhbHMsIHJlbGF0ZWQsIG5hbWUpIHtcbiAgY29uc3QgYm9keSA9IG5ldyBCaW5hcnlXcml0ZXIoY29kZS5pbmRleClcblxuICBib2R5LnN5bnRoZXRpYyh1MzIobG9jYWxzLmxlbmd0aCksIGBMb2NhbCBkZWNsYXJhdGlvbiBncm91cCBjb3VudCBmb3IgJHtuYW1lfWAsIHJlbGF0ZWQsIFwiZnVuY3Rpb24gbG9jYWxzXCIpXG4gIGZvciAoY29uc3QgbG9jYWwgb2YgbG9jYWxzKSB7XG4gICAgYm9keS5zeW50aGV0aWModTMyKDEpLCBgTG9jYWwgY291bnQgZm9yICR7bmFtZX1gLCByZWxhdGVkLCBcImxvY2FsIGNvdW50XCIpXG4gICAgYm9keS5zeW50aGV0aWMoW3ZhbHVlVHlwZXNbbG9jYWxdXSwgYExvY2FsIHZhbHVlIHR5cGUgZm9yICR7bmFtZX1gLCByZWxhdGVkLCBcImxvY2FsIHR5cGVcIilcbiAgfVxuICBib2R5LmFwcGVuZChpbnN0cnVjdGlvbnMpXG4gIGNvZGUuc3ludGhldGljKHUzMihib2R5LmJ5dGVzLmxlbmd0aCksIGBGdW5jdGlvbiBib2R5IGJ5dGUgbGVuZ3RoIGZvciAke25hbWV9YCwgcmVsYXRlZCwgXCJmdW5jdGlvbiBib2R5IGxlbmd0aFwiKVxuICBjb2RlLmFwcGVuZChib2R5KVxufVxuXG4vKipcbiAqIEVuY29kZXMgY2hlY2tlZCBzY3JhdGNoIGFsbG9jYXRpb24gYW5kIHN0cmluZyBjb25jYXRlbmF0aW9uLlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVHZW5lcmF0aW9uSW5kZXg+fSBpbmRleCAtIFByb3ZlbmFuY2UgaW5kZXguXG4gKiBAcGFyYW0ge1NlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBTZW1hbnRpYyBtb2R1bGUuXG4gKiBAcGFyYW0ge251bWJlcn0gc2NyYXRjaEJhc2UgLSBBcmVuYSBzdGFydCBhZGRyZXNzLlxuICogQHJldHVybnMge0JpbmFyeVdyaXRlcn0gRW5jb2RlZCBoZWxwZXIgYm9keS5cbiAqL1xuZnVuY3Rpb24gaGVscGVyQ29uY2F0KGluZGV4LCBtb2R1bGUsIHNjcmF0Y2hCYXNlKSB7XG4gIGNvbnN0IGUgPSBuZXcgU3ludGhldGljRW1pdHRlcihpbmRleCwgbW9kdWxlLCBcIiRjb25jYXRcIilcbiAgY29uc3QgdG90YWwgPSA0XG4gIGNvbnN0IHN0YXJ0ID0gNVxuICBjb25zdCBlbmQgPSA2XG4gIGNvbnN0IGN1cnNvciA9IDdcblxuICBlLmxvY2FsR2V0KDEpOyBlLmxvY2FsR2V0KDMpOyBlLm9wKDB4NmEsIFwiYWRkIHN0cmluZyBsZW5ndGhzXCIpOyBlLmxvY2FsVGVlKHRvdGFsKVxuICBlLmxvY2FsR2V0KDEpOyBlLm9wKDB4NDksIFwiZGV0ZWN0IHVuc2lnbmVkIHN0cmluZy1sZW5ndGggb3ZlcmZsb3dcIik7IGUudHJhcElmKFwic3RyaW5nLWxlbmd0aCBvdmVyZmxvd1wiKVxuICBlLmdsb2JhbEdldChjdXJzb3JHbG9iYWxJbmRleCk7IGUubG9jYWxUZWUoc3RhcnQpXG4gIGUubG9jYWxHZXQodG90YWwpOyBlLm9wKDB4NmEsIFwiYWRkIHNjcmF0Y2ggY3Vyc29yIGFuZCBhbGxvY2F0aW9uIGxlbmd0aFwiKTsgZS5sb2NhbFRlZShlbmQpXG4gIGUubG9jYWxHZXQoc3RhcnQpOyBlLm9wKDB4NDksIFwiZGV0ZWN0IHVuc2lnbmVkIHNjcmF0Y2gtY3Vyc29yIG92ZXJmbG93XCIpOyBlLnRyYXBJZihcInNjcmF0Y2ggY3Vyc29yIG92ZXJmbG93XCIpXG4gIGUubG9jYWxHZXQoZW5kKTsgZS5pMzIoc2NyYXRjaEJhc2UgKyBzY3JhdGNoQ2FwYWNpdHkpOyBlLm9wKDB4NGIsIFwiY29tcGFyZSBhbGxvY2F0aW9uIGVuZCB3aXRoIGFyZW5hIGVuZFwiKTsgZS50cmFwSWYoXCJzY3JhdGNoIGNhcGFjaXR5IGV4Y2VlZGVkXCIpXG4gIGUuaTMyKDApOyBlLmxvY2FsU2V0KGN1cnNvcilcbiAgZS5jb3B5TG9vcChjdXJzb3IsIDAsIDEsIHN0YXJ0LCB1bmRlZmluZWQpXG4gIGUuaTMyKDApOyBlLmxvY2FsU2V0KGN1cnNvcilcbiAgZS5jb3B5TG9vcChjdXJzb3IsIDIsIDMsIHN0YXJ0LCAxKVxuICBlLmxvY2FsR2V0KGVuZCk7IGUuZ2xvYmFsU2V0KGN1cnNvckdsb2JhbEluZGV4KVxuICBlLmxvY2FsR2V0KHN0YXJ0KTsgZS5sb2NhbEdldCh0b3RhbCk7IGUuZW5kKClcblxuICByZXR1cm4gZS53cml0ZXJcbn1cblxuLyoqXG4gKiBFbmNvZGVzIGJ5dGUtZXhhY3Qgc3RyaW5nIGVxdWFsaXR5LlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVHZW5lcmF0aW9uSW5kZXg+fSBpbmRleCAtIFByb3ZlbmFuY2UgaW5kZXguXG4gKiBAcGFyYW0ge1NlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBTZW1hbnRpYyBtb2R1bGUuXG4gKiBAcmV0dXJucyB7QmluYXJ5V3JpdGVyfSBFbmNvZGVkIGhlbHBlciBib2R5LlxuICovXG5mdW5jdGlvbiBoZWxwZXJTdHJpbmdFcXVhbChpbmRleCwgbW9kdWxlKSB7XG4gIGNvbnN0IGUgPSBuZXcgU3ludGhldGljRW1pdHRlcihpbmRleCwgbW9kdWxlLCBcIiRzdHJpbmdfZXF1YWxcIilcbiAgY29uc3QgY3Vyc29yID0gNFxuXG4gIGUubG9jYWxHZXQoMSk7IGUubG9jYWxHZXQoMyk7IGUub3AoMHg0NywgXCJjb21wYXJlIHN0cmluZyBsZW5ndGhzXCIpXG4gIGUub3AoMHgwNCwgXCJicmFuY2ggZm9yIHVuZXF1YWwgc3RyaW5nIGxlbmd0aHNcIik7IGUuaW1tZWRpYXRlKFsweDQwXSwgXCJlbXB0eSBibG9jayB0eXBlXCIpXG4gIGUuaTMyKDApOyBlLm9wKDB4MGYsIFwicmV0dXJuIGZhbHNlIGZvciB1bmVxdWFsIGxlbmd0aHNcIik7IGUub3AoMHgwYiwgXCJlbmQgbGVuZ3RoIGJyYW5jaFwiKVxuICBlLmkzMigwKTsgZS5sb2NhbFNldChjdXJzb3IpXG4gIGUub3AoMHgwMiwgXCJzdHJpbmcgY29tcGFyaXNvbiBleGl0IGJsb2NrXCIpOyBlLmltbWVkaWF0ZShbMHg0MF0sIFwiZW1wdHkgYmxvY2sgdHlwZVwiKVxuICBlLm9wKDB4MDMsIFwic3RyaW5nIGNvbXBhcmlzb24gbG9vcFwiKTsgZS5pbW1lZGlhdGUoWzB4NDBdLCBcImVtcHR5IGJsb2NrIHR5cGVcIilcbiAgZS5sb2NhbEdldChjdXJzb3IpOyBlLmxvY2FsR2V0KDEpOyBlLm9wKDB4NGYsIFwiY29tcGFyZSBjdXJzb3Igd2l0aCBzdHJpbmcgbGVuZ3RoXCIpXG4gIGUub3AoMHgwZCwgXCJleGl0IGNvbXBsZXRlZCBjb21wYXJpc29uXCIpOyBlLmltbWVkaWF0ZSh1MzIoMSksIFwiY29tcGFyaXNvbiBibG9jayBkZXB0aFwiKVxuICBlLmxvY2FsR2V0KDApOyBlLmxvY2FsR2V0KGN1cnNvcik7IGUub3AoMHg2YSwgXCJsZWZ0IGJ5dGUgYWRkcmVzc1wiKTsgZS5sb2FkOCgpXG4gIGUubG9jYWxHZXQoMik7IGUubG9jYWxHZXQoY3Vyc29yKTsgZS5vcCgweDZhLCBcInJpZ2h0IGJ5dGUgYWRkcmVzc1wiKTsgZS5sb2FkOCgpXG4gIGUub3AoMHg0NywgXCJjb21wYXJlIFVURi04IGJ5dGVzXCIpXG4gIGUub3AoMHgwNCwgXCJicmFuY2ggZm9yIHVuZXF1YWwgVVRGLTggYnl0ZXNcIik7IGUuaW1tZWRpYXRlKFsweDQwXSwgXCJlbXB0eSBibG9jayB0eXBlXCIpXG4gIGUuaTMyKDApOyBlLm9wKDB4MGYsIFwicmV0dXJuIGZhbHNlIGZvciB1bmVxdWFsIGJ5dGVzXCIpOyBlLm9wKDB4MGIsIFwiZW5kIGJ5dGUgYnJhbmNoXCIpXG4gIGUubG9jYWxHZXQoY3Vyc29yKTsgZS5pMzIoMSk7IGUub3AoMHg2YSwgXCJpbmNyZW1lbnQgY29tcGFyaXNvbiBjdXJzb3JcIik7IGUubG9jYWxTZXQoY3Vyc29yKVxuICBlLm9wKDB4MGMsIFwiY29udGludWUgc3RyaW5nIGNvbXBhcmlzb25cIik7IGUuaW1tZWRpYXRlKHUzMigwKSwgXCJjb21wYXJpc29uIGxvb3AgZGVwdGhcIilcbiAgZS5vcCgweDBiLCBcImVuZCBjb21wYXJpc29uIGxvb3BcIik7IGUub3AoMHgwYiwgXCJlbmQgY29tcGFyaXNvbiBibG9ja1wiKVxuICBlLmkzMigxKTsgZS5lbmQoKVxuXG4gIHJldHVybiBlLndyaXRlclxufVxuXG4vKipcbiAqIEVuY29kZXMgY2hlY2tlZCBzaWduZWQgaTY0IGFkZGl0aW9uLlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVHZW5lcmF0aW9uSW5kZXg+fSBpbmRleCAtIFByb3ZlbmFuY2UgaW5kZXguXG4gKiBAcGFyYW0ge1NlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBTZW1hbnRpYyBtb2R1bGUuXG4gKiBAcmV0dXJucyB7QmluYXJ5V3JpdGVyfSBFbmNvZGVkIGhlbHBlciBib2R5LlxuICovXG5mdW5jdGlvbiBoZWxwZXJDaGVja2VkQWRkKGluZGV4LCBtb2R1bGUpIHtcbiAgY29uc3QgZSA9IG5ldyBTeW50aGV0aWNFbWl0dGVyKGluZGV4LCBtb2R1bGUsIFwiJGNoZWNrZWRfYWRkXCIpXG5cbiAgZS5sb2NhbEdldCgwKTsgZS5sb2NhbEdldCgxKTsgZS5vcCgweDdjLCBcInNpZ25lZCBpNjQgYWRkaXRpb25cIik7IGUubG9jYWxTZXQoMilcbiAgZS5sb2NhbEdldCgwKTsgZS5sb2NhbEdldCgyKTsgZS5vcCgweDg1LCBcImFkZGl0aW9uIG92ZXJmbG93IHhvclwiKVxuICBlLmxvY2FsR2V0KDEpOyBlLmxvY2FsR2V0KDIpOyBlLm9wKDB4ODUsIFwiYWRkaXRpb24gb3ZlcmZsb3cgeG9yXCIpXG4gIGUub3AoMHg4MywgXCJhZGRpdGlvbiBvdmVyZmxvdyBtYXNrXCIpOyBlLmk2NCgwbik7IGUub3AoMHg1MywgXCJhZGRpdGlvbiBvdmVyZmxvdyBzaWduIHRlc3RcIik7IGUudHJhcElmKFwic2lnbmVkIGk2NCBhZGRpdGlvbiBvdmVyZmxvd1wiKVxuICBlLmxvY2FsR2V0KDIpOyBlLmVuZCgpXG5cbiAgcmV0dXJuIGUud3JpdGVyXG59XG5cbi8qKlxuICogRW5jb2RlcyBjaGVja2VkIHNpZ25lZCBpNjQgc3VidHJhY3Rpb24uXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIGNyZWF0ZUdlbmVyYXRpb25JbmRleD59IGluZGV4IC0gUHJvdmVuYW5jZSBpbmRleC5cbiAqIEBwYXJhbSB7U2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFNlbWFudGljIG1vZHVsZS5cbiAqIEByZXR1cm5zIHtCaW5hcnlXcml0ZXJ9IEVuY29kZWQgaGVscGVyIGJvZHkuXG4gKi9cbmZ1bmN0aW9uIGhlbHBlckNoZWNrZWRTdWJ0cmFjdChpbmRleCwgbW9kdWxlKSB7XG4gIGNvbnN0IGUgPSBuZXcgU3ludGhldGljRW1pdHRlcihpbmRleCwgbW9kdWxlLCBcIiRjaGVja2VkX3N1YnRyYWN0XCIpXG5cbiAgZS5sb2NhbEdldCgwKTsgZS5sb2NhbEdldCgxKTsgZS5vcCgweDdkLCBcInNpZ25lZCBpNjQgc3VidHJhY3Rpb25cIik7IGUubG9jYWxTZXQoMilcbiAgZS5sb2NhbEdldCgwKTsgZS5sb2NhbEdldCgxKTsgZS5vcCgweDg1LCBcInN1YnRyYWN0aW9uIG92ZXJmbG93IHhvclwiKVxuICBlLmxvY2FsR2V0KDApOyBlLmxvY2FsR2V0KDIpOyBlLm9wKDB4ODUsIFwic3VidHJhY3Rpb24gb3ZlcmZsb3cgeG9yXCIpXG4gIGUub3AoMHg4MywgXCJzdWJ0cmFjdGlvbiBvdmVyZmxvdyBtYXNrXCIpOyBlLmk2NCgwbik7IGUub3AoMHg1MywgXCJzdWJ0cmFjdGlvbiBvdmVyZmxvdyBzaWduIHRlc3RcIik7IGUudHJhcElmKFwic2lnbmVkIGk2NCBzdWJ0cmFjdGlvbiBvdmVyZmxvd1wiKVxuICBlLmxvY2FsR2V0KDIpOyBlLmVuZCgpXG5cbiAgcmV0dXJuIGUud3JpdGVyXG59XG5cbi8qKlxuICogRW5jb2RlcyBjaGVja2VkIHNpZ25lZCBpNjQgbXVsdGlwbGljYXRpb24uXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIGNyZWF0ZUdlbmVyYXRpb25JbmRleD59IGluZGV4IC0gUHJvdmVuYW5jZSBpbmRleC5cbiAqIEBwYXJhbSB7U2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFNlbWFudGljIG1vZHVsZS5cbiAqIEByZXR1cm5zIHtCaW5hcnlXcml0ZXJ9IEVuY29kZWQgaGVscGVyIGJvZHkuXG4gKi9cbmZ1bmN0aW9uIGhlbHBlckNoZWNrZWRNdWx0aXBseShpbmRleCwgbW9kdWxlKSB7XG4gIGNvbnN0IGUgPSBuZXcgU3ludGhldGljRW1pdHRlcihpbmRleCwgbW9kdWxlLCBcIiRjaGVja2VkX211bHRpcGx5XCIpXG5cbiAgZS5sb2NhbEdldCgwKTsgZS5vcCgweDUwLCBcImxlZnQgb3BlcmFuZCB6ZXJvIHRlc3RcIilcbiAgZS5sb2NhbEdldCgxKTsgZS5vcCgweDUwLCBcInJpZ2h0IG9wZXJhbmQgemVybyB0ZXN0XCIpOyBlLm9wKDB4NzIsIFwiemVybyBvcGVyYW5kIGNvbWJpbmF0aW9uXCIpXG4gIGUub3AoMHgwNCwgXCJ6ZXJvIG11bHRpcGxpY2F0aW9uIGJyYW5jaFwiKTsgZS5pbW1lZGlhdGUoW3ZhbHVlVHlwZXMuaTY0XSwgXCJpNjQgYnJhbmNoIHJlc3VsdCB0eXBlXCIpXG4gIGUuaTY0KDBuKVxuICBlLm9wKDB4MDUsIFwibm9uemVybyBtdWx0aXBsaWNhdGlvbiBicmFuY2hcIilcbiAgZS5sb2NhbEdldCgwKTsgZS5pNjQoLTFuKTsgZS5vcCgweDUxLCBcImxlZnQgbmVnYXRpdmUtb25lIHRlc3RcIilcbiAgZS5sb2NhbEdldCgxKTsgZS5pNjQoLTkyMjMzNzIwMzY4NTQ3NzU4MDhuKTsgZS5vcCgweDUxLCBcInJpZ2h0IG1pbmltdW0gdGVzdFwiKTsgZS5vcCgweDcxLCBcImZpcnN0IGRpdmlzaW9uIG92ZXJmbG93IGNvbWJpbmF0aW9uXCIpXG4gIGUubG9jYWxHZXQoMSk7IGUuaTY0KC0xbik7IGUub3AoMHg1MSwgXCJyaWdodCBuZWdhdGl2ZS1vbmUgdGVzdFwiKVxuICBlLmxvY2FsR2V0KDApOyBlLmk2NCgtOTIyMzM3MjAzNjg1NDc3NTgwOG4pOyBlLm9wKDB4NTEsIFwibGVmdCBtaW5pbXVtIHRlc3RcIik7IGUub3AoMHg3MSwgXCJzZWNvbmQgZGl2aXNpb24gb3ZlcmZsb3cgY29tYmluYXRpb25cIilcbiAgZS5vcCgweDcyLCBcImRpdmlzaW9uIG92ZXJmbG93IGNvbWJpbmF0aW9uXCIpOyBlLnRyYXBJZihcInNpZ25lZCBpNjQgbXVsdGlwbGljYXRpb24gb3ZlcmZsb3dcIilcbiAgZS5sb2NhbEdldCgwKTsgZS5sb2NhbEdldCgxKTsgZS5vcCgweDdlLCBcInNpZ25lZCBpNjQgbXVsdGlwbGljYXRpb25cIik7IGUubG9jYWxTZXQoMilcbiAgZS5sb2NhbEdldCgyKTsgZS5sb2NhbEdldCgxKTsgZS5vcCgweDdmLCBcInNpZ25lZCBpNjQgZGl2aXNpb24gb3ZlcmZsb3cgY2hlY2tcIik7IGUubG9jYWxHZXQoMCk7IGUub3AoMHg1MiwgXCJtdWx0aXBsaWNhdGlvbiBxdW90aWVudCBtaXNtYXRjaFwiKVxuICBlLnRyYXBJZihcInNpZ25lZCBpNjQgbXVsdGlwbGljYXRpb24gb3ZlcmZsb3dcIilcbiAgZS5sb2NhbEdldCgyKTsgZS5vcCgweDBiLCBcImVuZCBjaGVja2VkIG11bHRpcGxpY2F0aW9uIGJyYW5jaFwiKTsgZS5lbmQoKVxuXG4gIHJldHVybiBlLndyaXRlclxufVxuXG4vKipcbiAqIEVuY29kZXMgY2hlY2tlZCBzaWduZWQgaTY0IG5lZ2F0aW9uLlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVHZW5lcmF0aW9uSW5kZXg+fSBpbmRleCAtIFByb3ZlbmFuY2UgaW5kZXguXG4gKiBAcGFyYW0ge1NlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBTZW1hbnRpYyBtb2R1bGUuXG4gKiBAcmV0dXJucyB7QmluYXJ5V3JpdGVyfSBFbmNvZGVkIGhlbHBlciBib2R5LlxuICovXG5mdW5jdGlvbiBoZWxwZXJDaGVja2VkTmVnYXRlKGluZGV4LCBtb2R1bGUpIHtcbiAgY29uc3QgZSA9IG5ldyBTeW50aGV0aWNFbWl0dGVyKGluZGV4LCBtb2R1bGUsIFwiJGNoZWNrZWRfbmVnYXRlXCIpXG5cbiAgZS5sb2NhbEdldCgwKTsgZS5pNjQoLTkyMjMzNzIwMzY4NTQ3NzU4MDhuKTsgZS5vcCgweDUxLCBcIm1pbmltdW0gaTY0IG5lZ2F0ZSB0ZXN0XCIpOyBlLnRyYXBJZihcInNpZ25lZCBpNjQgbmVnYXRpb24gb3ZlcmZsb3dcIilcbiAgZS5pNjQoMG4pOyBlLmxvY2FsR2V0KDApOyBlLm9wKDB4N2QsIFwic2lnbmVkIGk2NCBuZWdhdGlvblwiKTsgZS5lbmQoKVxuXG4gIHJldHVybiBlLndyaXRlclxufVxuXG4vKiogSGVscGVyIGluc3RydWN0aW9uIGVtaXR0ZXIgd2l0aCBleHBsaWNpdCBzeW50aGV0aWMgcHJvdmVuYW5jZS4gKi9cbmNsYXNzIFN5bnRoZXRpY0VtaXR0ZXIge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIHN5bnRoZXRpYyBoZWxwZXIgZW1pdHRlci5cbiAgICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVHZW5lcmF0aW9uSW5kZXg+fSBpbmRleCAtIFByb3ZlbmFuY2UgaW5kZXguXG4gICAqIEBwYXJhbSB7U2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFJlbGF0ZWQgc2VtYW50aWMgbW9kdWxlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIEhlbHBlciBmdW5jdGlvbiBuYW1lLlxuICAgKi9cbiAgY29uc3RydWN0b3IoaW5kZXgsIG1vZHVsZSwgbmFtZSkge1xuICAgIHRoaXMud3JpdGVyID0gbmV3IEJpbmFyeVdyaXRlcihpbmRleClcbiAgICB0aGlzLnJlbGF0ZWQgPSB7bm9kZTogbW9kdWxlLCBwYXRoOiBcIlwifVxuICAgIHRoaXMubmFtZSA9IG5hbWVcbiAgfVxuXG4gIC8qKlxuICAgKiBXcml0ZXMgYW4gaW5zdHJ1Y3Rpb24gb3Bjb2RlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb3Bjb2RlIC0gV2FzbSBvcGNvZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb24gLSBTeW50aGV0aWMgcHJvdmVuYW5jZSByZWFzb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgb3Aob3Bjb2RlLCByZWFzb24pIHsgdGhpcy53cml0ZXIuc3ludGhldGljKFtvcGNvZGVdLCBgJHt0aGlzLm5hbWV9OiAke3JlYXNvbn1gLCB0aGlzLnJlbGF0ZWQsIFwiaW5zdHJ1Y3Rpb25cIikgfVxuXG4gIC8qKlxuICAgKiBXcml0ZXMgZW5jb2RlZCBpbnN0cnVjdGlvbiBpbW1lZGlhdGVzLlxuICAgKiBAcGFyYW0ge251bWJlcltdfSBieXRlcyAtIEltbWVkaWF0ZSBieXRlcy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHJlYXNvbiAtIFN5bnRoZXRpYyBwcm92ZW5hbmNlIHJlYXNvbi5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBpbW1lZGlhdGUoYnl0ZXMsIHJlYXNvbikgeyB0aGlzLndyaXRlci5zeW50aGV0aWMoYnl0ZXMsIGAke3RoaXMubmFtZX06ICR7cmVhc29ufWAsIHRoaXMucmVsYXRlZCwgXCJpbW1lZGlhdGVcIikgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyBvbmUgbG9jYWwuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIExvY2FsIGluZGV4LlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGxvY2FsR2V0KGluZGV4KSB7IHRoaXMub3AoMHgyMCwgXCJyZWFkIGxvY2FsXCIpOyB0aGlzLmltbWVkaWF0ZSh1MzIoaW5kZXgpLCBcImxvY2FsIGluZGV4XCIpIH1cblxuICAvKipcbiAgICogV3JpdGVzIG9uZSBsb2NhbC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IC0gTG9jYWwgaW5kZXguXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgbG9jYWxTZXQoaW5kZXgpIHsgdGhpcy5vcCgweDIxLCBcIndyaXRlIGxvY2FsXCIpOyB0aGlzLmltbWVkaWF0ZSh1MzIoaW5kZXgpLCBcImxvY2FsIGluZGV4XCIpIH1cblxuICAvKipcbiAgICogV3JpdGVzIGFuZCByZXRhaW5zIG9uZSBsb2NhbCB2YWx1ZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IC0gTG9jYWwgaW5kZXguXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgbG9jYWxUZWUoaW5kZXgpIHsgdGhpcy5vcCgweDIyLCBcInRlZSBsb2NhbFwiKTsgdGhpcy5pbW1lZGlhdGUodTMyKGluZGV4KSwgXCJsb2NhbCBpbmRleFwiKSB9XG5cbiAgLyoqXG4gICAqIFJlYWRzIG9uZSBnbG9iYWwuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIEdsb2JhbCBpbmRleC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBnbG9iYWxHZXQoaW5kZXgpIHsgdGhpcy5vcCgweDIzLCBcInJlYWQgZ2xvYmFsXCIpOyB0aGlzLmltbWVkaWF0ZSh1MzIoaW5kZXgpLCBcImdsb2JhbCBpbmRleFwiKSB9XG5cbiAgLyoqXG4gICAqIFdyaXRlcyBvbmUgZ2xvYmFsLlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggLSBHbG9iYWwgaW5kZXguXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgZ2xvYmFsU2V0KGluZGV4KSB7IHRoaXMub3AoMHgyNCwgXCJ3cml0ZSBnbG9iYWxcIik7IHRoaXMuaW1tZWRpYXRlKHUzMihpbmRleCksIFwiZ2xvYmFsIGluZGV4XCIpIH1cblxuICAvKipcbiAgICogV3JpdGVzIG9uZSBpMzIgY29uc3RhbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSAtIENvbnN0YW50IHZhbHVlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGkzMih2YWx1ZSkgeyB0aGlzLm9wKDB4NDEsIFwiaTMyIGNvbnN0YW50XCIpOyB0aGlzLmltbWVkaWF0ZShzMzIodmFsdWUpLCBcImkzMiBpbW1lZGlhdGVcIikgfVxuXG4gIC8qKlxuICAgKiBXcml0ZXMgb25lIGk2NCBjb25zdGFudC5cbiAgICogQHBhcmFtIHtiaWdpbnR9IHZhbHVlIC0gQ29uc3RhbnQgdmFsdWUuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgaTY0KHZhbHVlKSB7IHRoaXMub3AoMHg0MiwgXCJpNjQgY29uc3RhbnRcIik7IHRoaXMuaW1tZWRpYXRlKHM2NCh2YWx1ZSksIFwiaTY0IGltbWVkaWF0ZVwiKSB9XG5cbiAgLyoqXG4gICAqIExvYWRzIG9uZSB1bnNpZ25lZCBieXRlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGxvYWQ4KCkgeyB0aGlzLm9wKDB4MmQsIFwibG9hZCB1bnNpZ25lZCBieXRlXCIpOyB0aGlzLmltbWVkaWF0ZShbMHgwMCwgMHgwMF0sIFwiYnl0ZS1sb2FkIG1lbW9yeSBhcmd1bWVudHNcIikgfVxuXG4gIC8qKlxuICAgKiBTdG9yZXMgb25lIGJ5dGUuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgc3RvcmU4KCkgeyB0aGlzLm9wKDB4M2EsIFwic3RvcmUgYnl0ZVwiKTsgdGhpcy5pbW1lZGlhdGUoWzB4MDAsIDB4MDBdLCBcImJ5dGUtc3RvcmUgbWVtb3J5IGFyZ3VtZW50c1wiKSB9XG5cbiAgLyoqXG4gICAqIFRyYXBzIHdoZW4gdGhlIHN0YWNrJ3MgY29uZGl0aW9uIGlzIG5vbnplcm8uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb24gLSBUcmFwIHByb3ZlbmFuY2UgcmVhc29uLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHRyYXBJZihyZWFzb24pIHtcbiAgICB0aGlzLm9wKDB4MDQsIGAke3JlYXNvbn0gYnJhbmNoYCk7IHRoaXMuaW1tZWRpYXRlKFsweDQwXSwgXCJlbXB0eSBibG9jayB0eXBlXCIpXG4gICAgdGhpcy5vcCgweDAwLCBgJHtyZWFzb259IHRyYXBgKTsgdGhpcy5vcCgweDBiLCBgJHtyZWFzb259IGJyYW5jaCBlbmRgKVxuICB9XG4gIC8qKlxuICAgKiBDb3BpZXMgb25lIHN0cmluZyBvcGVyYW5kIGJ5dGUgYnkgYnl0ZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGN1cnNvciAtIExvb3AgY3Vyc29yIGxvY2FsLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc291cmNlUG9pbnRlciAtIFNvdXJjZSBwb2ludGVyIGxvY2FsLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc291cmNlTGVuZ3RoIC0gU291cmNlIGxlbmd0aCBsb2NhbC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGRlc3RpbmF0aW9uIC0gQWxsb2NhdGlvbiBzdGFydCBsb2NhbC5cbiAgICogQHBhcmFtIHtudW1iZXIgfCB1bmRlZmluZWR9IGRlc3RpbmF0aW9uT2Zmc2V0IC0gT3B0aW9uYWwgbGVmdC1sZW5ndGggbG9jYWwuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgY29weUxvb3AoY3Vyc29yLCBzb3VyY2VQb2ludGVyLCBzb3VyY2VMZW5ndGgsIGRlc3RpbmF0aW9uLCBkZXN0aW5hdGlvbk9mZnNldCkge1xuICAgIHRoaXMub3AoMHgwMiwgXCJjb3B5IGV4aXQgYmxvY2tcIik7IHRoaXMuaW1tZWRpYXRlKFsweDQwXSwgXCJlbXB0eSBibG9jayB0eXBlXCIpXG4gICAgdGhpcy5vcCgweDAzLCBcImNvcHkgbG9vcFwiKTsgdGhpcy5pbW1lZGlhdGUoWzB4NDBdLCBcImVtcHR5IGJsb2NrIHR5cGVcIilcbiAgICB0aGlzLmxvY2FsR2V0KGN1cnNvcik7IHRoaXMubG9jYWxHZXQoc291cmNlTGVuZ3RoKTsgdGhpcy5vcCgweDRmLCBcImNvbXBhcmUgY29weSBjdXJzb3Igd2l0aCBsZW5ndGhcIilcbiAgICB0aGlzLm9wKDB4MGQsIFwiZXhpdCBjb21wbGV0ZWQgY29weVwiKTsgdGhpcy5pbW1lZGlhdGUodTMyKDEpLCBcImNvcHkgYmxvY2sgZGVwdGhcIilcbiAgICB0aGlzLmxvY2FsR2V0KGRlc3RpbmF0aW9uKVxuICAgIGlmIChkZXN0aW5hdGlvbk9mZnNldCAhPT0gdW5kZWZpbmVkKSB7IHRoaXMubG9jYWxHZXQoZGVzdGluYXRpb25PZmZzZXQpOyB0aGlzLm9wKDB4NmEsIFwiYWRkIGRlc3RpbmF0aW9uIG9mZnNldFwiKSB9XG4gICAgdGhpcy5sb2NhbEdldChjdXJzb3IpOyB0aGlzLm9wKDB4NmEsIFwiYWRkIGRlc3RpbmF0aW9uIGN1cnNvclwiKVxuICAgIHRoaXMubG9jYWxHZXQoc291cmNlUG9pbnRlcik7IHRoaXMubG9jYWxHZXQoY3Vyc29yKTsgdGhpcy5vcCgweDZhLCBcImFkZCBzb3VyY2UgY3Vyc29yXCIpOyB0aGlzLmxvYWQ4KCk7IHRoaXMuc3RvcmU4KClcbiAgICB0aGlzLmxvY2FsR2V0KGN1cnNvcik7IHRoaXMuaTMyKDEpOyB0aGlzLm9wKDB4NmEsIFwiaW5jcmVtZW50IGNvcHkgY3Vyc29yXCIpOyB0aGlzLmxvY2FsU2V0KGN1cnNvcilcbiAgICB0aGlzLm9wKDB4MGMsIFwiY29udGludWUgY29weSBsb29wXCIpOyB0aGlzLmltbWVkaWF0ZSh1MzIoMCksIFwiY29weSBsb29wIGRlcHRoXCIpXG4gICAgdGhpcy5vcCgweDBiLCBcImVuZCBjb3B5IGxvb3BcIik7IHRoaXMub3AoMHgwYiwgXCJlbmQgY29weSBibG9ja1wiKVxuICB9XG4gIC8qKlxuICAgKiBFbmRzIG9uZSBoZWxwZXIgZnVuY3Rpb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgZW5kKCkgeyB0aGlzLm9wKDB4MGIsIFwiZnVuY3Rpb24gZW5kXCIpIH1cbn1cblxuLyoqXG4gKiBDb2xsZWN0cyBkZWR1cGxpY2F0ZWQgbGl0ZXJhbCBieXRlcyBhbmQgdGhlaXIgY29tYmluZWQgc2VtYW50aWMgb3JpZ2lucy5cbiAqIEBwYXJhbSB7U2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFNlbWFudGljIG1vZHVsZS5cbiAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlR2VuZXJhdGlvbkluZGV4Pn0gaW5kZXggLSBQcm92ZW5hbmNlIGluZGV4LlxuICogQHJldHVybnMge3tib3VuZGFyeTogbnVtYmVyLCBieVZhbHVlOiBNYXA8c3RyaW5nLCB7YWRkcmVzczogbnVtYmVyLCBieXRlczogVWludDhBcnJheX0+LCBlbnRyaWVzOiB7YWRkcmVzczogbnVtYmVyLCBieXRlczogVWludDhBcnJheSwgb3JpZ2luOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY09yaWdpbn1bXX19IExheW91dC5cbiAqL1xuZnVuY3Rpb24gY29sbGVjdExpdGVyYWxMYXlvdXQobW9kdWxlLCBpbmRleCkge1xuICAvKiogQHR5cGUge01hcDxzdHJpbmcsIHtieXRlczogVWludDhBcnJheSwgb2NjdXJyZW5jZXM6IFJldHVyblR5cGU8dHlwZW9mIGluZGV4LnJlY29yZEZvcj5bXX0+fSAqL1xuICBjb25zdCBjb2xsZWN0ZWQgPSBuZXcgTWFwKClcblxuICBmb3IgKGNvbnN0IHtub2RlLCBwYXRofSBvZiBzZW1hbnRpY0VudHJpZXMobW9kdWxlKSkge1xuICAgIGlmIChub2RlLmtpbmQgIT0gXCJTdHJpbmdMaXRlcmFsXCIpIGNvbnRpbnVlXG4gICAgY29uc3QgZXhpc3RpbmcgPSBjb2xsZWN0ZWQuZ2V0KG5vZGUudmFsdWUpXG5cbiAgICBpZiAoZXhpc3RpbmcpIGV4aXN0aW5nLm9jY3VycmVuY2VzLnB1c2goaW5kZXgucmVjb3JkRm9yKG5vZGUsIHBhdGgpKVxuICAgIGVsc2UgY29sbGVjdGVkLnNldChub2RlLnZhbHVlLCB7Ynl0ZXM6IGVuY29kZXIuZW5jb2RlKG5vZGUudmFsdWUpLCBvY2N1cnJlbmNlczogW2luZGV4LnJlY29yZEZvcihub2RlLCBwYXRoKV19KVxuICB9XG5cbiAgbGV0IGFkZHJlc3MgPSAxXG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywge2FkZHJlc3M6IG51bWJlciwgYnl0ZXM6IFVpbnQ4QXJyYXl9Pn0gKi9cbiAgY29uc3QgYnlWYWx1ZSA9IG5ldyBNYXAoKVxuICAvKiogQHR5cGUge3thZGRyZXNzOiBudW1iZXIsIGJ5dGVzOiBVaW50OEFycmF5LCBvcmlnaW46IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljT3JpZ2lufVtdfSAqL1xuICBjb25zdCBlbnRyaWVzID0gW11cblxuICBmb3IgKGNvbnN0IFt2YWx1ZSwgbGl0ZXJhbF0gb2YgY29sbGVjdGVkKSB7XG4gICAgY29uc3QgbmV4dCA9IGNoZWNrZWRTaXplKGFkZHJlc3MgKyBsaXRlcmFsLmJ5dGVzLmJ5dGVMZW5ndGgsIG1vZHVsZSwgXCJpbW11dGFibGUgbGl0ZXJhbCBtZW1vcnkgbGF5b3V0XCIpXG4gICAgY29uc3QgZXhhY3RPcmlnaW5zID0gbGl0ZXJhbC5vY2N1cnJlbmNlcy5tYXAoKHJlY29yZCkgPT4gb3JpZ2luRm9yUm9sZShpbmRleCwgcmVjb3JkLCBcImxpdGVyYWxcIikpXG4gICAgY29uc3Qgb3JpZ2lucyA9IGxpdGVyYWwub2NjdXJyZW5jZXMuZmxhdE1hcCgocmVjb3JkLCBvZmZzZXQpID0+IHJlbGF0ZWRPcmlnaW5zKHJlY29yZCwgZXhhY3RPcmlnaW5zW29mZnNldF0pKVxuICAgIGNvbnN0IG9yaWdpbiA9IGxpdGVyYWwub2NjdXJyZW5jZXMubGVuZ3RoID09IDEgPyBleGFjdE9yaWdpbnNbMF0gOiBvcmlnaW5zLmxlbmd0aCA+IDBcbiAgICAgID8ge2tpbmQ6IFwiZGVyaXZlZFwiLCBvcmlnaW5zfVxuICAgICAgOiB7a2luZDogXCJzeW50aGV0aWNcIiwgcmVhc29uOiBcIkRlZHVwbGljYXRlZCBpbW11dGFibGUgVVRGLTggbGl0ZXJhbCBkYXRhIHdpdGhvdXQgc291cmNlIHJhbmdlcy5cIiwgcmVsYXRlZE9yaWdpbnM6IFtdfVxuXG4gICAgZW50cmllcy5wdXNoKHthZGRyZXNzLCBieXRlczogbGl0ZXJhbC5ieXRlcywgb3JpZ2luOiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljT3JpZ2lufSAqLyAob3JpZ2luKX0pXG4gICAgYnlWYWx1ZS5zZXQodmFsdWUsIHthZGRyZXNzLCBieXRlczogbGl0ZXJhbC5ieXRlc30pXG4gICAgYWRkcmVzcyA9IG5leHRcbiAgfVxuXG4gIHJldHVybiB7Ym91bmRhcnk6IGFkZHJlc3MsIGJ5VmFsdWUsIGVudHJpZXN9XG59XG5cbi8qKlxuICogUGVyZm9ybXMgYm91bmRlZCBwYXRoLXNlbnNpdGl2ZSBhbGxvY2F0aW9uIGFuYWx5c2lzIGZyb20gcnVuLlxuICogQHBhcmFtIHtTZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gVmFsaWRhdGVkIG1vZHVsZS5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFdvcnN0IHJlYWNoYWJsZSBhbGxvY2F0aW9uIGJ5dGVzLlxuICovXG5mdW5jdGlvbiBhbmFseXplU2NyYXRjaFVzZShtb2R1bGUpIHtcbiAgY29uc3QgZnVuY3Rpb25zID0gbmV3IE1hcChtb2R1bGUuZnVuY3Rpb25zLm1hcCgoZGVjbGFyYXRpb24pID0+IFtkZWNsYXJhdGlvbi5uYW1lLCBkZWNsYXJhdGlvbl0pKVxuICBsZXQgc3RlcHMgPSAwXG5cbiAgY29uc3Qgc3RhdGVzID0gYmxvY2sobW9kdWxlLmVudHJ5UG9pbnQuYm9keSwgW3thbGxvY2F0ZWQ6IDAsIGVudjogbmV3IE1hcCgpfV0sIDApXG5cbiAgcmV0dXJuIE1hdGgubWF4KDAsIC4uLnN0YXRlcy5tYXAoKHthbGxvY2F0ZWR9KSA9PiBhbGxvY2F0ZWQpKVxuXG4gIC8qKlxuICAgKiBBbmFseXplcyBvbmUgYmxvY2sgZnJvbSBldmVyeSBpbmNvbWluZyBwYXRoIHN0YXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBzZW1hbnRpY0Jsb2NrIC0gQmxvY2sgdG8gYW5hbHl6ZS5cbiAgICogQHBhcmFtIHtBbmFseXNpc1N0YXRlW119IGluY29taW5nIC0gSW5jb21pbmcgcGF0aCBzdGF0ZXMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBkZXB0aCAtIEFjdGl2ZSBzZW1hbnRpYyBjYWxsIGRlcHRoLlxuICAgKiBAcmV0dXJucyB7QW5hbHlzaXNTdGF0ZVtdfSBSZXN1bHRpbmcgcGF0aCBzdGF0ZXMuXG4gICAqL1xuICBmdW5jdGlvbiBibG9jayhzZW1hbnRpY0Jsb2NrLCBpbmNvbWluZywgZGVwdGgpIHtcbiAgICBsZXQgc3RhdGVzID0gaW5jb21pbmdcblxuICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIHNlbWFudGljQmxvY2suc3RhdGVtZW50cykge1xuICAgICAgY29uc3QgbmV4dCA9IFtdXG5cbiAgICAgIGZvciAoY29uc3Qgc3RhdGUgb2Ygc3RhdGVzKSB7XG4gICAgICAgIGlmIChzdGF0ZS5yZXR1cm5lZCkgeyBuZXh0LnB1c2goc3RhdGUpOyBjb250aW51ZSB9XG4gICAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIikge1xuICAgICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIGV4cHJlc3Npb24oc3RhdGVtZW50LmluaXRpYWxpemVyLCBzdGF0ZSwgZGVwdGgpKSB7XG4gICAgICAgICAgICBjb25zdCBlbnYgPSBuZXcgTWFwKHJlc3VsdC5zdGF0ZS5lbnYpXG5cbiAgICAgICAgICAgIGVudi5zZXQoc3RhdGVtZW50Lm5hbWUsIHJlc3VsdC52YWx1ZSlcbiAgICAgICAgICAgIG5leHQucHVzaCh7Li4ucmVzdWx0LnN0YXRlLCBlbnZ9KVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIikge1xuICAgICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIGV4cHJlc3Npb24oc3RhdGVtZW50LmV4cHJlc3Npb24sIHN0YXRlLCBkZXB0aCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGVudiA9IG5ldyBNYXAocmVzdWx0LnN0YXRlLmVudilcblxuICAgICAgICAgICAgZW52LnNldChzdGF0ZW1lbnQudGFyZ2V0Lm5hbWUsIHJlc3VsdC52YWx1ZSlcbiAgICAgICAgICAgIG5leHQucHVzaCh7Li4ucmVzdWx0LnN0YXRlLCBlbnZ9KVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlByaW50U3RhdGVtZW50XCIpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiBleHByZXNzaW9uKHN0YXRlbWVudC5leHByZXNzaW9uLCBzdGF0ZSwgZGVwdGgpKSBuZXh0LnB1c2gocmVzdWx0LnN0YXRlKVxuICAgICAgICB9IGVsc2UgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUmV0dXJuU3RhdGVtZW50XCIpIHtcbiAgICAgICAgICBpZiAoIXN0YXRlbWVudC5leHByZXNzaW9uKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiV2FzbSBiYXJlIHJldHVybiByZWFjaGVkIGFic3RyYWN0IGV4ZWN1dGlvbi5cIilcbiAgICAgICAgICBmb3IgKGNvbnN0IHJlc3VsdCBvZiBleHByZXNzaW9uKHN0YXRlbWVudC5leHByZXNzaW9uLCBzdGF0ZSwgZGVwdGgpKSBuZXh0LnB1c2goey4uLnJlc3VsdC5zdGF0ZSwgcmV0dXJuZWQ6IHJlc3VsdC52YWx1ZX0pXG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJFeHByZXNzaW9uU3RhdGVtZW50XCIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiV2FzbSBUYXNrIDAwNSBleHByZXNzaW9uIHN0YXRlbWVudCByZWFjaGVkIGFic3RyYWN0IGV4ZWN1dGlvbi5cIilcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IGNvbmRpdGlvbiBvZiBleHByZXNzaW9uKHN0YXRlbWVudC5jb25kaXRpb24sIHN0YXRlLCBkZXB0aCkpIHtcbiAgICAgICAgICAgIGlmIChjb25kaXRpb24udmFsdWUua25vd25Cb29sZWFuICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICBuZXh0LnB1c2goLi4ud2l0aG91dEJyYW5jaExvY2FscyhibG9jayhzdGF0ZW1lbnQuY29uc2VxdWVudCwgW2Nsb25lU3RhdGUoY29uZGl0aW9uLnN0YXRlKV0sIGRlcHRoKSwgY29uZGl0aW9uLnN0YXRlLmVudikpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY29uZGl0aW9uLnZhbHVlLmtub3duQm9vbGVhbiAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgICBjb25zdCBhbHRlcm5hdGUgPSBzdGF0ZW1lbnQuYWx0ZXJuYXRlXG4gICAgICAgICAgICAgICAgPyBibG9jayhzdGF0ZW1lbnQuYWx0ZXJuYXRlLCBbY2xvbmVTdGF0ZShjb25kaXRpb24uc3RhdGUpXSwgZGVwdGgpXG4gICAgICAgICAgICAgICAgOiBbY2xvbmVTdGF0ZShjb25kaXRpb24uc3RhdGUpXVxuXG4gICAgICAgICAgICAgIG5leHQucHVzaCguLi53aXRob3V0QnJhbmNoTG9jYWxzKGFsdGVybmF0ZSwgY29uZGl0aW9uLnN0YXRlLmVudikpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJVbnN1cHBvcnRlZCBXYXNtIHN0YXRlbWVudCByZWFjaGVkIGFic3RyYWN0IGV4ZWN1dGlvbi5cIilcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgc3RhdGVzID0gYm91bmRlZFN0YXRlcyhuZXh0LCBzdGF0ZW1lbnQpXG4gICAgfVxuXG4gICAgcmV0dXJuIHN0YXRlc1xuICB9XG5cbiAgLyoqXG4gICAqIEV2YWx1YXRlcyBhYnN0cmFjdCB2YWx1ZXMgYW5kIGFsbG9jYXRpb24gZGVtYW5kIGZvciBvbmUgZXhwcmVzc2lvbi5cbiAgICogQHBhcmFtIHtFeHByZXNzaW9ufSB2YWx1ZSAtIEV4cHJlc3Npb24gdG8gYW5hbHl6ZS5cbiAgICogQHBhcmFtIHtBbmFseXNpc1N0YXRlfSBzdGF0ZSAtIEluY29taW5nIHBhdGggc3RhdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBkZXB0aCAtIEFjdGl2ZSBzZW1hbnRpYyBjYWxsIGRlcHRoLlxuICAgKiBAcmV0dXJucyB7e3N0YXRlOiBBbmFseXNpc1N0YXRlLCB2YWx1ZTogQWJzdHJhY3RWYWx1ZX1bXX0gUG9zc2libGUgb3V0Y29tZXMuXG4gICAqL1xuICBmdW5jdGlvbiBleHByZXNzaW9uKHZhbHVlLCBzdGF0ZSwgZGVwdGgpIHtcbiAgICBzdGVwcyArPSAxXG4gICAgaWYgKHN0ZXBzID4gbWF4aW11bUFuYWx5c2lzU3RlcHMpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShcIndhc21cIiwgXCJ1bnByb3ZhYmxlIHBhdGgtc2Vuc2l0aXZlIHNjcmF0Y2ggYWxsb2NhdGlvbiBib3VuZFwiLCB2YWx1ZS5sb2NhdGlvbilcblxuICAgIGlmICh2YWx1ZS5raW5kID09IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgZm91bmQgPSBzdGF0ZS5lbnYuZ2V0KHZhbHVlLm5hbWUpXG5cbiAgICAgIGlmICghZm91bmQpIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRlZCBXYXNtIGFuYWx5c2lzIG9taXR0ZWQgYW4gaWRlbnRpZmllciBiaW5kaW5nLlwiKVxuXG4gICAgICByZXR1cm4gW3tzdGF0ZSwgdmFsdWU6IGZvdW5kfV1cbiAgICB9XG4gICAgaWYgKHZhbHVlLmtpbmQgPT0gXCJJbnRlZ2VyTGl0ZXJhbFwiKSByZXR1cm4gW3tzdGF0ZSwgdmFsdWU6IHtrbm93bkludGVnZXI6IEJpZ0ludCh2YWx1ZS52YWx1ZSksIHR5cGU6IFwiaW50ZWdlclwifX1dXG4gICAgaWYgKHZhbHVlLmtpbmQgPT0gXCJCb29sZWFuTGl0ZXJhbFwiKSByZXR1cm4gW3tzdGF0ZSwgdmFsdWU6IHtrbm93bkJvb2xlYW46IHZhbHVlLnZhbHVlLCB0eXBlOiBcImJvb2xlYW5cIn19XVxuICAgIGlmICh2YWx1ZS5raW5kID09IFwiU3RyaW5nTGl0ZXJhbFwiKSB7XG4gICAgICByZXR1cm4gW3tzdGF0ZSwgdmFsdWU6IHtrbm93blN0cmluZzogdmFsdWUudmFsdWUsIHN0cmluZ0xlbmd0aDogZW5jb2Rlci5lbmNvZGUodmFsdWUudmFsdWUpLmJ5dGVMZW5ndGgsIHR5cGU6IFwic3RyaW5nXCJ9fV1cbiAgICB9XG4gICAgaWYgKHZhbHVlLmtpbmQgPT0gXCJDYWxsRXhwcmVzc2lvblwiKSB7XG4gICAgICBsZXQgYXJndW1lbnRzTGlzdCA9IFt7c3RhdGUsIHZhbHVlczogLyoqIEB0eXBlIHtBYnN0cmFjdFZhbHVlW119ICovIChbXSl9XVxuXG4gICAgICBmb3IgKGNvbnN0IGFyZ3VtZW50IG9mIHZhbHVlLmFyZ3VtZW50cykge1xuICAgICAgICBjb25zdCBuZXh0ID0gW11cblxuICAgICAgICBmb3IgKGNvbnN0IGN1cnJlbnQgb2YgYXJndW1lbnRzTGlzdCkge1xuICAgICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIGV4cHJlc3Npb24oYXJndW1lbnQsIGN1cnJlbnQuc3RhdGUsIGRlcHRoKSkge1xuICAgICAgICAgICAgbmV4dC5wdXNoKHtzdGF0ZTogcmVzdWx0LnN0YXRlLCB2YWx1ZXM6IFsuLi5jdXJyZW50LnZhbHVlcywgcmVzdWx0LnZhbHVlXX0pXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGFyZ3VtZW50c0xpc3QgPSBuZXh0XG4gICAgICB9XG4gICAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGZ1bmN0aW9ucy5nZXQodmFsdWUuY2FsbGVlKVxuXG4gICAgICBpZiAoIWRlY2xhcmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJWYWxpZGF0ZWQgV2FzbSBhbmFseXNpcyBvbWl0dGVkIGEgY2FsbCBkZWNsYXJhdGlvbi5cIilcbiAgICAgIGlmIChkZXB0aCA+PSBtYXhpbXVtQ2FsbERlcHRoKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkoXCJ3YXNtXCIsIGBzZW1hbnRpYyBjYWxsIGRlcHRoIGFib3ZlICR7bWF4aW11bUNhbGxEZXB0aH1gLCB2YWx1ZS5sb2NhdGlvbilcbiAgICAgIC8qKiBAdHlwZSB7e3N0YXRlOiBBbmFseXNpc1N0YXRlLCB2YWx1ZTogQWJzdHJhY3RWYWx1ZX1bXX0gKi9cbiAgICAgIGNvbnN0IG91dGNvbWVzID0gW11cblxuICAgICAgZm9yIChjb25zdCBhcmd1bWVudFNldCBvZiBhcmd1bWVudHNMaXN0KSB7XG4gICAgICAgIGNvbnN0IGVudiA9IG5ldyBNYXAoZGVjbGFyYXRpb24ucGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlciwgaW5kZXgpID0+IFtwYXJhbWV0ZXIubmFtZSwgYXJndW1lbnRTZXQudmFsdWVzW2luZGV4XV0pKVxuICAgICAgICBjb25zdCBjYWxsZWQgPSBibG9jayhkZWNsYXJhdGlvbi5ib2R5LCBbe2FsbG9jYXRlZDogMCwgZW52fV0sIGRlcHRoICsgMSlcblxuICAgICAgICBmb3IgKGNvbnN0IHJldHVybmVkIG9mIGNhbGxlZCkge1xuICAgICAgICAgIGlmICghcmV0dXJuZWQucmV0dXJuZWQpIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRlZCBXYXNtIGZ1bmN0aW9uIGFuYWx5c2lzIG9taXR0ZWQgYSByZXR1cm4gdmFsdWUuXCIpXG4gICAgICAgICAgb3V0Y29tZXMucHVzaCh7XG4gICAgICAgICAgICBzdGF0ZTogey4uLmFyZ3VtZW50U2V0LnN0YXRlLCBhbGxvY2F0ZWQ6IGFkZEFsbG9jYXRpb24oYXJndW1lbnRTZXQuc3RhdGUuYWxsb2NhdGVkLCByZXR1cm5lZC5hbGxvY2F0ZWQsIHZhbHVlKX0sXG4gICAgICAgICAgICB2YWx1ZTogcmV0dXJuZWQucmV0dXJuZWRcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBvdXRjb21lc1xuICAgIH1cbiAgICBpZiAodmFsdWUua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgICByZXR1cm4gZXhwcmVzc2lvbih2YWx1ZS5vcGVyYW5kLCBzdGF0ZSwgZGVwdGgpLm1hcCgob3BlcmFuZCkgPT4ge1xuICAgICAgICBpZiAodmFsdWUub3BlcmF0aW9uID09IFwiQm9vbGVhbk5vdFwiKSB7XG4gICAgICAgICAgcmV0dXJuIHtzdGF0ZTogb3BlcmFuZC5zdGF0ZSwgdmFsdWU6IHt0eXBlOiBcImJvb2xlYW5cIiwgLi4uKG9wZXJhbmQudmFsdWUua25vd25Cb29sZWFuID09PSB1bmRlZmluZWQgPyB7fSA6IHtrbm93bkJvb2xlYW46ICFvcGVyYW5kLnZhbHVlLmtub3duQm9vbGVhbn0pfX1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBrbm93bkludGVnZXIgPSBvcGVyYW5kLnZhbHVlLmtub3duSW50ZWdlciA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogY2hlY2tlZEk2NCgtb3BlcmFuZC52YWx1ZS5rbm93bkludGVnZXIsIHZhbHVlKVxuXG4gICAgICAgIHJldHVybiB7c3RhdGU6IG9wZXJhbmQuc3RhdGUsIHZhbHVlOiB7dHlwZTogXCJpbnRlZ2VyXCIsIC4uLihrbm93bkludGVnZXIgPT09IHVuZGVmaW5lZCA/IHt9IDoge2tub3duSW50ZWdlcn0pfX1cbiAgICAgIH0pXG4gICAgfVxuICAgIGlmICh2YWx1ZS5raW5kICE9IFwiQmluYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KFwid2FzbVwiLCBcImNvbGxlY3Rpb24gZXhwcmVzc2lvbiByZWFjaGVkIHNjYWxhciBhbmFseXNpc1wiLCB2YWx1ZS5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKHZhbHVlLm9wZXJhdGlvbiA9PSBcIkJvb2xlYW5BbmRcIiB8fCB2YWx1ZS5vcGVyYXRpb24gPT0gXCJCb29sZWFuT3JcIikge1xuICAgICAgLyoqIEB0eXBlIHt7c3RhdGU6IEFuYWx5c2lzU3RhdGUsIHZhbHVlOiBBYnN0cmFjdFZhbHVlfVtdfSAqL1xuICAgICAgY29uc3Qgb3V0Y29tZXMgPSBbXVxuXG4gICAgICBmb3IgKGNvbnN0IGxlZnQgb2YgZXhwcmVzc2lvbih2YWx1ZS5sZWZ0LCBzdGF0ZSwgZGVwdGgpKSB7XG4gICAgICAgIGNvbnN0IHNob3J0Q2lyY3VpdHMgPSB2YWx1ZS5vcGVyYXRpb24gPT0gXCJCb29sZWFuQW5kXCIgPyBsZWZ0LnZhbHVlLmtub3duQm9vbGVhbiA9PT0gZmFsc2UgOiBsZWZ0LnZhbHVlLmtub3duQm9vbGVhbiA9PT0gdHJ1ZVxuICAgICAgICBjb25zdCBtdXN0RXZhbHVhdGUgPSB2YWx1ZS5vcGVyYXRpb24gPT0gXCJCb29sZWFuQW5kXCIgPyBsZWZ0LnZhbHVlLmtub3duQm9vbGVhbiA9PT0gdHJ1ZSA6IGxlZnQudmFsdWUua25vd25Cb29sZWFuID09PSBmYWxzZVxuXG4gICAgICAgIGlmIChzaG9ydENpcmN1aXRzIHx8ICFtdXN0RXZhbHVhdGUpIG91dGNvbWVzLnB1c2goe3N0YXRlOiBsZWZ0LnN0YXRlLCB2YWx1ZToge2tub3duQm9vbGVhbjogdmFsdWUub3BlcmF0aW9uID09IFwiQm9vbGVhbk9yXCIsIHR5cGU6IFwiYm9vbGVhblwifX0pXG4gICAgICAgIGlmICghc2hvcnRDaXJjdWl0cykgb3V0Y29tZXMucHVzaCguLi5leHByZXNzaW9uKHZhbHVlLnJpZ2h0LCBjbG9uZVN0YXRlKGxlZnQuc3RhdGUpLCBkZXB0aCkpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBvdXRjb21lc1xuICAgIH1cblxuICAgIGNvbnN0IG91dGNvbWVzID0gW11cblxuICAgIGZvciAoY29uc3QgbGVmdCBvZiBleHByZXNzaW9uKHZhbHVlLmxlZnQsIHN0YXRlLCBkZXB0aCkpIHtcbiAgICAgIGZvciAoY29uc3QgcmlnaHQgb2YgZXhwcmVzc2lvbih2YWx1ZS5yaWdodCwgbGVmdC5zdGF0ZSwgZGVwdGgpKSB7XG4gICAgICAgIG91dGNvbWVzLnB1c2goYmluYXJ5KHZhbHVlLCBsZWZ0LnZhbHVlLCByaWdodC52YWx1ZSwgcmlnaHQuc3RhdGUpKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvdXRjb21lc1xuICB9XG5cbiAgLyoqXG4gICAqIENvbWJpbmVzIGFic3RyYWN0IG9wZXJhbmRzIGZvciBvbmUgYmluYXJ5IG9wZXJhdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CaW5hcnlFeHByZXNzaW9ufSBleHByZXNzaW9uTm9kZSAtIEJpbmFyeSBleHByZXNzaW9uLlxuICAgKiBAcGFyYW0ge0Fic3RyYWN0VmFsdWV9IGxlZnQgLSBBYnN0cmFjdCBsZWZ0IG9wZXJhbmQuXG4gICAqIEBwYXJhbSB7QWJzdHJhY3RWYWx1ZX0gcmlnaHQgLSBBYnN0cmFjdCByaWdodCBvcGVyYW5kLlxuICAgKiBAcGFyYW0ge0FuYWx5c2lzU3RhdGV9IHN0YXRlIC0gU3RhdGUgYWZ0ZXIgZXZhbHVhdGluZyBib3RoIG9wZXJhbmRzLlxuICAgKiBAcmV0dXJucyB7e3N0YXRlOiBBbmFseXNpc1N0YXRlLCB2YWx1ZTogQWJzdHJhY3RWYWx1ZX19IENvbWJpbmVkIG91dGNvbWUuXG4gICAqL1xuICBmdW5jdGlvbiBiaW5hcnkoZXhwcmVzc2lvbk5vZGUsIGxlZnQsIHJpZ2h0LCBzdGF0ZSkge1xuICAgIGNvbnN0IG9wZXJhdGlvbiA9IGV4cHJlc3Npb25Ob2RlLm9wZXJhdGlvblxuXG4gICAgaWYgKG9wZXJhdGlvbiA9PSBcIlN0cmluZ0NvbmNhdFwiKSB7XG4gICAgICBpZiAobGVmdC5zdHJpbmdMZW5ndGggPT09IHVuZGVmaW5lZCB8fCByaWdodC5zdHJpbmdMZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkoXCJ3YXNtXCIsIFwidW5wcm92YWJsZSBTdHJpbmdDb25jYXQgYnl0ZSBsZW5ndGhcIiwgZXhwcmVzc2lvbk5vZGUubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBjb25zdCBsZW5ndGggPSBhZGRBbGxvY2F0aW9uKGxlZnQuc3RyaW5nTGVuZ3RoLCByaWdodC5zdHJpbmdMZW5ndGgsIGV4cHJlc3Npb25Ob2RlKVxuICAgICAgY29uc3QgYWxsb2NhdGVkID0gYWRkQWxsb2NhdGlvbihzdGF0ZS5hbGxvY2F0ZWQsIGxlbmd0aCwgZXhwcmVzc2lvbk5vZGUpXG4gICAgICBjb25zdCBrbm93blN0cmluZyA9IGxlZnQua25vd25TdHJpbmcgIT09IHVuZGVmaW5lZCAmJiByaWdodC5rbm93blN0cmluZyAhPT0gdW5kZWZpbmVkID8gbGVmdC5rbm93blN0cmluZyArIHJpZ2h0Lmtub3duU3RyaW5nIDogdW5kZWZpbmVkXG5cbiAgICAgIHJldHVybiB7c3RhdGU6IHsuLi5zdGF0ZSwgYWxsb2NhdGVkfSwgdmFsdWU6IHt0eXBlOiBcInN0cmluZ1wiLCBzdHJpbmdMZW5ndGg6IGxlbmd0aCwgLi4uKGtub3duU3RyaW5nID09PSB1bmRlZmluZWQgPyB7fSA6IHtrbm93blN0cmluZ30pfX1cbiAgICB9XG4gICAgaWYgKFtcIkludGVnZXJBZGRcIiwgXCJJbnRlZ2VyU3VidHJhY3RcIiwgXCJJbnRlZ2VyTXVsdGlwbHlcIl0uaW5jbHVkZXMob3BlcmF0aW9uKSkge1xuICAgICAgbGV0IGtub3duSW50ZWdlclxuXG4gICAgICBpZiAobGVmdC5rbm93bkludGVnZXIgIT09IHVuZGVmaW5lZCAmJiByaWdodC5rbm93bkludGVnZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBrbm93bkludGVnZXIgPSBvcGVyYXRpb24gPT0gXCJJbnRlZ2VyQWRkXCIgPyBsZWZ0Lmtub3duSW50ZWdlciArIHJpZ2h0Lmtub3duSW50ZWdlciA6XG4gICAgICAgICAgb3BlcmF0aW9uID09IFwiSW50ZWdlclN1YnRyYWN0XCIgPyBsZWZ0Lmtub3duSW50ZWdlciAtIHJpZ2h0Lmtub3duSW50ZWdlciA6IGxlZnQua25vd25JbnRlZ2VyICogcmlnaHQua25vd25JbnRlZ2VyXG4gICAgICAgIGtub3duSW50ZWdlciA9IGNoZWNrZWRJNjQoa25vd25JbnRlZ2VyLCBleHByZXNzaW9uTm9kZSlcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtzdGF0ZSwgdmFsdWU6IHt0eXBlOiBcImludGVnZXJcIiwgLi4uKGtub3duSW50ZWdlciA9PT0gdW5kZWZpbmVkID8ge30gOiB7a25vd25JbnRlZ2VyfSl9fVxuICAgIH1cbiAgICBpZiAob3BlcmF0aW9uLnN0YXJ0c1dpdGgoXCJJbnRlZ2VyXCIpICYmIG9wZXJhdGlvbiAhPSBcIkludGVnZXJFcXVhbFwiICYmIG9wZXJhdGlvbiAhPSBcIkludGVnZXJOb3RFcXVhbFwiKSB7XG4gICAgICByZXR1cm4ge3N0YXRlLCB2YWx1ZToge2tub3duQm9vbGVhbjogY29tcGFyZUtub3duKG9wZXJhdGlvbiwgbGVmdC5rbm93bkludGVnZXIsIHJpZ2h0Lmtub3duSW50ZWdlciksIHR5cGU6IFwiYm9vbGVhblwifX1cbiAgICB9XG4gICAgaWYgKG9wZXJhdGlvbiA9PSBcIkludGVnZXJFcXVhbFwiIHx8IG9wZXJhdGlvbiA9PSBcIkludGVnZXJOb3RFcXVhbFwiKSB7XG4gICAgICByZXR1cm4ge3N0YXRlLCB2YWx1ZToge2tub3duQm9vbGVhbjogZXF1YWxLbm93bihsZWZ0Lmtub3duSW50ZWdlciwgcmlnaHQua25vd25JbnRlZ2VyLCBvcGVyYXRpb24uZW5kc1dpdGgoXCJOb3RFcXVhbFwiKSksIHR5cGU6IFwiYm9vbGVhblwifX1cbiAgICB9XG4gICAgaWYgKG9wZXJhdGlvbiA9PSBcIkJvb2xlYW5FcXVhbFwiIHx8IG9wZXJhdGlvbiA9PSBcIkJvb2xlYW5Ob3RFcXVhbFwiKSB7XG4gICAgICByZXR1cm4ge3N0YXRlLCB2YWx1ZToge2tub3duQm9vbGVhbjogZXF1YWxLbm93bihsZWZ0Lmtub3duQm9vbGVhbiwgcmlnaHQua25vd25Cb29sZWFuLCBvcGVyYXRpb24uZW5kc1dpdGgoXCJOb3RFcXVhbFwiKSksIHR5cGU6IFwiYm9vbGVhblwifX1cbiAgICB9XG5cbiAgICByZXR1cm4ge3N0YXRlLCB2YWx1ZToge2tub3duQm9vbGVhbjogZXF1YWxLbm93bihsZWZ0Lmtub3duU3RyaW5nLCByaWdodC5rbm93blN0cmluZywgb3BlcmF0aW9uID09IFwiU3RyaW5nTm90RXF1YWxcIiksIHR5cGU6IFwiYm9vbGVhblwifX1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWplY3RzIHBhdGgtc3RhdGUgZ3Jvd3RoIGJleW9uZCB0aGUgZGV0ZXJtaW5pc3RpYyBhbmFseXNpcyBib3VuZC5cbiAgICogQHBhcmFtIHtBbmFseXNpc1N0YXRlW119IGNhbmRpZGF0ZXMgLSBDYW5kaWRhdGUgc3RhdGVzLlxuICAgKiBAcGFyYW0ge3tsb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259fSBub2RlIC0gUmVsYXRlZCBzZW1hbnRpYyBub2RlLlxuICAgKiBAcmV0dXJucyB7QW5hbHlzaXNTdGF0ZVtdfSBBY2NlcHRlZCBzdGF0ZXMuXG4gICAqL1xuICBmdW5jdGlvbiBib3VuZGVkU3RhdGVzKGNhbmRpZGF0ZXMsIG5vZGUpIHtcbiAgICBpZiAoY2FuZGlkYXRlcy5sZW5ndGggPiBtYXhpbXVtQW5hbHlzaXNTdGVwcykgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KFwid2FzbVwiLCBcInVucHJvdmFibGUgcGF0aC1zZW5zaXRpdmUgc2NyYXRjaCBhbGxvY2F0aW9uIHN0YXRlIGNvdW50XCIsIG5vZGUubG9jYXRpb24pXG5cbiAgICByZXR1cm4gY2FuZGlkYXRlc1xuICB9XG59XG5cbi8qKlxuICogQ29tcGFyZXMgdHdvIGtub3duIGludGVnZXIgb3BlcmFuZHMgd2hlbiBhdmFpbGFibGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gb3BlcmF0aW9uIC0gU2VtYW50aWMgY29tcGFyaXNvbiBvcGVyYXRpb24uXG4gKiBAcGFyYW0ge2JpZ2ludCB8IHVuZGVmaW5lZH0gbGVmdCAtIEtub3duIGxlZnQgb3BlcmFuZC5cbiAqIEBwYXJhbSB7YmlnaW50IHwgdW5kZWZpbmVkfSByaWdodCAtIEtub3duIHJpZ2h0IG9wZXJhbmQuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbiB8IHVuZGVmaW5lZH0gS25vd24gY29tcGFyaXNvbiByZXN1bHQuXG4gKi9cbmZ1bmN0aW9uIGNvbXBhcmVLbm93bihvcGVyYXRpb24sIGxlZnQsIHJpZ2h0KSB7XG4gIGlmIChsZWZ0ID09PSB1bmRlZmluZWQgfHwgcmlnaHQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZFxuICBpZiAob3BlcmF0aW9uID09IFwiSW50ZWdlckxlc3NUaGFuXCIpIHJldHVybiBsZWZ0IDwgcmlnaHRcbiAgaWYgKG9wZXJhdGlvbiA9PSBcIkludGVnZXJMZXNzVGhhbk9yRXF1YWxcIikgcmV0dXJuIGxlZnQgPD0gcmlnaHRcbiAgaWYgKG9wZXJhdGlvbiA9PSBcIkludGVnZXJHcmVhdGVyVGhhblwiKSByZXR1cm4gbGVmdCA+IHJpZ2h0XG5cbiAgcmV0dXJuIGxlZnQgPj0gcmlnaHRcbn1cblxuLyoqXG4gKiBDb21wYXJlcyB0d28ga25vd24gc2FtZS10eXBlIG9wZXJhbmRzIHdoZW4gYXZhaWxhYmxlLlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSB7VCB8IHVuZGVmaW5lZH0gbGVmdCAtIEtub3duIGxlZnQgb3BlcmFuZC5cbiAqIEBwYXJhbSB7VCB8IHVuZGVmaW5lZH0gcmlnaHQgLSBLbm93biByaWdodCBvcGVyYW5kLlxuICogQHBhcmFtIHtib29sZWFufSBpbnZlcnQgLSBXaGV0aGVyIHRvIGludmVydCBlcXVhbGl0eS5cbiAqIEByZXR1cm5zIHtib29sZWFuIHwgdW5kZWZpbmVkfSBLbm93biBlcXVhbGl0eSByZXN1bHQuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsS25vd24obGVmdCwgcmlnaHQsIGludmVydCkge1xuICByZXR1cm4gbGVmdCA9PT0gdW5kZWZpbmVkIHx8IHJpZ2h0ID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBpbnZlcnQgPyBsZWZ0ICE9PSByaWdodCA6IGxlZnQgPT09IHJpZ2h0XG59XG5cbi8qKlxuICogQ2hlY2tzIG9uZSBjb21waWxlLXRpbWUgaW50ZWdlciBhZ2FpbnN0IHNpZ25lZCBpNjQgYm91bmRzLlxuICogQHBhcmFtIHtiaWdpbnR9IHZhbHVlIC0gQ2FuZGlkYXRlIGludGVnZXIuXG4gKiBAcGFyYW0ge3tsb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259fSBub2RlIC0gUmVsYXRlZCBzZW1hbnRpYyBub2RlLlxuICogQHJldHVybnMge2JpZ2ludH0gQ2hlY2tlZCBpbnRlZ2VyLlxuICovXG5mdW5jdGlvbiBjaGVja2VkSTY0KHZhbHVlLCBub2RlKSB7XG4gIGlmICh2YWx1ZSA8IC05MjIzMzcyMDM2ODU0Nzc1ODA4biB8fCB2YWx1ZSA+IDkyMjMzNzIwMzY4NTQ3NzU4MDduKSB7XG4gICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KFwid2FzbVwiLCBcImNvbXBpbGUtdGltZS1rbm93biBzaWduZWQgaTY0IG92ZXJmbG93XCIsIG5vZGUubG9jYXRpb24pXG4gIH1cblxuICByZXR1cm4gdmFsdWVcbn1cblxuLyoqXG4gKiBBZGRzIGJvdW5kZWQgYWxsb2NhdGlvbiBjb3VudHMgd2l0aG91dCBhcHByb3hpbWF0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IGxlZnQgLSBFeGlzdGluZyBhbGxvY2F0aW9uIGNvdW50LlxuICogQHBhcmFtIHtudW1iZXJ9IHJpZ2h0IC0gQWRkaXRpb25hbCBhbGxvY2F0aW9uIGNvdW50LlxuICogQHBhcmFtIHt7bG9jYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufX0gbm9kZSAtIFJlbGF0ZWQgc2VtYW50aWMgbm9kZS5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IENoZWNrZWQgdG90YWwuXG4gKi9cbmZ1bmN0aW9uIGFkZEFsbG9jYXRpb24obGVmdCwgcmlnaHQsIG5vZGUpIHtcbiAgY29uc3QgdG90YWwgPSBsZWZ0ICsgcmlnaHRcblxuICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKHRvdGFsKSB8fCB0b3RhbCA8IDApIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShcIndhc21cIiwgXCJzY3JhdGNoIGFsbG9jYXRpb24gYXJpdGhtZXRpYyBvdmVyZmxvd1wiLCBub2RlLmxvY2F0aW9uKVxuICBpZiAodG90YWwgPiBzY3JhdGNoQ2FwYWNpdHkpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShcIndhc21cIiwgYHNjcmF0Y2ggYWxsb2NhdGlvbiBhYm92ZSAke3NjcmF0Y2hDYXBhY2l0eX0gYnl0ZXNgLCBub2RlLmxvY2F0aW9uKVxuXG4gIHJldHVybiB0b3RhbFxufVxuXG4vKipcbiAqIENsb25lcyBvbmUgcGF0aCBzdGF0ZSBhbmQgaXRzIGxleGljYWwgZW52aXJvbm1lbnQuXG4gKiBAcGFyYW0ge0FuYWx5c2lzU3RhdGV9IHN0YXRlIC0gU3RhdGUgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7QW5hbHlzaXNTdGF0ZX0gRGV0YWNoZWQgc3RhdGUuXG4gKi9cbmZ1bmN0aW9uIGNsb25lU3RhdGUoc3RhdGUpIHsgcmV0dXJuIHsuLi5zdGF0ZSwgZW52OiBuZXcgTWFwKHN0YXRlLmVudil9IH1cblxuLyoqXG4gKiBSZW1vdmVzIGJpbmRpbmdzIGRlY2xhcmVkIG9ubHkgaW5zaWRlIGEgYnJhbmNoLlxuICogQHBhcmFtIHtBbmFseXNpc1N0YXRlW119IHN0YXRlcyAtIEJyYW5jaCByZXN1bHQgc3RhdGVzLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBBYnN0cmFjdFZhbHVlPn0gcGFyZW50IC0gUGFyZW50IGxleGljYWwgZW52aXJvbm1lbnQuXG4gKiBAcmV0dXJucyB7QW5hbHlzaXNTdGF0ZVtdfSBTdGF0ZXMgcmVzdHJpY3RlZCB0byBwYXJlbnQgYmluZGluZ3MuXG4gKi9cbmZ1bmN0aW9uIHdpdGhvdXRCcmFuY2hMb2NhbHMoc3RhdGVzLCBwYXJlbnQpIHtcbiAgcmV0dXJuIHN0YXRlcy5tYXAoKHN0YXRlKSA9PiB7XG4gICAgY29uc3QgZW52ID0gbmV3IE1hcChbLi4uc3RhdGUuZW52XS5maWx0ZXIoKFtuYW1lXSkgPT4gcGFyZW50LmhhcyhuYW1lKSkpXG5cbiAgICByZXR1cm4gey4uLnN0YXRlLCBlbnZ9XG4gIH0pXG59XG5cbi8qKlxuICogUmVzb2x2ZXMgb25lIGV4cHJlc3Npb24ncyBzZW1hbnRpYyBzY2FsYXIgdHlwZS5cbiAqIEBwYXJhbSB7RXhwcmVzc2lvbn0gZXhwcmVzc2lvbiAtIEV4cHJlc3Npb24gdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgTG9jYWxCaW5kaW5nPn0gYmluZGluZ3MgLSBMZXhpY2FsIGxvY2FsIGJpbmRpbmdzLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uPn0gZnVuY3Rpb25zIC0gU2VtYW50aWMgZGVjbGFyYXRpb25zIGJ5IG5hbWUuXG4gKiBAcmV0dXJucyB7U2NhbGFyfSBFeHByZXNzaW9uIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGV4cHJlc3Npb25UeXBlKGV4cHJlc3Npb24sIGJpbmRpbmdzLCBmdW5jdGlvbnMpIHtcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkludGVnZXJMaXRlcmFsXCIpIHJldHVybiBcImludGVnZXJcIlxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQm9vbGVhbkxpdGVyYWxcIikgcmV0dXJuIFwiYm9vbGVhblwiXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJTdHJpbmdMaXRlcmFsXCIpIHJldHVybiBcInN0cmluZ1wiXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJVbmFyeUV4cHJlc3Npb25cIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJCaW5hcnlFeHByZXNzaW9uXCIpIHJldHVybiBleHByZXNzaW9uLnR5cGVcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkNhbGxFeHByZXNzaW9uXCIpIHtcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGZ1bmN0aW9ucy5nZXQoZXhwcmVzc2lvbi5jYWxsZWUpXG5cbiAgICBpZiAoIWRlY2xhcmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJWYWxpZGF0ZWQgV2FzbSBleHByZXNzaW9uIG9taXR0ZWQgaXRzIGNhbGwgZGVjbGFyYXRpb24uXCIpXG5cbiAgICByZXR1cm4gd2FzbVJldHVyblR5cGUoZGVjbGFyYXRpb24pXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCAhPSBcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KFwid2FzbVwiLCBcImNvbGxlY3Rpb24gZXhwcmVzc2lvbiByZWFjaGVkIHNjYWxhciB0eXBlIGluZmVyZW5jZVwiLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IGJpbmRpbmcgPSBiaW5kaW5ncy5nZXQoZXhwcmVzc2lvbi5uYW1lKVxuXG4gIGlmICghYmluZGluZykgdGhyb3cgbmV3IEVycm9yKFwiVmFsaWRhdGVkIFdhc20gZXhwcmVzc2lvbiBvbWl0dGVkIGl0cyBsb2NhbCBiaW5kaW5nLlwiKVxuXG4gIHJldHVybiBiaW5kaW5nLnR5cGVcbn1cblxuLyoqXG4gKiBOYXJyb3dzIGEgZGVjbGFyYXRpb24gcmV0dXJuIGFmdGVyIHRoZSBXYXNtIFRhc2sgMDA1IGNhcGFiaWxpdHkgcHJlZmxpZ2h0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9ufSBkZWNsYXJhdGlvbiAtIFZhbGlkYXRlZCBkZWNsYXJhdGlvbi5cbiAqIEByZXR1cm5zIHtTY2FsYXJ9IFN1cHBvcnRlZCBXYXNtIHNjYWxhciByZXR1cm4uXG4gKi9cbmZ1bmN0aW9uIHdhc21SZXR1cm5UeXBlKGRlY2xhcmF0aW9uKSB7XG4gIGlmIChkZWNsYXJhdGlvbi5yZXR1cm5UeXBlLmtpbmQgIT0gXCJUeXBlUmVmZXJlbmNlXCIgfHwgZGVjbGFyYXRpb24ucmV0dXJuVHlwZS5uYW1lID09IFwidm9pZFwiKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShcIndhc21cIiwgXCJUYXNrIDAwNSB2b2lkIGZ1bmN0aW9uIHJldHVyblwiLCBkZWNsYXJhdGlvbi5sb2NhdGlvbilcbiAgfVxuXG4gIHJldHVybiBkZWNsYXJhdGlvbi5yZXR1cm5UeXBlLm5hbWVcbn1cblxuLyoqXG4gKiBOYXJyb3dzIG9uZSBzY2FsYXIgYWZ0ZXIgV2FzbSBjb2xsZWN0aW9uIGNhcGFiaWxpdHkgcmVqZWN0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZX0gdHlwZSAtIFNlbWFudGljIHZhbHVlIHR5cGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBsb2NhdGlvbiAtIE93bmluZyBsb2NhdGlvbi5cbiAqIEByZXR1cm5zIHtTY2FsYXJ9IFNjYWxhciB0eXBlLlxuICovXG5mdW5jdGlvbiB3YXNtU2NhbGFyVHlwZSh0eXBlLCBsb2NhdGlvbikge1xuICBpZiAodHlwZS5raW5kICE9IFwiVHlwZVJlZmVyZW5jZVwiKSByZXR1cm4gdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KFwid2FzbVwiLCBcIlRhc2sgMDA2IGltbXV0YWJsZSBjb2xsZWN0aW9uIHR5cGVcIiwgbG9jYXRpb24pXG5cbiAgcmV0dXJuIHR5cGUubmFtZVxufVxuXG4vKipcbiAqIEZsYXR0ZW5zIG9uZSBzZW1hbnRpYyBzY2FsYXIgaW50byBXYXNtIHZhbHVlIHR5cGVzLlxuICogQHBhcmFtIHtTY2FsYXJ9IHR5cGUgLSBTZW1hbnRpYyBzY2FsYXIgdHlwZS5cbiAqIEByZXR1cm5zIHsoXCJpMzJcIiB8IFwiaTY0XCIpW119IFdhc20gdmFsdWUgdHlwZXMuXG4gKi9cbmZ1bmN0aW9uIHdhc21UeXBlcyh0eXBlKSB7IHJldHVybiB0eXBlID09IFwiaW50ZWdlclwiID8gW1wiaTY0XCJdIDogdHlwZSA9PSBcImJvb2xlYW5cIiA/IFtcImkzMlwiXSA6IFtcImkzMlwiLCBcImkzMlwiXSB9XG5cbi8qKlxuICogQWxpZ25zIGFuIHVuc2lnbmVkIHNpemUgdXB3YXJkLlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIC0gVW5hbGlnbmVkIHZhbHVlLlxuICogQHBhcmFtIHtudW1iZXJ9IGFsaWdubWVudCAtIFJlcXVpcmVkIGFsaWdubWVudC5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IEFsaWduZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGFsaWduKHZhbHVlLCBhbGlnbm1lbnQpIHsgcmV0dXJuIE1hdGguY2VpbCh2YWx1ZSAvIGFsaWdubWVudCkgKiBhbGlnbm1lbnQgfVxuXG4vKipcbiAqIENoZWNrcyBhIGNvbXB1dGVkIG1vZHVsZSBzaXplIGFnYWluc3QgdGhlIHBvcnRhYmxlIHUzMiBkb21haW4uXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgLSBDYW5kaWRhdGUgc2l6ZS5cbiAqIEBwYXJhbSB7e2xvY2F0aW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn19IG5vZGUgLSBSZWxhdGVkIHNlbWFudGljIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gY2FwYWJpbGl0eSAtIEZhaWx1cmUgY2FwYWJpbGl0eSBkZXNjcmlwdGlvbi5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IENoZWNrZWQgc2l6ZS5cbiAqL1xuZnVuY3Rpb24gY2hlY2tlZFNpemUodmFsdWUsIG5vZGUsIGNhcGFiaWxpdHkpIHtcbiAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcih2YWx1ZSkgfHwgdmFsdWUgPCAwIHx8IHZhbHVlID4gMHhmZmZmZmZmZikgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KFwid2FzbVwiLCBjYXBhYmlsaXR5LCBub2RlLmxvY2F0aW9uKVxuXG4gIHJldHVybiB2YWx1ZVxufVxuXG4vKipcbiAqIEVuY29kZXMgYW4gdW5zaWduZWQgdTMyIExFQjEyOCB2YWx1ZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSAtIFVuc2lnbmVkIHZhbHVlLlxuICogQHJldHVybnMge251bWJlcltdfSBFbmNvZGVkIGJ5dGVzLlxuICovXG5mdW5jdGlvbiB1MzIodmFsdWUpIHtcbiAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcih2YWx1ZSkgfHwgdmFsdWUgPCAwIHx8IHZhbHVlID4gMHhmZmZmZmZmZikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJVbnNpZ25lZCBXZWJBc3NlbWJseSBpbnRlZ2VyIGlzIG91dHNpZGUgdTMyLlwiKVxuICBjb25zdCBieXRlcyA9IFtdXG4gIGxldCByZW1haW5pbmcgPSB2YWx1ZVxuXG4gIGRvIHtcbiAgICBsZXQgYnl0ZSA9IHJlbWFpbmluZyAlIDEyOFxuXG4gICAgcmVtYWluaW5nID0gTWF0aC5mbG9vcihyZW1haW5pbmcgLyAxMjgpXG4gICAgaWYgKHJlbWFpbmluZyAhPSAwKSBieXRlIHw9IDB4ODBcbiAgICBieXRlcy5wdXNoKGJ5dGUpXG4gIH0gd2hpbGUgKHJlbWFpbmluZyAhPSAwKVxuXG4gIHJldHVybiBieXRlc1xufVxuXG4vKipcbiAqIEVuY29kZXMgYSBzaWduZWQgaTMyIExFQjEyOCB2YWx1ZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSAtIFNpZ25lZCB2YWx1ZS5cbiAqIEByZXR1cm5zIHtudW1iZXJbXX0gRW5jb2RlZCBieXRlcy5cbiAqL1xuZnVuY3Rpb24gczMyKHZhbHVlKSB7IHJldHVybiBzNjQoQmlnSW50KHZhbHVlKSkgfVxuXG4vKipcbiAqIEVuY29kZXMgYSBzaWduZWQgaTY0IExFQjEyOCB2YWx1ZS5cbiAqIEBwYXJhbSB7YmlnaW50fSB2YWx1ZSAtIFNpZ25lZCB2YWx1ZS5cbiAqIEByZXR1cm5zIHtudW1iZXJbXX0gRW5jb2RlZCBieXRlcy5cbiAqL1xuZnVuY3Rpb24gczY0KHZhbHVlKSB7XG4gIGNvbnN0IGJ5dGVzID0gW11cbiAgbGV0IHJlbWFpbmluZyA9IHZhbHVlXG4gIGxldCBkb25lID0gZmFsc2VcblxuICB3aGlsZSAoIWRvbmUpIHtcbiAgICBsZXQgYnl0ZSA9IE51bWJlcihyZW1haW5pbmcgJiAweDdmbilcblxuICAgIHJlbWFpbmluZyA+Pj0gN25cbiAgICBjb25zdCBzaWduU2V0ID0gKGJ5dGUgJiAweDQwKSAhPSAwXG5cbiAgICBkb25lID0gcmVtYWluaW5nID09IDBuICYmICFzaWduU2V0IHx8IHJlbWFpbmluZyA9PSAtMW4gJiYgc2lnblNldFxuICAgIGlmICghZG9uZSkgYnl0ZSB8PSAweDgwXG4gICAgYnl0ZXMucHVzaChieXRlKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbi8qKlxuICogRW5jb2RlcyBhIGxlbmd0aC1wcmVmaXhlZCBVVEYtOCBXYXNtIG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgLSBOYW1lIHZhbHVlLlxuICogQHJldHVybnMge251bWJlcltdfSBFbmNvZGVkIGJ5dGVzLlxuICovXG5mdW5jdGlvbiBuYW1lQnl0ZXModmFsdWUpIHtcbiAgY29uc3QgYnl0ZXMgPSBlbmNvZGVyLmVuY29kZSh2YWx1ZSlcblxuICByZXR1cm4gWy4uLnUzMihieXRlcy5ieXRlTGVuZ3RoKSwgLi4uYnl0ZXNdXG59XG5cbi8qKlxuICogRXh0cmFjdHMgY29udGV4dHVhbCByZWxhdGVkIG9yaWdpbnMgZnJvbSBvbmUgc2VtYW50aWMgcmVjb3JkLlxuICogQHBhcmFtIHtTZW1hbnRpY05vZGVQcm92ZW5hbmNlfSByZWNvcmQgLSBTZW1hbnRpYyBwcm92ZW5hbmNlIHJlY29yZC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNPcmlnaW59IFtvcmlnaW5dIC0gT3B0aW9uYWwgZXhhY3Qgc2VtYW50aWMgb3JpZ2luLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlbGF0ZWRPcmlnaW5bXX0gUmVsYXRlZCBvcmlnaW5zLlxuICovXG5mdW5jdGlvbiByZWxhdGVkT3JpZ2lucyhyZWNvcmQsIG9yaWdpbiA9IHJlY29yZC5vcmlnaW4pIHtcbiAgaWYgKG9yaWdpbi5raW5kID09IFwic291cmNlXCIpIHtcbiAgICByZXR1cm4gW3tsb2NhdGlvbjogb3JpZ2luLmxvY2F0aW9uLCBub2RlSWQ6IHJlY29yZC5pZCwgcm9sZTogXCJyZWxhdGVkIHNlbWFudGljIG9jY3VycmVuY2VcIiwgc291cmNlSWQ6IG9yaWdpbi5zb3VyY2VJZCxcbiAgICAgIC4uLihyZWNvcmQuc3ltYm9sSWQgPyB7c3ltYm9sSWQ6IHJlY29yZC5zeW1ib2xJZH0gOiB7fSl9XVxuICB9XG4gIGNvbnN0IG9yaWdpbnMgPSBvcmlnaW4ua2luZCA9PSBcImRlcml2ZWRcIiA/IG9yaWdpbi5vcmlnaW5zIDogb3JpZ2luLnJlbGF0ZWRPcmlnaW5zXG5cbiAgcmV0dXJuIG9yaWdpbnMubWFwKChvcmlnaW4pID0+ICh7Li4ub3JpZ2luLCBub2RlSWQ6IG9yaWdpbi5ub2RlSWQgPz8gcmVjb3JkLmlkLCByb2xlOiBvcmlnaW4ucm9sZSA/PyBcInJlbGF0ZWQgc2VtYW50aWMgb2NjdXJyZW5jZVwiLFxuICAgIC4uLihyZWNvcmQuc3ltYm9sSWQgJiYgIW9yaWdpbi5zeW1ib2xJZCA/IHtzeW1ib2xJZDogcmVjb3JkLnN5bWJvbElkfSA6IHt9KX0pKVxufVxuXG4vKipcbiAqIFJlc29sdmVzIGEgcGFyc2VyLW93bmVkIHRva2VuIHJvbGUgdG8gaXRzIGNhbm9uaWNhbCBzb3VyY2UgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIGNyZWF0ZUdlbmVyYXRpb25JbmRleD59IGluZGV4IC0gQ2Fub25pY2FsIHByb3ZlbmFuY2UgaW5kZXguXG4gKiBAcGFyYW0ge1NlbWFudGljTm9kZVByb3ZlbmFuY2V9IHJlY29yZCAtIFNlbWFudGljIG9jY3VycmVuY2UgcmVjb3JkLlxuICogQHBhcmFtIHtzdHJpbmd9IHJvbGUgLSBQYXJzZXItb3duZWQgdG9rZW4gcm9sZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY09yaWdpbn0gRXhhY3Qgcm9sZSBvcmlnaW4sIG9yIHRoZSBvY2N1cnJlbmNlIG9yaWdpbiB3aGVuIHVuYXZhaWxhYmxlLlxuICovXG5mdW5jdGlvbiBvcmlnaW5Gb3JSb2xlKGluZGV4LCByZWNvcmQsIHJvbGUpIHtcbiAgY29uc3QgbG9jYXRpb24gPSByZWNvcmQucmFuZ2VzW3JvbGVdXG5cbiAgaWYgKCFsb2NhdGlvbikgcmV0dXJuIHJlY29yZC5vcmlnaW5cbiAgLyoqIEB0eXBlIHtzdHJpbmcgfCB1bmRlZmluZWR9ICovXG4gIGxldCBmYWxsYmFja1NvdXJjZUlkXG5cbiAgaWYgKHJlY29yZC5vcmlnaW4ua2luZCA9PSBcInNvdXJjZVwiICYmIHJlY29yZC5vcmlnaW4ubG9jYXRpb24uZmlsZW5hbWUgPT0gbG9jYXRpb24uZmlsZW5hbWUpIGZhbGxiYWNrU291cmNlSWQgPSByZWNvcmQub3JpZ2luLnNvdXJjZUlkXG4gIGVsc2UgaWYgKHJlY29yZC5vcmlnaW4ua2luZCA9PSBcImRlcml2ZWRcIikge1xuICAgIGZhbGxiYWNrU291cmNlSWQgPSByZWNvcmQub3JpZ2luLm9yaWdpbnMuZmluZCgob3JpZ2luKSA9PiBvcmlnaW4ubG9jYXRpb24uZmlsZW5hbWUgPT0gbG9jYXRpb24uZmlsZW5hbWUpPy5zb3VyY2VJZFxuICB9IGVsc2UgaWYgKHJlY29yZC5vcmlnaW4ua2luZCA9PSBcInN5bnRoZXRpY1wiKSB7XG4gICAgZmFsbGJhY2tTb3VyY2VJZCA9IHJlY29yZC5vcmlnaW4ucmVsYXRlZE9yaWdpbnMuZmluZCgob3JpZ2luKSA9PiBvcmlnaW4ubG9jYXRpb24uZmlsZW5hbWUgPT0gbG9jYXRpb24uZmlsZW5hbWUpPy5zb3VyY2VJZFxuICB9XG4gIGNvbnN0IHNvdXJjZSA9IGluZGV4LnByb3ZlbmFuY2Uuc291cmNlcy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5pZCA9PSBmYWxsYmFja1NvdXJjZUlkKSA/P1xuICAgIGluZGV4LnByb3ZlbmFuY2Uuc291cmNlcy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5maWxlbmFtZSA9PSBsb2NhdGlvbi5maWxlbmFtZSlcblxuICByZXR1cm4gc291cmNlID8ge2tpbmQ6IFwic291cmNlXCIsIGxvY2F0aW9uLCBzb3VyY2VJZDogc291cmNlLmlkfSA6IHJlY29yZC5vcmlnaW5cbn1cblxuLyoqXG4gKiBQcm9qZWN0cyBieXRlIHByb3ZlbmFuY2UgdG8gdGhlIFdhc20gU291cmNlIE1hcCB2MyBjb252ZW50aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpZm9sZEJ5dGVNYXBwaW5nfSBtYXBwaW5nIC0gQXV0aG9yaXRhdGl2ZSBieXRlIG1hcHBpbmcuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvdmVuYW5jZX0gcHJvdmVuYW5jZSAtIFNvdXJjZSByZWdpc3RyeS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCJAanJpZGdld2VsbC9nZW4tbWFwcGluZ1wiKS5FbmNvZGVkU291cmNlTWFwfSBTb3VyY2UgTWFwIHYzIHByb2plY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVdhc21Tb3VyY2VNYXAobWFwcGluZywgcHJvdmVuYW5jZSkge1xuICBjb25zdCBnZW5lcmF0ZWQgPSBuZXcgR2VuTWFwcGluZyh7ZmlsZTogbWFwcGluZy5nZW5lcmF0ZWQucGF0aH0pXG4gIGNvbnN0IHNvdXJjZXNCeUlkID0gbmV3IE1hcChwcm92ZW5hbmNlLnNvdXJjZXMubWFwKChzb3VyY2UpID0+IFtzb3VyY2UuaWQsIHNvdXJjZV0pKVxuICBjb25zdCBzeW1ib2xzQnlJZCA9IG5ldyBNYXAocHJvdmVuYW5jZS5zeW1ib2xzLm1hcCgoc3ltYm9sKSA9PiBbc3ltYm9sLmlkLCBzeW1ib2xdKSlcblxuICBmb3IgKGNvbnN0IHNvdXJjZSBvZiBwcm92ZW5hbmNlLnNvdXJjZXMpIHNldFNvdXJjZUNvbnRlbnQoZ2VuZXJhdGVkLCBzb3VyY2UuZmlsZW5hbWUsIHNvdXJjZS5jb250ZW50KVxuICBmb3IgKGNvbnN0IHJhbmdlIG9mIG1hcHBpbmcucmFuZ2VzKSB7XG4gICAgY29uc3QgbG9jYXRpb24gPSBwcmltYXJ5TG9jYXRpb24ocmFuZ2Uub3JpZ2luKVxuXG4gICAgaWYgKCFsb2NhdGlvbiB8fCByYW5nZS5vcmlnaW4ua2luZCA9PSBcInN5bnRoZXRpY1wiKSB7XG4gICAgICBtYXliZUFkZFNlZ21lbnQoZ2VuZXJhdGVkLCAwLCByYW5nZS5nZW5lcmF0ZWQuc3RhcnQpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBjb25zdCBzb3VyY2VJZCA9IHJhbmdlLm9yaWdpbi5raW5kID09IFwic291cmNlXCIgPyByYW5nZS5vcmlnaW4uc291cmNlSWQgOiByYW5nZS5vcmlnaW4ub3JpZ2luc1swXT8uc291cmNlSWRcbiAgICBjb25zdCBzb3VyY2UgPSBzb3VyY2VJZCA/IHNvdXJjZXNCeUlkLmdldChzb3VyY2VJZCkgOiB1bmRlZmluZWRcblxuICAgIGlmICghc291cmNlKSB0aHJvdyBuZXcgRXJyb3IoXCJWYWxpZGF0ZWQgV2FzbSBieXRlIG9yaWdpbiBvbWl0dGVkIGl0cyByZWdpc3RlcmVkIHNvdXJjZS5cIilcbiAgICBpZiAocmFuZ2Uuc3ltYm9sSWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgYWRkU2VnbWVudChnZW5lcmF0ZWQsIDAsIHJhbmdlLmdlbmVyYXRlZC5zdGFydCwgc291cmNlLmZpbGVuYW1lLCBsb2NhdGlvbi5zdGFydC5saW5lIC0gMSwgbG9jYXRpb24uc3RhcnQuY29sdW1uIC0gMSxcbiAgICAgICAgbnVsbCwgc291cmNlLmNvbnRlbnQpXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHN5bWJvbCA9IHN5bWJvbHNCeUlkLmdldChyYW5nZS5zeW1ib2xJZClcblxuICAgICAgaWYgKCFzeW1ib2wpIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRlZCBXYXNtIGJ5dGUgcmFuZ2Ugb21pdHRlZCBpdHMgc2VtYW50aWMgc3ltYm9sLlwiKVxuICAgICAgYWRkU2VnbWVudChnZW5lcmF0ZWQsIDAsIHJhbmdlLmdlbmVyYXRlZC5zdGFydCwgc291cmNlLmZpbGVuYW1lLCBsb2NhdGlvbi5zdGFydC5saW5lIC0gMSwgbG9jYXRpb24uc3RhcnQuY29sdW1uIC0gMSxcbiAgICAgICAgc3ltYm9sLm5hbWUsIHNvdXJjZS5jb250ZW50KVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0b0VuY29kZWRNYXAoZ2VuZXJhdGVkKVxufVxuXG4vKipcbiAqIENyZWF0ZXMgb25lIG1hcHBlZCBnZW5lcmF0ZWQgdGV4dCBhcnRpZmFjdC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZW50IC0gQ29tcGxldGUgYXJ0aWZhY3QgY29udGVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gQXJ0aWZhY3QgcGF0aC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuR2VuZXJhdGVkVGV4dExhbmd1YWdlfSBsYW5ndWFnZSAtIEdlbmVyYXRlZCB0ZXh0IHN5bnRheC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuR2VuZXJhdGVkQXJ0aWZhY3RSb2xlfSByb2xlIC0gQXJ0aWZhY3Qgcm9sZS5cbiAqIEBwYXJhbSB7U2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFNvdXJjZSBzZW1hbnRpYyBtb2R1bGUuXG4gKiBAcGFyYW0ge3tmaWxlbmFtZTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcsIGxhbmd1YWdlPzogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX1bXSB8IHVuZGVmaW5lZH0gc291cmNlcyAtIFNvdXJjZSBvdmVycmlkZXMuXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVhc29uIC0gU3ludGhldGljIG1hcHBpbmcgcmVhc29uLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkdlbmVyYXRlZFNldEFydGlmYWN0fSBHZW5lcmF0ZWQgYXJ0aWZhY3QuXG4gKi9cbmZ1bmN0aW9uIHRleHRBcnRpZmFjdChjb250ZW50LCBwYXRoLCBsYW5ndWFnZSwgcm9sZSwgbW9kdWxlLCBzb3VyY2VzLCByZWFzb24pIHtcbiAgY29uc3Qgd3JpdGVyID0gbmV3IFNvdXJjZVdyaXRlcih7ZmlsZW5hbWU6IHBhdGgsIGxhbmd1YWdlLCBtb2R1bGUsIHNvdXJjZXN9KVxuXG4gIHdyaXRlci5zeW50aGV0aWMoY29udGVudCwgcmVhc29uLCBbbW9kdWxlXSwgW1wiXCJdKVxuICBjb25zdCBtYXBwaW5nID0gZmluYWxpemVNYXBwaW5nKHdyaXRlci5maW5pc2goKSlcblxuICByZXR1cm4ge1xuICAgIGNvbnRlbnQsXG4gICAgY29udGVudEtpbmQ6IFwidGV4dFwiLFxuICAgIG1lZGlhVHlwZTogcGF0aC5lbmRzV2l0aChcIi5odG1sXCIpID8gXCJ0ZXh0L2h0bWxcIiA6IFwidGV4dC9qYXZhc2NyaXB0XCIsXG4gICAgb3duZXJzaGlwOiBcImdlbmVyYXRlZFwiLFxuICAgIHBhdGgsXG4gICAgcHJvdmVuYW5jZToge2tpbmQ6IFwidGV4dFwiLCBtYXBwaW5nLCBzb3VyY2VNYXA6IHRvU291cmNlTWFwVjMobWFwcGluZyl9LFxuICAgIHJvbGVcbiAgfVxufVxuXG5jb25zdCBzZW1hbnRpZm9sZExvYWRlciA9IGBjb25zdCBleHBlY3RlZEltcG9ydHMgPSBbXG4gIFtcInNlbWFudGlmb2xkXCIsIFwicHJpbnRfaTY0XCIsIFtcImk2NFwiXSwgW11dLFxuICBbXCJzZW1hbnRpZm9sZFwiLCBcInByaW50X2Jvb2xcIiwgW1wiaTMyXCJdLCBbXV0sXG4gIFtcInNlbWFudGlmb2xkXCIsIFwicHJpbnRfc3RyaW5nXCIsIFtcImkzMlwiLCBcImkzMlwiXSwgW11dXG5dXG5cbmV4cG9ydCBjbGFzcyBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3Ioc3RhZ2UsIG1lc3NhZ2UsIGNhdXNlKSB7XG4gICAgc3VwZXIobWVzc2FnZSwgY2F1c2UgaW5zdGFuY2VvZiBFcnJvciA/IHtjYXVzZX0gOiB1bmRlZmluZWQpXG4gICAgdGhpcy5uYW1lID0gXCJTZW1hbnRpZm9sZEJyb3dzZXJFcnJvclwiXG4gICAgdGhpcy5zdGFnZSA9IHN0YWdlXG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWRTZW1hbnRpZm9sZCh1cmwsIHtmZXRjaDogZmV0Y2hJbXBsZW1lbnRhdGlvbiA9IGdsb2JhbFRoaXMuZmV0Y2gsIHNpbmssIHRpbWVvdXRNcyA9IDEwMDAwfSA9IHt9KSB7XG4gIGlmICh0eXBlb2YgZmV0Y2hJbXBsZW1lbnRhdGlvbiAhPSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJBIGZldGNoIGltcGxlbWVudGF0aW9uIGlzIHJlcXVpcmVkLlwiKVxuICBpZiAodHlwZW9mIHNpbmsgIT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQSB0ZXh0IHNpbmsgZnVuY3Rpb24gaXMgcmVxdWlyZWQuXCIpXG4gIGlmICghTnVtYmVyLmlzU2FmZUludGVnZXIodGltZW91dE1zKSB8fCB0aW1lb3V0TXMgPD0gMCB8fCB0aW1lb3V0TXMgPiAyMTQ3NDgzNjQ3KSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInRpbWVvdXRNcyBtdXN0IGJlIGFuIGludGVnZXIgZnJvbSAxIHRocm91Z2ggMjE0NzQ4MzY0Ny5cIilcbiAgfVxuICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpXG4gIGxldCB0aW1lZE91dCA9IGZhbHNlXG4gIGxldCB0aW1lb3V0XG4gIGNvbnN0IGRlYWRsaW5lID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHRpbWVvdXRDYXVzZSA9IG5ldyBFcnJvcihcIlNlbWFudGlmb2xkIGJyb3dzZXIgbG9hZCB0aW1lZCBvdXQuXCIpXG5cbiAgICB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aW1lZE91dCA9IHRydWVcbiAgICAgIGNvbnRyb2xsZXIuYWJvcnQodGltZW91dENhdXNlKVxuICAgICAgcmVqZWN0KG5ldyBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcihcInRpbWVvdXRcIiwgXCJXYXNtIGxvYWRpbmcgdGltZWQgb3V0LlwiLCB0aW1lb3V0Q2F1c2UpKVxuICAgIH0sIHRpbWVvdXRNcylcbiAgfSlcbiAgY29uc3QgYmVmb3JlRGVhZGxpbmUgPSAob3BlcmF0aW9uKSA9PiBQcm9taXNlLnJhY2UoW29wZXJhdGlvbiwgZGVhZGxpbmVdKVxuICBjb25zdCB0aW1lb3V0RmFpbHVyZSA9IChjYXVzZSkgPT4gbmV3IFNlbWFudGlmb2xkQnJvd3NlckVycm9yKFwidGltZW91dFwiLCBcIldhc20gbG9hZGluZyB0aW1lZCBvdXQuXCIsXG4gICAgY2F1c2UgaW5zdGFuY2VvZiBFcnJvciA/IGNhdXNlIDogY29udHJvbGxlci5zaWduYWwucmVhc29uKVxuICBjb25zdCBib2R5RmFpbHVyZSA9IChjYXVzZSkgPT4ge1xuICAgIGlmIChjYXVzZSBpbnN0YW5jZW9mIFNlbWFudGlmb2xkQnJvd3NlckVycm9yKSByZXR1cm4gY2F1c2VcbiAgICBpZiAodGltZWRPdXQpIHJldHVybiB0aW1lb3V0RmFpbHVyZShjYXVzZSlcbiAgICByZXR1cm4gbmV3IFNlbWFudGlmb2xkQnJvd3NlckVycm9yKFwiZmV0Y2gvTUlNRVwiLCBcIldhc20gcmVzcG9uc2UgYm9keSBjb3VsZCBub3QgYmUgcmVhZC5cIiwgY2F1c2UpXG4gIH1cbiAgY29uc3QgaW5zdGFudGlhdGlvbkZhaWx1cmUgPSAoY2F1c2UpID0+IHtcbiAgICBpZiAoY2F1c2UgaW5zdGFuY2VvZiBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcikgcmV0dXJuIGNhdXNlXG4gICAgaWYgKHRpbWVkT3V0KSByZXR1cm4gdGltZW91dEZhaWx1cmUoY2F1c2UpXG4gICAgY29uc3Qgc3RhZ2UgPSBjYXVzZSBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5LkNvbXBpbGVFcnJvciA/IFwiY29tcGlsZVwiIDogXCJpbnN0YW50aWF0ZS9pbXBvcnRcIlxuXG4gICAgcmV0dXJuIG5ldyBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcihzdGFnZSwgXFxgV2FzbSBcXCR7c3RhZ2V9IGZhaWxlZC5cXGAsIGNhdXNlKVxuICB9XG4gIGNvbnN0IHJlYWRCb2R5ID0gYXN5bmMgKGJvZHkpID0+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGF3YWl0IGJlZm9yZURlYWRsaW5lKGJvZHkuYXJyYXlCdWZmZXIoKSkpXG4gICAgfSBjYXRjaCAoY2F1c2UpIHtcbiAgICAgIHRocm93IGJvZHlGYWlsdXJlKGNhdXNlKVxuICAgIH1cbiAgfVxuICBjb25zdCBpbnN0YW50aWF0ZSA9IGFzeW5jIChvcGVyYXRpb24pID0+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IGJlZm9yZURlYWRsaW5lKG9wZXJhdGlvbigpKVxuICAgIH0gY2F0Y2ggKGNhdXNlKSB7XG4gICAgICB0aHJvdyBpbnN0YW50aWF0aW9uRmFpbHVyZShjYXVzZSlcbiAgICB9XG4gIH1cbiAgbGV0IHJlc3BvbnNlXG5cbiAgdHJ5IHtcbiAgICByZXNwb25zZSA9IGF3YWl0IGJlZm9yZURlYWRsaW5lKFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT5cbiAgICAgIGZldGNoSW1wbGVtZW50YXRpb24odXJsLCB7Y3JlZGVudGlhbHM6IFwic2FtZS1vcmlnaW5cIiwgcmVkaXJlY3Q6IFwiZXJyb3JcIiwgc2lnbmFsOiBjb250cm9sbGVyLnNpZ25hbH0pKSlcbiAgfSBjYXRjaCAoY2F1c2UpIHtcbiAgICBjbGVhclRpbWVvdXQodGltZW91dClcbiAgICBpZiAoY2F1c2UgaW5zdGFuY2VvZiBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcikgdGhyb3cgY2F1c2VcbiAgICBjb25zdCBzdGFnZSA9IHRpbWVkT3V0ID8gXCJ0aW1lb3V0XCIgOiBcImZldGNoL01JTUVcIlxuICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcihzdGFnZSwgc3RhZ2UgPT0gXCJ0aW1lb3V0XCIgPyBcIldhc20gbG9hZGluZyB0aW1lZCBvdXQuXCIgOiBcIldhc20gZmV0Y2ggZmFpbGVkLlwiLCBjYXVzZSlcbiAgfVxuICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpXG4gICAgdGhyb3cgbmV3IFNlbWFudGlmb2xkQnJvd3NlckVycm9yKFwiZmV0Y2gvTUlNRVwiLCBcXGBXYXNtIGZldGNoIHJldHVybmVkIEhUVFAgXFwke3Jlc3BvbnNlLnN0YXR1c30uXFxgKVxuICB9XG4gIGNvbnN0IG1lZGlhVHlwZSA9IHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiY29udGVudC10eXBlXCIpPy5zcGxpdChcIjtcIiwgMSlbMF0udHJpbSgpLnRvTG93ZXJDYXNlKClcblxuICBpZiAobWVkaWFUeXBlICE9IFwiYXBwbGljYXRpb24vd2FzbVwiKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpXG4gICAgdGhyb3cgbmV3IFNlbWFudGlmb2xkQnJvd3NlckVycm9yKFwiZmV0Y2gvTUlNRVwiLCBcIldhc20gcmVzcG9uc2UgcmVxdWlyZXMgYXBwbGljYXRpb24vd2FzbS5cIilcbiAgfVxuXG4gIGxldCBpbnN0YW5jZVxuICBsZXQgbW9kdWxlXG4gIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoXCJ1dGYtOFwiLCB7ZmF0YWw6IHRydWUsIGlnbm9yZUJPTTogdHJ1ZX0pXG4gIGxldCBtZW1vcnlcbiAgbGV0IGFiaUFwcHJvdmVkID0gZmFsc2VcbiAgY29uc3QgcmVxdWlyZUFwcHJvdmVkQWJpID0gKCkgPT4ge1xuICAgIGlmICghYWJpQXBwcm92ZWQpIHRocm93IG5ldyBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcihcImluc3RhbnRpYXRlL2ltcG9ydFwiLCBcIldhc20gaG9zdCBpbXBvcnRzIGFyZSBsb2NrZWQgdW50aWwgQUJJIGluc3BlY3Rpb24gc3VjY2VlZHMuXCIpXG4gIH1cbiAgY29uc3QgYXBwZW5kID0gKHRleHQpID0+IHNpbmsoXFxgXFwke3RleHR9XFxcXG5cXGApXG4gIGNvbnN0IGltcG9ydHMgPSB7c2VtYW50aWZvbGQ6IHtcbiAgICBwcmludF9pNjQodmFsdWUpIHtcbiAgICAgIHJlcXVpcmVBcHByb3ZlZEFiaSgpXG4gICAgICBpZiAodHlwZW9mIHZhbHVlICE9IFwiYmlnaW50XCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJwcmludF9pNjQgcmVxdWlyZXMgYmlnaW50LlwiKVxuICAgICAgYXBwZW5kKHZhbHVlLnRvU3RyaW5nKDEwKSlcbiAgICB9LFxuICAgIHByaW50X2Jvb2wodmFsdWUpIHtcbiAgICAgIHJlcXVpcmVBcHByb3ZlZEFiaSgpXG4gICAgICBpZiAodmFsdWUgIT09IDAgJiYgdmFsdWUgIT09IDEpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJwcmludF9ib29sIHJlcXVpcmVzIGNhbm9uaWNhbCAwIG9yIDEuXCIpXG4gICAgICBhcHBlbmQodmFsdWUgPT09IDEgPyBcInRydWVcIiA6IFwiZmFsc2VcIilcbiAgICB9LFxuICAgIHByaW50X3N0cmluZyhwb2ludGVyLCBsZW5ndGgpIHtcbiAgICAgIHJlcXVpcmVBcHByb3ZlZEFiaSgpXG4gICAgICBpZiAoIW1lbW9yeSB8fCAhTnVtYmVyLmlzSW50ZWdlcihwb2ludGVyKSB8fCBwb2ludGVyIDwgMCB8fCAhTnVtYmVyLmlzSW50ZWdlcihsZW5ndGgpIHx8IGxlbmd0aCA8IDApIHtcbiAgICAgICAgY29uc3QgY2F1c2UgPSBuZXcgVHlwZUVycm9yKFwicHJpbnRfc3RyaW5nIHJlcXVpcmVzIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIgcG9pbnRlciBhbmQgbGVuZ3RoLlwiKVxuXG4gICAgICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcihcIm1lbW9yeSBib3VuZHMvVVRGLThcIiwgY2F1c2UubWVzc2FnZSwgY2F1c2UpXG4gICAgICB9XG4gICAgICBjb25zdCBlbmQgPSBwb2ludGVyICsgbGVuZ3RoXG5cbiAgICAgIGlmICghTnVtYmVyLmlzU2FmZUludGVnZXIoZW5kKSB8fCBlbmQgPCBwb2ludGVyIHx8IGVuZCA+IG1lbW9yeS5idWZmZXIuYnl0ZUxlbmd0aCkge1xuICAgICAgICBjb25zdCBjYXVzZSA9IG5ldyBSYW5nZUVycm9yKFwicHJpbnRfc3RyaW5nIHJhbmdlIGlzIG91dHNpZGUgZXhwb3J0ZWQgbWVtb3J5LlwiKVxuXG4gICAgICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcihcIm1lbW9yeSBib3VuZHMvVVRGLThcIiwgY2F1c2UubWVzc2FnZSwgY2F1c2UpXG4gICAgICB9XG4gICAgICBsZXQgdGV4dFxuXG4gICAgICB0cnkge1xuICAgICAgICB0ZXh0ID0gZGVjb2Rlci5kZWNvZGUobmV3IFVpbnQ4QXJyYXkobWVtb3J5LmJ1ZmZlciwgcG9pbnRlciwgbGVuZ3RoKSlcbiAgICAgIH0gY2F0Y2ggKGNhdXNlKSB7XG4gICAgICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcihcIm1lbW9yeSBib3VuZHMvVVRGLThcIiwgXCJwcmludF9zdHJpbmcgYnl0ZXMgYXJlIG5vdCB2YWxpZCBVVEYtOC5cIiwgY2F1c2UpXG4gICAgICB9XG4gICAgICBhcHBlbmQodGV4dClcbiAgICB9XG4gIH19XG5cbiAgbGV0IHJlc3VsdFxuXG4gIHRyeSB7XG4gICAgaWYgKHR5cGVvZiBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZVN0cmVhbWluZyA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGxldCBib2R5XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGJvZHkgPSByZXNwb25zZS5jbG9uZSgpXG4gICAgICB9IGNhdGNoIChjYXVzZSkge1xuICAgICAgICB0aHJvdyBib2R5RmFpbHVyZShjYXVzZSlcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBlbmRpbmcgPSBpbnN0YW50aWF0ZSgoKSA9PiBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZVN0cmVhbWluZyhyZXNwb25zZSwgaW1wb3J0cykpXG4gICAgICAgIC50aGVuKCh2YWx1ZSkgPT4gKHt2YWx1ZX0pLCAoZXJyb3IpID0+ICh7ZXJyb3J9KSlcbiAgICAgIGNvbnN0IGJ5dGVzID0gYXdhaXQgcmVhZEJvZHkoYm9keSlcblxuICAgICAgaW5zcGVjdEFiaShieXRlcylcbiAgICAgIGFiaUFwcHJvdmVkID0gdHJ1ZVxuICAgICAgY29uc3Qgc2V0dGxlZCA9IGF3YWl0IHBlbmRpbmdcblxuICAgICAgaWYgKFwiZXJyb3JcIiBpbiBzZXR0bGVkKSB0aHJvdyBzZXR0bGVkLmVycm9yXG4gICAgICByZXN1bHQgPSBzZXR0bGVkLnZhbHVlXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGJ5dGVzID0gYXdhaXQgcmVhZEJvZHkocmVzcG9uc2UpXG5cbiAgICAgIGluc3BlY3RBYmkoYnl0ZXMpXG4gICAgICBhYmlBcHByb3ZlZCA9IHRydWVcbiAgICAgIHJlc3VsdCA9IGF3YWl0IGluc3RhbnRpYXRlKCgpID0+IFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKGJ5dGVzLCBpbXBvcnRzKSlcbiAgICB9XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpXG4gICAgdGhyb3cgZXJyb3JcbiAgfVxuICBjbGVhclRpbWVvdXQodGltZW91dClcbiAgaW5zdGFuY2UgPSByZXN1bHQuaW5zdGFuY2VcbiAgbW9kdWxlID0gcmVzdWx0Lm1vZHVsZVxuICB2YWxpZGF0ZU1vZHVsZVNoYXBlKG1vZHVsZSwgaW5zdGFuY2UpXG4gIG1lbW9yeSA9IGluc3RhbmNlLmV4cG9ydHMubWVtb3J5XG4gIGxldCBhY3RpdmUgPSBmYWxzZVxuICBsZXQgcG9pc29uZWQgPSBmYWxzZVxuXG4gIHJldHVybiBPYmplY3QuZnJlZXplKHtcbiAgICBtZW1vcnksXG4gICAgcnVuKCkge1xuICAgICAgaWYgKHBvaXNvbmVkKSB0aHJvdyBuZXcgU2VtYW50aWZvbGRCcm93c2VyRXJyb3IoXCJpbnZvY2F0aW9uL3RyYXBcIiwgXCJXYXNtIGluc3RhbmNlIGlzIHBvaXNvbmVkIGFmdGVyIGEgdHJhcC5cIilcbiAgICAgIGlmIChhY3RpdmUpIHRocm93IG5ldyBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcihcImludm9jYXRpb24vdHJhcFwiLCBcIlJlZW50cmFudCBydW4gaW52b2NhdGlvbiBpcyBmb3JiaWRkZW4uXCIpXG4gICAgICBhY3RpdmUgPSB0cnVlXG4gICAgICB0cnkge1xuICAgICAgICBpbnN0YW5jZS5leHBvcnRzLnJ1bigpXG4gICAgICB9IGNhdGNoIChjYXVzZSkge1xuICAgICAgICBwb2lzb25lZCA9IHRydWVcbiAgICAgICAgaWYgKGNhdXNlIGluc3RhbmNlb2YgU2VtYW50aWZvbGRCcm93c2VyRXJyb3IpIHRocm93IGNhdXNlXG4gICAgICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcihcImludm9jYXRpb24vdHJhcFwiLCBcIldhc20gcnVuIHRyYXBwZWQuXCIsIGNhdXNlKVxuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYWN0aXZlID0gZmFsc2VcbiAgICAgIH1cbiAgICB9XG4gIH0pXG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlTW9kdWxlU2hhcGUobW9kdWxlLCBpbnN0YW5jZSkge1xuICBjb25zdCBpbXBvcnRzID0gV2ViQXNzZW1ibHkuTW9kdWxlLmltcG9ydHMobW9kdWxlKVxuICBjb25zdCBleHBvcnRzID0gV2ViQXNzZW1ibHkuTW9kdWxlLmV4cG9ydHMobW9kdWxlKVxuXG4gIGlmIChKU09OLnN0cmluZ2lmeShpbXBvcnRzLm1hcCgoe2tpbmQsIG1vZHVsZSwgbmFtZX0pID0+IFttb2R1bGUsIG5hbWUsIGtpbmRdKSkgIT1cbiAgICBKU09OLnN0cmluZ2lmeShleHBlY3RlZEltcG9ydHMubWFwKChbbW9kdWxlLCBuYW1lXSkgPT4gW21vZHVsZSwgbmFtZSwgXCJmdW5jdGlvblwiXSkpKSB7XG4gICAgdGhyb3cgbmV3IFNlbWFudGlmb2xkQnJvd3NlckVycm9yKFwiaW5zdGFudGlhdGUvaW1wb3J0XCIsIFwiV2FzbSBpbXBvcnRzIGRvIG5vdCBtYXRjaCBzZW1hbnRpZm9sZC5icm93c2VyLnYxLlwiKVxuICB9XG4gIGlmIChKU09OLnN0cmluZ2lmeShleHBvcnRzLm1hcCgoe2tpbmQsIG5hbWV9KSA9PiBbbmFtZSwga2luZF0pKSAhPSBKU09OLnN0cmluZ2lmeShbW1wibWVtb3J5XCIsIFwibWVtb3J5XCJdLCBbXCJydW5cIiwgXCJmdW5jdGlvblwiXV0pIHx8XG4gICAgIShpbnN0YW5jZS5leHBvcnRzLm1lbW9yeSBpbnN0YW5jZW9mIFdlYkFzc2VtYmx5Lk1lbW9yeSkgfHwgdHlwZW9mIGluc3RhbmNlLmV4cG9ydHMucnVuICE9IFwiZnVuY3Rpb25cIiB8fCBpbnN0YW5jZS5leHBvcnRzLnJ1bi5sZW5ndGggIT0gMCkge1xuICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcihcImluc3RhbnRpYXRlL2ltcG9ydFwiLCBcIldhc20gZXhwb3J0cyBkbyBub3QgbWF0Y2ggc2VtYW50aWZvbGQuYnJvd3Nlci52MS5cIilcbiAgfVxufVxuXG5mdW5jdGlvbiBpbnNwZWN0QWJpKGJ5dGVzKSB7XG4gIHRyeSB7XG4gICAgbGV0IG9mZnNldCA9IDhcbiAgICBjb25zdCB0eXBlcyA9IFtdXG4gICAgY29uc3QgaW1wb3J0ZWRUeXBlcyA9IFtdXG4gICAgY29uc3QgZGVmaW5lZFR5cGVzID0gW11cbiAgICBjb25zdCBleHBvcnRzID0gW11cbiAgICBjb25zdCBtZW1vcmllcyA9IFtdXG5cbiAgICBpZiAoYnl0ZXMubGVuZ3RoIDwgOCB8fCBieXRlc1swXSAhPSAwIHx8IGJ5dGVzWzFdICE9IDk3IHx8IGJ5dGVzWzJdICE9IDExNSB8fCBieXRlc1szXSAhPSAxMDkgfHwgYnl0ZXNbNF0gIT0gMSB8fFxuICAgICAgYnl0ZXNbNV0gIT0gMCB8fCBieXRlc1s2XSAhPSAwIHx8IGJ5dGVzWzddICE9IDApIHRocm93IG5ldyBXZWJBc3NlbWJseS5Db21waWxlRXJyb3IoXCJJbnZhbGlkIFdhc20gaGVhZGVyLlwiKVxuICAgIHdoaWxlIChvZmZzZXQgPCBieXRlcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IGlkID0gYnl0ZXNbb2Zmc2V0KytdXG4gICAgICBjb25zdCBzaXplVmFsdWUgPSByZWFkVTMyKGJ5dGVzLCBvZmZzZXQpXG4gICAgICBvZmZzZXQgPSBzaXplVmFsdWUubmV4dFxuICAgICAgY29uc3QgZW5kID0gb2Zmc2V0ICsgc2l6ZVZhbHVlLnZhbHVlXG5cbiAgICAgIGlmIChlbmQgPiBieXRlcy5sZW5ndGgpIHRocm93IG5ldyBXZWJBc3NlbWJseS5Db21waWxlRXJyb3IoXCJUcnVuY2F0ZWQgV2FzbSBzZWN0aW9uLlwiKVxuICAgICAgaWYgKGlkID09IDEpIHtcbiAgICAgICAgY29uc3QgY291bnQgPSByZWFkVTMyKGJ5dGVzLCBvZmZzZXQpOyBvZmZzZXQgPSBjb3VudC5uZXh0XG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBjb3VudC52YWx1ZTsgaW5kZXggKz0gMSkge1xuICAgICAgICAgIGlmIChieXRlc1tvZmZzZXQrK10gIT0gMHg2MCkgdGhyb3cgbmV3IFdlYkFzc2VtYmx5LkNvbXBpbGVFcnJvcihcIkludmFsaWQgZnVuY3Rpb24gdHlwZS5cIilcbiAgICAgICAgICBjb25zdCBwYXJhbWV0ZXJzID0gcmVhZFR5cGVzKGJ5dGVzLCBvZmZzZXQpOyBvZmZzZXQgPSBwYXJhbWV0ZXJzLm5leHRcbiAgICAgICAgICBjb25zdCByZXN1bHRzID0gcmVhZFR5cGVzKGJ5dGVzLCBvZmZzZXQpOyBvZmZzZXQgPSByZXN1bHRzLm5leHRcbiAgICAgICAgICB0eXBlcy5wdXNoKFtwYXJhbWV0ZXJzLnZhbHVlcywgcmVzdWx0cy52YWx1ZXNdKVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGlkID09IDIpIHtcbiAgICAgICAgY29uc3QgY291bnQgPSByZWFkVTMyKGJ5dGVzLCBvZmZzZXQpOyBvZmZzZXQgPSBjb3VudC5uZXh0XG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBjb3VudC52YWx1ZTsgaW5kZXggKz0gMSkge1xuICAgICAgICAgIGNvbnN0IG1vZHVsZU5hbWUgPSByZWFkTmFtZShieXRlcywgb2Zmc2V0KTsgb2Zmc2V0ID0gbW9kdWxlTmFtZS5uZXh0XG4gICAgICAgICAgY29uc3QgZmllbGROYW1lID0gcmVhZE5hbWUoYnl0ZXMsIG9mZnNldCk7IG9mZnNldCA9IGZpZWxkTmFtZS5uZXh0XG4gICAgICAgICAgaWYgKGJ5dGVzW29mZnNldCsrXSAhPSAwKSB0aHJvdyBuZXcgU2VtYW50aWZvbGRCcm93c2VyRXJyb3IoXCJpbnN0YW50aWF0ZS9pbXBvcnRcIiwgXCJPbmx5IGZ1bmN0aW9uIGltcG9ydHMgYXJlIGFsbG93ZWQuXCIpXG4gICAgICAgICAgY29uc3QgdHlwZSA9IHJlYWRVMzIoYnl0ZXMsIG9mZnNldCk7IG9mZnNldCA9IHR5cGUubmV4dFxuICAgICAgICAgIGltcG9ydGVkVHlwZXMucHVzaChbbW9kdWxlTmFtZS52YWx1ZSwgZmllbGROYW1lLnZhbHVlLCB0eXBlLnZhbHVlXSlcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChpZCA9PSAzKSB7XG4gICAgICAgIGNvbnN0IGNvdW50ID0gcmVhZFUzMihieXRlcywgb2Zmc2V0KTsgb2Zmc2V0ID0gY291bnQubmV4dFxuICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgY291bnQudmFsdWU7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICBjb25zdCB0eXBlID0gcmVhZFUzMihieXRlcywgb2Zmc2V0KTsgb2Zmc2V0ID0gdHlwZS5uZXh0OyBkZWZpbmVkVHlwZXMucHVzaCh0eXBlLnZhbHVlKVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGlkID09IDUpIHtcbiAgICAgICAgY29uc3QgY291bnQgPSByZWFkVTMyKGJ5dGVzLCBvZmZzZXQpOyBvZmZzZXQgPSBjb3VudC5uZXh0XG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBjb3VudC52YWx1ZTsgaW5kZXggKz0gMSkge1xuICAgICAgICAgIGNvbnN0IGZsYWdzID0gYnl0ZXNbb2Zmc2V0KytdXG4gICAgICAgICAgY29uc3QgbWluaW11bSA9IHJlYWRVMzIoYnl0ZXMsIG9mZnNldCk7IG9mZnNldCA9IG1pbmltdW0ubmV4dFxuICAgICAgICAgIGxldCBtYXhpbXVtXG4gICAgICAgICAgaWYgKChmbGFncyAmIDEpICE9IDApIHsgbWF4aW11bSA9IHJlYWRVMzIoYnl0ZXMsIG9mZnNldCk7IG9mZnNldCA9IG1heGltdW0ubmV4dCB9XG4gICAgICAgICAgbWVtb3JpZXMucHVzaChbZmxhZ3MsIG1pbmltdW0udmFsdWUsIG1heGltdW0/LnZhbHVlXSlcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChpZCA9PSA3KSB7XG4gICAgICAgIGNvbnN0IGNvdW50ID0gcmVhZFUzMihieXRlcywgb2Zmc2V0KTsgb2Zmc2V0ID0gY291bnQubmV4dFxuICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgY291bnQudmFsdWU7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICBjb25zdCBuYW1lID0gcmVhZE5hbWUoYnl0ZXMsIG9mZnNldCk7IG9mZnNldCA9IG5hbWUubmV4dFxuICAgICAgICAgIGNvbnN0IGtpbmQgPSBieXRlc1tvZmZzZXQrK11cbiAgICAgICAgICBjb25zdCB0YXJnZXQgPSByZWFkVTMyKGJ5dGVzLCBvZmZzZXQpOyBvZmZzZXQgPSB0YXJnZXQubmV4dFxuICAgICAgICAgIGV4cG9ydHMucHVzaChbbmFtZS52YWx1ZSwga2luZCwgdGFyZ2V0LnZhbHVlXSlcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChpZCA9PSA4KSB0aHJvdyBuZXcgU2VtYW50aWZvbGRCcm93c2VyRXJyb3IoXCJpbnN0YW50aWF0ZS9pbXBvcnRcIiwgXCJBIFdhc20gc3RhcnQgc2VjdGlvbiBpcyBmb3JiaWRkZW4uXCIpXG4gICAgICBvZmZzZXQgPSBlbmRcbiAgICB9XG4gICAgaWYgKGltcG9ydGVkVHlwZXMubGVuZ3RoICE9IGV4cGVjdGVkSW1wb3J0cy5sZW5ndGgpIHRocm93IG5ldyBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcihcImluc3RhbnRpYXRlL2ltcG9ydFwiLCBcIlVuZXhwZWN0ZWQgV2FzbSBpbXBvcnQgY291bnQuXCIpXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGV4cGVjdGVkSW1wb3J0cy5sZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gZXhwZWN0ZWRJbXBvcnRzW2luZGV4XVxuICAgICAgY29uc3QgYWN0dWFsID0gaW1wb3J0ZWRUeXBlc1tpbmRleF1cbiAgICAgIGNvbnN0IHR5cGUgPSB0eXBlc1thY3R1YWw/LlsyXV1cblxuICAgICAgaWYgKCFhY3R1YWwgfHwgYWN0dWFsWzBdICE9IGV4cGVjdGVkWzBdIHx8IGFjdHVhbFsxXSAhPSBleHBlY3RlZFsxXSB8fCAhdHlwZSB8fFxuICAgICAgICBKU09OLnN0cmluZ2lmeSh0eXBlKSAhPSBKU09OLnN0cmluZ2lmeShbZXhwZWN0ZWRbMl0sIGV4cGVjdGVkWzNdXSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFNlbWFudGlmb2xkQnJvd3NlckVycm9yKFwiaW5zdGFudGlhdGUvaW1wb3J0XCIsIFwiV2FzbSBpbXBvcnQgc2lnbmF0dXJlIGRvZXMgbm90IG1hdGNoIHNlbWFudGlmb2xkLmJyb3dzZXIudjEuXCIpXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChtZW1vcmllcy5sZW5ndGggIT0gMSB8fCBtZW1vcmllc1swXVswXSAhPSAxIHx8IG1lbW9yaWVzWzBdWzFdICE9IG1lbW9yaWVzWzBdWzJdKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGRCcm93c2VyRXJyb3IoXCJpbnN0YW50aWF0ZS9pbXBvcnRcIiwgXCJXYXNtIG1lbW9yeSBtdXN0IGhhdmUgZXF1YWwgZml4ZWQgaW5pdGlhbCBhbmQgbWF4aW11bSBsaW1pdHMuXCIpXG4gICAgfVxuICAgIGlmIChleHBvcnRzLmxlbmd0aCAhPSAyIHx8IGV4cG9ydHNbMF1bMF0gIT0gXCJtZW1vcnlcIiB8fCBleHBvcnRzWzBdWzFdICE9IDIgfHwgZXhwb3J0c1swXVsyXSAhPSAwIHx8XG4gICAgICBleHBvcnRzWzFdWzBdICE9IFwicnVuXCIgfHwgZXhwb3J0c1sxXVsxXSAhPSAwKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGRCcm93c2VyRXJyb3IoXCJpbnN0YW50aWF0ZS9pbXBvcnRcIiwgXCJXYXNtIGV4cG9ydHMgZG8gbm90IG1hdGNoIHNlbWFudGlmb2xkLmJyb3dzZXIudjEuXCIpXG4gICAgfVxuICAgIGNvbnN0IHJ1blR5cGUgPSB0eXBlc1tkZWZpbmVkVHlwZXNbZXhwb3J0c1sxXVsyXSAtIGltcG9ydGVkVHlwZXMubGVuZ3RoXV1cblxuICAgIGlmICghcnVuVHlwZSB8fCBydW5UeXBlWzBdLmxlbmd0aCAhPSAwIHx8IHJ1blR5cGVbMV0ubGVuZ3RoICE9IDApIHtcbiAgICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcihcImluc3RhbnRpYXRlL2ltcG9ydFwiLCBcIldhc20gcnVuIHNpZ25hdHVyZSBkb2VzIG5vdCBtYXRjaCBzZW1hbnRpZm9sZC5icm93c2VyLnYxLlwiKVxuICAgIH1cbiAgfSBjYXRjaCAoY2F1c2UpIHtcbiAgICBpZiAoY2F1c2UgaW5zdGFuY2VvZiBTZW1hbnRpZm9sZEJyb3dzZXJFcnJvcikgdGhyb3cgY2F1c2VcbiAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGRCcm93c2VyRXJyb3IoXCJjb21waWxlXCIsIFwiV2FzbSBiaW5hcnkgaW5zcGVjdGlvbiBmYWlsZWQuXCIsIGNhdXNlKVxuICB9XG59XG5cbmZ1bmN0aW9uIHJlYWRUeXBlcyhieXRlcywgb2Zmc2V0KSB7XG4gIGNvbnN0IGNvdW50ID0gcmVhZFUzMihieXRlcywgb2Zmc2V0KTsgb2Zmc2V0ID0gY291bnQubmV4dDsgY29uc3QgdmFsdWVzID0gW11cbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGNvdW50LnZhbHVlOyBpbmRleCArPSAxKSB7XG4gICAgY29uc3QgdHlwZSA9IGJ5dGVzW29mZnNldCsrXVxuICAgIGlmICh0eXBlID09IDB4N2YpIHZhbHVlcy5wdXNoKFwiaTMyXCIpXG4gICAgZWxzZSBpZiAodHlwZSA9PSAweDdlKSB2YWx1ZXMucHVzaChcImk2NFwiKVxuICAgIGVsc2UgaWYgKHR5cGUgPT0gMHg3ZCkgdmFsdWVzLnB1c2goXCJmMzJcIilcbiAgICBlbHNlIGlmICh0eXBlID09IDB4N2MpIHZhbHVlcy5wdXNoKFwiZjY0XCIpXG4gICAgZWxzZSBpZiAodHlwZSA9PSAweDdiKSB2YWx1ZXMucHVzaChcInYxMjhcIilcbiAgICBlbHNlIGlmICh0eXBlID09IDB4NzApIHZhbHVlcy5wdXNoKFwiZnVuY3JlZlwiKVxuICAgIGVsc2UgaWYgKHR5cGUgPT0gMHg2ZikgdmFsdWVzLnB1c2goXCJleHRlcm5yZWZcIilcbiAgICBlbHNlIHRocm93IG5ldyBXZWJBc3NlbWJseS5Db21waWxlRXJyb3IoXCJVbnN1cHBvcnRlZCBBQkkgdmFsdWUgdHlwZS5cIilcbiAgfVxuICByZXR1cm4ge25leHQ6IG9mZnNldCwgdmFsdWVzfVxufVxuXG5mdW5jdGlvbiByZWFkTmFtZShieXRlcywgb2Zmc2V0KSB7XG4gIGNvbnN0IGxlbmd0aCA9IHJlYWRVMzIoYnl0ZXMsIG9mZnNldCk7IGNvbnN0IGVuZCA9IGxlbmd0aC5uZXh0ICsgbGVuZ3RoLnZhbHVlXG4gIGlmIChlbmQgPiBieXRlcy5sZW5ndGgpIHRocm93IG5ldyBXZWJBc3NlbWJseS5Db21waWxlRXJyb3IoXCJUcnVuY2F0ZWQgV2FzbSBuYW1lLlwiKVxuICByZXR1cm4ge25leHQ6IGVuZCwgdmFsdWU6IG5ldyBUZXh0RGVjb2RlcihcInV0Zi04XCIsIHtmYXRhbDogdHJ1ZX0pLmRlY29kZShieXRlcy5zdWJhcnJheShsZW5ndGgubmV4dCwgZW5kKSl9XG59XG5cbmZ1bmN0aW9uIHJlYWRVMzIoYnl0ZXMsIG9mZnNldCkge1xuICBsZXQgdmFsdWUgPSAwXG4gIGxldCBzaGlmdCA9IDBcbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IDU7IGluZGV4ICs9IDEpIHtcbiAgICBpZiAob2Zmc2V0ID49IGJ5dGVzLmxlbmd0aCkgdGhyb3cgbmV3IFdlYkFzc2VtYmx5LkNvbXBpbGVFcnJvcihcIlRydW5jYXRlZCB1bnNpZ25lZCBMRUIxMjguXCIpXG4gICAgY29uc3QgYnl0ZSA9IGJ5dGVzW29mZnNldCsrXVxuICAgIHZhbHVlICs9IChieXRlICYgMHg3ZikgKiAyICoqIHNoaWZ0XG4gICAgaWYgKChieXRlICYgMHg4MCkgPT0gMCkgcmV0dXJuIHtuZXh0OiBvZmZzZXQsIHZhbHVlfVxuICAgIHNoaWZ0ICs9IDdcbiAgfVxuICB0aHJvdyBuZXcgV2ViQXNzZW1ibHkuQ29tcGlsZUVycm9yKFwiT3ZlcnNpemVkIHVuc2lnbmVkIExFQjEyOC5cIilcbn1cblxuYXN5bmMgZnVuY3Rpb24gcnVuQnJvd3Nlckhhcm5lc3MoKSB7XG4gIGNvbnN0IG91dHB1dCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjb3V0cHV0XCIpXG5cbiAgdHJ5IHtcbiAgICBjb25zdCBwcm9ncmFtID0gYXdhaXQgbG9hZFNlbWFudGlmb2xkKFwiLi9wcm9ncmFtLndhc21cIiwge3Npbms6IChsaW5lKSA9PiB7IG91dHB1dC50ZXh0Q29udGVudCArPSBsaW5lIH19KVxuICAgIHByb2dyYW0ucnVuKClcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZGF0YXNldC5zZW1hbnRpZm9sZE91dHB1dCA9IFsuLi5uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUob3V0cHV0LnRleHRDb250ZW50KV1cbiAgICAgIC5tYXAoKGJ5dGUpID0+IGJ5dGUudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIFwiMFwiKSkuam9pbihcIlwiKVxuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5kYXRhc2V0LnNlbWFudGlmb2xkID0gXCJwYXNzXCJcbiAgICBjb25zb2xlLmxvZyhcIlNFTUFOVElGT0xEX0JST1dTRVJfT0tcIilcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZGF0YXNldC5zZW1hbnRpZm9sZCA9IFwiZmFpbFwiXG4gICAgb3V0cHV0LnRleHRDb250ZW50ICs9IFxcYEVSUk9SW1xcJHtlcnJvci5zdGFnZSA/PyBcInVua25vd25cIn1dOiBcXCR7ZXJyb3IubWVzc2FnZX1cXFxcblxcYFxuICAgIGNvbnNvbGUuZXJyb3IoXCJTRU1BTlRJRk9MRF9CUk9XU0VSX0ZBSUxFRFwiLCBlcnJvcilcbiAgfVxufVxuXG5pZiAodHlwZW9mIGRvY3VtZW50ICE9IFwidW5kZWZpbmVkXCIgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmRhdGFzZXQuc2VtYW50aWZvbGQgPT0gXCJwZW5kaW5nXCIpIHZvaWQgcnVuQnJvd3Nlckhhcm5lc3MoKVxuYFxuXG5jb25zdCBicm93c2VySGFybmVzcyA9IGA8IWRvY3R5cGUgaHRtbD5cbjxodG1sIGxhbmc9XCJlblwiIGRhdGEtc2VtYW50aWZvbGQ9XCJwZW5kaW5nXCI+XG48bWV0YSBjaGFyc2V0PVwidXRmLThcIj5cbjxtZXRhIGh0dHAtZXF1aXY9XCJDb250ZW50LVNlY3VyaXR5LVBvbGljeVwiIGNvbnRlbnQ9XCJkZWZhdWx0LXNyYyAnbm9uZSc7IHNjcmlwdC1zcmMgJ3NlbGYnICd3YXNtLXVuc2FmZS1ldmFsJzsgY29ubmVjdC1zcmMgJ3NlbGYnOyBiYXNlLXVyaSAnbm9uZSc7IGZvcm0tYWN0aW9uICdub25lJ1wiPlxuPHRpdGxlPlNlbWFudGlmb2xkIEJyb3dzZXIgV2FzbTwvdGl0bGU+XG48cHJlIGlkPVwib3V0cHV0XCI+PC9wcmU+XG48c2NyaXB0IHR5cGU9XCJtb2R1bGVcIiBzcmM9XCIuL3NlbWFudGlmb2xkLWxvYWRlci5tanNcIj48L3NjcmlwdD5cbjwvaHRtbD5cbmBcbiJdfQ==