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
@@ -2,11 +2,16 @@
2
2
  import PhpParser from "php-parser";
3
3
  import { parse as parseComment } from "comment-parser";
4
4
  import { missingType, parseFailure, unsupportedSyntax } from "../diagnostic.js";
5
+ import { blockReferencesProtectedEntry } from "../semantic/effects.js";
5
6
  import { locationFromOffsets, moduleLocation } from "../semantic/location.js";
6
7
  import { withAdaptedOperation } from "../semantic/operators.js";
7
8
  import { withParserRanges } from "../semantic/provenance.js";
8
- import { hasOnlyUnicodeScalars } from "../semantic/scalars.js";
9
- import { requireSourceScalarType } from "./scalars.js";
9
+ import { isTask034ResourceProbe } from "../semantic/capabilities.js";
10
+ import { hasExactEffectSupport } from "../backends/effects.js";
11
+ import { hasOnlyUnicodeScalars, scalarType } from "../semantic/scalars.js";
12
+ import { typeContainsAnyVariable } from "../semantic/generics.js";
13
+ import { requireSourceReturnType, requireSourceScalarType, sourceScalarType } from "./scalars.js";
14
+ import { capabilityFunctionSignatures, documentedValueType, instantiatedRecordFieldType, iterationBindingType, iterationOperandType, knownCallParameterTypes, knownCallReturnType, optionalType, orderedMapTypeFromMap, ownedResourceType, preservesGenericOptionalEvidence, recordType, referenceType, sameValueType } from "./types.js";
10
15
  const parser = new PhpParser.Engine({
11
16
  ast: { withPositions: true },
12
17
  parser: { extractDoc: true, suppressErrors: false }
@@ -29,6 +34,29 @@ const phpBinaryOperations = new Map([
29
34
  [">=", "GreaterThanOrEqual"],
30
35
  [".", "StringConcat"]
31
36
  ]);
37
+ /**
38
+ * @typedef PhpConversionContext
39
+ * @property {Map<string, import("../semantic/types.js").SemanticBindingType>} bindings - Explicitly typed visible bindings.
40
+ * @property {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Reference classes by identity.
41
+ * @property {import("../semantic/types.js").ClassDeclaration} [currentClass] - Enclosing reference class.
42
+ * @property {Map<string, import("../semantic/types.js").ErrorDeclaration>} errorNames - Error declarations by source name.
43
+ * @property {Map<string, import("../semantic/types.js").ErrorDeclaration>} errors - Error declarations by identity.
44
+ * @property {Map<string, PhpFunctionSignature>} functions - Explicit module function signatures.
45
+ * @property {Set<object>} [orderedMapDeclarations] - Exact local declarations selected by parser-owned pair iteration.
46
+ * @property {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
47
+ * @property {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Record declarations by identity.
48
+ * @property {import("../semantic/types.js").SemanticFunctionReturnType | undefined} returnType - Enclosing return type.
49
+ * @property {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
50
+ */
51
+ /**
52
+ * @typedef PhpFunctionSignature
53
+ * @property {import("../semantic/types.js").SourceLocation} location - Complete declaration location.
54
+ * @property {import("../semantic/types.js").SourceLocation} nameLocation - Parser-owned name location.
55
+ * @property {string} name - Function name.
56
+ * @property {import("../semantic/types.js").Parameter[]} parameters - Semantic parameters.
57
+ * @property {import("../semantic/types.js").SemanticFunctionReturnType} returnType - Semantic return type.
58
+ * @property {import("../semantic/types.js").TypeParameter[]} [typeParameters] - Declaration-scoped parameters.
59
+ */
32
60
  /**
33
61
  * Returns a normalized PHP node location.
34
62
  * @param {import("php-parser").Node} node - PHP parser node.
@@ -100,15 +128,43 @@ function tokenLocation(tokenText, startOffset, endOffset, filename, source) {
100
128
  * @param {import("php-parser").Expression} node - PHP expression.
101
129
  * @param {string} filename - Source filename.
102
130
  * @param {string} source - Complete source.
131
+ * @param {PhpConversionContext} context - Typed conversion context.
132
+ * @param {import("../semantic/types.js").SemanticValueType} [expectedType] - Contextual type for empty PHP arrays.
133
+ * @param {boolean} [preserveOptional] - Whether an optional identifier remains wrapped.
103
134
  * @returns {import("../semantic/types.js").Expression} Semantic expression.
104
135
  */
105
- function convertExpression(node, filename, source) {
136
+ function convertExpression(node, filename, source, context, expectedType, preserveOptional = false) {
106
137
  const location = nodeLocation(node, filename, source);
138
+ if (expectedType?.kind == "OptionalType") {
139
+ if (node.kind == "nullkeyword") {
140
+ return withParserRanges({ kind: /** @type {const} */ ("OptionalNone"), location }, { absence: location });
141
+ }
142
+ if (knownExpressionType(node, context)?.kind == "OptionalType") {
143
+ return convertExpression(node, filename, source, context, undefined, true);
144
+ }
145
+ return withParserRanges({
146
+ kind: /** @type {const} */ ("OptionalSome"),
147
+ location,
148
+ value: convertExpression(node, filename, source, context, expectedType.valueType)
149
+ }, { some: location });
150
+ }
151
+ if (node.kind == "nullkeyword")
152
+ return unsupportedSyntax("php", "null outside an explicit optional context", location);
107
153
  if (node.kind == "variable") {
108
154
  const variable = /** @type {import("php-parser").Variable} */ (node);
109
155
  if (typeof variable.name != "string")
110
156
  return unsupportedSyntax("php", "dynamic variable", location);
111
- return withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location, name: variable.name }, { name: location });
157
+ if (variable.name == "this") {
158
+ if (!context.currentClass)
159
+ return unsupportedSyntax("php", "receiver outside a reference class", location);
160
+ return withParserRanges({ classId: /** @type {string} */ (context.currentClass.id),
161
+ kind: /** @type {const} */ ("ReceiverExpression"), location }, { receiver: location });
162
+ }
163
+ const identifier = withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location, name: variable.name }, { name: location });
164
+ if (!preserveOptional && context.bindings.get(variable.name)?.kind == "OptionalType") {
165
+ return withParserRanges({ kind: /** @type {const} */ ("OptionalUnwrap"), location, operand: identifier }, { unwrap: location });
166
+ }
167
+ return identifier;
112
168
  }
113
169
  if (node.kind == "number") {
114
170
  const literal = /** @type {import("php-parser").Number} */ (node);
@@ -144,6 +200,153 @@ function convertExpression(node, filename, source) {
144
200
  }
145
201
  if (node.kind == "nowdoc")
146
202
  return unsupportedSyntax("php", "nowdoc string", location);
203
+ if (node.kind == "array") {
204
+ const literal = /** @type {import("php-parser").Array} */ (node);
205
+ const invalidEntry = literal.items.find((entry) => {
206
+ if (entry.kind != "entry")
207
+ return true;
208
+ const candidate = /** @type {import("php-parser").Entry} */ (entry);
209
+ return candidate.byRef || candidate.unpack;
210
+ });
211
+ if (invalidEntry)
212
+ return unsupportedSyntax("php", "array reference or unpacking", nodeLocation(invalidEntry, filename, source));
213
+ const entries = /** @type {import("php-parser").Entry[]} */ (literal.items);
214
+ const hasKeys = entries.some((entry) => entry.key != null);
215
+ const hasImplicit = entries.some((entry) => entry.key == null);
216
+ const collectionKind = entries.length == 0 ? expectedType?.kind : hasKeys && !hasImplicit
217
+ ? expectedType?.kind == "OrderedMapType" ? "OrderedMapType" : "MapType"
218
+ : !hasKeys ? "ListType" : "mixed";
219
+ if (collectionKind == "mixed")
220
+ return unsupportedSyntax("php", "mixed list/map array literal", location);
221
+ if (collectionKind == "ListType") {
222
+ const elementType = expectedType?.kind == "ListType" ? expectedType.elementType : undefined;
223
+ return withParserRanges({
224
+ elements: entries.map((entry) => convertExpression(entry.value, filename, source, context, elementType)),
225
+ kind: /** @type {const} */ ("ListLiteral"),
226
+ location
227
+ }, { literal: location });
228
+ }
229
+ if (collectionKind == "MapType" || collectionKind == "OrderedMapType") {
230
+ const valueType = expectedType?.kind == "MapType" || expectedType?.kind == "OrderedMapType"
231
+ ? expectedType.valueType : undefined;
232
+ const semanticEntries = entries.map((entry) => {
233
+ if (!entry.key || entry.key.kind != "string") {
234
+ return unsupportedSyntax("php", "map key other than a literal string", entry.key ? nodeLocation(entry.key, filename, source) : nodeLocation(entry, filename, source));
235
+ }
236
+ const key = convertExpression(entry.key, filename, source, context);
237
+ return withParserRanges({
238
+ key: /** @type {import("../semantic/types.js").StringLiteral} */ (key),
239
+ kind: /** @type {const} */ ("MapEntry"),
240
+ location: nodeLocation(entry, filename, source),
241
+ value: convertExpression(entry.value, filename, source, context, valueType)
242
+ }, { operator: tokenLocation("=>", entry.key.loc?.end.offset ?? 0, entry.value.loc?.start.offset ?? source.length, filename, source) });
243
+ });
244
+ return withParserRanges({
245
+ entries: semanticEntries,
246
+ kind: collectionKind == "OrderedMapType"
247
+ ? /** @type {const} */ ("OrderedMapLiteral")
248
+ : /** @type {const} */ ("MapLiteral"),
249
+ location
250
+ }, { literal: location });
251
+ }
252
+ return unsupportedSyntax("php", "empty array without a list or map type", location);
253
+ }
254
+ if (node.kind == "new") {
255
+ const construction = /** @type {import("php-parser").New} */ (node);
256
+ const name = construction.what.kind == "name" ? /** @type {import("php-parser").Name} */ (construction.what) : undefined;
257
+ if (!name || name.resolution != "uqn" || typeof name.name != "string") {
258
+ return unsupportedSyntax("php", "dynamic or qualified record construction", nodeLocation(construction.what, filename, source));
259
+ }
260
+ const declaration = context.recordNames.get(name.name);
261
+ if (!declaration)
262
+ return unsupportedSyntax("php", "construction of an unknown nominal class", nodeLocation(construction.what, filename, source));
263
+ if (declaration.kind == "ClassDeclaration") {
264
+ const unsupportedArgument = construction.arguments.find((argument) => argument.kind == "namedargument" || argument.kind == "variadic" || Reflect.get(argument, "byref") === true);
265
+ if (unsupportedArgument)
266
+ return unsupportedSyntax("php", "non-positional reference constructor argument", nodeLocation(unsupportedArgument, filename, source));
267
+ const classLocation = nodeLocation(construction.what, filename, source);
268
+ return withParserRanges({ arguments: construction.arguments.map((argument, index) => convertExpression(argument, filename, source, context, declaration.constructor.parameters[index]?.type)),
269
+ kind: /** @type {const} */ ("ReferenceConstruction"), location,
270
+ reference: referenceType(/** @type {string} */ (declaration.id), classLocation) }, { class: classLocation });
271
+ }
272
+ if (declaration.kind == "EffectResourceDeclaration") {
273
+ return unsupportedSyntax("php", "owned resource construction", nodeLocation(construction, filename, source));
274
+ }
275
+ const contextualTypeArguments = expectedType?.kind == "RecordType" && expectedType.declarationId == declaration.id
276
+ ? expectedType.arguments
277
+ : undefined;
278
+ const visibleTypeParameterIds = new Set([...context.typeParameters?.values() ?? []]
279
+ .map((parameter) => /** @type {string} */ (parameter.id)));
280
+ const typeArguments = contextualTypeArguments &&
281
+ !contextualTypeArguments.some((argument) => typeContainsAnyVariable(argument, visibleTypeParameterIds))
282
+ ? contextualTypeArguments
283
+ : undefined;
284
+ return withParserRanges({
285
+ arguments: construction.arguments.map((argument, index) => convertExpression(argument, filename, source, context, instantiatedRecordFieldType(declaration, typeArguments, index))),
286
+ kind: /** @type {const} */ ("RecordConstruction"),
287
+ location,
288
+ record: recordType(/** @type {string} */ (declaration.id), nodeLocation(construction.what, filename, source), typeArguments)
289
+ }, { record: nodeLocation(construction.what, filename, source) });
290
+ }
291
+ if (node.kind == "propertylookup") {
292
+ const read = /** @type {import("php-parser").PropertyLookup} */ (node);
293
+ const offset = read.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (read.offset) : undefined;
294
+ if (!offset || typeof offset.name != "string") {
295
+ return unsupportedSyntax("php", "dynamic or computed member access", nodeLocation(read.offset, filename, source));
296
+ }
297
+ if (read.what.kind == "variable" && /** @type {import("php-parser").Variable} */ (read.what).name == "this" &&
298
+ context.currentClass) {
299
+ const field = context.currentClass.fields.find((candidate) => candidate.name == offset.name);
300
+ if (!field)
301
+ return unsupportedSyntax("php", `unknown private field '${offset.name}'`, nodeLocation(offset, filename, source));
302
+ return withParserRanges({ field: /** @type {string} */ (field.id), kind: /** @type {const} */ ("PrivateFieldRead"), location,
303
+ receiver: /** @type {import("../semantic/types.js").ReceiverExpression} */ (convertExpression(read.what, filename, source, context)) }, { member: nodeLocation(offset, filename, source) });
304
+ }
305
+ const receiverType = knownExpressionType(read.what, context);
306
+ if (receiverType?.kind == "ReferenceType") {
307
+ return unsupportedSyntax("php", "private reference-class field access", location);
308
+ }
309
+ const receiverRecord = receiverType?.kind == "OptionalType" ? receiverType.valueType : receiverType;
310
+ const declaration = receiverRecord?.kind == "RecordType" ? context.records.get(receiverRecord.declarationId) : undefined;
311
+ if ((declaration?.typeParameters?.length ?? 0) > 0) {
312
+ return unsupportedSyntax("php", "generic record property access", nodeLocation(read.offset, filename, source));
313
+ }
314
+ return withParserRanges({
315
+ field: offset.name,
316
+ kind: /** @type {const} */ ("MemberRead"),
317
+ location,
318
+ receiver: convertExpression(read.what, filename, source, context)
319
+ }, { member: nodeLocation(read.offset, filename, source) });
320
+ }
321
+ if (node.kind == "offsetlookup") {
322
+ const lookup = /** @type {import("php-parser").OffsetLookup} */ (node);
323
+ if (!lookup.offset)
324
+ return unsupportedSyntax("php", "append or missing array index", location);
325
+ const receiver = lookup.what.kind == "variable" ? /** @type {import("php-parser").Variable} */ (lookup.what) : undefined;
326
+ const receiverType = receiver && typeof receiver.name == "string" ? context.bindings.get(receiver.name) : undefined;
327
+ const accessKind = receiverType?.kind == "ListType" ? "list" :
328
+ receiverType?.kind == "MapType" || receiverType?.kind == "OrderedMapType" ? "map" :
329
+ lookup.offset.kind == "number" ? "list" : lookup.offset.kind == "string" ? "map" : undefined;
330
+ if (accessKind == "list" && ["number", "string", "variable"].includes(lookup.offset.kind)) {
331
+ return withParserRanges({
332
+ collection: convertExpression(lookup.what, filename, source, context),
333
+ index: convertExpression(lookup.offset, filename, source, context),
334
+ kind: /** @type {const} */ ("ListIndexExpression"),
335
+ location,
336
+ totality: /** @type {const} */ ("proven")
337
+ }, { operator: tokenLocation("[", lookup.what.loc?.end.offset ?? 0, lookup.offset.loc?.start.offset ?? source.length, filename, source) });
338
+ }
339
+ if (accessKind == "map" && ["number", "string", "variable"].includes(lookup.offset.kind)) {
340
+ return withParserRanges({
341
+ collection: convertExpression(lookup.what, filename, source, context),
342
+ key: convertExpression(lookup.offset, filename, source, context),
343
+ kind: /** @type {const} */ ("MapLookupExpression"),
344
+ location,
345
+ totality: /** @type {const} */ ("proven")
346
+ }, { operator: tokenLocation("[", lookup.what.loc?.end.offset ?? 0, lookup.offset.loc?.start.offset ?? source.length, filename, source) });
347
+ }
348
+ return unsupportedSyntax("php", "nonliteral array access", nodeLocation(lookup.offset, filename, source));
349
+ }
147
350
  if (node.kind == "unary") {
148
351
  const unary = /** @type {import("php-parser").Unary} */ (node);
149
352
  if (!["!", "-"].includes(unary.type))
@@ -151,7 +354,7 @@ function convertExpression(node, filename, source) {
151
354
  const semantic = withAdaptedOperation(withParserRanges({
152
355
  kind: "UnaryExpression",
153
356
  location,
154
- operand: convertExpression(unary.what, filename, source)
357
+ operand: convertExpression(unary.what, filename, source, context)
155
358
  }, {
156
359
  operator: tokenLocation(unary.type, unary.loc?.start.offset ?? 0, unary.what.loc?.start.offset ?? unary.loc?.end.offset ?? source.length, filename, source)
157
360
  }), unary.type == "!" ? "Not" : "Negate");
@@ -159,6 +362,12 @@ function convertExpression(node, filename, source) {
159
362
  }
160
363
  if (node.kind == "bin") {
161
364
  const binary = /** @type {import("php-parser").Bin} */ (node);
365
+ if (binary.type == "!==" && binary.left.kind == "variable" && binary.right.kind == "nullkeyword") {
366
+ const operand = /** @type {import("../semantic/types.js").IdentifierExpression} */ (convertExpression(binary.left, filename, source, context, undefined, true));
367
+ return withParserRanges({ kind: /** @type {const} */ ("OptionalIsPresent"), location, operand }, {
368
+ operator: tokenLocation(binary.type, binary.left.loc?.end.offset ?? 0, binary.right.loc?.start.offset ?? source.length, filename, source)
369
+ });
370
+ }
162
371
  if (["==", "!="].includes(binary.type))
163
372
  return unsupportedSyntax("php", `coercive equality ${binary.type}`, location);
164
373
  if (["and", "or"].includes(binary.type))
@@ -167,9 +376,9 @@ function convertExpression(node, filename, source) {
167
376
  return unsupportedSyntax("php", `binary ${binary.type}`, location);
168
377
  const semantic = withAdaptedOperation({
169
378
  kind: /** @type {const} */ ("BinaryExpression"),
170
- left: convertExpression(binary.left, filename, source),
379
+ left: convertExpression(binary.left, filename, source, context),
171
380
  location,
172
- right: convertExpression(binary.right, filename, source)
381
+ right: convertExpression(binary.right, filename, source, context)
173
382
  }, /** @type {import("../semantic/operators.js").AdaptedOperation} */ (phpBinaryOperations.get(binary.type)));
174
383
  return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(withParserRanges(semantic, {
175
384
  operator: tokenLocation(binary.type, binary.left.loc?.end.offset ?? 0, binary.right.loc?.start.offset ?? source.length, filename, source)
@@ -177,12 +386,69 @@ function convertExpression(node, filename, source) {
177
386
  }
178
387
  if (node.kind == "call") {
179
388
  const call = /** @type {import("php-parser").Call} */ (node);
180
- if (call.what.kind != "name" && call.what.kind != "identifier") {
389
+ if (call.what.kind == "propertylookup") {
390
+ const lookup = /** @type {import("php-parser").PropertyLookup} */ ( /** @type {unknown} */(call.what));
391
+ const member = lookup.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (lookup.offset) : undefined;
392
+ const receiverType = knownExpressionType(lookup.what, context);
393
+ if (member && typeof member.name == "string" && receiverType?.kind == "ReferenceType") {
394
+ const method = context.classes.get(receiverType.declarationId)?.methods.find((candidate) => candidate.name == member.name);
395
+ const unsupportedArgument = call.arguments.find((argument) => argument.kind == "namedargument" || argument.kind == "variadic" || Reflect.get(argument, "byref") === true);
396
+ if (unsupportedArgument)
397
+ return unsupportedSyntax("php", "non-positional method argument", nodeLocation(unsupportedArgument, filename, source));
398
+ return withParserRanges({ arguments: call.arguments.map((argument, index) => convertExpression(argument, filename, source, context, method?.parameters[index]?.type)),
399
+ kind: /** @type {const} */ ("MethodCallExpression"), location, method: method?.id ?? member.name,
400
+ receiver: convertExpression(lookup.what, filename, source, context) }, { member: nodeLocation(member, filename, source) });
401
+ }
402
+ }
403
+ if (call.what.kind == "propertylookup" && call.arguments.length == 0) {
404
+ const lookup = /** @type {import("php-parser").PropertyLookup} */ ( /** @type {unknown} */(call.what));
405
+ const receiver = lookup.what.kind == "variable" ? /** @type {import("php-parser").Variable} */ (lookup.what) : undefined;
406
+ const member = lookup.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (lookup.offset) : undefined;
407
+ if (receiver && typeof receiver.name == "string" && member?.name == "getMessage" && context.bindings.get(receiver.name)?.kind == "ErrorType") {
408
+ const receiverLocation = nodeLocation(receiver, filename, source);
409
+ return withParserRanges({
410
+ kind: /** @type {const} */ ("ErrorMessageRead"),
411
+ location,
412
+ receiver: withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location: receiverLocation, name: receiver.name }, {
413
+ name: receiverLocation
414
+ })
415
+ }, { member: nodeLocation(member, filename, source) });
416
+ }
417
+ if (member && typeof member.name == "string" && knownGenericRecordAccessorType(lookup, context)) {
418
+ return withParserRanges({
419
+ field: member.name,
420
+ kind: /** @type {const} */ ("MemberRead"),
421
+ location,
422
+ receiver: convertExpression(lookup.what, filename, source, context)
423
+ }, { member: nodeLocation(member, filename, source) });
424
+ }
425
+ }
426
+ if (call.what.kind == "name" && call.what.name == "count" && call.arguments.length == 1) {
427
+ return withParserRanges({
428
+ collection: convertExpression(call.arguments[0], filename, source, context),
429
+ kind: /** @type {const} */ ("CollectionSizeExpression"),
430
+ location
431
+ }, { operator: nodeLocation(call.what, filename, source) });
432
+ }
433
+ if (call.what.kind != "name") {
181
434
  return unsupportedSyntax("php", "dynamic call", location);
182
435
  }
183
- const callee = /** @type {import("php-parser").Name | import("php-parser").Identifier} */ (call.what).name;
436
+ const calledName = /** @type {import("php-parser").Name} */ (call.what);
437
+ if (calledName.resolution != "uqn" || calledName.name.includes("\\")) {
438
+ return unsupportedSyntax("php", "qualified call", nodeLocation(call.what, filename, source));
439
+ }
440
+ const unsupportedArgument = call.arguments.find((argument) => argument.kind == "namedargument" || argument.kind == "variadic" || Reflect.get(argument, "byref") === true);
441
+ if (unsupportedArgument) {
442
+ const detail = unsupportedArgument.kind == "namedargument" ? "named argument" :
443
+ unsupportedArgument.kind == "variadic" ? "unpacked argument" : "by-reference argument";
444
+ return unsupportedSyntax("php", detail, nodeLocation(unsupportedArgument, filename, source));
445
+ }
446
+ const callee = calledName.name;
447
+ const signature = context.functions.get(callee);
448
+ const knownArguments = call.arguments.map((argument) => knownCallArgumentType(argument, context));
449
+ const parameterTypes = signature ? knownCallParameterTypes(signature, knownArguments) : undefined;
184
450
  return withParserRanges({
185
- arguments: call.arguments.map((argument) => convertExpression(argument, filename, source)),
451
+ arguments: call.arguments.map((argument, index) => convertExpression(argument, filename, source, context, parameterTypes?.[index] ?? signature?.parameters[index]?.type, preservesGenericOptionalEvidence(signature, index))),
186
452
  callee,
187
453
  kind: "CallExpression",
188
454
  location
@@ -190,21 +456,144 @@ function convertExpression(node, filename, source) {
190
456
  }
191
457
  return unsupportedSyntax("php", node.kind, location);
192
458
  }
459
+ /**
460
+ * Resolves only result types established by explicit signatures and bindings.
461
+ * @param {import("php-parser").Expression} node - Parser-owned expression.
462
+ * @param {PhpConversionContext} context - Typed conversion context.
463
+ * @returns {import("../semantic/types.js").SemanticFunctionReturnType | import("../semantic/types.js").ErrorType | undefined} Known result type.
464
+ */
465
+ function knownExpressionType(node, context) {
466
+ if (node.kind == "variable") {
467
+ const variable = /** @type {import("php-parser").Variable} */ (node);
468
+ if (variable.name == "this" && context.currentClass?.id) {
469
+ return { declarationId: context.currentClass.id, kind: "ReferenceType" };
470
+ }
471
+ if (typeof variable.name == "string")
472
+ return context.bindings.get(variable.name);
473
+ }
474
+ if (node.kind == "call") {
475
+ const call = /** @type {import("php-parser").Call} */ (node);
476
+ const name = call.what.kind == "name" && typeof call.what.name == "string" ? call.what.name : undefined;
477
+ if (name) {
478
+ const signature = context.functions.get(name);
479
+ if (signature)
480
+ return knownCallReturnType(signature, call.arguments.map((argument) => knownExpressionType(argument, context)));
481
+ }
482
+ if (call.what.kind == "propertylookup" && call.arguments.length == 0) {
483
+ return knownGenericRecordAccessorType(
484
+ /** @type {import("php-parser").PropertyLookup} */ ( /** @type {unknown} */(call.what)), context);
485
+ }
486
+ if (call.what.kind == "propertylookup") {
487
+ const lookup = /** @type {import("php-parser").PropertyLookup} */ ( /** @type {unknown} */(call.what));
488
+ const receiver = knownExpressionType(lookup.what, context);
489
+ const member = lookup.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (lookup.offset) : undefined;
490
+ if (receiver?.kind == "ReferenceType" && member && typeof member.name == "string") {
491
+ return context.classes.get(receiver.declarationId)?.methods.find((method) => method.name == member.name)?.returnType;
492
+ }
493
+ }
494
+ }
495
+ if (node.kind == "offsetlookup") {
496
+ const lookup = /** @type {import("php-parser").OffsetLookup} */ (node);
497
+ const collectionType = knownExpressionType(lookup.what, context);
498
+ if (collectionType?.kind == "ListType")
499
+ return collectionType.elementType;
500
+ if (collectionType?.kind == "MapType" || collectionType?.kind == "OrderedMapType")
501
+ return collectionType.valueType;
502
+ }
503
+ if (node.kind == "new") {
504
+ const construction = /** @type {import("php-parser").New} */ (node);
505
+ const name = construction.what.kind == "name" ? /** @type {import("php-parser").Name} */ (construction.what) : undefined;
506
+ const declaration = name && typeof name.name == "string" ? context.recordNames.get(name.name) : undefined;
507
+ if (declaration?.id)
508
+ return declaration.kind == "ClassDeclaration"
509
+ ? { declarationId: declaration.id, kind: "ReferenceType" }
510
+ : { declarationId: declaration.id, kind: "RecordType" };
511
+ }
512
+ if (node.kind == "propertylookup") {
513
+ const read = /** @type {import("php-parser").PropertyLookup} */ (node);
514
+ const receiver = knownExpressionType(read.what, context);
515
+ if (read.what.kind == "variable" && /** @type {import("php-parser").Variable} */ (read.what).name == "this" &&
516
+ context.currentClass) {
517
+ const offset = read.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (read.offset) : undefined;
518
+ return context.currentClass.fields.find((field) => field.name == offset?.name)?.type;
519
+ }
520
+ if (receiver?.kind != "RecordType")
521
+ return undefined;
522
+ const declaration = context.records.get(receiver.declarationId);
523
+ const offset = read.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (read.offset) : undefined;
524
+ const memberName = offset && typeof offset.name == "string" ? offset.name : undefined;
525
+ if (memberName && declaration) {
526
+ const index = declaration.fields.findIndex((field) => field.name == memberName);
527
+ return instantiatedRecordFieldType(declaration, receiver.arguments, index);
528
+ }
529
+ }
530
+ return undefined;
531
+ }
532
+ /**
533
+ * Resolves exact parser-known argument evidence without changing the established
534
+ * expression-result classifier used for optional conversion.
535
+ * @param {import("php-parser").Expression} node - Parser-owned call argument.
536
+ * @param {PhpConversionContext} context - Typed conversion context.
537
+ * @returns {import("../semantic/types.js").SemanticFunctionReturnType | import("../semantic/types.js").ErrorType | undefined} Known argument type.
538
+ */
539
+ function knownCallArgumentType(node, context) {
540
+ const known = knownExpressionType(node, context);
541
+ if (known)
542
+ return known;
543
+ if (node.kind == "number" && Number.isSafeInteger(Number(/** @type {import("php-parser").Number} */ (node).value))) {
544
+ return scalarType("integer");
545
+ }
546
+ if (node.kind == "boolean" && typeof /** @type {import("php-parser").Boolean} */ (node).value == "boolean") {
547
+ return scalarType("boolean");
548
+ }
549
+ if (node.kind == "string" && typeof /** @type {import("php-parser").String} */ (node).value == "string" &&
550
+ hasOnlyUnicodeScalars(/** @type {import("php-parser").String} */ (node).value)) {
551
+ return scalarType("string");
552
+ }
553
+ return undefined;
554
+ }
555
+ /**
556
+ * Resolves PHP's exact zero-argument accessor carrier against its receiver's
557
+ * generic record declaration.
558
+ * @param {import("php-parser").PropertyLookup} lookup - Parser-owned method lookup.
559
+ * @param {PhpConversionContext} context - Typed conversion context.
560
+ * @returns {import("../semantic/types.js").SemanticValueType | undefined} Instantiated field type.
561
+ */
562
+ function knownGenericRecordAccessorType(lookup, context) {
563
+ const receiver = knownExpressionType(lookup.what, context);
564
+ const receiverRecord = receiver?.kind == "OptionalType" ? receiver.valueType : receiver;
565
+ if (receiverRecord?.kind != "RecordType")
566
+ return undefined;
567
+ const declaration = context.records.get(receiverRecord.declarationId);
568
+ const member = lookup.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (lookup.offset) : undefined;
569
+ const index = member && typeof member.name == "string"
570
+ ? declaration?.fields.findIndex((field) => field.name == member.name) ?? -1
571
+ : -1;
572
+ if (!declaration || (declaration.typeParameters?.length ?? 0) == 0 || index < 0)
573
+ return undefined;
574
+ return instantiatedRecordFieldType(declaration, receiverRecord.arguments, index);
575
+ }
193
576
  /**
194
577
  * Converts one explicit PHP return.
195
578
  * @param {import("php-parser").Node} node - PHP node.
196
579
  * @param {string} filename - Source filename.
197
580
  * @param {string} source - Complete source.
581
+ * @param {PhpConversionContext} context - Typed conversion context.
198
582
  * @returns {import("../semantic/types.js").ReturnStatement} Semantic return.
199
583
  */
200
- function convertReturn(node, filename, source) {
584
+ function convertReturn(node, filename, source, context) {
201
585
  const location = nodeLocation(node, filename, source);
202
586
  if (node.kind != "return")
203
587
  return unsupportedSyntax("php", node.kind, location);
204
588
  const returnNode = /** @type {import("php-parser").Return} */ (node);
205
- if (!returnNode.expr)
206
- return unsupportedSyntax("php", "empty return", location);
207
- return { expression: convertExpression(returnNode.expr, filename, source), kind: "ReturnStatement", location };
589
+ const expectedType = context.returnType?.kind == "TypeReference" && context.returnType.name == "void"
590
+ ? undefined
591
+ : /** @type {import("../semantic/types.js").SemanticValueType | undefined} */ (context.returnType);
592
+ return {
593
+ ...(returnNode.expr ? { expression: convertExpression(returnNode.expr, filename, source, context, expectedType) } : {}),
594
+ kind: "ReturnStatement",
595
+ location
596
+ };
208
597
  }
209
598
  /**
210
599
  * Reads one exact PHP local `@var` carrier and immutability marker.
@@ -212,9 +601,11 @@ function convertReturn(node, filename, source) {
212
601
  * @param {string} name - Local name.
213
602
  * @param {string} filename - Source filename.
214
603
  * @param {string} source - Complete source.
215
- * @returns {{immutable: boolean, type: import("../semantic/types.js").TypeReference} | undefined} Metadata when present.
604
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
605
+ * @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
606
+ * @returns {{immutable: boolean, type: import("../semantic/types.js").SemanticValueType} | undefined} Metadata when present.
216
607
  */
217
- function localMetadata(node, name, filename, source) {
608
+ function localMetadata(node, name, filename, source, recordNames, typeParameters = new Map()) {
218
609
  const comments = node.leadingComments ?? [];
219
610
  const comment = comments.at(-1);
220
611
  if (!comment || comment.kind != "commentblock" || !comment.loc || !node.loc)
@@ -237,18 +628,27 @@ function localMetadata(node, name, filename, source) {
237
628
  }
238
629
  return {
239
630
  immutable: immutable.length == 1,
240
- type: requireSourceScalarType("php", variables[0].name, `Local '${name}'`, location, commentTagLocation(comment, variables[0], "name", filename, source))
631
+ type: documentedValueType({
632
+ language: "php",
633
+ location: commentTagLocation(comment, variables[0], "name", filename, source),
634
+ ownerLocation: location,
635
+ records: recordNames,
636
+ source,
637
+ sourceType: variables[0].name,
638
+ subject: `Local '${name}'`,
639
+ typeParameters
640
+ })
241
641
  };
242
642
  }
243
643
  /**
244
644
  * Converts one PHP local declaration or assignment.
245
645
  * @param {import("php-parser").Node} node - PHP statement.
246
- * @param {Set<string>} visible - Names visible during adaptation.
247
646
  * @param {string} filename - Source filename.
248
647
  * @param {string} source - Complete source.
249
- * @returns {import("../semantic/types.js").LocalStatement} Semantic local statement.
648
+ * @param {PhpConversionContext} context - Typed conversion context.
649
+ * @returns {import("../semantic/types.js").LocalStatement | import("../semantic/types.js").PrivateFieldWriteStatement} Semantic local or private-field statement.
250
650
  */
251
- function convertLocalStatement(node, visible, filename, source) {
651
+ function convertLocalStatement(node, filename, source, context) {
252
652
  const location = nodeLocation(node, filename, source);
253
653
  if (node.kind != "expressionstatement")
254
654
  return unsupportedSyntax("php", node.kind, location);
@@ -258,34 +658,76 @@ function convertLocalStatement(node, visible, filename, source) {
258
658
  const assignment = /** @type {import("php-parser").Assign} */ (expression);
259
659
  if (assignment.operator != "=")
260
660
  return unsupportedSyntax("php", `assignment ${assignment.operator}`, location);
661
+ if (assignment.left.kind == "propertylookup" && context.currentClass) {
662
+ const lookup = /** @type {import("php-parser").PropertyLookup} */ (assignment.left);
663
+ const receiver = lookup.what.kind == "variable" ? /** @type {import("php-parser").Variable} */ (lookup.what) : undefined;
664
+ const member = lookup.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (lookup.offset) : undefined;
665
+ const field = receiver?.name == "this" && member && typeof member.name == "string"
666
+ ? context.currentClass.fields.find((candidate) => candidate.name == member.name)
667
+ : undefined;
668
+ if (!field)
669
+ return unsupportedSyntax("php", "private field write outside the declaring receiver", nodeLocation(assignment.left, filename, source));
670
+ return withParserRanges({ expression: convertExpression(assignment.right, filename, source, context, field.type),
671
+ field: /** @type {string} */ (field.id), kind: /** @type {const} */ ("PrivateFieldWriteStatement"), location,
672
+ receiver: /** @type {import("../semantic/types.js").ReceiverExpression} */ (convertExpression(lookup.what, filename, source, context)) }, { member: nodeLocation(/** @type {import("php-parser").Identifier} */ (member), filename, source), operator: tokenLocation("=", assignment.left.loc?.end.offset ?? 0, assignment.right.loc?.start.offset ?? source.length, filename, source) });
673
+ }
261
674
  if (assignment.left.kind != "variable")
262
675
  return unsupportedSyntax("php", assignment.left.kind, nodeLocation(assignment.left, filename, source));
676
+ if (assignment.right.kind == "throw") {
677
+ return unsupportedSyntax("php", "throw expression in a value context", nodeLocation(assignment.right, filename, source));
678
+ }
263
679
  const variable = /** @type {import("php-parser").Variable} */ (assignment.left);
264
680
  const targetLocation = nodeLocation(variable, filename, source);
265
681
  if (typeof variable.name != "string" || variable.curly)
266
682
  return unsupportedSyntax("php", "dynamic variable", targetLocation);
267
- const metadata = localMetadata(node, variable.name, filename, source);
683
+ const metadata = localMetadata(node, variable.name, filename, source, context.recordNames, context.typeParameters);
268
684
  if (metadata) {
269
- visible.add(variable.name);
685
+ let declaredType = metadata.type;
686
+ let ordered = false;
687
+ if (declaredType.kind == "MapType" && context.orderedMapDeclarations?.has(assignment) && assignment.right.kind == "array") {
688
+ declaredType = orderedMapTypeFromMap(declaredType, location);
689
+ ordered = true;
690
+ }
691
+ const initializer = convertExpression(assignment.right, filename, source, context, declaredType);
692
+ context.bindings.set(variable.name, declaredType);
270
693
  return withParserRanges({
271
- initializer: convertExpression(assignment.right, filename, source),
694
+ initializer,
272
695
  kind: "LocalDeclaration",
273
696
  location,
274
- mutable: !metadata.immutable,
697
+ mutable: ordered ? false : !metadata.immutable,
698
+ name: variable.name,
699
+ type: declaredType
700
+ }, {
701
+ name: targetLocation,
702
+ operator: tokenLocation("=", assignment.left.loc?.end.offset ?? 0, assignment.right.loc?.start.offset ?? source.length, filename, source)
703
+ });
704
+ }
705
+ const inferredType = knownExpressionType(assignment.right, context);
706
+ if (inferredType?.kind == "RecordType" || inferredType?.kind == "ReferenceType" ||
707
+ inferredType?.kind == "OwnedResourceType") {
708
+ const initializer = convertExpression(assignment.right, filename, source, context, inferredType);
709
+ context.bindings.set(variable.name, inferredType);
710
+ return withParserRanges({
711
+ initializer,
712
+ kind: /** @type {const} */ ("LocalDeclaration"),
713
+ location,
714
+ mutable: false,
275
715
  name: variable.name,
276
- type: metadata.type
716
+ type: inferredType
277
717
  }, {
278
718
  name: targetLocation,
279
719
  operator: tokenLocation("=", assignment.left.loc?.end.offset ?? 0, assignment.right.loc?.start.offset ?? source.length, filename, source)
280
720
  });
281
721
  }
282
- if (!visible.has(variable.name))
722
+ const bindingType = context.bindings.get(variable.name);
723
+ if (!bindingType)
283
724
  return missingType("php", `Local '${variable.name}'`, location);
284
725
  const target = withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location: targetLocation, name: variable.name }, {
285
726
  name: targetLocation
286
727
  });
728
+ const value = convertExpression(assignment.right, filename, source, context, bindingType.kind == "ErrorType" ? undefined : bindingType);
287
729
  return withParserRanges({
288
- expression: convertExpression(assignment.right, filename, source),
730
+ expression: value,
289
731
  kind: "AssignmentStatement",
290
732
  location,
291
733
  target
@@ -296,35 +738,225 @@ function convertLocalStatement(node, visible, filename, source) {
296
738
  /**
297
739
  * Converts one exhaustive PHP statement.
298
740
  * @param {import("php-parser").Node} node - PHP statement.
299
- * @param {Set<string>} visible - Names visible during adaptation.
300
741
  * @param {string} filename - Source filename.
301
742
  * @param {string} source - Complete source.
743
+ * @param {PhpConversionContext} context - Typed conversion context.
302
744
  * @returns {import("../semantic/types.js").Statement} Semantic statement.
303
745
  */
304
- function convertStatement(node, visible, filename, source) {
746
+ function convertStatement(node, filename, source, context) {
305
747
  if (node.kind == "return")
306
- return convertReturn(node, filename, source);
748
+ return convertReturn(node, filename, source, context);
307
749
  if (node.kind == "if")
308
- return convertIf(/** @type {import("php-parser").If} */ (node), visible, filename, source);
750
+ return convertIf(/** @type {import("php-parser").If} */ (node), filename, source, context);
751
+ if (node.kind == "throw")
752
+ return convertPhpRaise(node, filename, source, context);
753
+ if (node.kind == "try")
754
+ return convertPhpTry(node, filename, source, context);
755
+ if (node.kind == "while")
756
+ return convertWhile(/** @type {import("php-parser").While} */ (node), filename, source, context);
757
+ if (node.kind == "foreach")
758
+ return convertForEach(/** @type {import("php-parser").Foreach} */ (node), filename, source, context);
759
+ if (node.kind == "break" || node.kind == "continue") {
760
+ const control = /** @type {import("php-parser").Break | import("php-parser").Continue} */ (node);
761
+ if (control.level)
762
+ return unsupportedSyntax("php", `${node.kind} level`, nodeLocation(node, filename, source));
763
+ const location = tokenLocation(node.kind, node.loc?.start.offset ?? 0, node.loc?.end.offset ?? source.length, filename, source);
764
+ return withParserRanges({
765
+ kind: /** @type {"BreakStatement" | "ContinueStatement"} */ (node.kind == "break" ? "BreakStatement" : "ContinueStatement"),
766
+ location
767
+ }, { keyword: location });
768
+ }
309
769
  if (node.kind == "echo")
310
- return convertPrint(/** @type {import("php-parser").Echo} */ (node), filename, source);
311
- if (node.kind == "expressionstatement")
312
- return convertLocalStatement(node, visible, filename, source);
770
+ return convertPrint(/** @type {import("php-parser").Echo} */ (node), filename, source, context);
771
+ if (node.kind == "expressionstatement") {
772
+ const expression = /** @type {import("php-parser").ExpressionStatement} */ (node).expression;
773
+ if (expression.kind == "call") {
774
+ return {
775
+ expression: /** @type {import("../semantic/types.js").CallExpression | import("../semantic/types.js").MethodCallExpression} */ (convertExpression(expression, filename, source, context)),
776
+ kind: "ExpressionStatement",
777
+ location: nodeLocation(node, filename, source)
778
+ };
779
+ }
780
+ return convertLocalStatement(node, filename, source, context);
781
+ }
313
782
  return unsupportedSyntax("php", node.kind, nodeLocation(node, filename, source));
314
783
  }
784
+ /**
785
+ * Converts exact `throw new DeclaredError(message)`.
786
+ * @param {import("php-parser").Node} node - PHP throw node.
787
+ * @param {string} filename - Source filename.
788
+ * @param {string} source - Complete source.
789
+ * @param {PhpConversionContext} context - Typed lexical context.
790
+ * @returns {import("../semantic/types.js").RaiseStatement} Semantic raise.
791
+ */
792
+ function convertPhpRaise(node, filename, source, context) {
793
+ const location = nodeLocation(node, filename, source);
794
+ const construction = Reflect.get(node, "what");
795
+ if (!construction || construction.kind != "new" || construction.what?.kind != "name" ||
796
+ construction.what.resolution != "uqn" || !context.errorNames.has(construction.what.name) ||
797
+ !Array.isArray(construction.arguments) || construction.arguments.length != 1 ||
798
+ construction.arguments[0].kind == "namedargument" || construction.arguments[0].kind == "variadic") {
799
+ return unsupportedSyntax("php", "throw other than exact declared error construction", location);
800
+ }
801
+ const declaration = /** @type {import("../semantic/types.js").ErrorDeclaration} */ (context.errorNames.get(construction.what.name));
802
+ const typeLocation = nodeLocation(construction.what, filename, source);
803
+ return withParserRanges({
804
+ error: withParserRanges({
805
+ error: withParserRanges({ declarationId: /** @type {string} */ (declaration.id), kind: /** @type {const} */ ("ErrorType") }, { type: typeLocation }),
806
+ kind: /** @type {const} */ ("ErrorConstruction"),
807
+ location: nodeLocation(construction, filename, source),
808
+ message: convertExpression(construction.arguments[0], filename, source, context)
809
+ }, { type: typeLocation }),
810
+ kind: /** @type {const} */ ("RaiseStatement"),
811
+ location
812
+ }, { keyword: tokenLocation("throw", node.loc?.start.offset ?? 0, construction.loc?.start.offset ?? source.length, filename, source) });
813
+ }
814
+ /**
815
+ * Converts one exact typed catch with no finally.
816
+ * @param {import("php-parser").Node} node - PHP try node.
817
+ * @param {string} filename - Source filename.
818
+ * @param {string} source - Complete source.
819
+ * @param {PhpConversionContext} context - Typed lexical context.
820
+ * @returns {import("../semantic/types.js").TryStatement} Semantic exact handler.
821
+ */
822
+ function convertPhpTry(node, filename, source, context) {
823
+ const location = nodeLocation(node, filename, source);
824
+ const catches = Reflect.get(node, "catches");
825
+ const body = Reflect.get(node, "body");
826
+ if (Reflect.get(node, "always") || !Array.isArray(catches) || catches.length != 1 || body?.kind != "block") {
827
+ return unsupportedSyntax("php", "try without one typed catch and no finally", location);
828
+ }
829
+ const handler = catches[0];
830
+ const caught = handler.what?.[0];
831
+ const binding = handler.variable;
832
+ if (handler.what?.length != 1 || caught?.kind != "name" || caught.resolution != "uqn" ||
833
+ !context.errorNames.has(caught.name) || binding?.kind != "variable" || typeof binding.name != "string" ||
834
+ binding.curly || handler.body?.kind != "block") {
835
+ return unsupportedSyntax("php", "broad, multiple, or malformed catch", nodeLocation(handler, filename, source));
836
+ }
837
+ const declaration = /** @type {import("../semantic/types.js").ErrorDeclaration} */ (context.errorNames.get(caught.name));
838
+ const caughtLocation = nodeLocation(caught, filename, source);
839
+ const catchType = withParserRanges({ declarationId: /** @type {string} */ (declaration.id), kind: /** @type {const} */ ("ErrorType") }, {
840
+ type: caughtLocation
841
+ });
842
+ const bodyContext = { ...context, bindings: new Map(context.bindings) };
843
+ const catchContext = { ...context, bindings: new Map(context.bindings) };
844
+ catchContext.bindings.set(binding.name, catchType);
845
+ return withParserRanges({
846
+ body: convertBlock(body, filename, source, bodyContext),
847
+ catchBinding: withParserRanges({
848
+ kind: /** @type {const} */ ("CatchBinding"),
849
+ location: nodeLocation(binding, filename, source),
850
+ mutable: /** @type {const} */ (false),
851
+ name: binding.name,
852
+ type: catchType
853
+ }, { name: nodeLocation(binding, filename, source) }),
854
+ catchBody: convertBlock(handler.body, filename, source, catchContext),
855
+ catchType,
856
+ kind: /** @type {const} */ ("TryStatement"),
857
+ location
858
+ }, { catch: nodeLocation(handler, filename, source), try: tokenLocation("try", node.loc?.start.offset ?? 0, body.loc?.start.offset ?? source.length, filename, source) });
859
+ }
860
+ /**
861
+ * Converts exact block-form PHP `foreach ($list as $value)`.
862
+ * @param {import("php-parser").Foreach} node - PHP foreach node.
863
+ * @param {string} filename - Source filename.
864
+ * @param {string} source - Complete source.
865
+ * @param {PhpConversionContext} context - Typed conversion context.
866
+ * @returns {import("../semantic/types.js").ForEachStatement | import("../semantic/types.js").ForEachMapStatement} Semantic loop.
867
+ */
868
+ function convertForEach(node, filename, source, context) {
869
+ const location = nodeLocation(node, filename, source);
870
+ if (node.shortForm)
871
+ return unsupportedSyntax("php", "alternative foreach syntax", location);
872
+ if (node.value.kind != "variable")
873
+ return unsupportedSyntax("php", "foreach destructuring", nodeLocation(node.value, filename, source));
874
+ const variable = /** @type {import("php-parser").Variable} */ (node.value);
875
+ if (Reflect.get(variable, "byref") === true)
876
+ return unsupportedSyntax("php", "by-reference foreach", nodeLocation(variable, filename, source));
877
+ if (typeof variable.name != "string" || variable.curly)
878
+ return unsupportedSyntax("php", "dynamic foreach binding", nodeLocation(variable, filename, source));
879
+ if (!node.body || node.body.kind != "block") {
880
+ return unsupportedSyntax("php", "foreach without block body", node.body ? nodeLocation(node.body, filename, source) : location);
881
+ }
882
+ const body = /** @type {import("php-parser").Block} */ (node.body);
883
+ const collectionType = iterationOperandType(knownExpressionType(node.source, context));
884
+ if (node.key) {
885
+ if (node.key.kind != "variable")
886
+ return unsupportedSyntax("php", "foreach key binding shape", nodeLocation(node.key, filename, source));
887
+ const keyVariable = /** @type {import("php-parser").Variable} */ (node.key);
888
+ if (Reflect.get(keyVariable, "byref") === true || typeof keyVariable.name != "string" || keyVariable.curly) {
889
+ return unsupportedSyntax("php", "invalid foreach key binding", nodeLocation(keyVariable, filename, source));
890
+ }
891
+ if (collectionType?.kind == "MapType") {
892
+ return unsupportedSyntax("php", "unordered map iteration", nodeLocation(node.source, filename, source));
893
+ }
894
+ if (!collectionType || collectionType.kind != "OrderedMapType") {
895
+ return missingType("php", "Ordered map iteration collection", nodeLocation(node.source, filename, source));
896
+ }
897
+ const keyLocation = nodeLocation(keyVariable, filename, source);
898
+ const valueLocation = nodeLocation(variable, filename, source);
899
+ const keyType = iterationBindingType(collectionType.keyType, keyLocation);
900
+ const valueType = iterationBindingType(collectionType.valueType, valueLocation);
901
+ const keyBinding = withParserRanges({
902
+ kind: /** @type {const} */ ("ValueBinding"), location: keyLocation, mutable: /** @type {const} */ (false),
903
+ name: keyVariable.name, type: keyType
904
+ }, { name: keyLocation });
905
+ const valueBinding = withParserRanges({
906
+ kind: /** @type {const} */ ("ValueBinding"), location: valueLocation, mutable: /** @type {const} */ (false),
907
+ name: variable.name, type: valueType
908
+ }, { name: valueLocation });
909
+ const bodyContext = { ...context, bindings: new Map(context.bindings) };
910
+ bodyContext.bindings.set(keyVariable.name, keyType);
911
+ bodyContext.bindings.set(variable.name, valueType);
912
+ return withParserRanges({
913
+ body: convertBlock(body, filename, source, bodyContext),
914
+ keyBinding,
915
+ kind: /** @type {const} */ ("ForEachMapStatement"),
916
+ location,
917
+ map: convertExpression(node.source, filename, source, context),
918
+ valueBinding
919
+ }, { operator: tokenLocation("foreach", node.loc?.start.offset ?? 0, node.source.loc?.start.offset ?? source.length, filename, source) });
920
+ }
921
+ if (collectionType?.kind == "MapType" || collectionType?.kind == "OrderedMapType") {
922
+ return unsupportedSyntax("php", "map iteration without key/value pair binding", nodeLocation(node.source, filename, source));
923
+ }
924
+ if (!collectionType || collectionType.kind != "ListType") {
925
+ return missingType("php", "Iteration collection", nodeLocation(node.source, filename, source));
926
+ }
927
+ const bindingLocation = nodeLocation(variable, filename, source);
928
+ const inferredType = collectionType.elementType;
929
+ const bindingType = iterationBindingType(inferredType, bindingLocation);
930
+ const valueBinding = withParserRanges({
931
+ kind: /** @type {const} */ ("ValueBinding"),
932
+ location: bindingLocation,
933
+ mutable: /** @type {const} */ (false),
934
+ name: variable.name,
935
+ type: bindingType
936
+ }, { name: bindingLocation });
937
+ const bodyContext = { ...context, bindings: new Map(context.bindings) };
938
+ bodyContext.bindings.set(variable.name, bindingType);
939
+ return withParserRanges({
940
+ body: convertBlock(body, filename, source, bodyContext),
941
+ kind: /** @type {const} */ ("ForEachStatement"),
942
+ list: convertExpression(node.source, filename, source, context),
943
+ location,
944
+ valueBinding
945
+ }, { operator: tokenLocation("foreach", node.loc?.start.offset ?? 0, node.source.loc?.start.offset ?? source.length, filename, source) });
946
+ }
315
947
  /**
316
948
  * Converts an ordered PHP block with its own adaptation scope.
317
949
  * @param {import("php-parser").Block} node - PHP parser block.
318
- * @param {Set<string>} visible - Names visible on block entry.
319
950
  * @param {string} filename - Source filename.
320
951
  * @param {string} source - Complete source.
952
+ * @param {PhpConversionContext} context - Typed conversion context.
321
953
  * @returns {import("../semantic/types.js").Block} Semantic block.
322
954
  */
323
- function convertBlock(node, visible, filename, source) {
955
+ function convertBlock(node, filename, source, context) {
324
956
  return {
325
957
  kind: "Block",
326
958
  location: nodeLocation(node, filename, source),
327
- statements: node.children.map((statement) => convertStatement(statement, visible, filename, source))
959
+ statements: node.children.map((statement) => convertStatement(statement, filename, source, context))
328
960
  };
329
961
  }
330
962
  /**
@@ -334,85 +966,688 @@ function convertBlock(node, visible, filename, source) {
334
966
  * @param {import("../semantic/types.js").SourceLocation} location - Source location.
335
967
  * @param {string} filename - Source filename.
336
968
  * @param {string} source - Complete source.
337
- * @returns {import("../semantic/types.js").TypeReference} Semantic type.
969
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
970
+ * @returns {import("../semantic/types.js").SemanticValueType} Semantic type.
338
971
  */
339
- function convertType(sourceType, subject, location, filename, source) {
972
+ function convertType(sourceType, subject, location, filename, source, recordNames = new Map()) {
340
973
  if (!sourceType)
341
974
  return requireSourceScalarType("php", undefined, subject, location);
342
975
  if (sourceType.kind != "typereference" && sourceType.kind != "name" && sourceType.kind != "identifier") {
343
976
  return unsupportedSyntax("php", "unsupported scalar type", nodeLocation(sourceType, filename, source));
344
977
  }
345
978
  const typeName = /** @type {import("php-parser").TypeReference | import("php-parser").Name | import("php-parser").Identifier} */ (sourceType).name;
346
- return requireSourceScalarType("php", typeName, subject, location, nodeLocation(sourceType, filename, source));
979
+ const typeLocation = nodeLocation(sourceType, filename, source);
980
+ const declaration = recordNames.get(typeName);
981
+ if (declaration?.id)
982
+ return declaration.kind == "ClassDeclaration"
983
+ ? referenceType(declaration.id, typeLocation)
984
+ : declaration.kind == "EffectResourceDeclaration"
985
+ ? ownedResourceType(declaration.id, typeLocation)
986
+ : recordType(declaration.id, typeLocation);
987
+ return requireSourceScalarType("php", typeName, subject, location, typeLocation);
347
988
  }
348
989
  /**
349
- * Converts a PHP function.
990
+ * Reads the exact PHPDoc container signature attached to one function.
991
+ * @param {import("php-parser").Function} node - Function declaration.
992
+ * @param {string} filename - Source filename.
993
+ * @param {string} source - Complete source.
994
+ * @param {string} [ownerId] - Stable declaration identity.
995
+ * @returns {{parameters: Map<string, {location: import("../semantic/types.js").SourceLocation, sourceType: string}>, returnType: {location: import("../semantic/types.js").SourceLocation, sourceType: string} | undefined, typeParameters?: import("../semantic/types.js").TypeParameter[]}} Documented types.
996
+ */
997
+ function functionDocumentedTypes(node, filename, source, ownerId) {
998
+ const comment = node.leadingComments?.at(-1);
999
+ if (!comment || comment.kind != "commentblock" || !comment.loc || !node.loc ||
1000
+ !/^\s*$/u.test(source.slice(comment.loc.end.offset, node.loc.start.offset)))
1001
+ return { parameters: new Map(), returnType: undefined };
1002
+ const block = parseComment(comment.value)[0];
1003
+ const tags = block?.tags ?? [];
1004
+ const parameterTags = tags.filter((tag) => tag.tag == "param");
1005
+ const returnTags = tags.filter((tag) => tag.tag == "return" || tag.tag == "returns");
1006
+ const templateTags = tags.filter((tag) => tag.tag == "template");
1007
+ const malformedTemplate = tags.find((tag) => tag.tag.startsWith("template") && tag.tag != "template");
1008
+ const malformed = tags.some((tag) => !["param", "return", "returns", "template"].includes(tag.tag)) || returnTags.length > 1 ||
1009
+ parameterTags.some((tag) => tag.type != "" || !/^\$[A-Za-z_][A-Za-z0-9_]*$/u.test(tag.description)) ||
1010
+ returnTags.some((tag) => tag.type != "" || tag.description != "") || malformedTemplate ||
1011
+ templateTags.some((tag) => !/^[A-Za-z_][A-Za-z0-9_]*$/u.test(tag.name) || tag.type != "" || tag.description != "") ||
1012
+ templateTags.length > 0 && !ownerId;
1013
+ if (malformed)
1014
+ return unsupportedSyntax("php", "malformed function type annotation", nodeLocation(node, filename, source));
1015
+ const parameters = new Map(parameterTags.map((tag) => [tag.description.slice(1), {
1016
+ location: commentTagLocation(comment, tag, "name", filename, source),
1017
+ sourceType: tag.name
1018
+ }]));
1019
+ if (parameters.size != parameterTags.length) {
1020
+ return unsupportedSyntax("php", "duplicate parameter annotation", nodeLocation(node, filename, source));
1021
+ }
1022
+ const returnTag = returnTags[0];
1023
+ const typeParameters = templateTags.map((tag, index) => {
1024
+ const location = commentTagLocation(comment, tag, "name", filename, source);
1025
+ return withParserRanges({ id: `${ownerId}:type:${index}`, kind: /** @type {const} */ ("TypeParameter"), location, name: tag.name }, { name: location });
1026
+ });
1027
+ return {
1028
+ parameters,
1029
+ returnType: returnTag ? {
1030
+ location: commentTagLocation(comment, returnTag, "name", filename, source),
1031
+ sourceType: returnTag.name
1032
+ } : undefined,
1033
+ ...(typeParameters.length > 0 ? { typeParameters } : {})
1034
+ };
1035
+ }
1036
+ /**
1037
+ * Reads an optional exact class-level PHPDoc template list.
1038
+ * @param {import("php-parser").Class} node - Class declaration.
1039
+ * @param {string} ownerId - Stable record identity.
1040
+ * @param {string} filename - Source filename.
1041
+ * @param {string} source - Complete source.
1042
+ * @returns {import("../semantic/types.js").TypeParameter[] | undefined} Ordered parameters.
1043
+ */
1044
+ function classDocumentedTypeParameters(node, ownerId, filename, source) {
1045
+ const documented = functionDocumentedTypes(
1046
+ /** @type {import("php-parser").Function} */ ( /** @type {unknown} */(node)), filename, source, ownerId);
1047
+ if (documented.parameters.size || documented.returnType) {
1048
+ return unsupportedSyntax("php", "function type annotation on record declaration", nodeLocation(node, filename, source));
1049
+ }
1050
+ return documented.typeParameters;
1051
+ }
1052
+ /**
1053
+ * Returns a native PHP type name from one supported parser node.
1054
+ * @param {import("php-parser").Node | null} type - Native type node.
1055
+ * @returns {string | undefined} Type name.
1056
+ */
1057
+ function phpTypeName(type) {
1058
+ if (!type || !["typereference", "name", "identifier"].includes(type.kind))
1059
+ return undefined;
1060
+ return /** @type {import("php-parser").TypeReference | import("php-parser").Name | import("php-parser").Identifier} */ (type).name;
1061
+ }
1062
+ /**
1063
+ * Wraps one parser-declared canonical PHP nullable type.
1064
+ * @param {import("../semantic/types.js").SemanticValueType} valueType - Present-value semantic type.
1065
+ * @param {import("php-parser").Node} sourceType - Native parser type node.
1066
+ * @param {number} ownerStart - Earliest owning parser offset.
1067
+ * @param {string} filename - Source filename.
1068
+ * @param {string} source - Complete source.
1069
+ * @returns {import("../semantic/types.js").OptionalType} Optional semantic type.
1070
+ */
1071
+ function nullableType(valueType, sourceType, ownerStart, filename, source) {
1072
+ if (!sourceType.loc)
1073
+ throw new Error("PHP parser omitted nullable type location.");
1074
+ const valueLocation = nodeLocation(sourceType, filename, source);
1075
+ const marker = tokenLocation("?", ownerStart, sourceType.loc.start.offset, filename, source);
1076
+ if (marker.end.offset != valueLocation.start.offset) {
1077
+ return unsupportedSyntax("php", "noncanonical nullable type", marker);
1078
+ }
1079
+ return optionalType(valueType, locationFromOffsets(filename, source, marker.start.offset, valueLocation.end.offset), valueLocation);
1080
+ }
1081
+ /**
1082
+ * Converts one explicit PHP function return type.
1083
+ * @param {import("php-parser").Node | null} sourceType - PHP return type node.
1084
+ * @param {string} subject - Typed function return.
1085
+ * @param {import("../semantic/types.js").SourceLocation} location - Function location.
1086
+ * @param {string} filename - Source filename.
1087
+ * @param {string} source - Complete source.
1088
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
1089
+ * @returns {import("../semantic/types.js").SemanticFunctionReturnType} Semantic return type.
1090
+ */
1091
+ function convertReturnType(sourceType, subject, location, filename, source, recordNames = new Map()) {
1092
+ if (!sourceType)
1093
+ return requireSourceReturnType("php", undefined, subject, location);
1094
+ if (sourceType.kind != "typereference" && sourceType.kind != "name" && sourceType.kind != "identifier") {
1095
+ return unsupportedSyntax("php", "unsupported return type", nodeLocation(sourceType, filename, source));
1096
+ }
1097
+ const typeName = /** @type {import("php-parser").TypeReference | import("php-parser").Name | import("php-parser").Identifier} */ (sourceType).name;
1098
+ const declaration = recordNames.get(typeName);
1099
+ if (declaration?.id)
1100
+ return declaration.kind == "ClassDeclaration"
1101
+ ? referenceType(declaration.id, nodeLocation(sourceType, filename, source))
1102
+ : declaration.kind == "EffectResourceDeclaration"
1103
+ ? ownedResourceType(declaration.id, nodeLocation(sourceType, filename, source))
1104
+ : recordType(declaration.id, nodeLocation(sourceType, filename, source));
1105
+ return requireSourceReturnType("php", typeName, subject, location, nodeLocation(sourceType, filename, source));
1106
+ }
1107
+ /**
1108
+ * Converts the explicit type signature of one PHP function before any body expressions.
350
1109
  * @param {import("php-parser").Function} node - PHP function node.
351
1110
  * @param {string} filename - Source filename.
352
1111
  * @param {string} source - Complete source.
353
- * @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
1112
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
1113
+ * @param {string} ownerId - Stable function identity.
1114
+ * @returns {PhpFunctionSignature} Typed function signature.
354
1115
  */
355
- function convertFunction(node, filename, source) {
1116
+ function convertFunctionSignature(node, filename, source, recordNames, ownerId) {
356
1117
  const location = nodeLocation(node, filename, source);
357
1118
  const name = typeof node.name == "string" ? node.name : node.name.name;
358
1119
  if (!node.body) {
359
1120
  return unsupportedSyntax("php", "function body", location);
360
1121
  }
1122
+ const documented = functionDocumentedTypes(node, filename, source, ownerId);
1123
+ const typeParameterNames = new Map((documented.typeParameters ?? []).map((parameter) => [parameter.name, parameter]));
361
1124
  const parameters = node.arguments.map((parameter) => {
362
1125
  const parameterLocation = nodeLocation(parameter, filename, source);
363
1126
  const parameterName = typeof parameter.name == "string" ? parameter.name : parameter.name.name;
364
- if (parameter.nullable)
365
- return unsupportedSyntax("php", "unsupported scalar type", parameterLocation);
1127
+ if (parameter.byref)
1128
+ return unsupportedSyntax("php", "by-reference parameter", parameterLocation);
1129
+ if (parameter.variadic)
1130
+ return unsupportedSyntax("php", "variadic parameter", parameterLocation);
1131
+ if (parameter.value)
1132
+ return unsupportedSyntax("php", "default parameter", parameterLocation);
366
1133
  const parameterNode = typeof parameter.name == "string" ? parameter : parameter.name;
1134
+ const documentedType = documented.parameters.get(parameterName);
1135
+ const nativeType = phpTypeName(parameter.type);
1136
+ let parameterType = documentedType
1137
+ ? documentedValueType({ language: "php", location: documentedType.location, ownerLocation: parameterLocation, source,
1138
+ records: recordNames, sourceType: documentedType.sourceType, subject: `Parameter '${parameterName}'`, typeParameters: typeParameterNames })
1139
+ : convertType(parameter.type, `Parameter '${parameterName}'`, parameterLocation, filename, source, recordNames);
1140
+ if (nativeType == "array" && !documentedType)
1141
+ return missingType("php", `Parameter '${parameterName}'`, parameterLocation);
1142
+ if (documentedType && !phpDocumentedNativeTypeMatches(nativeType, parameter.nullable, parameterType, recordNames)) {
1143
+ return unsupportedSyntax("php", "documented parameter type incompatible with native type", documentedType.location);
1144
+ }
1145
+ if (parameter.nullable && parameterType.kind != "OptionalType") {
1146
+ if (!parameter.type)
1147
+ return missingType("php", `Parameter '${parameterName}'`, parameterLocation);
1148
+ parameterType = nullableType(parameterType, parameter.type, parameter.loc?.start.offset ?? 0, filename, source);
1149
+ }
1150
+ else if (!parameter.nullable && parameterType.kind == "OptionalType" &&
1151
+ parameterType.valueType.kind != "TypeVariableReference") {
1152
+ return unsupportedSyntax("php", "optional annotation without nullable native type", documentedType?.location ?? parameterLocation);
1153
+ }
367
1154
  const semanticParameter = {
368
1155
  kind: /** @type {const} */ ("Parameter"),
369
1156
  location: parameterLocation,
370
1157
  name: parameterName,
371
- type: convertType(parameter.type, `Parameter '${parameterName}'`, parameterLocation, filename, source)
1158
+ type: parameterType
372
1159
  };
373
1160
  return withParserRanges(semanticParameter, { name: nodeLocation(parameterNode, filename, source) });
374
1161
  });
375
- if (node.nullable)
376
- return unsupportedSyntax("php", "unsupported scalar type", location);
377
- const visible = new Set(parameters.map((parameter) => parameter.name));
378
- const body = convertBlock(node.body, visible, filename, source);
1162
+ const extraDocumentedParameter = [...documented.parameters.keys()].find((name) => !node.arguments.some((parameter) => (typeof parameter.name == "string" ? parameter.name : parameter.name.name) == name));
1163
+ if (extraDocumentedParameter)
1164
+ return unsupportedSyntax("php", `annotation for unknown parameter '${extraDocumentedParameter}'`, location);
1165
+ if (node.byref)
1166
+ return unsupportedSyntax("php", "by-reference return", location);
379
1167
  const nameNode = typeof node.name == "string" ? node : node.name;
380
- return withParserRanges({
381
- body,
382
- kind: "FunctionDeclaration",
1168
+ const nativeReturnType = phpTypeName(node.type);
1169
+ let returnType;
1170
+ if (documented.returnType) {
1171
+ returnType = documentedValueType({ language: "php", location: documented.returnType.location, ownerLocation: location, source,
1172
+ records: recordNames, sourceType: documented.returnType.sourceType, subject: `Function '${name}' return`, typeParameters: typeParameterNames });
1173
+ if (!phpDocumentedNativeTypeMatches(nativeReturnType, node.nullable, returnType, recordNames)) {
1174
+ return unsupportedSyntax("php", "documented return type incompatible with native type", documented.returnType.location);
1175
+ }
1176
+ }
1177
+ else {
1178
+ if (nativeReturnType == "array")
1179
+ return missingType("php", `Function '${name}' return`, location);
1180
+ returnType = convertReturnType(node.type, `Function '${name}' return`, location, filename, source, recordNames);
1181
+ }
1182
+ if (node.nullable && returnType.kind != "OptionalType") {
1183
+ if (!node.type)
1184
+ return missingType("php", `Function '${name}' return`, location);
1185
+ const typeStart = node.type.loc?.start.offset ?? 0;
1186
+ returnType = nullableType(
1187
+ /** @type {import("../semantic/types.js").SemanticValueType} */ (returnType), node.type, Math.max(node.loc?.start.offset ?? 0, typeStart - 2), filename, source);
1188
+ }
1189
+ else if (!node.nullable && returnType.kind == "OptionalType" &&
1190
+ returnType.valueType.kind != "TypeVariableReference") {
1191
+ return unsupportedSyntax("php", "optional annotation without nullable native return type", documented.returnType?.location ?? location);
1192
+ }
1193
+ return {
383
1194
  location,
384
1195
  name,
1196
+ nameLocation: nodeLocation(nameNode, filename, source),
385
1197
  parameters,
386
- returnType: convertType(node.type, `Function '${name}' return`, location, filename, source)
387
- }, { name: nodeLocation(nameNode, filename, source) });
1198
+ returnType,
1199
+ ...(documented.typeParameters ? { typeParameters: documented.typeParameters } : {})
1200
+ };
1201
+ }
1202
+ /**
1203
+ * Checks the exact runtime carrier permitted beside a precise PHPDoc type.
1204
+ * @param {string | undefined} nativeType - Native PHP type name.
1205
+ * @param {boolean} nativeNullable - Whether the native carrier has PHP's nullable marker.
1206
+ * @param {import("../semantic/types.js").SemanticValueType} documentedType - Exact semantic document type.
1207
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} records - Visible nominal declarations by name.
1208
+ * @returns {boolean} Whether the native carrier agrees without changing meaning.
1209
+ */
1210
+ function phpDocumentedNativeTypeMatches(nativeType, nativeNullable, documentedType, records) {
1211
+ if (documentedType.kind == "OptionalType") {
1212
+ if (documentedType.valueType.kind == "TypeVariableReference") {
1213
+ return nativeType === undefined && !nativeNullable;
1214
+ }
1215
+ return nativeNullable && phpDocumentedNativeTypeMatches(nativeType, false, documentedType.valueType, records);
1216
+ }
1217
+ if (nativeNullable)
1218
+ return false;
1219
+ if (documentedType.kind == "TypeVariableReference")
1220
+ return nativeType === undefined;
1221
+ if (documentedType.kind == "TypeReference") {
1222
+ return nativeType !== undefined && sourceScalarType("php", nativeType)?.name == documentedType.name;
1223
+ }
1224
+ if (documentedType.kind == "ListType" || documentedType.kind == "MapType" || documentedType.kind == "OrderedMapType") {
1225
+ return nativeType == "array";
1226
+ }
1227
+ if (documentedType.kind == "RecordType") {
1228
+ return nativeType !== undefined && records.get(nativeType)?.id == documentedType.declarationId;
1229
+ }
1230
+ if (documentedType.kind == "ReferenceType") {
1231
+ return nativeType !== undefined && records.get(nativeType)?.id == documentedType.declarationId;
1232
+ }
1233
+ return false;
1234
+ }
1235
+ /**
1236
+ * Converts a PHP function body using the already-proved module signatures.
1237
+ * @param {import("php-parser").Function} node - PHP function node.
1238
+ * @param {PhpFunctionSignature} signature - Preconverted explicit signature.
1239
+ * @param {Map<string, PhpFunctionSignature>} functions - Module function signatures.
1240
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
1241
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Record declarations by identity.
1242
+ * @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Reference classes by identity.
1243
+ * @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errorNames - Error declarations by source name.
1244
+ * @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errors - Error declarations by identity.
1245
+ * @param {string} filename - Source filename.
1246
+ * @param {string} source - Complete source.
1247
+ * @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
1248
+ */
1249
+ function convertFunction(node, signature, functions, recordNames, records, classes, errorNames, errors, filename, source) {
1250
+ if (!node.body)
1251
+ return unsupportedSyntax("php", "function body", signature.location);
1252
+ const context = {
1253
+ bindings: new Map(signature.parameters.map((parameter) => [parameter.name, parameter.type])),
1254
+ classes,
1255
+ errorNames,
1256
+ errors,
1257
+ functions,
1258
+ orderedMapDeclarations: orderedMapDeclarationsForPhp(node.body),
1259
+ recordNames,
1260
+ records,
1261
+ returnType: signature.returnType,
1262
+ typeParameters: new Map((signature.typeParameters ?? []).map((parameter) => [parameter.name, parameter]))
1263
+ };
1264
+ return withParserRanges({
1265
+ body: convertBlock(node.body, filename, source, context),
1266
+ kind: "FunctionDeclaration",
1267
+ location: signature.location,
1268
+ name: signature.name,
1269
+ parameters: signature.parameters,
1270
+ returnType: signature.returnType,
1271
+ ...(signature.typeParameters ? { typeParameters: signature.typeParameters } : {})
1272
+ }, { name: signature.nameLocation });
1273
+ }
1274
+ /**
1275
+ * Resolves parser-owned key/value loops to exact declarations inside one lexical owner.
1276
+ * Ambiguous same-name declarations produce no evidence and fail during loop conversion.
1277
+ * @param {unknown} value - Function body or entry-point subtree.
1278
+ * @returns {Set<object>} Exact pair-iterated parser declarations.
1279
+ */
1280
+ function orderedMapDeclarationsForPhp(value) {
1281
+ /** @type {{declaration: object, name: string, offset: number}[]} */
1282
+ const declarations = [];
1283
+ /** @type {{name: string, offset: number}[]} */
1284
+ const receivers = [];
1285
+ const seen = new WeakSet();
1286
+ /**
1287
+ * Visits one parser candidate.
1288
+ * @param {unknown} candidate - Parser candidate.
1289
+ */
1290
+ const visit = (candidate) => {
1291
+ if (!candidate || typeof candidate != "object" || seen.has(candidate))
1292
+ return;
1293
+ seen.add(candidate);
1294
+ const kind = Reflect.get(candidate, "kind");
1295
+ if (kind == "function" || kind == "class")
1296
+ return;
1297
+ if (kind == "assign") {
1298
+ const variable = Reflect.get(candidate, "left");
1299
+ if (Reflect.get(variable, "kind") == "variable" && typeof Reflect.get(variable, "name") == "string") {
1300
+ declarations.push({
1301
+ declaration: candidate,
1302
+ name: Reflect.get(variable, "name"),
1303
+ offset: Reflect.get(variable, "loc")?.start.offset
1304
+ });
1305
+ }
1306
+ }
1307
+ else if (kind == "foreach") {
1308
+ const receiver = Reflect.get(candidate, "source");
1309
+ if (Reflect.get(receiver, "kind") == "variable" && typeof Reflect.get(receiver, "name") == "string" &&
1310
+ Reflect.get(candidate, "key"))
1311
+ receivers.push({
1312
+ name: Reflect.get(receiver, "name"),
1313
+ offset: Reflect.get(candidate, "loc")?.start.offset
1314
+ });
1315
+ }
1316
+ for (const [key, child] of Object.entries(candidate)) {
1317
+ if (["loc", "leadingComments", "trailingComments"].includes(key))
1318
+ continue;
1319
+ if (Array.isArray(child)) {
1320
+ for (const item of child)
1321
+ visit(item);
1322
+ }
1323
+ else
1324
+ visit(child);
1325
+ }
1326
+ };
1327
+ visit(value);
1328
+ const selected = new Set();
1329
+ for (const receiver of receivers) {
1330
+ const matches = declarations.filter(({ name, offset }) => name == receiver.name && offset < receiver.offset);
1331
+ if (matches.length == 1)
1332
+ selected.add(matches[0].declaration);
1333
+ }
1334
+ return selected;
1335
+ }
1336
+ /**
1337
+ * Converts one exact final RuntimeException subclass.
1338
+ * @param {import("php-parser").Class} node - PHP class declaration.
1339
+ * @param {import("../semantic/types.js").ErrorDeclaration} declaration - Predeclared semantic error.
1340
+ * @param {string} filename - Source filename.
1341
+ * @param {string} source - Complete source.
1342
+ * @returns {import("../semantic/types.js").ErrorDeclaration} Semantic error declaration.
1343
+ */
1344
+ function convertPhpError(node, declaration, filename, source) {
1345
+ const location = nodeLocation(node, filename, source);
1346
+ const parent = node.extends;
1347
+ const parentName = parent?.kind == "name" ? /** @type {import("php-parser").Name} */ ( /** @type {unknown} */(parent)) : undefined;
1348
+ if (node.isAnonymous || !node.isFinal || node.isReadonly || node.isAbstract || node.implements?.length ||
1349
+ node.attrGroups.length || node.body.length != 0 || !parentName ||
1350
+ !(parentName.name == "RuntimeException" && parentName.resolution == "uqn" ||
1351
+ parentName.name == "\\RuntimeException" && parentName.resolution == "fqn")) {
1352
+ return unsupportedSyntax("php", "noncanonical typed error declaration", location);
1353
+ }
1354
+ const nameNode = typeof node.name == "string" ? node : node.name;
1355
+ return withParserRanges(declaration, { name: nodeLocation(nameNode, filename, source), type: nodeLocation(parentName, filename, source) });
1356
+ }
1357
+ /**
1358
+ * Reads one exact public PHP constructor or instance-method signature.
1359
+ * @param {import("php-parser").Method} node - Parser-owned method.
1360
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} nominalNames - Visible nominal declarations.
1361
+ * @param {string} ownerId - Stable callable identity.
1362
+ * @param {boolean} constructor - Whether this is the sole constructor.
1363
+ * @param {string} filename - Source filename.
1364
+ * @param {string} source - Complete source.
1365
+ * @returns {{location: import("../semantic/types.js").SourceLocation, name: string, nameLocation: import("../semantic/types.js").SourceLocation, parameters: import("../semantic/types.js").Parameter[], returnType?: import("../semantic/types.js").SemanticFunctionReturnType}} Exact signature.
1366
+ */
1367
+ function convertPhpClassCallableSignature(node, nominalNames, ownerId, constructor, filename, source) {
1368
+ const location = nodeLocation(node, filename, source);
1369
+ const name = typeof node.name == "string" ? node.name : node.name.name;
1370
+ if (!constructor && /^__/u.test(name))
1371
+ return unsupportedSyntax("php", `reserved reference method '${name}'`, location);
1372
+ if (node.visibility != "public" || node.isStatic || node.isAbstract || node.isFinal || Reflect.get(node, "isReadonly") || node.byref ||
1373
+ node.attrGroups.length || !node.body || constructor != (name == "__construct")) {
1374
+ return unsupportedSyntax("php", "noncanonical reference class callable", location);
1375
+ }
1376
+ const documented = functionDocumentedTypes(/** @type {import("php-parser").Function} */ ( /** @type {unknown} */(node)), filename, source, ownerId);
1377
+ if (documented.typeParameters?.length)
1378
+ return unsupportedSyntax("php", "generic reference class callable", location);
1379
+ if (constructor && (node.type || node.nullable || documented.returnType)) {
1380
+ return unsupportedSyntax("php", "constructor return annotation", location);
1381
+ }
1382
+ const parameters = node.arguments.map((parameter) => {
1383
+ const parameterLocation = nodeLocation(parameter, filename, source);
1384
+ const parameterName = typeof parameter.name == "string" ? parameter.name : parameter.name.name;
1385
+ if (parameter.byref || parameter.variadic || parameter.value || parameter.flags || parameter.readonly ||
1386
+ parameter.hooks.length || parameter.attrGroups.length) {
1387
+ return unsupportedSyntax("php", "noncanonical reference class parameter", parameterLocation);
1388
+ }
1389
+ const documentedType = documented.parameters.get(parameterName);
1390
+ const nativeType = phpTypeName(parameter.type);
1391
+ let type = documentedType
1392
+ ? documentedValueType({ language: "php", location: documentedType.location, ownerLocation: parameterLocation,
1393
+ records: nominalNames, source, sourceType: documentedType.sourceType, subject: `Parameter '${parameterName}'` })
1394
+ : convertType(parameter.type, `Parameter '${parameterName}'`, parameterLocation, filename, source, nominalNames);
1395
+ if (nativeType == "array" && !documentedType)
1396
+ return missingType("php", `Parameter '${parameterName}'`, parameterLocation);
1397
+ if (documentedType && !phpDocumentedNativeTypeMatches(nativeType, parameter.nullable, type, nominalNames)) {
1398
+ return unsupportedSyntax("php", "documented parameter type incompatible with native type", documentedType.location);
1399
+ }
1400
+ if (parameter.nullable && type.kind != "OptionalType") {
1401
+ if (!parameter.type)
1402
+ return missingType("php", `Parameter '${parameterName}'`, parameterLocation);
1403
+ type = nullableType(type, parameter.type, parameter.loc?.start.offset ?? 0, filename, source);
1404
+ }
1405
+ else if (!parameter.nullable && type.kind == "OptionalType") {
1406
+ return unsupportedSyntax("php", "optional annotation without nullable native type", documentedType?.location ?? parameterLocation);
1407
+ }
1408
+ const nameNode = typeof parameter.name == "string" ? parameter : parameter.name;
1409
+ return withParserRanges({ kind: /** @type {const} */ ("Parameter"), location: parameterLocation,
1410
+ name: parameterName, type }, { name: nodeLocation(nameNode, filename, source) });
1411
+ });
1412
+ if ([...documented.parameters.keys()].some((parameterName) => !node.arguments.some((parameter) => (typeof parameter.name == "string" ? parameter.name : parameter.name.name) == parameterName))) {
1413
+ return unsupportedSyntax("php", "method PHPDoc parameter mismatch", location);
1414
+ }
1415
+ const nameNode = typeof node.name == "string" ? node : node.name;
1416
+ if (constructor)
1417
+ return { location, name: "constructor", nameLocation: nodeLocation(nameNode, filename, source), parameters };
1418
+ let returnType;
1419
+ const nativeReturnType = phpTypeName(node.type);
1420
+ if (documented.returnType) {
1421
+ returnType = documentedValueType({ language: "php", location: documented.returnType.location, ownerLocation: location,
1422
+ records: nominalNames, source, sourceType: documented.returnType.sourceType, subject: `Method '${name}' return` });
1423
+ if (!phpDocumentedNativeTypeMatches(nativeReturnType, node.nullable, returnType, nominalNames)) {
1424
+ return unsupportedSyntax("php", "documented method return type incompatible with native type", documented.returnType.location);
1425
+ }
1426
+ }
1427
+ else {
1428
+ if (nativeReturnType == "array")
1429
+ return missingType("php", `Method '${name}' return`, location);
1430
+ returnType = convertReturnType(node.type, `Method '${name}' return`, location, filename, source, nominalNames);
1431
+ }
1432
+ if (node.nullable && returnType.kind != "OptionalType") {
1433
+ if (!node.type)
1434
+ return missingType("php", `Method '${name}' return`, location);
1435
+ returnType = nullableType(/** @type {import("../semantic/types.js").SemanticValueType} */ (returnType), node.type, node.type.loc?.start.offset ?? 0, filename, source);
1436
+ }
1437
+ else if (!node.nullable && returnType.kind == "OptionalType") {
1438
+ return unsupportedSyntax("php", "optional annotation without nullable native return type", documented.returnType?.location ?? location);
1439
+ }
1440
+ return { location, name, nameLocation: nodeLocation(nameNode, filename, source), parameters, returnType };
1441
+ }
1442
+ /**
1443
+ * Converts the bounded final/private-field PHP reference-class profile.
1444
+ * @param {import("php-parser").Class} node - Parser class.
1445
+ * @param {import("../semantic/types.js").ClassDeclaration} declaration - Predeclared class identity.
1446
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} nominalNames - Visible nominal declarations.
1447
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Records by identity.
1448
+ * @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Classes by identity.
1449
+ * @param {Map<string, PhpFunctionSignature>} functions - Top-level signatures.
1450
+ * @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errorNames - Errors by name.
1451
+ * @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errors - Errors by identity.
1452
+ * @param {string} filename - Source filename.
1453
+ * @param {string} source - Complete source.
1454
+ * @returns {import("../semantic/types.js").ClassDeclaration} Semantic class.
1455
+ */
1456
+ function convertPhpReferenceClass(node, declaration, nominalNames, records, classes, functions, errorNames, errors, filename, source) {
1457
+ const location = nodeLocation(node, filename, source);
1458
+ if (node.isAnonymous || !node.isFinal || node.isReadonly || node.isAbstract || node.extends || node.implements?.length ||
1459
+ node.attrGroups.length)
1460
+ return unsupportedSyntax("php", "reference class inheritance or noncanonical modifier", location);
1461
+ const fieldStatements = node.body.filter((member) => member.kind == "propertystatement");
1462
+ const methodNodes = /** @type {import("php-parser").Method[]} */ (node.body.filter((member) => member.kind == "method"));
1463
+ const constructors = methodNodes.filter((method) => (typeof method.name == "string" ? method.name : method.name.name) == "__construct");
1464
+ const ordinaryMethods = methodNodes.filter((method) => !constructors.includes(method));
1465
+ if (constructors.length != 1 || fieldStatements.length == 0 || fieldStatements.length + methodNodes.length != node.body.length) {
1466
+ return unsupportedSyntax("php", "reference class requires private fields, one constructor, and ordinary methods", location);
1467
+ }
1468
+ declaration.fields = fieldStatements.map((statement, index) => {
1469
+ const fieldLocation = nodeLocation(statement, filename, source);
1470
+ const properties = Reflect.get(statement, "properties");
1471
+ const property = Array.isArray(properties) && properties.length == 1 ? properties[0] : undefined;
1472
+ const nameNode = property?.name;
1473
+ const name = typeof nameNode == "string" ? nameNode : nameNode?.name;
1474
+ if (Reflect.get(statement, "visibility") != "private" || Reflect.get(statement, "isStatic") ||
1475
+ Reflect.get(statement, "isAbstract") || Reflect.get(statement, "isFinal") || !property ||
1476
+ typeof name != "string" || property.value || property.readonly || property.nullable || property.attrGroups?.length ||
1477
+ property.hooks?.length)
1478
+ return unsupportedSyntax("php", "noncanonical private instance field", fieldLocation);
1479
+ const type = convertType(property.type, `Private field '${name}'`, fieldLocation, filename, source, nominalNames);
1480
+ return withParserRanges({ id: `${declaration.id}:field:${index}`, kind: /** @type {const} */ ("PrivateField"),
1481
+ location: fieldLocation, name, type }, { name: nodeLocation(typeof nameNode == "string" ? property : nameNode, filename, source) });
1482
+ });
1483
+ const constructorNode = constructors[0];
1484
+ const constructorSignature = convertPhpClassCallableSignature(constructorNode, nominalNames, `${declaration.id}:constructor`, true, filename, source);
1485
+ declaration.constructor = withParserRanges({ body: /** @type {import("../semantic/types.js").Block} */ ({}),
1486
+ id: `${declaration.id}:constructor`, kind: /** @type {const} */ ("ConstructorDeclaration"),
1487
+ location: constructorSignature.location, parameters: constructorSignature.parameters }, { constructor: constructorSignature.nameLocation });
1488
+ const methodSignatures = ordinaryMethods.map((method, index) => convertPhpClassCallableSignature(method, nominalNames, `${declaration.id}:method:${index}`, false, filename, source));
1489
+ declaration.methods = methodSignatures.map((signature, index) => withParserRanges({
1490
+ body: /** @type {import("../semantic/types.js").Block} */ ({}), id: `${declaration.id}:method:${index}`,
1491
+ kind: /** @type {const} */ ("MethodDeclaration"), location: signature.location, name: signature.name,
1492
+ parameters: signature.parameters,
1493
+ returnType: /** @type {import("../semantic/types.js").SemanticFunctionReturnType} */ (signature.returnType)
1494
+ }, { name: signature.nameLocation }));
1495
+ const base = { bindings: new Map(), classes, currentClass: declaration, errorNames, errors, functions,
1496
+ recordNames: nominalNames, records };
1497
+ declaration.constructor.body = convertBlock(/** @type {import("php-parser").Block} */ (constructorNode.body), filename, source, { ...base, bindings: new Map(declaration.constructor.parameters.map((parameter) => [parameter.name, parameter.type])),
1498
+ returnType: { kind: /** @type {const} */ ("TypeReference"), name: /** @type {const} */ ("void") } });
1499
+ for (let index = 0; index < ordinaryMethods.length; index += 1) {
1500
+ const method = declaration.methods[index];
1501
+ method.body = convertBlock(/** @type {import("php-parser").Block} */ (ordinaryMethods[index].body), filename, source, { ...base, bindings: new Map(method.parameters.map((parameter) => [parameter.name, parameter.type])), returnType: method.returnType });
1502
+ }
1503
+ const nameNode = typeof node.name == "string" ? node : node.name;
1504
+ return withParserRanges(declaration, { name: nodeLocation(nameNode, filename, source) });
1505
+ }
1506
+ /**
1507
+ * Converts one exact final readonly promoted-property PHP record.
1508
+ * @param {import("php-parser").Class} node - PHP class declaration.
1509
+ * @param {import("../semantic/types.js").RecordDeclaration} declaration - Predeclared nominal identity.
1510
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration>} recordNames - Record declarations by name.
1511
+ * @param {string} filename - Source filename.
1512
+ * @param {string} source - Complete source.
1513
+ * @returns {import("../semantic/types.js").RecordDeclaration} Semantic record.
1514
+ */
1515
+ function convertPhpRecord(node, declaration, recordNames, filename, source) {
1516
+ const location = nodeLocation(node, filename, source);
1517
+ const generic = (declaration.typeParameters?.length ?? 0) > 0;
1518
+ if (node.isAnonymous || !node.isFinal || node.isReadonly == generic || node.isAbstract || node.extends || node.implements?.length ||
1519
+ node.attrGroups.length)
1520
+ return unsupportedSyntax("php", "noncanonical record class modifiers", location);
1521
+ if (node.body.length < 1 || node.body[0].kind != "method" || !generic && node.body.length != 1) {
1522
+ return unsupportedSyntax("php", "record class body outside one constructor", nodeLocation(node.body[1] ?? node.body[0] ?? node, filename, source));
1523
+ }
1524
+ const constructor = /** @type {import("php-parser").Method} */ (node.body[0]);
1525
+ const typeParameterNames = new Map((declaration.typeParameters ?? []).map((parameter) => [parameter.name, parameter]));
1526
+ const constructorName = typeof constructor.name == "string" ? constructor.name : constructor.name.name;
1527
+ if (constructorName != "__construct" || constructor.visibility != "public" || constructor.isStatic || constructor.isAbstract ||
1528
+ constructor.isFinal || Reflect.get(constructor, "isReadonly") || constructor.byref || constructor.type || constructor.nullable ||
1529
+ constructor.attrGroups.length || !constructor.body || constructor.body.children.length != 0) {
1530
+ return unsupportedSyntax("php", "noncanonical record constructor", nodeLocation(constructor, filename, source));
1531
+ }
1532
+ const documented = functionDocumentedTypes(/** @type {import("php-parser").Function} */ ( /** @type {unknown} */(constructor)), filename, source);
1533
+ declaration.fields = constructor.arguments.map((parameter) => {
1534
+ const fieldLocation = nodeLocation(parameter, filename, source);
1535
+ const name = typeof parameter.name == "string" ? parameter.name : parameter.name.name;
1536
+ const documentedType = documented.parameters.get(name);
1537
+ const nativeType = phpTypeName(parameter.type);
1538
+ if (parameter.flags != (generic ? 4 : 1) || parameter.byref || parameter.variadic || parameter.value || parameter.readonly ||
1539
+ parameter.hooks.length || parameter.attrGroups.length) {
1540
+ return unsupportedSyntax("php", "record field outside public promoted-property profile", fieldLocation);
1541
+ }
1542
+ if (nativeType == "array" && !documentedType)
1543
+ return missingType("php", `Record field '${name}'`, fieldLocation);
1544
+ let type = documentedType
1545
+ ? documentedValueType({ language: "php", location: documentedType.location, ownerLocation: fieldLocation, records: recordNames,
1546
+ source, sourceType: documentedType.sourceType, subject: `Record field '${name}'`, typeParameters: typeParameterNames })
1547
+ : convertType(parameter.type, `Record field '${name}'`, fieldLocation, filename, source, recordNames);
1548
+ if (documentedType && !phpDocumentedNativeTypeMatches(nativeType, parameter.nullable, type, recordNames)) {
1549
+ return unsupportedSyntax("php", "documented record field type incompatible with native type", documentedType.location);
1550
+ }
1551
+ if (parameter.nullable && type.kind != "OptionalType") {
1552
+ if (!parameter.type)
1553
+ return missingType("php", `Record field '${name}'`, fieldLocation);
1554
+ type = nullableType(type, parameter.type, parameter.loc?.start.offset ?? 0, filename, source);
1555
+ }
1556
+ else if (!parameter.nullable && type.kind == "OptionalType" && type.valueType.kind != "TypeVariableReference") {
1557
+ return unsupportedSyntax("php", "optional annotation without nullable native record field", documentedType?.location ?? fieldLocation);
1558
+ }
1559
+ const field = { kind: /** @type {const} */ ("RecordField"), location: fieldLocation, name, type };
1560
+ const nameNode = typeof parameter.name == "string" ? parameter : parameter.name;
1561
+ return withParserRanges(field, { name: nodeLocation(nameNode, filename, source) });
1562
+ });
1563
+ const extraDocumented = [...documented.parameters.keys()].find((name) => !constructor.arguments.some((parameter) => (typeof parameter.name == "string" ? parameter.name : parameter.name.name) == name));
1564
+ if (extraDocumented || documented.returnType)
1565
+ return unsupportedSyntax("php", "invalid record constructor annotation", location);
1566
+ if (generic)
1567
+ validatePhpGenericRecordGetters(node, declaration, recordNames, filename, source);
1568
+ const nameNode = typeof node.name == "string" ? node : node.name;
1569
+ return withParserRanges(declaration, { name: nodeLocation(nameNode, filename, source) });
1570
+ }
1571
+ /**
1572
+ * Validates the exact accessor half of PHP's documented generic-record profile.
1573
+ * @param {import("php-parser").Class} node - PHP class declaration.
1574
+ * @param {import("../semantic/types.js").RecordDeclaration} declaration - Converted record.
1575
+ * @param {Map<string, import("../semantic/types.js").RecordDeclaration>} recordNames - Visible records.
1576
+ * @param {string} filename - Source filename.
1577
+ * @param {string} source - Complete source.
1578
+ * @returns {void}
1579
+ */
1580
+ function validatePhpGenericRecordGetters(node, declaration, recordNames, filename, source) {
1581
+ const getters = node.body.slice(1);
1582
+ const typeParameters = new Map((declaration.typeParameters ?? []).map((parameter) => [parameter.name, parameter]));
1583
+ if (getters.length != declaration.fields.length) {
1584
+ return unsupportedSyntax("php", "generic record getter count", nodeLocation(getters[declaration.fields.length] ?? node, filename, source));
1585
+ }
1586
+ getters.forEach((candidate, index) => {
1587
+ const field = declaration.fields[index];
1588
+ if (candidate.kind != "method")
1589
+ return unsupportedSyntax("php", "noncanonical generic record getter", nodeLocation(candidate, filename, source));
1590
+ const getter = /** @type {import("php-parser").Method} */ (candidate);
1591
+ const name = typeof getter.name == "string" ? getter.name : getter.name.name;
1592
+ const statement = getter.body?.children[0];
1593
+ const returned = statement?.kind == "return" ? /** @type {import("php-parser").Return} */ (statement).expr : undefined;
1594
+ const lookup = returned?.kind == "propertylookup" ? /** @type {import("php-parser").PropertyLookup} */ (returned) : undefined;
1595
+ const receiver = lookup?.what.kind == "variable" ? /** @type {import("php-parser").Variable} */ (lookup.what) : undefined;
1596
+ const member = lookup?.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (lookup.offset) : undefined;
1597
+ if (name != field.name || getter.visibility != "public" || getter.isStatic || getter.isAbstract || getter.isFinal ||
1598
+ Reflect.get(getter, "isReadonly") || getter.byref || getter.arguments.length || getter.attrGroups.length ||
1599
+ !getter.body || getter.body.children.length != 1 || receiver?.name != "this" || member?.name != field.name) {
1600
+ return unsupportedSyntax("php", "noncanonical generic record getter", nodeLocation(getter, filename, source));
1601
+ }
1602
+ const documented = functionDocumentedTypes(
1603
+ /** @type {import("php-parser").Function} */ ( /** @type {unknown} */(getter)), filename, source);
1604
+ if (documented.parameters.size || documented.typeParameters || !documented.returnType) {
1605
+ return unsupportedSyntax("php", "missing or invalid generic record getter type", nodeLocation(getter, filename, source));
1606
+ }
1607
+ const returnType = documentedValueType({ language: "php", location: documented.returnType.location,
1608
+ ownerLocation: nodeLocation(getter, filename, source), records: recordNames, source,
1609
+ sourceType: documented.returnType.sourceType, subject: `Record getter '${name}'`, typeParameters });
1610
+ const nativeType = phpTypeName(getter.type);
1611
+ if (!phpDocumentedNativeTypeMatches(nativeType, getter.nullable, returnType, recordNames) ||
1612
+ !sameValueType(returnType, field.type)) {
1613
+ return unsupportedSyntax("php", "generic record getter type mismatch", documented.returnType.location);
1614
+ }
1615
+ });
388
1616
  }
389
1617
  /**
390
1618
  * Converts the existing PHP if/else terminal with restricted branch prefixes.
391
1619
  * @param {import("php-parser").If} node - PHP if node.
392
- * @param {Set<string>} visible - Enclosing visible names.
393
1620
  * @param {string} filename - Source filename.
394
1621
  * @param {string} source - Complete source.
1622
+ * @param {PhpConversionContext} context - Typed conversion context.
395
1623
  * @returns {import("../semantic/types.js").IfStatement} Semantic branch.
396
1624
  */
397
- function convertIf(node, visible, filename, source) {
1625
+ function convertIf(node, filename, source, context) {
398
1626
  const location = nodeLocation(node, filename, source);
399
1627
  if (node.shortForm)
400
1628
  return unsupportedSyntax("php", "alternative if syntax", location);
401
1629
  if (node.body.kind != "block")
402
1630
  return unsupportedSyntax("php", "if without block consequent", location);
403
- const consequentVisible = new Set(visible);
1631
+ if (node.test.kind == "variable") {
1632
+ const tested = /** @type {import("php-parser").Variable} */ (node.test);
1633
+ if (typeof tested.name == "string" && context.bindings.get(tested.name)?.kind == "OptionalType") {
1634
+ return unsupportedSyntax("php", "optional truthiness condition", nodeLocation(tested, filename, source));
1635
+ }
1636
+ }
1637
+ const condition = convertExpression(node.test, filename, source, context);
1638
+ const consequentContext = { ...context, bindings: new Map(context.bindings) };
1639
+ const alternateContext = { ...context, bindings: new Map(context.bindings) };
404
1640
  let alternate;
405
1641
  if (node.alternate) {
406
- const alternateVisible = new Set(visible);
407
1642
  if (node.alternate.kind == "block") {
408
- alternate = convertBlock(/** @type {import("php-parser").Block} */ (node.alternate), alternateVisible, filename, source);
1643
+ alternate = convertBlock(/** @type {import("php-parser").Block} */ (node.alternate), filename, source, alternateContext);
409
1644
  }
410
1645
  else if (node.alternate.kind == "if") {
411
1646
  const nested = /** @type {import("php-parser").If} */ (node.alternate);
412
1647
  alternate = {
413
1648
  kind: /** @type {const} */ ("Block"),
414
1649
  location: nodeLocation(nested, filename, source),
415
- statements: [convertIf(nested, alternateVisible, filename, source)]
1650
+ statements: [convertIf(nested, filename, source, alternateContext)]
416
1651
  };
417
1652
  }
418
1653
  else
@@ -420,54 +1655,164 @@ function convertIf(node, visible, filename, source) {
420
1655
  }
421
1656
  return {
422
1657
  ...(alternate ? { alternate } : {}),
423
- condition: convertExpression(node.test, filename, source),
424
- consequent: convertBlock(node.body, consequentVisible, filename, source),
1658
+ condition,
1659
+ consequent: convertBlock(node.body, filename, source, consequentContext),
425
1660
  kind: "IfStatement",
426
1661
  location
427
1662
  };
428
1663
  }
1664
+ /**
1665
+ * Converts exact braced PHP `while ($condition) { ... }` syntax.
1666
+ * @param {import("php-parser").While} node - PHP while node.
1667
+ * @param {string} filename - Source filename.
1668
+ * @param {string} source - Complete source.
1669
+ * @param {PhpConversionContext} context - Typed conversion context.
1670
+ * @returns {import("../semantic/types.js").WhileStatement} Semantic loop.
1671
+ */
1672
+ function convertWhile(node, filename, source, context) {
1673
+ const location = nodeLocation(node, filename, source);
1674
+ if (node.shortForm)
1675
+ return unsupportedSyntax("php", "alternative while syntax", location);
1676
+ if (!node.body || node.body.kind != "block") {
1677
+ return unsupportedSyntax("php", "while without block body", node.body ? nodeLocation(node.body, filename, source) : location);
1678
+ }
1679
+ const bodyContext = { ...context, bindings: new Map(context.bindings) };
1680
+ return withParserRanges({
1681
+ body: convertBlock(/** @type {import("php-parser").Block} */ (node.body), filename, source, bodyContext),
1682
+ condition: convertExpression(node.test, filename, source, context, undefined, true),
1683
+ kind: /** @type {const} */ ("WhileStatement"),
1684
+ location
1685
+ }, { keyword: tokenLocation("while", node.loc?.start.offset ?? 0, node.test.loc?.start.offset ?? source.length, filename, source) });
1686
+ }
429
1687
  /**
430
1688
  * Converts a PHP echo entry point.
431
1689
  * @param {import("php-parser").Echo} node - PHP echo node.
432
1690
  * @param {string} filename - Source filename.
433
1691
  * @param {string} source - Complete source.
1692
+ * @param {PhpConversionContext} context - Typed conversion context.
434
1693
  * @returns {import("../semantic/types.js").PrintStatement} Print statement.
435
1694
  */
436
- function convertPrint(node, filename, source) {
1695
+ function convertPrint(node, filename, source, context) {
437
1696
  const location = nodeLocation(node, filename, source);
438
1697
  if (node.expressions.length != 2 || node.expressions[1].kind != "name" ||
439
1698
  /** @type {import("php-parser").Name} */ (node.expressions[1]).name != "PHP_EOL") {
440
1699
  return unsupportedSyntax("php", "echo without one expression and PHP_EOL", location);
441
1700
  }
442
- return { expression: convertExpression(node.expressions[0], filename, source), kind: "PrintStatement", location };
1701
+ return { expression: convertExpression(node.expressions[0], filename, source, context), kind: "PrintStatement", location };
443
1702
  }
444
1703
  /**
445
1704
  * Parses PHP into the shared semantic module.
446
1705
  * @param {object} input - Parser input.
447
1706
  * @param {string} input.filename - Source filename.
448
1707
  * @param {string} input.source - Source text.
1708
+ * @param {readonly import("../semantic/types.js").EffectCapabilityDeclaration[]} [input.capabilities] - Compiler-authorized declarations.
1709
+ * @param {{isEntry: boolean, functions: Map<string, import("../semantic/types.js").FunctionDeclaration>, records: Map<string, import("../semantic/types.js").RecordDeclaration>, errors?: Map<string, import("../semantic/types.js").ErrorDeclaration>}} [input.program] - Resolved program imports and entry role.
449
1710
  * @returns {import("../semantic/types.js").SemanticModule} Semantic module.
450
1711
  */
451
- export function parsePhp({ filename, source }) {
1712
+ export function parsePhp({ capabilities = [], filename, source, program: programContext }) {
452
1713
  const program = parsePhpProgram(filename, source);
453
1714
  validateDeclareNodes(program.children, filename, source);
454
- const functions = program.children.filter((node) => node.kind == "function")
455
- .map((node) => convertFunction(/** @type {import("php-parser").Function} */ (node), filename, source));
456
- const executableNodes = program.children.filter((node) => node.kind != "function" && node.kind != "declare" && node.kind != "noop");
1715
+ let body = task034PhpBody(program.children, capabilities, filename, source);
1716
+ if (programContext) {
1717
+ inspectPhpModule({ filename, source });
1718
+ const namespace = /** @type {import("php-parser").Namespace} */ (body.find((node) => node.kind == "namespace"));
1719
+ body = namespace.children.filter((node) => node.kind != "usegroup" && !isPhpRequireOnce(node));
1720
+ }
1721
+ const classNodes = /** @type {import("php-parser").Class[]} */ (body.filter((node) => node.kind == "class"));
1722
+ const errorNodes = classNodes.filter((node) => node.extends?.kind == "name" &&
1723
+ ["RuntimeException", "\\RuntimeException"].includes(node.extends.name));
1724
+ const referenceClassNodes = classNodes.filter((node) => !errorNodes.includes(node) &&
1725
+ node.body.some((member) => member.kind == "propertystatement"));
1726
+ const recordNodes = classNodes.filter((node) => !errorNodes.includes(node) && !referenceClassNodes.includes(node));
1727
+ const errorDeclarations = errorNodes.map((node, index) => ({
1728
+ id: `error:${index}`,
1729
+ kind: /** @type {const} */ ("ErrorDeclaration"),
1730
+ location: nodeLocation(node, filename, source),
1731
+ name: typeof node.name == "string" ? node.name : node.name.name
1732
+ }));
1733
+ const recordDeclarations = recordNodes.map((node, index) => {
1734
+ const id = `record:${index}`;
1735
+ const typeParameters = classDocumentedTypeParameters(node, id, filename, source);
1736
+ return {
1737
+ fields: [],
1738
+ id,
1739
+ kind: /** @type {const} */ ("RecordDeclaration"),
1740
+ location: nodeLocation(node, filename, source),
1741
+ name: typeof node.name == "string" ? node.name : node.name.name,
1742
+ ...(typeParameters ? { typeParameters } : {})
1743
+ };
1744
+ });
1745
+ const classDeclarations = referenceClassNodes.map((node, index) => ({
1746
+ constructor: /** @type {import("../semantic/types.js").ConstructorDeclaration} */ ({}),
1747
+ fields: [], id: `class:${index}`, kind: /** @type {const} */ ("ClassDeclaration"),
1748
+ location: nodeLocation(node, filename, source), methods: [],
1749
+ name: typeof node.name == "string" ? node.name : node.name.name
1750
+ }));
1751
+ const recordNames = /** @type {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} */ (new Map(programContext?.records ?? []));
1752
+ for (const resource of capabilities.flatMap(({ resources }) => resources))
1753
+ recordNames.set(resource.name, resource);
1754
+ const errorNames = new Map(programContext?.errors ?? []);
1755
+ for (const failure of capabilities.flatMap(({ failures }) => failures)) {
1756
+ errorNames.set(failure.name, /** @type {import("../semantic/types.js").ErrorDeclaration} */ ( /** @type {unknown} */(failure)));
1757
+ }
1758
+ for (const declaration of errorDeclarations)
1759
+ errorNames.set(declaration.name, declaration);
1760
+ const errorsById = new Map([...errorNames.values()].map((declaration) => [/** @type {string} */ (declaration.id), declaration]));
1761
+ const errors = errorNodes.map((node, index) => convertPhpError(node, errorDeclarations[index], filename, source));
1762
+ for (const declaration of recordDeclarations)
1763
+ recordNames.set(declaration.name, declaration);
1764
+ for (const declaration of classDeclarations)
1765
+ recordNames.set(declaration.name, declaration);
1766
+ const recordsById = new Map([...recordNames.values()]
1767
+ .filter((declaration) => declaration.kind == "RecordDeclaration")
1768
+ .map((declaration) => [/** @type {string} */ (declaration.id), declaration]));
1769
+ const classesById = new Map(classDeclarations.map((declaration) => [/** @type {string} */ (declaration.id), declaration]));
1770
+ const records = recordNodes.map((node, index) => convertPhpRecord(node, recordDeclarations[index],
1771
+ /** @type {Map<string, import("../semantic/types.js").RecordDeclaration>} */ ( /** @type {unknown} */(recordNames)), filename, source));
1772
+ const functionNodes = /** @type {import("php-parser").Function[]} */ (body.filter((node) => node.kind == "function"));
1773
+ const signatures = functionNodes.map((node, index) => convertFunctionSignature(node, filename, source, recordNames, `function:${index}`));
1774
+ const functionSignatures = new Map([...capabilityFunctionSignatures(capabilities, moduleLocation(filename, source)),
1775
+ ...(programContext?.functions ?? [])].map(([localName, declaration]) => [localName, {
1776
+ location: declaration.location,
1777
+ name: localName,
1778
+ nameLocation: declaration.location,
1779
+ parameters: declaration.parameters,
1780
+ returnType: declaration.returnType,
1781
+ ...(declaration.typeParameters ? { typeParameters: declaration.typeParameters } : {})
1782
+ }]));
1783
+ for (const signature of signatures)
1784
+ functionSignatures.set(signature.name, signature);
1785
+ const classes = referenceClassNodes.map((node, index) => convertPhpReferenceClass(node, classDeclarations[index], recordNames, recordsById, classesById, functionSignatures, errorNames, errorsById, filename, source));
1786
+ const functions = functionNodes.map((node, index) => convertFunction(node, signatures[index], functionSignatures, recordNames, recordsById, classesById, errorNames, errorsById, filename, source));
1787
+ const executableNodes = body.filter((node) => !["class", "function", "declare", "noop"].includes(node.kind));
457
1788
  const location = moduleLocation(filename, source);
458
- if (functions.length == 0)
459
- return unsupportedSyntax("php", "module without a function", location);
1789
+ if (programContext && !programContext.isEntry && executableNodes.length > 0) {
1790
+ return unsupportedSyntax("php", "top-level side effect outside the selected entry module", nodeLocation(executableNodes[0], filename, source));
1791
+ }
460
1792
  const first = executableNodes[0];
461
1793
  const last = executableNodes.at(-1) ?? first;
462
1794
  const entryLocation = first
463
1795
  ? locationFromOffsets(filename, source, first.loc?.start.offset ?? 0, last?.loc?.end.offset ?? source.length)
464
1796
  : location;
465
- const entryVisible = new Set();
1797
+ const entryContext = {
1798
+ bindings: new Map(),
1799
+ classes: classesById,
1800
+ errorNames,
1801
+ errors: errorsById,
1802
+ functions: functionSignatures,
1803
+ orderedMapDeclarations: orderedMapDeclarationsForPhp(executableNodes),
1804
+ recordNames,
1805
+ records: recordsById,
1806
+ returnType: undefined
1807
+ };
466
1808
  const entryBlock = {
467
1809
  kind: /** @type {const} */ ("Block"),
468
1810
  location: entryLocation,
469
- statements: executableNodes.map((node) => convertStatement(node, entryVisible, filename, source))
1811
+ statements: executableNodes.map((node) => convertStatement(node, filename, source, entryContext))
470
1812
  };
1813
+ if (!programContext && functions.length == 0 && capabilities.length == 0 && !blockReferencesProtectedEntry(entryBlock)) {
1814
+ return unsupportedSyntax("php", "module without a function", location);
1815
+ }
471
1816
  return {
472
1817
  entryPoint: {
473
1818
  body: entryBlock,
@@ -476,9 +1821,142 @@ export function parsePhp({ filename, source }) {
476
1821
  },
477
1822
  functions,
478
1823
  kind: "Module",
479
- location
1824
+ location,
1825
+ ...(errors.length > 0 ? { errors } : {}),
1826
+ ...(classes.length > 0 ? { classes } : {}),
1827
+ ...(records.length > 0 ? { records } : {})
480
1828
  };
481
1829
  }
1830
+ /**
1831
+ * Removes exact protected PHP probe support before portable conversion.
1832
+ * @param {import("php-parser").Statement[]} body - Parsed top-level statements.
1833
+ * @param {readonly import("../semantic/types.js").EffectCapabilityDeclaration[]} capabilities - Authorized declarations.
1834
+ * @param {string} filename - Source filename.
1835
+ * @param {string} source - Complete source.
1836
+ * @returns {import("php-parser").Statement[]} Portable statements.
1837
+ */
1838
+ function task034PhpBody(body, capabilities, filename, source) {
1839
+ if (!isTask034ResourceProbe(capabilities))
1840
+ return body;
1841
+ const start = body.findIndex((node) => node.leadingComments?.some(({ value }) => value == "/* semantifold-task034-support */"));
1842
+ if (start < 0)
1843
+ return body;
1844
+ if (!hasExactEffectSupport(source, "php")) {
1845
+ return unsupportedSyntax("php", "malformed protected Task 034 support", nodeLocation(body[start], filename, source));
1846
+ }
1847
+ const expected = [
1848
+ ["class", "ProbeOperationFailure"], ["class", "ProbeAcquireFailure"], ["class", "ProbeReadFailure"],
1849
+ ["class", "ProbeCloseFailure"], ["class", "ProbeResourceClosed"], ["class", "ProbeResource"],
1850
+ ["expressionstatement", undefined], ["function", "probeEffect"], ["function", "probeAcquire"],
1851
+ ["function", "probeRead"], ["function", "probeClose"], ["function", "probeTrace"]
1852
+ ];
1853
+ const matches = expected.every(([kind, name], index) => {
1854
+ const node = body[start + index];
1855
+ const rawName = node ? Reflect.get(node, "name") : undefined;
1856
+ const actualName = typeof rawName == "string" ? rawName : rawName && typeof rawName == "object" ? Reflect.get(rawName, "name") : undefined;
1857
+ return node?.kind == kind && actualName == name;
1858
+ });
1859
+ const next = body[start + expected.length];
1860
+ if (!matches || next && !next.leadingComments?.some(({ value }) => value == "/* semantifold-task034-support-end */")) {
1861
+ return unsupportedSyntax("php", "malformed protected Task 034 support", nodeLocation(body[start], filename, source));
1862
+ }
1863
+ return [...body.slice(0, start), ...body.slice(start + expected.length)];
1864
+ }
1865
+ /**
1866
+ * Reads the canonical parser-owned PHP namespace, use bindings, and literal require_once edges.
1867
+ * @param {object} input - Parser input.
1868
+ * @param {string} input.filename - Source filename.
1869
+ * @param {string} input.source - Source text.
1870
+ * @returns {{bindings: {importedName: string, localName: string, location: import("../semantic/types.js").SourceLocation, nativeName: string, symbolKind: import("../semantic/types.js").SemanticDeclarationKind, typeOnly: false}[], imports: {importedName: string, localName: string, location: import("../semantic/types.js").SourceLocation, namespace: true, pathLocation: import("../semantic/types.js").SourceLocation, specifier: string, typeOnly: false}[], exports: {exportedName: string, localName: string, location: import("../semantic/types.js").SourceLocation, typeOnly: false}[], nativeName: string}} Parser-owned PHP module header.
1871
+ */
1872
+ export function inspectPhpModule({ filename, source }) {
1873
+ const program = parsePhpProgram(filename, source);
1874
+ validateDeclareNodes(program.children, filename, source);
1875
+ const namespaces = program.children.filter((node) => node.kind == "namespace");
1876
+ const invalidOuter = program.children.find((node) => !["declare", "namespace", "noop"].includes(node.kind));
1877
+ const namespace = /** @type {import("php-parser").Namespace | undefined} */ (namespaces[0]);
1878
+ if (!namespace || namespaces.length != 1 || namespace.withBrackets || typeof namespace.name != "string" || invalidOuter) {
1879
+ return unsupportedSyntax("php", "one canonical unbracketed namespace", nodeLocation(invalidOuter ?? namespaces[1] ?? namespace ?? program, filename, source));
1880
+ }
1881
+ const bindings = [];
1882
+ for (const node of namespace.children.filter((child) => child.kind == "usegroup")) {
1883
+ const group = /** @type {import("php-parser").UseGroup} */ (node);
1884
+ if (group.name !== null || ![null, "function"].includes(group.type) || group.items.length == 0) {
1885
+ return unsupportedSyntax("php", "grouped, constant, or empty use declaration", nodeLocation(group, filename, source));
1886
+ }
1887
+ for (const item of group.items) {
1888
+ if (item.type !== null || typeof item.name != "string" || !item.name.includes("\\")) {
1889
+ return unsupportedSyntax("php", "grouped or unqualified use item", nodeLocation(item, filename, source));
1890
+ }
1891
+ const importedName = item.name.split("\\").at(-1);
1892
+ const alias = item.alias;
1893
+ if (!importedName || alias && alias.kind != "identifier") {
1894
+ return unsupportedSyntax("php", "invalid use alias", nodeLocation(item, filename, source));
1895
+ }
1896
+ bindings.push({
1897
+ importedName,
1898
+ localName: alias ? alias.name : importedName,
1899
+ location: nodeLocation(item, filename, source),
1900
+ nativeName: item.name,
1901
+ symbolKind: /** @type {import("../semantic/types.js").SemanticDeclarationKind} */ (group.type == "function" ? "function" : "record"),
1902
+ typeOnly: /** @type {const} */ (false)
1903
+ });
1904
+ }
1905
+ }
1906
+ const imports = namespace.children.filter(isPhpIncludeStatement).map((node) => {
1907
+ if (!isPhpRequireOnce(node)) {
1908
+ return unsupportedSyntax("php", "include/require outside literal require_once __DIR__ profile", nodeLocation(node, filename, source));
1909
+ }
1910
+ const statement = /** @type {import("php-parser").ExpressionStatement} */ (node);
1911
+ const include = /** @type {import("php-parser").Include} */ (statement.expression);
1912
+ const target = /** @type {import("php-parser").Bin} */ (include.target);
1913
+ const path = /** @type {import("php-parser").String} */ (target.right);
1914
+ if (!path.value.startsWith("/") || path.value.includes("\0")) {
1915
+ return unsupportedSyntax("php", "unsafe require_once path", nodeLocation(path, filename, source));
1916
+ }
1917
+ return {
1918
+ importedName: "*",
1919
+ localName: "",
1920
+ location: nodeLocation(node, filename, source),
1921
+ namespace: /** @type {const} */ (true),
1922
+ pathLocation: nodeLocation(path, filename, source),
1923
+ specifier: `.${path.value}`,
1924
+ typeOnly: /** @type {const} */ (false)
1925
+ };
1926
+ });
1927
+ const exports = namespace.children.flatMap((node) => {
1928
+ if (node.kind != "class" && node.kind != "function")
1929
+ return [];
1930
+ const declaration = /** @type {import("php-parser").Class | import("php-parser").Function} */ (node);
1931
+ const name = typeof declaration.name == "string" ? declaration.name : declaration.name.name;
1932
+ return [{ exportedName: name, localName: name, location: nodeLocation(node, filename, source), typeOnly: /** @type {const} */ (false) }];
1933
+ });
1934
+ return { bindings, exports, imports, nativeName: namespace.name };
1935
+ }
1936
+ /**
1937
+ * Reports whether a PHP statement is any include/require expression.
1938
+ * @param {import("php-parser").Node} node - Candidate statement.
1939
+ * @returns {boolean} Whether the node is an include expression statement.
1940
+ */
1941
+ function isPhpIncludeStatement(node) {
1942
+ return node.kind == "expressionstatement" &&
1943
+ /** @type {import("php-parser").ExpressionStatement} */ (node).expression.kind == "include";
1944
+ }
1945
+ /**
1946
+ * Reports whether a PHP statement is the canonical literal project load edge.
1947
+ * @param {import("php-parser").Node} node - Candidate statement.
1948
+ * @returns {boolean} Whether the node is a supported require-once statement.
1949
+ */
1950
+ function isPhpRequireOnce(node) {
1951
+ if (!isPhpIncludeStatement(node))
1952
+ return false;
1953
+ const statement = /** @type {import("php-parser").ExpressionStatement} */ (node);
1954
+ const include = /** @type {import("php-parser").Include} */ (statement.expression);
1955
+ const target = include.target.kind == "bin" ? /** @type {import("php-parser").Bin} */ (include.target) : undefined;
1956
+ const left = target?.left.kind == "magic" ? /** @type {import("php-parser").Magic} */ (target.left) : undefined;
1957
+ return include.once && include.require && target?.type == "." &&
1958
+ left?.value == "__DIR__" && target.right.kind == "string";
1959
+ }
482
1960
  /**
483
1961
  * Accepts only an optional single `declare(strict_types=1)` directive.
484
1962
  * @param {import("php-parser").Node[]} nodes - Top-level PHP nodes.
@@ -517,7 +1995,36 @@ function parsePhpProgram(filename, source) {
517
1995
  return parser.parseCode(source, filename);
518
1996
  }
519
1997
  catch (error) {
520
- return parseFailure("php", error);
1998
+ return parseFailure("php", error, phpParserFailureLocation(error, filename, source));
1999
+ }
2000
+ }
2001
+ /**
2002
+ * Normalizes php-parser's one-based line and zero-based column when present.
2003
+ * A module range remains the deterministic fallback for opaque parser errors.
2004
+ * @param {unknown} error - Native parser error.
2005
+ * @param {string} filename - Requested source filename.
2006
+ * @param {string} source - Complete source.
2007
+ * @returns {import("../semantic/types.js").SourceLocation} Failure range.
2008
+ */
2009
+ function phpParserFailureLocation(error, filename, source) {
2010
+ if (!error || typeof error != "object")
2011
+ return moduleLocation(filename, source);
2012
+ const line = Reflect.get(error, "lineNumber");
2013
+ const column = Reflect.get(error, "columnNumber");
2014
+ if (typeof line != "number" || !Number.isSafeInteger(line) || line < 1 ||
2015
+ typeof column != "number" || !Number.isSafeInteger(column) || column < 0) {
2016
+ return moduleLocation(filename, source);
2017
+ }
2018
+ let lineStart = 0;
2019
+ for (let current = 1; current < line; current++) {
2020
+ const newline = source.indexOf("\n", lineStart);
2021
+ if (newline < 0)
2022
+ return moduleLocation(filename, source);
2023
+ lineStart = newline + 1;
521
2024
  }
2025
+ const lineEnd = source.indexOf("\n", lineStart);
2026
+ const boundedEnd = lineEnd < 0 ? source.length : lineEnd;
2027
+ const offset = Math.min(lineStart + column, boundedEnd);
2028
+ return locationFromOffsets(filename, source, offset, Math.min(offset + 1, source.length));
522
2029
  }
523
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGhwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Zyb250ZW5kcy9waHAuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sU0FBUyxNQUFNLFlBQVksQ0FBQTtBQUNsQyxPQUFPLEVBQUMsS0FBSyxJQUFJLFlBQVksRUFBQyxNQUFNLGdCQUFnQixDQUFBO0FBQ3BELE9BQU8sRUFBQyxXQUFXLEVBQUUsWUFBWSxFQUFFLGlCQUFpQixFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDN0UsT0FBTyxFQUFDLG1CQUFtQixFQUFFLGNBQWMsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQzNFLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLDBCQUEwQixDQUFBO0FBQzdELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLDJCQUEyQixDQUFBO0FBQzFELE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLHdCQUF3QixDQUFBO0FBQzVELE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLGNBQWMsQ0FBQTtBQUNwRCxNQUFNLE1BQU0sR0FBRyxJQUFJLFNBQVMsQ0FBQyxNQUFNLENBQUM7SUFDbEMsR0FBRyxFQUFFLEVBQUMsYUFBYSxFQUFFLElBQUksRUFBQztJQUMxQixNQUFNLEVBQUUsRUFBQyxVQUFVLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxLQUFLLEVBQUM7Q0FDbEQsQ0FBQyxDQUFBO0FBQ0YsaUNBQWlDO0FBQ2pDLElBQUksaUJBQWlCLENBQUE7QUFDckIsMkRBQTJEO0FBQzNELElBQUksaUJBQWlCLEdBQUcsRUFBRSxDQUFBO0FBQzFCLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDbEMsQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDO0lBQ2YsQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDO0lBQ2pCLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQztJQUNqQixDQUFDLElBQUksRUFBRSxL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QUMsQ0FBQyxDQUFBO0lBQzVDLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFBRSxJQUFJLElBQUksRUFBRSxDQUFBO0lBQzlCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksS0FBSyxDQUFDLENBQUE7SUFDeEQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSx1QkFBdUIsQ0FBQyxDQUFBO0lBQzFFLE1BQU0sUUFBUSxHQUFHLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBRXJELElBQUksU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDO1FBQUUsT0FBTyxTQUFTLENBQUE7SUFFcEUsTUFBTSxhQUFhLEdBQUcsU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxFQUFFLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsSUFBSSxJQUFJLElBQUksRUFBRSxDQUFBO0lBQ2hILE1BQU0sY0FBYyxHQUFHLFNBQVMsQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDLENBQUE7SUFDbkksTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxLQUFLLElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSSx1QkFBdUIsQ0FBQyxDQUFBO0lBRTdG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S0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFBO0lBQ25DLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBQaHBQYXJzZXIgZnJvbSBcInBocC1wYXJzZXJcIlxuaW1wb3J0IHtwYXJzZSBhcyBwYXJzZUNvbW1lbnR9IGZyb20gXCJjb21tZW50LXBhcnNlclwiXG5pbXBvcnQge21pc3NpbmdUeXBlLCBwYXJzZUZhaWx1cmUsIHVuc3VwcG9ydGVkU3ludGF4fSBmcm9tIFwiLi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge2xvY2F0aW9uRnJvbU9mZnNldHMsIG1vZHVsZUxvY2F0aW9ufSBmcm9tIFwiLi4vc2VtYW50aWMvbG9jYXRpb24uanNcIlxuaW1wb3J0IHt3aXRoQWRhcHRlZE9wZXJhdGlvbn0gZnJvbSBcIi4uL3NlbWFudGljL29wZXJhdG9ycy5qc1wiXG5pbXBvcnQge3dpdGhQYXJzZXJSYW5nZXN9IGZyb20gXCIuLi9zZW1hbnRpYy9wcm92ZW5hbmNlLmpzXCJcbmltcG9ydCB7aGFzT25seVVuaWNvZGVTY2FsYXJzfSBmcm9tIFwiLi4vc2VtYW50aWMvc2NhbGFycy5qc1wiXG5pbXBvcnQge3JlcXVpcmVTb3VyY2VTY2FsYXJUeXBlfSBmcm9tIFwiLi9zY2FsYXJzLmpzXCJcbmNvbnN0IHBhcnNlciA9IG5ldyBQaHBQYXJzZXIuRW5naW5lKHtcbiAgYXN0OiB7d2l0aFBvc2l0aW9uczogdHJ1ZX0sXG4gIHBhcnNlcjoge2V4dHJhY3REb2M6IHRydWUsIHN1cHByZXNzRXJyb3JzOiBmYWxzZX1cbn0pXG4vKiogQHR5cGUge3N0cmluZyB8IHVuZGVmaW5lZH0gKi9cbmxldCBjYWNoZWRUb2tlblNvdXJjZVxuLyoqIEB0eXBlIHt7ZW5kOiBudW1iZXIsIHN0YXJ0OiBudW1iZXIsIHRleHQ6IHN0cmluZ31bXX0gKi9cbmxldCBjYWNoZWRUb2tlblJhbmdlcyA9IFtdXG5jb25zdCBwaHBCaW5hcnlPcGVyYXRpb25zID0gbmV3IE1hcChbXG4gIFtcIitcIiwgXCJQaHBBZGRcIl0sXG4gIFtcIi1cIiwgXCJTdWJ0cmFjdFwiXSxcbiAgW1wiKlwiLCBcIk11bHRpcGx5XCJdLFxuICBbXCImJlwiLCBcIkFuZFwiXSxcbiAgW1wifHxcIiwgXCJPclwiXSxcbiAgW1wiPT09XCIsIFwiRXF1YWxcIl0sXG4gIFtcIiE9PVwiLCBcIk5vdEVxdWFsXCJdLFxuICBbXCI8XCIsIFwiTGVzc1RoYW5cIl0sXG4gIFtcIjw9XCIsIFwiTGVzc1RoYW5PckVxdWFsXCJdLFxuICBbXCI+XCIsIFwiR3JlYXRlclRoYW5cIl0sXG4gIFtcIj49XCIsIFwiR3JlYXRlclRoYW5PckVxdWFsXCJdLFxuICBbXCIuXCIsIFwiU3RyaW5nQ29uY2F0XCJdXG5dKVxuXG4vKipcbiAqIFJldHVybnMgYSBub3JtYWxpemVkIFBIUCBub2RlIGxvY2F0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGV9IG5vZGUgLSBQSFAgcGFyc2VyIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBTb3VyY2UgbG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGlmICghbm9kZS5sb2MpIHRocm93IG5ldyBFcnJvcihgUEhQIHBhcnNlciBvbWl0dGVkIHNvdXJjZSBsb2NhdGlvbiBmb3IgJHtub2RlLmtpbmR9LmApXG5cbiAgcmV0dXJuIGxvY2F0aW9uRnJvbU9mZnNldHMoZmlsZW5hbWUsIHNvdXJjZSwgbm9kZS5sb2Muc3RhcnQub2Zmc2V0LCBub2RlLmxvYy5lbmQub2Zmc2V0KVxufVxuXG4vKipcbiAqIExvY2F0ZXMgYSBjb21tZW50LXBhcnNlciB0b2tlbiBpbnNpZGUgYSBQSFAgcGFyc2VyLW93bmVkIGRvYyBjb21tZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkNvbW1lbnRCbG9ja30gY29tbWVudCAtIFBIUCBkb2MgY29tbWVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiY29tbWVudC1wYXJzZXJcIikuU3BlY30gdGFnIC0gUGFyc2VkIGRvYyB0YWcuXG4gKiBAcGFyYW0ge1wibmFtZVwiIHwgXCJ0eXBlXCJ9IGZpZWxkIC0gVG9rZW4gZmllbGQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBFeGFjdCB0b2tlbiBsb2NhdGlvbi5cbiAqL1xuZnVuY3Rpb24gY29tbWVudFRhZ0xvY2F0aW9uKGNvbW1lbnQsIHRhZywgZmllbGQsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbGluZSA9IHRhZy5zb3VyY2VbMF1cblxuICBpZiAoIWNvbW1lbnQubG9jIHx8ICFsaW5lKSB0aHJvdyBuZXcgRXJyb3IoYENvbW1lbnQgcGFyc2VyIG9taXR0ZWQgdGhlIEAke3RhZy50YWd9IHNvdXJjZSB0b2tlbi5gKVxuXG4gIGxldCBsaW5lU3RhcnQgPSBjb21tZW50LmxvYy5zdGFydC5vZmZzZXRcblxuICBmb3IgKGxldCBsaW5lTnVtYmVyID0gMDsgbGluZU51bWJlciA8IGxpbmUubnVtYmVyOyBsaW5lTnVtYmVyKyspIHtcbiAgICB3aGlsZSAobGluZVN0YXJ0IDwgc291cmNlLmxlbmd0aCAmJiBzb3VyY2VbbGluZVN0YXJ0XSAhPSBcIlxcclwiICYmIHNvdXJjZVtsaW5lU3RhcnRdICE9IFwiXFxuXCIpIGxpbmVTdGFydCsrXG4gICAgaWYgKHNvdXJjZVtsaW5lU3RhcnRdID09IFwiXFxyXCIgJiYgc291cmNlW2xpbmVTdGFydCArIDFdID09IFwiXFxuXCIpIGxpbmVTdGFydCArPSAyXG4gICAgZWxzZSBsaW5lU3RhcnQrK1xuICB9XG5cbiAgY29uc3Qgb3JkZXJlZEZpZWxkcyA9IFtcInN0YXJ0XCIsIFwiZGVsaW1pdGVyXCIsIFwicG9zdERlbGltaXRlclwiLCBcInRhZ1wiLCBcInBvc3RUYWdcIiwgXCJuYW1lXCIsIFwicG9zdE5hbWVcIiwgXCJ0eXBlXCJdXG4gIGNvbnN0IGZpZWxkSW5kZXggPSBvcmRlcmVkRmllbGRzLmluZGV4T2YoZmllbGQpXG4gIGNvbnN0IHN0YXJ0ID0gbGluZVN0YXJ0ICsgb3JkZXJlZEZpZWxkcy5zbGljZSgwLCBmaWVsZEluZGV4KS5yZWR1Y2UoKGxlbmd0aCwga2V5KSA9PlxuICAgIGxlbmd0aCArIGxpbmUudG9rZW5zWy8qKiBAdHlwZSB7a2V5b2YgdHlwZW9mIGxpbmUudG9rZW5zfSAqLyAoa2V5KV0ubGVuZ3RoLCAwKVxuICBjb25zdCB2YWx1ZSA9IGxpbmUudG9rZW5zW2ZpZWxkXVxuXG4gIHJldHVybiBsb2NhdGlvbkZyb21PZmZzZXRzKGZpbGVuYW1lLCBzb3VyY2UsIHN0YXJ0LCBzdGFydCArIHZhbHVlLmxlbmd0aClcbn1cblxuLyoqXG4gKiBGaW5kcyBvbmUgcGFyc2VyIHRva2VuIGJldHdlZW4gcGFyc2VyLW93bmVkIG5vZGUgYm91bmRhcmllcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0b2tlblRleHQgLSBFeGFjdCB0b2tlbiB0ZXh0LlxuICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0T2Zmc2V0IC0gSW5jbHVzaXZlIHNlYXJjaCBib3VuZGFyeS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmRPZmZzZXQgLSBFeGNsdXNpdmUgc2VhcmNoIGJvdW5kYXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gVG9rZW4gbG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIHRva2VuTG9jYXRpb24odG9rZW5UZXh0LCBzdGFydE9mZnNldCwgZW5kT2Zmc2V0LCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGlmIChjYWNoZWRUb2tlblNvdXJjZSAhPSBzb3VyY2UpIHtcbiAgICBsZXQgb2Zmc2V0ID0gMFxuXG4gICAgY2FjaGVkVG9rZW5SYW5nZXMgPSBwYXJzZXIudG9rZW5HZXRBbGwoc291cmNlKS5tYXAoKHRva2VuKSA9PiB7XG4gICAgICBjb25zdCB0ZXh0ID0gdHlwZW9mIHRva2VuID09IFwic3RyaW5nXCIgPyB0b2tlbiA6IHRva2VuWzFdXG4gICAgICBjb25zdCByYW5nZSA9IHtlbmQ6IG9mZnNldCArIHRleHQubGVuZ3RoLCBzdGFydDogb2Zmc2V0LCB0ZXh0fVxuXG4gICAgICBvZmZzZXQgPSByYW5nZS5lbmRcblxuICAgICAgcmV0dXJuIHJhbmdlXG4gICAgfSlcbiAgICBjYWNoZWRUb2tlblNvdXJjZSA9IHNvdXJjZVxuICB9XG5cbiAgY29uc3QgdG9rZW4gPSBjYWNoZWRUb2tlblJhbmdlcy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS50ZXh0ID09IHRva2VuVGV4dCAmJiBjYW5kaWRhdGUuc3RhcnQgPj0gc3RhcnRPZmZzZXQgJiZcbiAgICBjYW5kaWRhdGUuZW5kIDw9IGVuZE9mZnNldClcblxuICBpZiAodG9rZW4pIHJldHVybiBsb2NhdGlvbkZyb21PZmZzZXRzKGZpbGVuYW1lLCBzb3VyY2UsIHRva2VuLnN0YXJ0LCB0b2tlbi5lbmQpXG5cbiAgdGhyb3cgbmV3IEVycm9yKGBQSFAgcGFyc2VyIG9taXR0ZWQgdG9rZW4gJyR7dG9rZW5UZXh0fScgYmV0d2VlbiAke3N0YXJ0T2Zmc2V0fSBhbmQgJHtlbmRPZmZzZXR9LmApXG59XG5cbi8qKlxuICogQ29udmVydHMgYSBzdXBwb3J0ZWQgUEhQIGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuRXhwcmVzc2lvbn0gbm9kZSAtIFBIUCBleHByZXNzaW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBTZW1hbnRpYyBleHByZXNzaW9uLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0RXhwcmVzc2lvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG5vZGUua2luZCA9PSBcInZhcmlhYmxlXCIpIHtcbiAgICBjb25zdCB2YXJpYWJsZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5WYXJpYWJsZX0gKi8gKG5vZGUpXG5cbiAgICBpZiAodHlwZW9mIHZhcmlhYmxlLm5hbWUgIT0gXCJzdHJpbmdcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZHluYW1pYyB2YXJpYWJsZVwiLCBsb2NhdGlvbilcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb24sIG5hbWU6IHZhcmlhYmxlLm5hbWV9LCB7bmFtZTogbG9jYXRpb259KVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcIm51bWJlclwiKSB7XG4gICAgY29uc3QgbGl0ZXJhbCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5OdW1iZXJ9ICovIChub2RlKVxuICAgIGNvbnN0IHZhbHVlID0gTnVtYmVyKGxpdGVyYWwudmFsdWUpXG5cbiAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKHZhbHVlKSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibm9uLXNhZmUgaW50ZWdlciBsaXRlcmFsXCIsIGxvY2F0aW9uKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkludGVnZXJMaXRlcmFsXCIpLCBsb2NhdGlvbiwgdmFsdWV9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcImJvb2xlYW5cIikge1xuICAgIGNvbnN0IGxpdGVyYWwgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuQm9vbGVhbn0gKi8gKG5vZGUpXG5cbiAgICBpZiAodHlwZW9mIGxpdGVyYWwudmFsdWUgIT0gXCJib29sZWFuXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImludmFsaWQgYm9vbGVhbiBsaXRlcmFsIHZhbHVlXCIsIGxvY2F0aW9uKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkJvb2xlYW5MaXRlcmFsXCIpLCBsb2NhdGlvbiwgdmFsdWU6IGxpdGVyYWwudmFsdWV9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcInN0cmluZ1wiKSB7XG4gICAgY29uc3QgbGl0ZXJhbCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5TdHJpbmd9ICovIChub2RlKVxuXG4gICAgaWYgKHR5cGVvZiBsaXRlcmFsLnJhdyA9PSBcInN0cmluZ1wiICYmIGxpdGVyYWwucmF3LnN0YXJ0c1dpdGgoXCI8PDxcIikpIHtcbiAgICAgIGNvbnN0IGRldGFpbCA9IGxpdGVyYWwucmF3LnN0YXJ0c1dpdGgoXCI8PDwnXCIpID8gXCJub3dkb2Mgc3RyaW5nXCIgOiBcImhlcmVkb2Mgc3RyaW5nXCJcblxuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGRldGFpbCwgbG9jYXRpb24pXG4gICAgfVxuICAgIGlmICh0eXBlb2YgbGl0ZXJhbC5yYXcgPT0gXCJzdHJpbmdcIiAmJiBbXCJiXFxcIlwiLCBcIkJcXFwiXCIsIFwiYidcIiwgXCJCJ1wiXS5zb21lKChwcmVmaXgpID0+IGxpdGVyYWwucmF3LnN0YXJ0c1dpdGgocHJlZml4KSkpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImJpbmFyeSBzdHJpbmcgbGl0ZXJhbFwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBsaXRlcmFsLnZhbHVlICE9IFwic3RyaW5nXCIgfHwgIWhhc09ubHlVbmljb2RlU2NhbGFycyhsaXRlcmFsLnZhbHVlKSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiaW52YWxpZCBVbmljb2RlIHN0cmluZyBsaXRlcmFsXCIsIGxvY2F0aW9uKVxuICAgIH1cblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJTdHJpbmdMaXRlcmFsXCIpLCBsb2NhdGlvbiwgdmFsdWU6IGxpdGVyYWwudmFsdWV9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcImVuY2Fwc2VkXCIpIHtcbiAgICBjb25zdCBsaXRlcmFsID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkVuY2Fwc2VkfSAqLyAobm9kZSlcbiAgICBjb25zdCBkZXRhaWwgPSBsaXRlcmFsLnR5cGUgPT0gXCJzdHJpbmdcIiA/IFwiaW50ZXJwb2xhdGVkIHN0cmluZ1wiIDogYCR7bGl0ZXJhbC50eXBlfSBzdHJpbmdgXG5cbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgZGV0YWlsLCBsb2NhdGlvbilcbiAgfVxuXG4gIGlmIChub2RlLmtpbmQgPT0gXCJub3dkb2NcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibm93ZG9jIHN0cmluZ1wiLCBsb2NhdGlvbilcblxuICBpZiAobm9kZS5raW5kID09IFwidW5hcnlcIikge1xuICAgIGNvbnN0IHVuYXJ5ID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlVuYXJ5fSAqLyAobm9kZSlcblxuICAgIGlmICghW1wiIVwiLCBcIi1cIl0uaW5jbHVkZXModW5hcnkudHlwZSkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBgdW5hcnkgJHt1bmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuXG4gICAgY29uc3Qgc2VtYW50aWMgPSB3aXRoQWRhcHRlZE9wZXJhdGlvbih3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IFwiVW5hcnlFeHByZXNzaW9uXCIsXG4gICAgICBsb2NhdGlvbixcbiAgICAgIG9wZXJhbmQ6IGNvbnZlcnRFeHByZXNzaW9uKHVuYXJ5LndoYXQsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSwge1xuICAgICAgb3BlcmF0b3I6IHRva2VuTG9jYXRpb24odW5hcnkudHlwZSwgdW5hcnkubG9jPy5zdGFydC5vZmZzZXQgPz8gMCwgdW5hcnkud2hhdC5sb2M/LnN0YXJ0Lm9mZnNldCA/PyB1bmFyeS5sb2M/LmVuZC5vZmZzZXQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9KSwgdW5hcnkudHlwZSA9PSBcIiFcIiA/IFwiTm90XCIgOiBcIk5lZ2F0ZVwiKVxuXG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKHNlbWFudGljKSlcbiAgfVxuXG4gIGlmIChub2RlLmtpbmQgPT0gXCJiaW5cIikge1xuICAgIGNvbnN0IGJpbmFyeSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5CaW59ICovIChub2RlKVxuICAgIGlmIChbXCI9PVwiLCBcIiE9XCJdLmluY2x1ZGVzKGJpbmFyeS50eXBlKSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGBjb2VyY2l2ZSBlcXVhbGl0eSAke2JpbmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuICAgIGlmIChbXCJhbmRcIiwgXCJvclwiXS5pbmNsdWRlcyhiaW5hcnkudHlwZSkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBgcHJlY2VkZW5jZS1zZW5zaXRpdmUgYm9vbGVhbiAke2JpbmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuICAgIGlmICghcGhwQmluYXJ5T3BlcmF0aW9ucy5oYXMoYmluYXJ5LnR5cGUpKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgYGJpbmFyeSAke2JpbmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuXG4gICAgY29uc3Qgc2VtYW50aWMgPSB3aXRoQWRhcHRlZE9wZXJhdGlvbih7XG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJCaW5hcnlFeHByZXNzaW9uXCIpLFxuICAgICAgbGVmdDogY29udmVydEV4cHJlc3Npb24oYmluYXJ5LmxlZnQsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgbG9jYXRpb24sXG4gICAgICByaWdodDogY29udmVydEV4cHJlc3Npb24oYmluYXJ5LnJpZ2h0LCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0sIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCIpLkFkYXB0ZWRPcGVyYXRpb259ICovIChwaHBCaW5hcnlPcGVyYXRpb25zLmdldChiaW5hcnkudHlwZSkpKVxuXG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKHdpdGhQYXJzZXJSYW5nZXMoc2VtYW50aWMsIHtcbiAgICAgIG9wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKGJpbmFyeS50eXBlLCBiaW5hcnkubGVmdC5sb2M/LmVuZC5vZmZzZXQgPz8gMCwgYmluYXJ5LnJpZ2h0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSkpKVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcImNhbGxcIikge1xuICAgIGNvbnN0IGNhbGwgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuQ2FsbH0gKi8gKG5vZGUpXG5cbiAgICBpZiAoY2FsbC53aGF0LmtpbmQgIT0gXCJuYW1lXCIgJiYgY2FsbC53aGF0LmtpbmQgIT0gXCJpZGVudGlmaWVyXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImR5bmFtaWMgY2FsbFwiLCBsb2NhdGlvbilcbiAgICB9XG5cbiAgICBjb25zdCBjYWxsZWUgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTmFtZSB8IGltcG9ydChcInBocC1wYXJzZXJcIikuSWRlbnRpZmllcn0gKi8gKGNhbGwud2hhdCkubmFtZVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgYXJndW1lbnRzOiBjYWxsLmFyZ3VtZW50cy5tYXAoKGFyZ3VtZW50KSA9PiBjb252ZXJ0RXhwcmVzc2lvbihhcmd1bWVudCwgZmlsZW5hbWUsIHNvdXJjZSkpLFxuICAgICAgY2FsbGVlLFxuICAgICAga2luZDogXCJDYWxsRXhwcmVzc2lvblwiLFxuICAgICAgbG9jYXRpb25cbiAgICB9LCB7Y2FsbGVlOiBub2RlTG9jYXRpb24oY2FsbC53aGF0LCBmaWxlbmFtZSwgc291cmNlKX0pXG4gIH1cblxuICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgbm9kZS5raW5kLCBsb2NhdGlvbilcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgZXhwbGljaXQgUEhQIHJldHVybi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlfSBub2RlIC0gUEhQIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJldHVyblN0YXRlbWVudH0gU2VtYW50aWMgcmV0dXJuLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UmV0dXJuKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS5raW5kICE9IFwicmV0dXJuXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBub2RlLmtpbmQsIGxvY2F0aW9uKVxuXG4gIGNvbnN0IHJldHVybk5vZGUgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuUmV0dXJufSAqLyAobm9kZSlcblxuICBpZiAoIXJldHVybk5vZGUuZXhwcikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZW1wdHkgcmV0dXJuXCIsIGxvY2F0aW9uKVxuXG4gIHJldHVybiB7ZXhwcmVzc2lvbjogY29udmVydEV4cHJlc3Npb24ocmV0dXJuTm9kZS5leHByLCBmaWxlbmFtZSwgc291cmNlKSwga2luZDogXCJSZXR1cm5TdGF0ZW1lbnRcIiwgbG9jYXRpb259XG59XG5cbi8qKlxuICogUmVhZHMgb25lIGV4YWN0IFBIUCBsb2NhbCBgQHZhcmAgY2FycmllciBhbmQgaW1tdXRhYmlsaXR5IG1hcmtlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlfSBub2RlIC0gQXNzaWdubWVudC1vd25pbmcgc3RhdGVtZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBMb2NhbCBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHt7aW1tdXRhYmxlOiBib29sZWFuLCB0eXBlOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUmVmZXJlbmNlfSB8IHVuZGVmaW5lZH0gTWV0YWRhdGEgd2hlbiBwcmVzZW50LlxuICovXG5mdW5jdGlvbiBsb2NhbE1ldGFkYXRhKG5vZGUsIG5hbWUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgY29tbWVudHMgPSBub2RlLmxlYWRpbmdDb21tZW50cyA/PyBbXVxuICBjb25zdCBjb21tZW50ID0gY29tbWVudHMuYXQoLTEpXG5cbiAgaWYgKCFjb21tZW50IHx8IGNvbW1lbnQua2luZCAhPSBcImNvbW1lbnRibG9ja1wiIHx8ICFjb21tZW50LmxvYyB8fCAhbm9kZS5sb2MpIHJldHVybiB1bmRlZmluZWRcblxuICBjb25zdCBnYXAgPSBzb3VyY2Uuc2xpY2UoY29tbWVudC5sb2MuZW5kLm9mZnNldCwgbm9kZS5sb2Muc3RhcnQub2Zmc2V0KVxuXG4gIGlmICghL15cXHMqJC91LnRlc3QoZ2FwKSB8fCAoZ2FwLm1hdGNoKC9cXG4vZ3UpPy5sZW5ndGggPz8gMCkgPiAxKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgY29uc3QgYmxvY2sgPSBwYXJzZUNvbW1lbnQoY29tbWVudC52YWx1ZSlbMF1cbiAgY29uc3QgdGFncyA9IGJsb2NrPy50YWdzID8/IFtdXG4gIGNvbnN0IHZhcmlhYmxlcyA9IHRhZ3MuZmlsdGVyKCh0YWcpID0+IHRhZy50YWcgPT0gXCJ2YXJcIilcbiAgY29uc3QgaW1tdXRhYmxlID0gdGFncy5maWx0ZXIoKHRhZykgPT4gdGFnLnRhZyA9PSBcInNlbWFudGlmb2xkLWltbXV0YWJsZVwiKVxuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmICh2YXJpYWJsZXMubGVuZ3RoID09IDAgJiYgaW1tdXRhYmxlLmxlbmd0aCA9PSAwKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgY29uc3QgZXhhY3RWYXJpYWJsZSA9IHZhcmlhYmxlcy5sZW5ndGggPT0gMSAmJiB2YXJpYWJsZXNbMF0udHlwZSA9PSBcIlwiICYmIHZhcmlhYmxlc1swXS5kZXNjcmlwdGlvbiA9PSBgJCR7bmFtZX1gXG4gIGNvbnN0IGV4YWN0SW1tdXRhYmxlID0gaW1tdXRhYmxlLmxlbmd0aCA8PSAxICYmIGltbXV0YWJsZS5ldmVyeSgodGFnKSA9PiB0YWcubmFtZSA9PSBcIlwiICYmIHRhZy50eXBlID09IFwiXCIgJiYgdGFnLmRlc2NyaXB0aW9uID09IFwiXCIpXG4gIGNvbnN0IGtub3duVGFncyA9IHRhZ3MuZXZlcnkoKHRhZykgPT4gdGFnLnRhZyA9PSBcInZhclwiIHx8IHRhZy50YWcgPT0gXCJzZW1hbnRpZm9sZC1pbW11dGFibGVcIilcblxuICBpZiAoIWV4YWN0VmFyaWFibGUgfHwgIWV4YWN0SW1tdXRhYmxlIHx8ICFrbm93blRhZ3MpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJtYWxmb3JtZWQgbG9jYWwgdHlwZSBtZXRhZGF0YVwiLCBsb2NhdGlvbilcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgaW1tdXRhYmxlOiBpbW11dGFibGUubGVuZ3RoID09IDEsXG4gICAgdHlwZTogcmVxdWlyZVNvdXJjZVNjYWxhclR5cGUoXG4gICAgICBcInBocFwiLFxuICAgICAgdmFyaWFibGVzWzBdLm5hbWUsXG4gICAgICBgTG9jYWwgJyR7bmFtZX0nYCxcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgY29tbWVudFRhZ0xvY2F0aW9uKGNvbW1lbnQsIHZhcmlhYmxlc1swXSwgXCJuYW1lXCIsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgKVxuICB9XG59XG5cbi8qKlxuICogQ29udmVydHMgb25lIFBIUCBsb2NhbCBkZWNsYXJhdGlvbiBvciBhc3NpZ25tZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGV9IG5vZGUgLSBQSFAgc3RhdGVtZW50LlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gdmlzaWJsZSAtIE5hbWVzIHZpc2libGUgZHVyaW5nIGFkYXB0YXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkxvY2FsU3RhdGVtZW50fSBTZW1hbnRpYyBsb2NhbCBzdGF0ZW1lbnQuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRMb2NhbFN0YXRlbWVudChub2RlLCB2aXNpYmxlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG5vZGUua2luZCAhPSBcImV4cHJlc3Npb25zdGF0ZW1lbnRcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIG5vZGUua2luZCwgbG9jYXRpb24pXG5cbiAgY29uc3QgZXhwcmVzc2lvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5FeHByZXNzaW9uU3RhdGVtZW50fSAqLyAobm9kZSkuZXhwcmVzc2lvblxuXG4gIGlmIChleHByZXNzaW9uLmtpbmQgIT0gXCJhc3NpZ25cIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGV4cHJlc3Npb24ua2luZCwgbm9kZUxvY2F0aW9uKGV4cHJlc3Npb24sIGZpbGVuYW1lLCBzb3VyY2UpKVxuXG4gIGNvbnN0IGFzc2lnbm1lbnQgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuQXNzaWdufSAqLyAoZXhwcmVzc2lvbilcblxuICBpZiAoYXNzaWdubWVudC5vcGVyYXRvciAhPSBcIj1cIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGBhc3NpZ25tZW50ICR7YXNzaWdubWVudC5vcGVyYXRvcn1gLCBsb2NhdGlvbilcbiAgaWYgKGFzc2lnbm1lbnQubGVmdC5raW5kICE9IFwidmFyaWFibGVcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGFzc2lnbm1lbnQubGVmdC5raW5kLCBub2RlTG9jYXRpb24oYXNzaWdubWVudC5sZWZ0LCBmaWxlbmFtZSwgc291cmNlKSlcblxuICBjb25zdCB2YXJpYWJsZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5WYXJpYWJsZX0gKi8gKGFzc2lnbm1lbnQubGVmdClcbiAgY29uc3QgdGFyZ2V0TG9jYXRpb24gPSBub2RlTG9jYXRpb24odmFyaWFibGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKHR5cGVvZiB2YXJpYWJsZS5uYW1lICE9IFwic3RyaW5nXCIgfHwgdmFyaWFibGUuY3VybHkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImR5bmFtaWMgdmFyaWFibGVcIiwgdGFyZ2V0TG9jYXRpb24pXG5cbiAgY29uc3QgbWV0YWRhdGEgPSBsb2NhbE1ldGFkYXRhKG5vZGUsIHZhcmlhYmxlLm5hbWUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG1ldGFkYXRhKSB7XG4gICAgdmlzaWJsZS5hZGQodmFyaWFibGUubmFtZSlcbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBpbml0aWFsaXplcjogY29udmVydEV4cHJlc3Npb24oYXNzaWdubWVudC5yaWdodCwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBraW5kOiBcIkxvY2FsRGVjbGFyYXRpb25cIixcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgbXV0YWJsZTogIW1ldGFkYXRhLmltbXV0YWJsZSxcbiAgICAgIG5hbWU6IHZhcmlhYmxlLm5hbWUsXG4gICAgICB0eXBlOiBtZXRhZGF0YS50eXBlXG4gICAgfSwge1xuICAgICAgbmFtZTogdGFyZ2V0TG9jYXRpb24sXG4gICAgICBvcGVyYXRvcjogdG9rZW5Mb2NhdGlvbihcIj1cIiwgYXNzaWdubWVudC5sZWZ0LmxvYz8uZW5kLm9mZnNldCA/PyAwLCBhc3NpZ25tZW50LnJpZ2h0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSlcbiAgfVxuXG4gIGlmICghdmlzaWJsZS5oYXModmFyaWFibGUubmFtZSkpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgTG9jYWwgJyR7dmFyaWFibGUubmFtZX0nYCwgbG9jYXRpb24pXG5cbiAgY29uc3QgdGFyZ2V0ID0gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiSWRlbnRpZmllckV4cHJlc3Npb25cIiksIGxvY2F0aW9uOiB0YXJnZXRMb2NhdGlvbiwgbmFtZTogdmFyaWFibGUubmFtZX0sIHtcbiAgICBuYW1lOiB0YXJnZXRMb2NhdGlvblxuICB9KVxuXG4gIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICBleHByZXNzaW9uOiBjb252ZXJ0RXhwcmVzc2lvbihhc3NpZ25tZW50LnJpZ2h0LCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICBraW5kOiBcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIixcbiAgICBsb2NhdGlvbixcbiAgICB0YXJnZXRcbiAgfSwge1xuICAgIG9wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKFwiPVwiLCBhc3NpZ25tZW50LmxlZnQubG9jPy5lbmQub2Zmc2V0ID8/IDAsIGFzc2lnbm1lbnQucmlnaHQubG9jPy5zdGFydC5vZmZzZXQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgfSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgZXhoYXVzdGl2ZSBQSFAgc3RhdGVtZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGV9IG5vZGUgLSBQSFAgc3RhdGVtZW50LlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gdmlzaWJsZSAtIE5hbWVzIHZpc2libGUgZHVyaW5nIGFkYXB0YXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0YXRlbWVudH0gU2VtYW50aWMgc3RhdGVtZW50LlxuICovXG5mdW5jdGlvbiBjb252ZXJ0U3RhdGVtZW50KG5vZGUsIHZpc2libGUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgaWYgKG5vZGUua2luZCA9PSBcInJldHVyblwiKSByZXR1cm4gY29udmVydFJldHVybihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuICBpZiAobm9kZS5raW5kID09IFwiaWZcIikgcmV0dXJuIGNvbnZlcnRJZigvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuSWZ9ICovIChub2RlKSwgdmlzaWJsZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgaWYgKG5vZGUua2luZCA9PSBcImVjaG9cIikgcmV0dXJuIGNvbnZlcnRQcmludCgvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuRWNob30gKi8gKG5vZGUpLCBmaWxlbmFtZSwgc291cmNlKVxuICBpZiAobm9kZS5raW5kID09IFwiZXhwcmVzc2lvbnN0YXRlbWVudFwiKSByZXR1cm4gY29udmVydExvY2FsU3RhdGVtZW50KG5vZGUsIHZpc2libGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIG5vZGUua2luZCwgbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxufVxuXG4vKipcbiAqIENvbnZlcnRzIGFuIG9yZGVyZWQgUEhQIGJsb2NrIHdpdGggaXRzIG93biBhZGFwdGF0aW9uIHNjb3BlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkJsb2NrfSBub2RlIC0gUEhQIHBhcnNlciBibG9jay5cbiAqIEBwYXJhbSB7U2V0PHN0cmluZz59IHZpc2libGUgLSBOYW1lcyB2aXNpYmxlIG9uIGJsb2NrIGVudHJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gU2VtYW50aWMgYmxvY2suXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRCbG9jayhub2RlLCB2aXNpYmxlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIHJldHVybiB7XG4gICAga2luZDogXCJCbG9ja1wiLFxuICAgIGxvY2F0aW9uOiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgc3RhdGVtZW50czogbm9kZS5jaGlsZHJlbi5tYXAoKHN0YXRlbWVudCkgPT4gY29udmVydFN0YXRlbWVudChzdGF0ZW1lbnQsIHZpc2libGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG59XG5cbi8qKlxuICogUmVxdWlyZXMgYW4gZXhhY3QgUEhQIHNjYWxhciBkZWNsYXJhdGlvbiB0eXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGUgfCBudWxsfSBzb3VyY2VUeXBlIC0gUEhQIHR5cGUgbm9kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdWJqZWN0IC0gVHlwZWQgc3ViamVjdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gU291cmNlIGxvY2F0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUmVmZXJlbmNlfSBTZW1hbnRpYyB0eXBlLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0VHlwZShzb3VyY2VUeXBlLCBzdWJqZWN0LCBsb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAoIXNvdXJjZVR5cGUpIHJldHVybiByZXF1aXJlU291cmNlU2NhbGFyVHlwZShcInBocFwiLCB1bmRlZmluZWQsIHN1YmplY3QsIGxvY2F0aW9uKVxuICBpZiAoc291cmNlVHlwZS5raW5kICE9IFwidHlwZXJlZmVyZW5jZVwiICYmIHNvdXJjZVR5cGUua2luZCAhPSBcIm5hbWVcIiAmJiBzb3VyY2VUeXBlLmtpbmQgIT0gXCJpZGVudGlmaWVyXCIpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJ1bnN1cHBvcnRlZCBzY2FsYXIgdHlwZVwiLCBub2RlTG9jYXRpb24oc291cmNlVHlwZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cblxuICBjb25zdCB0eXBlTmFtZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5UeXBlUmVmZXJlbmNlIHwgaW1wb3J0KFwicGhwLXBhcnNlclwiKS5OYW1lIHwgaW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZGVudGlmaWVyfSAqLyAoc291cmNlVHlwZSkubmFtZVxuXG4gIHJldHVybiByZXF1aXJlU291cmNlU2NhbGFyVHlwZShcInBocFwiLCB0eXBlTmFtZSwgc3ViamVjdCwgbG9jYXRpb24sIG5vZGVMb2NhdGlvbihzb3VyY2VUeXBlLCBmaWxlbmFtZSwgc291cmNlKSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIFBIUCBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5GdW5jdGlvbn0gbm9kZSAtIFBIUCBmdW5jdGlvbiBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9ufSBTZW1hbnRpYyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY29udmVydEZ1bmN0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgbmFtZSA9IHR5cGVvZiBub2RlLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG5vZGUubmFtZSA6IG5vZGUubmFtZS5uYW1lXG5cbiAgaWYgKCFub2RlLmJvZHkpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJmdW5jdGlvbiBib2R5XCIsIGxvY2F0aW9uKVxuICB9XG5cbiAgY29uc3QgcGFyYW1ldGVycyA9IG5vZGUuYXJndW1lbnRzLm1hcCgocGFyYW1ldGVyKSA9PiB7XG4gICAgY29uc3QgcGFyYW1ldGVyTG9jYXRpb24gPSBub2RlTG9jYXRpb24ocGFyYW1ldGVyLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIGNvbnN0IHBhcmFtZXRlck5hbWUgPSB0eXBlb2YgcGFyYW1ldGVyLm5hbWUgPT0gXCJzdHJpbmdcIiA/IHBhcmFtZXRlci5uYW1lIDogcGFyYW1ldGVyLm5hbWUubmFtZVxuXG4gICAgaWYgKHBhcmFtZXRlci5udWxsYWJsZSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwidW5zdXBwb3J0ZWQgc2NhbGFyIHR5cGVcIiwgcGFyYW1ldGVyTG9jYXRpb24pXG5cbiAgICBjb25zdCBwYXJhbWV0ZXJOb2RlID0gdHlwZW9mIHBhcmFtZXRlci5uYW1lID09IFwic3RyaW5nXCIgPyBwYXJhbWV0ZXIgOiBwYXJhbWV0ZXIubmFtZVxuICAgIGNvbnN0IHNlbWFudGljUGFyYW1ldGVyID0ge1xuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUGFyYW1ldGVyXCIpLFxuICAgICAgbG9jYXRpb246IHBhcmFtZXRlckxvY2F0aW9uLFxuICAgICAgbmFtZTogcGFyYW1ldGVyTmFtZSxcbiAgICAgIHR5cGU6IGNvbnZlcnRUeXBlKHBhcmFtZXRlci50eXBlLCBgUGFyYW1ldGVyICcke3BhcmFtZXRlck5hbWV9J2AsIHBhcmFtZXRlckxvY2F0aW9uLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH1cblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHNlbWFudGljUGFyYW1ldGVyLCB7bmFtZTogbm9kZUxvY2F0aW9uKHBhcmFtZXRlck5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgfSlcbiAgaWYgKG5vZGUubnVsbGFibGUpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInVuc3VwcG9ydGVkIHNjYWxhciB0eXBlXCIsIGxvY2F0aW9uKVxuICBjb25zdCB2aXNpYmxlID0gbmV3IFNldChwYXJhbWV0ZXJzLm1hcCgocGFyYW1ldGVyKSA9PiBwYXJhbWV0ZXIubmFtZSkpXG4gIGNvbnN0IGJvZHkgPSBjb252ZXJ0QmxvY2sobm9kZS5ib2R5LCB2aXNpYmxlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGNvbnN0IG5hbWVOb2RlID0gdHlwZW9mIG5vZGUubmFtZSA9PSBcInN0cmluZ1wiID8gbm9kZSA6IG5vZGUubmFtZVxuXG4gIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICBib2R5LFxuICAgIGtpbmQ6IFwiRnVuY3Rpb25EZWNsYXJhdGlvblwiLFxuICAgIGxvY2F0aW9uLFxuICAgIG5hbWUsXG4gICAgcGFyYW1ldGVycyxcbiAgICByZXR1cm5UeXBlOiBjb252ZXJ0VHlwZShub2RlLnR5cGUsIGBGdW5jdGlvbiAnJHtuYW1lfScgcmV0dXJuYCwgbG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UpXG4gIH0sIHtuYW1lOiBub2RlTG9jYXRpb24obmFtZU5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZXhpc3RpbmcgUEhQIGlmL2Vsc2UgdGVybWluYWwgd2l0aCByZXN0cmljdGVkIGJyYW5jaCBwcmVmaXhlcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZn0gbm9kZSAtIFBIUCBpZiBub2RlLlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gdmlzaWJsZSAtIEVuY2xvc2luZyB2aXNpYmxlIG5hbWVzLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5JZlN0YXRlbWVudH0gU2VtYW50aWMgYnJhbmNoLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0SWYobm9kZSwgdmlzaWJsZSwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChub2RlLnNob3J0Rm9ybSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiYWx0ZXJuYXRpdmUgaWYgc3ludGF4XCIsIGxvY2F0aW9uKVxuICBpZiAobm9kZS5ib2R5LmtpbmQgIT0gXCJibG9ja1wiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJpZiB3aXRob3V0IGJsb2NrIGNvbnNlcXVlbnRcIiwgbG9jYXRpb24pXG5cbiAgY29uc3QgY29uc2VxdWVudFZpc2libGUgPSBuZXcgU2V0KHZpc2libGUpXG4gIGxldCBhbHRlcm5hdGVcblxuICBpZiAobm9kZS5hbHRlcm5hdGUpIHtcbiAgICBjb25zdCBhbHRlcm5hdGVWaXNpYmxlID0gbmV3IFNldCh2aXNpYmxlKVxuXG4gICAgaWYgKG5vZGUuYWx0ZXJuYXRlLmtpbmQgPT0gXCJibG9ja1wiKSB7XG4gICAgICBhbHRlcm5hdGUgPSBjb252ZXJ0QmxvY2soLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkJsb2NrfSAqLyAobm9kZS5hbHRlcm5hdGUpLCBhbHRlcm5hdGVWaXNpYmxlLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0gZWxzZSBpZiAobm9kZS5hbHRlcm5hdGUua2luZCA9PSBcImlmXCIpIHtcbiAgICAgIGNvbnN0IG5lc3RlZCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZn0gKi8gKG5vZGUuYWx0ZXJuYXRlKVxuXG4gICAgICBhbHRlcm5hdGUgPSB7XG4gICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkJsb2NrXCIpLFxuICAgICAgICBsb2NhdGlvbjogbm9kZUxvY2F0aW9uKG5lc3RlZCwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICAgIHN0YXRlbWVudHM6IFtjb252ZXJ0SWYobmVzdGVkLCBhbHRlcm5hdGVWaXNpYmxlLCBmaWxlbmFtZSwgc291cmNlKV1cbiAgICAgIH1cbiAgICB9IGVsc2UgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGBpZiBhbHRlcm5hdGUgJHtub2RlLmFsdGVybmF0ZS5raW5kfWAsIG5vZGVMb2NhdGlvbihub2RlLmFsdGVybmF0ZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLihhbHRlcm5hdGUgPyB7YWx0ZXJuYXRlfSA6IHt9KSxcbiAgICBjb25kaXRpb246IGNvbnZlcnRFeHByZXNzaW9uKG5vZGUudGVzdCwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgY29uc2VxdWVudDogY29udmVydEJsb2NrKG5vZGUuYm9keSwgY29uc2VxdWVudFZpc2libGUsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgIGtpbmQ6IFwiSWZTdGF0ZW1lbnRcIixcbiAgICBsb2NhdGlvblxuICB9XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBQSFAgZWNobyBlbnRyeSBwb2ludC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5FY2hvfSBub2RlIC0gUEhQIGVjaG8gbm9kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUHJpbnRTdGF0ZW1lbnR9IFByaW50IHN0YXRlbWVudC5cbiAqL1xuZnVuY3Rpb24gY29udmVydFByaW50KG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS5leHByZXNzaW9ucy5sZW5ndGggIT0gMiB8fCBub2RlLmV4cHJlc3Npb25zWzFdLmtpbmQgIT0gXCJuYW1lXCIgfHxcbiAgICAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTmFtZX0gKi8gKG5vZGUuZXhwcmVzc2lvbnNbMV0pLm5hbWUgIT0gXCJQSFBfRU9MXCIpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJlY2hvIHdpdGhvdXQgb25lIGV4cHJlc3Npb24gYW5kIFBIUF9FT0xcIiwgbG9jYXRpb24pXG4gIH1cblxuICByZXR1cm4ge2V4cHJlc3Npb246IGNvbnZlcnRFeHByZXNzaW9uKG5vZGUuZXhwcmVzc2lvbnNbMF0sIGZpbGVuYW1lLCBzb3VyY2UpLCBraW5kOiBcIlByaW50U3RhdGVtZW50XCIsIGxvY2F0aW9ufVxufVxuXG4vKipcbiAqIFBhcnNlcyBQSFAgaW50byB0aGUgc2hhcmVkIHNlbWFudGljIG1vZHVsZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBpbnB1dCAtIFBhcnNlciBpbnB1dC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dC5maWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dC5zb3VyY2UgLSBTb3VyY2UgdGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gU2VtYW50aWMgbW9kdWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VQaHAoe2ZpbGVuYW1lLCBzb3VyY2V9KSB7XG4gIGNvbnN0IHByb2dyYW0gPSBwYXJzZVBocFByb2dyYW0oZmlsZW5hbWUsIHNvdXJjZSlcbiAgdmFsaWRhdGVEZWNsYXJlTm9kZXMocHJvZ3JhbS5jaGlsZHJlbiwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgZnVuY3Rpb25zID0gcHJvZ3JhbS5jaGlsZHJlbi5maWx0ZXIoKG5vZGUpID0+IG5vZGUua2luZCA9PSBcImZ1bmN0aW9uXCIpXG4gICAgLm1hcCgobm9kZSkgPT4gY29udmVydEZ1bmN0aW9uKC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5GdW5jdGlvbn0gKi8gKG5vZGUpLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgY29uc3QgZXhlY3V0YWJsZU5vZGVzID0gcHJvZ3JhbS5jaGlsZHJlbi5maWx0ZXIoKG5vZGUpID0+IG5vZGUua2luZCAhPSBcImZ1bmN0aW9uXCIgJiYgbm9kZS5raW5kICE9IFwiZGVjbGFyZVwiICYmIG5vZGUua2luZCAhPSBcIm5vb3BcIilcbiAgY29uc3QgbG9jYXRpb24gPSBtb2R1bGVMb2NhdGlvbihmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChmdW5jdGlvbnMubGVuZ3RoID09IDApIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm1vZHVsZSB3aXRob3V0IGEgZnVuY3Rpb25cIiwgbG9jYXRpb24pXG4gIGNvbnN0IGZpcnN0ID0gZXhlY3V0YWJsZU5vZGVzWzBdXG4gIGNvbnN0IGxhc3QgPSBleGVjdXRhYmxlTm9kZXMuYXQoLTEpID8/IGZpcnN0XG4gIGNvbnN0IGVudHJ5TG9jYXRpb24gPSBmaXJzdFxuICAgID8gbG9jYXRpb25Gcm9tT2Zmc2V0cyhmaWxlbmFtZSwgc291cmNlLCBmaXJzdC5sb2M/LnN0YXJ0Lm9mZnNldCA/PyAwLCBsYXN0Py5sb2M/LmVuZC5vZmZzZXQgPz8gc291cmNlLmxlbmd0aClcbiAgICA6IGxvY2F0aW9uXG4gIGNvbnN0IGVudHJ5VmlzaWJsZSA9IG5ldyBTZXQoKVxuICBjb25zdCBlbnRyeUJsb2NrID0ge1xuICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkJsb2NrXCIpLFxuICAgIGxvY2F0aW9uOiBlbnRyeUxvY2F0aW9uLFxuICAgIHN0YXRlbWVudHM6IGV4ZWN1dGFibGVOb2Rlcy5tYXAoKG5vZGUpID0+IGNvbnZlcnRTdGF0ZW1lbnQobm9kZSwgZW50cnlWaXNpYmxlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZW50cnlQb2ludDoge1xuICAgICAgYm9keTogZW50cnlCbG9jayxcbiAgICAgIGtpbmQ6IFwiRW50cnlQb2ludFwiLFxuICAgICAgbG9jYXRpb246IGVudHJ5TG9jYXRpb25cbiAgICB9LFxuICAgIGZ1bmN0aW9ucyxcbiAgICBraW5kOiBcIk1vZHVsZVwiLFxuICAgIGxvY2F0aW9uXG4gIH1cbn1cblxuLyoqXG4gKiBBY2NlcHRzIG9ubHkgYW4gb3B0aW9uYWwgc2luZ2xlIGBkZWNsYXJlKHN0cmljdF90eXBlcz0xKWAgZGlyZWN0aXZlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGVbXX0gbm9kZXMgLSBUb3AtbGV2ZWwgUEhQIG5vZGVzLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZURlY2xhcmVOb2Rlcyhub2RlcywgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBjb25zdCBkZWNsYXJhdGlvbnMgPSBub2Rlcy5maWx0ZXIoKG5vZGUpID0+IG5vZGUua2luZCA9PSBcImRlY2xhcmVcIilcblxuICBpZiAoZGVjbGFyYXRpb25zLmxlbmd0aCA+IDEpIHtcbiAgICB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm11bHRpcGxlIGRlY2xhcmUgZGlyZWN0aXZlc1wiLCBub2RlTG9jYXRpb24oZGVjbGFyYXRpb25zWzFdLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb25Ob2RlIG9mIGRlY2xhcmF0aW9ucykge1xuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkRlY2xhcmV9ICovIChkZWNsYXJhdGlvbk5vZGUpXG4gICAgY29uc3QgZGlyZWN0aXZlID0gZGVjbGFyYXRpb24uZGlyZWN0aXZlc1swXVxuICAgIGNvbnN0IGtleSA9IGRpcmVjdGl2ZT8ua2V5XG4gICAgY29uc3QgdmFsdWUgPSBkaXJlY3RpdmU/LnZhbHVlXG4gICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09IFwib2JqZWN0XCIgJiYgdmFsdWUua2luZCA9PSBcIm51bWJlclwiXG4gICAgICA/IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5OdW1iZXJ9ICovICh2YWx1ZSlcbiAgICAgIDogdW5kZWZpbmVkXG4gICAgY29uc3QgdmFsdWVJc09uZSA9IG51bWVyaWNWYWx1ZT8ubG9jICYmIHNvdXJjZS5zbGljZShudW1lcmljVmFsdWUubG9jLnN0YXJ0Lm9mZnNldCwgbnVtZXJpY1ZhbHVlLmxvYy5lbmQub2Zmc2V0KSA9PSBcIjFcIlxuICAgIGNvbnN0IHZhbGlkID0gZGVjbGFyYXRpb24ubW9kZSA9PSBcIm5vbmVcIiAmJiBkZWNsYXJhdGlvbi5jaGlsZHJlbi5sZW5ndGggPT0gMCAmJiBkZWNsYXJhdGlvbi5kaXJlY3RpdmVzLmxlbmd0aCA9PSAxICYmXG4gICAgICBrZXkua2luZCA9PSBcImlkZW50aWZpZXJcIiAmJiBrZXkubmFtZSA9PSBcInN0cmljdF90eXBlc1wiICYmIHZhbHVlSXNPbmVcblxuICAgIGlmICghdmFsaWQpIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZGVjbGFyZSBvdGhlciB0aGFuIHN0cmljdF90eXBlcz0xXCIsIG5vZGVMb2NhdGlvbihkZWNsYXJhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbn1cblxuLyoqXG4gKiBJbnZva2VzIHBocC1wYXJzZXIgYW5kIG5vcm1hbGl6ZXMgc3ludGF4IGZhaWx1cmVzLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIFNvdXJjZSB0ZXh0LlxuICogQHJldHVybnMge2ltcG9ydChcInBocC1wYXJzZXJcIikuUHJvZ3JhbX0gUEhQIHByb2dyYW0uXG4gKi9cbmZ1bmN0aW9uIHBhcnNlUGhwUHJvZ3JhbShmaWxlbmFtZSwgc291cmNlKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHBhcnNlci5wYXJzZUNvZGUoc291cmNlLCBmaWxlbmFtZSlcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4gcGFyc2VGYWlsdXJlKFwicGhwXCIsIGVycm9yKVxuICB9XG59XG4iXX0=
2030
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGhwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Zyb250ZW5kcy9waHAuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sU0FBUyxNQUFNLFlBQVksQ0FBQTtBQUNsQyxPQUFPLEVBQUMsS0FBSyxJQUFJLFlBQVksRUFBQyxNQUFNLGdCQUFnQixDQUFBO0FBQ3BELE9BQU8sRUFBQyxXQUFXLEVBQUUsWUFBWSxFQUFFLGlCQUFpQixFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDN0UsT0FBTyxFQUFDLDZCQUE2QixFQUFDLE1BQU0sd0JBQXdCLENBQUE7QUFDcEUsT0FBTyxFQUFDLG1CQUFtQixFQUFFLGNBQWMsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQzNFLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLDBCQUEwQixDQUFBO0FBQzdELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLDJCQUEyQixDQUFBO0FBQzFELE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLDZCQUE2QixDQUFBO0FBQ2xFLE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLHdCQUF3QixDQUFBO0FBQzVELE9BQU8sRUFBQyxxQkFBcUIsRUFBRSxVQUFVLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQTtBQUN4RSxPQUFPLEVBQUMsdUJBQXVCLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUMvRCxPQUFPLEVBQUMsdUJBQXVCLEVBQUUsdUJBQXVCLEVBQUUsZ0JBQWdCLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFDL0YsT0FBTyxFQUFDLDRCQUE0QixFQUFFLG1CQUFtQixFQUFFLDJCQUEyQixFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUFFLHVCQUF1QixFQUFFLG1CQUFtQixFQUFFLFlBQVksRUFBRSxxQkFBcUIsRUFBRSxpQkFBaUIsRUFBRSxnQ0FBZ0MsRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBQyxNQUFNLFlB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Q0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFBRSxPQUFPLEVBQUMsVUFBVSxFQUFFLElBQUksR0FBRyxFQUFFLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBQyxDQUFBO0lBQ3BJLE1BQU0sS0FBSyxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDNUMsTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLElBQUksSUFBSSxFQUFFLENBQUE7SUFDOUIsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxPQUFPLENBQUMsQ0FBQTtJQUM5RCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLFFBQVEsSUFBSSxHQUFHLENBQUMsR0FBRyxJQUFJLFNBQVMsQ0FBQyxDQUFBO0lBQ3BGLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksVUFBVSxDQUFDLENBQUE7SUFDaEUsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsSUFBSSxHQUFHLENBQUMsR0FBRyxJQUFJLFVBQVUsQ0FBQyxDQUFBO0lBQ3JHLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDO1FBQzFILGFBQWEs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R0FBRyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUE7SUFFdkQsT0FBTyxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUE7QUFDM0YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgUGhwUGFyc2VyIGZyb20gXCJwaHAtcGFyc2VyXCJcbmltcG9ydCB7cGFyc2UgYXMgcGFyc2VDb21tZW50fSBmcm9tIFwiY29tbWVudC1wYXJzZXJcIlxuaW1wb3J0IHttaXNzaW5nVHlwZSwgcGFyc2VGYWlsdXJlLCB1bnN1cHBvcnRlZFN5bnRheH0gZnJvbSBcIi4uL2RpYWdub3N0aWMuanNcIlxuaW1wb3J0IHtibG9ja1JlZmVyZW5jZXNQcm90ZWN0ZWRFbnRyeX0gZnJvbSBcIi4uL3NlbWFudGljL2VmZmVjdHMuanNcIlxuaW1wb3J0IHtsb2NhdGlvbkZyb21PZmZzZXRzLCBtb2R1bGVMb2NhdGlvbn0gZnJvbSBcIi4uL3NlbWFudGljL2xvY2F0aW9uLmpzXCJcbmltcG9ydCB7d2l0aEFkYXB0ZWRPcGVyYXRpb259IGZyb20gXCIuLi9zZW1hbnRpYy9vcGVyYXRvcnMuanNcIlxuaW1wb3J0IHt3aXRoUGFyc2VyUmFuZ2VzfSBmcm9tIFwiLi4vc2VtYW50aWMvcHJvdmVuYW5jZS5qc1wiXG5pbXBvcnQge2lzVGFzazAzNFJlc291cmNlUHJvYmV9IGZyb20gXCIuLi9zZW1hbnRpYy9jYXBhYmlsaXRpZXMuanNcIlxuaW1wb3J0IHtoYXNFeGFjdEVmZmVjdFN1cHBvcnR9IGZyb20gXCIuLi9iYWNrZW5kcy9lZmZlY3RzLmpzXCJcbmltcG9ydCB7aGFzT25seVVuaWNvZGVTY2FsYXJzLCBzY2FsYXJUeXBlfSBmcm9tIFwiLi4vc2VtYW50aWMvc2NhbGFycy5qc1wiXG5pbXBvcnQge3R5cGVDb250YWluc0FueVZhcmlhYmxlfSBmcm9tIFwiLi4vc2VtYW50aWMvZ2VuZXJpY3MuanNcIlxuaW1wb3J0IHtyZXF1aXJlU291cmNlUmV0dXJuVHlwZSwgcmVxdWlyZVNvdXJjZVNjYWxhclR5cGUsIHNvdXJjZVNjYWxhclR5cGV9IGZyb20gXCIuL3NjYWxhcnMuanNcIlxuaW1wb3J0IHtjYXBhYmlsaXR5RnVuY3Rpb25TaWduYXR1cmVzLCBkb2N1bWVudGVkVmFsdWVUeXBlLCBpbnN0YW50aWF0ZWRSZWNvcmRGaWVsZFR5cGUsIGl0ZXJhdGlvbkJpbmRpbmdUeXBlLCBpdGVyYXRpb25PcGVyYW5kVHlwZSwga25vd25DYWxsUGFyYW1ldGVyVHlwZXMsIGtub3duQ2FsbFJldHVyblR5cGUsIG9wdGlvbmFsVHlwZSwgb3JkZXJlZE1hcFR5cGVGcm9tTWFwLCBvd25lZFJlc291cmNlVHlwZSwgcHJlc2VydmVzR2VuZXJpY09wdGlvbmFsRXZpZGVuY2UsIHJlY29yZFR5cGUsIHJlZmVyZW5jZVR5cGUsIHNhbWVWYWx1ZVR5cGV9IGZyb20gXCIuL3R5cGVzLmpzXCJcbmNvbnN0IHBhcnNlciA9IG5ldyBQaHBQYXJzZXIuRW5naW5lKHtcbiAgYXN0OiB7d2l0aFBvc2l0aW9uczogdHJ1ZX0sXG4gIHBhcnNlcjoge2V4dHJhY3REb2M6IHRydWUsIHN1cHByZXNzRXJyb3JzOiBmYWxzZX1cbn0pXG4vKiogQHR5cGUge3N0cmluZyB8IHVuZGVmaW5lZH0gKi9cbmxldCBjYWNoZWRUb2tlblNvdXJjZVxuLyoqIEB0eXBlIHt7ZW5kOiBudW1iZXIsIHN0YXJ0OiBudW1iZXIsIHRleHQ6IHN0cmluZ31bXX0gKi9cbmxldCBjYWNoZWRUb2tlblJhbmdlcyA9IFtdXG5jb25zdCBwaHBCaW5hcnlPcGVyYXRpb25zID0gbmV3IE1hcChbXG4gIFtcIitcIiwgXCJQaHBBZGRcIl0sXG4gIFtcIi1cIiwgXCJTdWJ0cmFjdFwiXSxcbiAgW1wiKlwiLCBcIk11bHRpcGx5XCJdLFxuICBbXCImJlwiLCBcIkFuZFwiXSxcbiAgW1wifHxcIiwgXCJPclwiXSxcbiAgW1wiPT09XCIsIFwiRXF1YWxcIl0sXG4gIFtcIiE9PVwiLCBcIk5vdEVxdWFsXCJdLFxuICBbXCI8XCIsIFwiTGVzc1RoYW5cIl0sXG4gIFtcIjw9XCIsIFwiTGVzc1RoYW5PckVxdWFsXCJdLFxuICBbXCI+XCIsIFwiR3JlYXRlclRoYW5cIl0sXG4gIFtcIj49XCIsIFwiR3JlYXRlclRoYW5PckVxdWFsXCJdLFxuICBbXCIuXCIsIFwiU3RyaW5nQ29uY2F0XCJdXG5dKVxuXG4vKipcbiAqIEB0eXBlZGVmIFBocENvbnZlcnNpb25Db250ZXh0XG4gKiBAcHJvcGVydHkge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljQmluZGluZ1R5cGU+fSBiaW5kaW5ncyAtIEV4cGxpY2l0bHkgdHlwZWQgdmlzaWJsZSBiaW5kaW5ncy5cbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbj59IGNsYXNzZXMgLSBSZWZlcmVuY2UgY2xhc3NlcyBieSBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbn0gW2N1cnJlbnRDbGFzc10gLSBFbmNsb3NpbmcgcmVmZXJlbmNlIGNsYXNzLlxuICogQHByb3BlcnR5IHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9uPn0gZXJyb3JOYW1lcyAtIEVycm9yIGRlY2xhcmF0aW9ucyBieSBzb3VyY2UgbmFtZS5cbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXJyb3JEZWNsYXJhdGlvbj59IGVycm9ycyAtIEVycm9yIGRlY2xhcmF0aW9ucyBieSBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgUGhwRnVuY3Rpb25TaWduYXR1cmU+fSBmdW5jdGlvbnMgLSBFeHBsaWNpdCBtb2R1bGUgZnVuY3Rpb24gc2lnbmF0dXJlcy5cbiAqIEBwcm9wZXJ0eSB7U2V0PG9iamVjdD59IFtvcmRlcmVkTWFwRGVjbGFyYXRpb25zXSAtIEV4YWN0IGxvY2FsIGRlY2xhcmF0aW9ucyBzZWxlY3RlZCBieSBwYXJzZXItb3duZWQgcGFpciBpdGVyYXRpb24uXG4gKiBAcHJvcGVydHkge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb24+fSByZWNvcmROYW1lcyAtIE5vbWluYWwgZGVjbGFyYXRpb25zIGJ5IHNvdXJjZSBuYW1lLlxuICogQHByb3BlcnR5IHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbj59IHJlY29yZHMgLSBSZWNvcmQgZGVjbGFyYXRpb25zIGJ5IGlkZW50aXR5LlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZSB8IHVuZGVmaW5lZH0gcmV0dXJuVHlwZSAtIEVuY2xvc2luZyByZXR1cm4gdHlwZS5cbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVBhcmFtZXRlcj59IFt0eXBlUGFyYW1ldGVyc10gLSBEZWNsYXJhdGlvbi1zY29wZWQgcGFyYW1ldGVycy5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIFBocEZ1bmN0aW9uU2lnbmF0dXJlXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBsb2NhdGlvbiAtIENvbXBsZXRlIGRlY2xhcmF0aW9uIGxvY2F0aW9uLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gbmFtZUxvY2F0aW9uIC0gUGFyc2VyLW93bmVkIG5hbWUgbG9jYXRpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gbmFtZSAtIEZ1bmN0aW9uIG5hbWUuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlBhcmFtZXRlcltdfSBwYXJhbWV0ZXJzIC0gU2VtYW50aWMgcGFyYW1ldGVycy5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9IHJldHVyblR5cGUgLSBTZW1hbnRpYyByZXR1cm4gdHlwZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVBhcmFtZXRlcltdfSBbdHlwZVBhcmFtZXRlcnNdIC0gRGVjbGFyYXRpb24tc2NvcGVkIHBhcmFtZXRlcnMuXG4gKi9cblxuLyoqXG4gKiBSZXR1cm5zIGEgbm9ybWFsaXplZCBQSFAgbm9kZSBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlfSBub2RlIC0gUEhQIHBhcnNlciBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gU291cmNlIGxvY2F0aW9uLlxuICovXG5mdW5jdGlvbiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAoIW5vZGUubG9jKSB0aHJvdyBuZXcgRXJyb3IoYFBIUCBwYXJzZXIgb21pdHRlZCBzb3VyY2UgbG9jYXRpb24gZm9yICR7bm9kZS5raW5kfS5gKVxuXG4gIHJldHVybiBsb2NhdGlvbkZyb21PZmZzZXRzKGZpbGVuYW1lLCBzb3VyY2UsIG5vZGUubG9jLnN0YXJ0Lm9mZnNldCwgbm9kZS5sb2MuZW5kLm9mZnNldClcbn1cblxuLyoqXG4gKiBMb2NhdGVzIGEgY29tbWVudC1wYXJzZXIgdG9rZW4gaW5zaWRlIGEgUEhQIHBhcnNlci1vd25lZCBkb2MgY29tbWVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Db21tZW50QmxvY2t9IGNvbW1lbnQgLSBQSFAgZG9jIGNvbW1lbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcImNvbW1lbnQtcGFyc2VyXCIpLlNwZWN9IHRhZyAtIFBhcnNlZCBkb2MgdGFnLlxuICogQHBhcmFtIHtcIm5hbWVcIiB8IFwidHlwZVwifSBmaWVsZCAtIFRva2VuIGZpZWxkLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gRXhhY3QgdG9rZW4gbG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIGNvbW1lbnRUYWdMb2NhdGlvbihjb21tZW50LCB0YWcsIGZpZWxkLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGxpbmUgPSB0YWcuc291cmNlWzBdXG5cbiAgaWYgKCFjb21tZW50LmxvYyB8fCAhbGluZSkgdGhyb3cgbmV3IEVycm9yKGBDb21tZW50IHBhcnNlciBvbWl0dGVkIHRoZSBAJHt0YWcudGFnfSBzb3VyY2UgdG9rZW4uYClcblxuICBsZXQgbGluZVN0YXJ0ID0gY29tbWVudC5sb2Muc3RhcnQub2Zmc2V0XG5cbiAgZm9yIChsZXQgbGluZU51bWJlciA9IDA7IGxpbmVOdW1iZXIgPCBsaW5lLm51bWJlcjsgbGluZU51bWJlcisrKSB7XG4gICAgd2hpbGUgKGxpbmVTdGFydCA8IHNvdXJjZS5sZW5ndGggJiYgc291cmNlW2xpbmVTdGFydF0gIT0gXCJcXHJcIiAmJiBzb3VyY2VbbGluZVN0YXJ0XSAhPSBcIlxcblwiKSBsaW5lU3RhcnQrK1xuICAgIGlmIChzb3VyY2VbbGluZVN0YXJ0XSA9PSBcIlxcclwiICYmIHNvdXJjZVtsaW5lU3RhcnQgKyAxXSA9PSBcIlxcblwiKSBsaW5lU3RhcnQgKz0gMlxuICAgIGVsc2UgbGluZVN0YXJ0KytcbiAgfVxuXG4gIGNvbnN0IG9yZGVyZWRGaWVsZHMgPSBbXCJzdGFydFwiLCBcImRlbGltaXRlclwiLCBcInBvc3REZWxpbWl0ZXJcIiwgXCJ0YWdcIiwgXCJwb3N0VGFnXCIsIFwibmFtZVwiLCBcInBvc3ROYW1lXCIsIFwidHlwZVwiXVxuICBjb25zdCBmaWVsZEluZGV4ID0gb3JkZXJlZEZpZWxkcy5pbmRleE9mKGZpZWxkKVxuICBjb25zdCBzdGFydCA9IGxpbmVTdGFydCArIG9yZGVyZWRGaWVsZHMuc2xpY2UoMCwgZmllbGRJbmRleCkucmVkdWNlKChsZW5ndGgsIGtleSkgPT5cbiAgICBsZW5ndGggKyBsaW5lLnRva2Vuc1svKiogQHR5cGUge2tleW9mIHR5cGVvZiBsaW5lLnRva2Vuc30gKi8gKGtleSldLmxlbmd0aCwgMClcbiAgY29uc3QgdmFsdWUgPSBsaW5lLnRva2Vuc1tmaWVsZF1cblxuICByZXR1cm4gbG9jYXRpb25Gcm9tT2Zmc2V0cyhmaWxlbmFtZSwgc291cmNlLCBzdGFydCwgc3RhcnQgKyB2YWx1ZS5sZW5ndGgpXG59XG5cbi8qKlxuICogRmluZHMgb25lIHBhcnNlciB0b2tlbiBiZXR3ZWVuIHBhcnNlci1vd25lZCBub2RlIGJvdW5kYXJpZXMuXG4gKiBAcGFyYW0ge3N0cmluZ30gdG9rZW5UZXh0IC0gRXhhY3QgdG9rZW4gdGV4dC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydE9mZnNldCAtIEluY2x1c2l2ZSBzZWFyY2ggYm91bmRhcnkuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kT2Zmc2V0IC0gRXhjbHVzaXZlIHNlYXJjaCBib3VuZGFyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IFRva2VuIGxvY2F0aW9uLlxuICovXG5mdW5jdGlvbiB0b2tlbkxvY2F0aW9uKHRva2VuVGV4dCwgc3RhcnRPZmZzZXQsIGVuZE9mZnNldCwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAoY2FjaGVkVG9rZW5Tb3VyY2UgIT0gc291cmNlKSB7XG4gICAgbGV0IG9mZnNldCA9IDBcblxuICAgIGNhY2hlZFRva2VuUmFuZ2VzID0gcGFyc2VyLnRva2VuR2V0QWxsKHNvdXJjZSkubWFwKCh0b2tlbikgPT4ge1xuICAgICAgY29uc3QgdGV4dCA9IHR5cGVvZiB0b2tlbiA9PSBcInN0cmluZ1wiID8gdG9rZW4gOiB0b2tlblsxXVxuICAgICAgY29uc3QgcmFuZ2UgPSB7ZW5kOiBvZmZzZXQgKyB0ZXh0Lmxlbmd0aCwgc3RhcnQ6IG9mZnNldCwgdGV4dH1cblxuICAgICAgb2Zmc2V0ID0gcmFuZ2UuZW5kXG5cbiAgICAgIHJldHVybiByYW5nZVxuICAgIH0pXG4gICAgY2FjaGVkVG9rZW5Tb3VyY2UgPSBzb3VyY2VcbiAgfVxuXG4gIGNvbnN0IHRva2VuID0gY2FjaGVkVG9rZW5SYW5nZXMuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUudGV4dCA9PSB0b2tlblRleHQgJiYgY2FuZGlkYXRlLnN0YXJ0ID49IHN0YXJ0T2Zmc2V0ICYmXG4gICAgY2FuZGlkYXRlLmVuZCA8PSBlbmRPZmZzZXQpXG5cbiAgaWYgKHRva2VuKSByZXR1cm4gbG9jYXRpb25Gcm9tT2Zmc2V0cyhmaWxlbmFtZSwgc291cmNlLCB0b2tlbi5zdGFydCwgdG9rZW4uZW5kKVxuXG4gIHRocm93IG5ldyBFcnJvcihgUEhQIHBhcnNlciBvbWl0dGVkIHRva2VuICcke3Rva2VuVGV4dH0nIGJldHdlZW4gJHtzdGFydE9mZnNldH0gYW5kICR7ZW5kT2Zmc2V0fS5gKVxufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgc3VwcG9ydGVkIFBIUCBleHByZXNzaW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkV4cHJlc3Npb259IG5vZGUgLSBQSFAgZXhwcmVzc2lvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge1BocENvbnZlcnNpb25Db250ZXh0fSBjb250ZXh0IC0gVHlwZWQgY29udmVyc2lvbiBjb250ZXh0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZX0gW2V4cGVjdGVkVHlwZV0gLSBDb250ZXh0dWFsIHR5cGUgZm9yIGVtcHR5IFBIUCBhcnJheXMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtwcmVzZXJ2ZU9wdGlvbmFsXSAtIFdoZXRoZXIgYW4gb3B0aW9uYWwgaWRlbnRpZmllciByZW1haW5zIHdyYXBwZWQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gU2VtYW50aWMgZXhwcmVzc2lvbi5cbiAqL1xuZnVuY3Rpb24gY29udmVydEV4cHJlc3Npb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCwgZXhwZWN0ZWRUeXBlLCBwcmVzZXJ2ZU9wdGlvbmFsID0gZmFsc2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAoZXhwZWN0ZWRUeXBlPy5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIpIHtcbiAgICBpZiAobm9kZS5raW5kID09IFwibnVsbGtleXdvcmRcIikge1xuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIk9wdGlvbmFsTm9uZVwiKSwgbG9jYXRpb259LCB7YWJzZW5jZTogbG9jYXRpb259KVxuICAgIH1cbiAgICBpZiAoa25vd25FeHByZXNzaW9uVHlwZShub2RlLCBjb250ZXh0KT8ua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgICByZXR1cm4gY29udmVydEV4cHJlc3Npb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCwgdW5kZWZpbmVkLCB0cnVlKVxuICAgIH1cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJPcHRpb25hbFNvbWVcIiksXG4gICAgICBsb2NhdGlvbixcbiAgICAgIHZhbHVlOiBjb252ZXJ0RXhwcmVzc2lvbihub2RlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0LCBleHBlY3RlZFR5cGUudmFsdWVUeXBlKVxuICAgIH0sIHtzb21lOiBsb2NhdGlvbn0pXG4gIH1cblxuICBpZiAobm9kZS5raW5kID09IFwibnVsbGtleXdvcmRcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibnVsbCBvdXRzaWRlIGFuIGV4cGxpY2l0IG9wdGlvbmFsIGNvbnRleHRcIiwgbG9jYXRpb24pXG5cbiAgaWYgKG5vZGUua2luZCA9PSBcInZhcmlhYmxlXCIpIHtcbiAgICBjb25zdCB2YXJpYWJsZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5WYXJpYWJsZX0gKi8gKG5vZGUpXG5cbiAgICBpZiAodHlwZW9mIHZhcmlhYmxlLm5hbWUgIT0gXCJzdHJpbmdcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZHluYW1pYyB2YXJpYWJsZVwiLCBsb2NhdGlvbilcbiAgICBpZiAodmFyaWFibGUubmFtZSA9PSBcInRoaXNcIikge1xuICAgICAgaWYgKCFjb250ZXh0LmN1cnJlbnRDbGFzcykgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwicmVjZWl2ZXIgb3V0c2lkZSBhIHJlZmVyZW5jZSBjbGFzc1wiLCBsb2NhdGlvbilcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtjbGFzc0lkOiAvKiogQHR5cGUge3N0cmluZ30gKi8gKGNvbnRleHQuY3VycmVudENsYXNzLmlkKSxcbiAgICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUmVjZWl2ZXJFeHByZXNzaW9uXCIpLCBsb2NhdGlvbn0sIHtyZWNlaXZlcjogbG9jYXRpb259KVxuICAgIH1cblxuICAgIGNvbnN0IGlkZW50aWZpZXIgPSB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb24sIG5hbWU6IHZhcmlhYmxlLm5hbWV9LCB7bmFtZTogbG9jYXRpb259KVxuXG4gICAgaWYgKCFwcmVzZXJ2ZU9wdGlvbmFsICYmIGNvbnRleHQuYmluZGluZ3MuZ2V0KHZhcmlhYmxlLm5hbWUpPy5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIpIHtcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJPcHRpb25hbFVud3JhcFwiKSwgbG9jYXRpb24sIG9wZXJhbmQ6IGlkZW50aWZpZXJ9LCB7dW53cmFwOiBsb2NhdGlvbn0pXG4gICAgfVxuXG4gICAgcmV0dXJuIGlkZW50aWZpZXJcbiAgfVxuXG4gIGlmIChub2RlLmtpbmQgPT0gXCJudW1iZXJcIikge1xuICAgIGNvbnN0IGxpdGVyYWwgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTnVtYmVyfSAqLyAobm9kZSlcbiAgICBjb25zdCB2YWx1ZSA9IE51bWJlcihsaXRlcmFsLnZhbHVlKVxuXG4gICAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcih2YWx1ZSkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm5vbi1zYWZlIGludGVnZXIgbGl0ZXJhbFwiLCBsb2NhdGlvbilcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJbnRlZ2VyTGl0ZXJhbFwiKSwgbG9jYXRpb24sIHZhbHVlfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgfVxuXG4gIGlmIChub2RlLmtpbmQgPT0gXCJib29sZWFuXCIpIHtcbiAgICBjb25zdCBsaXRlcmFsID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkJvb2xlYW59ICovIChub2RlKVxuXG4gICAgaWYgKHR5cGVvZiBsaXRlcmFsLnZhbHVlICE9IFwiYm9vbGVhblwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJpbnZhbGlkIGJvb2xlYW4gbGl0ZXJhbCB2YWx1ZVwiLCBsb2NhdGlvbilcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJCb29sZWFuTGl0ZXJhbFwiKSwgbG9jYXRpb24sIHZhbHVlOiBsaXRlcmFsLnZhbHVlfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgfVxuXG4gIGlmIChub2RlLmtpbmQgPT0gXCJzdHJpbmdcIikge1xuICAgIGNvbnN0IGxpdGVyYWwgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuU3RyaW5nfSAqLyAobm9kZSlcblxuICAgIGlmICh0eXBlb2YgbGl0ZXJhbC5yYXcgPT0gXCJzdHJpbmdcIiAmJiBsaXRlcmFsLnJhdy5zdGFydHNXaXRoKFwiPDw8XCIpKSB7XG4gICAgICBjb25zdCBkZXRhaWwgPSBsaXRlcmFsLnJhdy5zdGFydHNXaXRoKFwiPDw8J1wiKSA/IFwibm93ZG9jIHN0cmluZ1wiIDogXCJoZXJlZG9jIHN0cmluZ1wiXG5cbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBkZXRhaWwsIGxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGxpdGVyYWwucmF3ID09IFwic3RyaW5nXCIgJiYgW1wiYlxcXCJcIiwgXCJCXFxcIlwiLCBcImInXCIsIFwiQidcIl0uc29tZSgocHJlZml4KSA9PiBsaXRlcmFsLnJhdy5zdGFydHNXaXRoKHByZWZpeCkpKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJiaW5hcnkgc3RyaW5nIGxpdGVyYWxcIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGlmICh0eXBlb2YgbGl0ZXJhbC52YWx1ZSAhPSBcInN0cmluZ1wiIHx8ICFoYXNPbmx5VW5pY29kZVNjYWxhcnMobGl0ZXJhbC52YWx1ZSkpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImludmFsaWQgVW5pY29kZSBzdHJpbmcgbGl0ZXJhbFwiLCBsb2NhdGlvbilcbiAgICB9XG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiU3RyaW5nTGl0ZXJhbFwiKSwgbG9jYXRpb24sIHZhbHVlOiBsaXRlcmFsLnZhbHVlfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgfVxuXG4gIGlmIChub2RlLmtpbmQgPT0gXCJlbmNhcHNlZFwiKSB7XG4gICAgY29uc3QgbGl0ZXJhbCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5FbmNhcHNlZH0gKi8gKG5vZGUpXG4gICAgY29uc3QgZGV0YWlsID0gbGl0ZXJhbC50eXBlID09IFwic3RyaW5nXCIgPyBcImludGVycG9sYXRlZCBzdHJpbmdcIiA6IGAke2xpdGVyYWwudHlwZX0gc3RyaW5nYFxuXG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGRldGFpbCwgbG9jYXRpb24pXG4gIH1cblxuICBpZiAobm9kZS5raW5kID09IFwibm93ZG9jXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm5vd2RvYyBzdHJpbmdcIiwgbG9jYXRpb24pXG5cbiAgaWYgKG5vZGUua2luZCA9PSBcImFycmF5XCIpIHtcbiAgICBjb25zdCBsaXRlcmFsID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkFycmF5fSAqLyAobm9kZSlcbiAgICBjb25zdCBpbnZhbGlkRW50cnkgPSBsaXRlcmFsLml0ZW1zLmZpbmQoKGVudHJ5KSA9PiB7XG4gICAgICBpZiAoZW50cnkua2luZCAhPSBcImVudHJ5XCIpIHJldHVybiB0cnVlXG4gICAgICBjb25zdCBjYW5kaWRhdGUgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuRW50cnl9ICovIChlbnRyeSlcblxuICAgICAgcmV0dXJuIGNhbmRpZGF0ZS5ieVJlZiB8fCBjYW5kaWRhdGUudW5wYWNrXG4gICAgfSlcblxuICAgIGlmIChpbnZhbGlkRW50cnkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImFycmF5IHJlZmVyZW5jZSBvciB1bnBhY2tpbmdcIiwgbm9kZUxvY2F0aW9uKGludmFsaWRFbnRyeSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgY29uc3QgZW50cmllcyA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5FbnRyeVtdfSAqLyAobGl0ZXJhbC5pdGVtcylcbiAgICBjb25zdCBoYXNLZXlzID0gZW50cmllcy5zb21lKChlbnRyeSkgPT4gZW50cnkua2V5ICE9IG51bGwpXG4gICAgY29uc3QgaGFzSW1wbGljaXQgPSBlbnRyaWVzLnNvbWUoKGVudHJ5KSA9PiBlbnRyeS5rZXkgPT0gbnVsbClcbiAgICBjb25zdCBjb2xsZWN0aW9uS2luZCA9IGVudHJpZXMubGVuZ3RoID09IDAgPyBleHBlY3RlZFR5cGU/LmtpbmQgOiBoYXNLZXlzICYmICFoYXNJbXBsaWNpdFxuICAgICAgPyBleHBlY3RlZFR5cGU/LmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiID8gXCJPcmRlcmVkTWFwVHlwZVwiIDogXCJNYXBUeXBlXCJcbiAgICAgIDogIWhhc0tleXMgPyBcIkxpc3RUeXBlXCIgOiBcIm1peGVkXCJcblxuICAgIGlmIChjb2xsZWN0aW9uS2luZCA9PSBcIm1peGVkXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm1peGVkIGxpc3QvbWFwIGFycmF5IGxpdGVyYWxcIiwgbG9jYXRpb24pXG4gICAgaWYgKGNvbGxlY3Rpb25LaW5kID09IFwiTGlzdFR5cGVcIikge1xuICAgICAgY29uc3QgZWxlbWVudFR5cGUgPSBleHBlY3RlZFR5cGU/LmtpbmQgPT0gXCJMaXN0VHlwZVwiID8gZXhwZWN0ZWRUeXBlLmVsZW1lbnRUeXBlIDogdW5kZWZpbmVkXG5cbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgICAgZWxlbWVudHM6IGVudHJpZXMubWFwKChlbnRyeSkgPT4gY29udmVydEV4cHJlc3Npb24oZW50cnkudmFsdWUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIGVsZW1lbnRUeXBlKSksXG4gICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkxpc3RMaXRlcmFsXCIpLFxuICAgICAgICBsb2NhdGlvblxuICAgICAgfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgICB9XG4gICAgaWYgKGNvbGxlY3Rpb25LaW5kID09IFwiTWFwVHlwZVwiIHx8IGNvbGxlY3Rpb25LaW5kID09IFwiT3JkZXJlZE1hcFR5cGVcIikge1xuICAgICAgY29uc3QgdmFsdWVUeXBlID0gZXhwZWN0ZWRUeXBlPy5raW5kID09IFwiTWFwVHlwZVwiIHx8IGV4cGVjdGVkVHlwZT8ua2luZCA9PSBcIk9yZGVyZWRNYXBUeXBlXCJcbiAgICAgICAgPyBleHBlY3RlZFR5cGUudmFsdWVUeXBlIDogdW5kZWZpbmVkXG4gICAgICBjb25zdCBzZW1hbnRpY0VudHJpZXMgPSBlbnRyaWVzLm1hcCgoZW50cnkpID0+IHtcbiAgICAgICAgaWYgKCFlbnRyeS5rZXkgfHwgZW50cnkua2V5LmtpbmQgIT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm1hcCBrZXkgb3RoZXIgdGhhbiBhIGxpdGVyYWwgc3RyaW5nXCIsIGVudHJ5LmtleSA/IG5vZGVMb2NhdGlvbihlbnRyeS5rZXksIGZpbGVuYW1lLCBzb3VyY2UpIDogbm9kZUxvY2F0aW9uKGVudHJ5LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBrZXkgPSBjb252ZXJ0RXhwcmVzc2lvbihlbnRyeS5rZXksIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpXG5cbiAgICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgICAgIGtleTogLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TdHJpbmdMaXRlcmFsfSAqLyAoa2V5KSxcbiAgICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJNYXBFbnRyeVwiKSxcbiAgICAgICAgICBsb2NhdGlvbjogbm9kZUxvY2F0aW9uKGVudHJ5LCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgICAgICB2YWx1ZTogY29udmVydEV4cHJlc3Npb24oZW50cnkudmFsdWUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIHZhbHVlVHlwZSlcbiAgICAgICAgfSwge29wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKFwiPT5cIiwgZW50cnkua2V5LmxvYz8uZW5kLm9mZnNldCA/PyAwLCBlbnRyeS52YWx1ZS5sb2M/LnN0YXJ0Lm9mZnNldCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKX0pXG4gICAgICB9KVxuXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICAgIGVudHJpZXM6IHNlbWFudGljRW50cmllcyxcbiAgICAgICAga2luZDogY29sbGVjdGlvbktpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiXG4gICAgICAgICAgPyAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJPcmRlcmVkTWFwTGl0ZXJhbFwiKVxuICAgICAgICAgIDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiTWFwTGl0ZXJhbFwiKSxcbiAgICAgICAgbG9jYXRpb25cbiAgICAgIH0sIHtsaXRlcmFsOiBsb2NhdGlvbn0pXG4gICAgfVxuXG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZW1wdHkgYXJyYXkgd2l0aG91dCBhIGxpc3Qgb3IgbWFwIHR5cGVcIiwgbG9jYXRpb24pXG4gIH1cblxuICBpZiAobm9kZS5raW5kID09IFwibmV3XCIpIHtcbiAgICBjb25zdCBjb25zdHJ1Y3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTmV3fSAqLyAobm9kZSlcbiAgICBjb25zdCBuYW1lID0gY29uc3RydWN0aW9uLndoYXQua2luZCA9PSBcIm5hbWVcIiA/IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5OYW1lfSAqLyAoY29uc3RydWN0aW9uLndoYXQpIDogdW5kZWZpbmVkXG5cbiAgICBpZiAoIW5hbWUgfHwgbmFtZS5yZXNvbHV0aW9uICE9IFwidXFuXCIgfHwgdHlwZW9mIG5hbWUubmFtZSAhPSBcInN0cmluZ1wiKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJkeW5hbWljIG9yIHF1YWxpZmllZCByZWNvcmQgY29uc3RydWN0aW9uXCIsIG5vZGVMb2NhdGlvbihjb25zdHJ1Y3Rpb24ud2hhdCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgfVxuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gY29udGV4dC5yZWNvcmROYW1lcy5nZXQobmFtZS5uYW1lKVxuXG4gICAgaWYgKCFkZWNsYXJhdGlvbikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiY29uc3RydWN0aW9uIG9mIGFuIHVua25vd24gbm9taW5hbCBjbGFzc1wiLCBub2RlTG9jYXRpb24oY29uc3RydWN0aW9uLndoYXQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIGlmIChkZWNsYXJhdGlvbi5raW5kID09IFwiQ2xhc3NEZWNsYXJhdGlvblwiKSB7XG4gICAgICBjb25zdCB1bnN1cHBvcnRlZEFyZ3VtZW50ID0gY29uc3RydWN0aW9uLmFyZ3VtZW50cy5maW5kKChhcmd1bWVudCkgPT5cbiAgICAgICAgYXJndW1lbnQua2luZCA9PSBcIm5hbWVkYXJndW1lbnRcIiB8fCBhcmd1bWVudC5raW5kID09IFwidmFyaWFkaWNcIiB8fCBSZWZsZWN0LmdldChhcmd1bWVudCwgXCJieXJlZlwiKSA9PT0gdHJ1ZSlcblxuICAgICAgaWYgKHVuc3VwcG9ydGVkQXJndW1lbnQpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm5vbi1wb3NpdGlvbmFsIHJlZmVyZW5jZSBjb25zdHJ1Y3RvciBhcmd1bWVudFwiLFxuICAgICAgICBub2RlTG9jYXRpb24odW5zdXBwb3J0ZWRBcmd1bWVudCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICBjb25zdCBjbGFzc0xvY2F0aW9uID0gbm9kZUxvY2F0aW9uKGNvbnN0cnVjdGlvbi53aGF0LCBmaWxlbmFtZSwgc291cmNlKVxuXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7YXJndW1lbnRzOiBjb25zdHJ1Y3Rpb24uYXJndW1lbnRzLm1hcCgoYXJndW1lbnQsIGluZGV4KSA9PlxuICAgICAgICBjb252ZXJ0RXhwcmVzc2lvbihhcmd1bWVudCwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCwgZGVjbGFyYXRpb24uY29uc3RydWN0b3IucGFyYW1ldGVyc1tpbmRleF0/LnR5cGUpKSxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlJlZmVyZW5jZUNvbnN0cnVjdGlvblwiKSwgbG9jYXRpb24sXG4gICAgICByZWZlcmVuY2U6IHJlZmVyZW5jZVR5cGUoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZWNsYXJhdGlvbi5pZCksIGNsYXNzTG9jYXRpb24pfSwge2NsYXNzOiBjbGFzc0xvY2F0aW9ufSlcbiAgICB9XG4gICAgaWYgKGRlY2xhcmF0aW9uLmtpbmQgPT0gXCJFZmZlY3RSZXNvdXJjZURlY2xhcmF0aW9uXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm93bmVkIHJlc291cmNlIGNvbnN0cnVjdGlvblwiLCBub2RlTG9jYXRpb24oY29uc3RydWN0aW9uLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgY29uc3QgY29udGV4dHVhbFR5cGVBcmd1bWVudHMgPSBleHBlY3RlZFR5cGU/LmtpbmQgPT0gXCJSZWNvcmRUeXBlXCIgJiYgZXhwZWN0ZWRUeXBlLmRlY2xhcmF0aW9uSWQgPT0gZGVjbGFyYXRpb24uaWRcbiAgICAgID8gZXhwZWN0ZWRUeXBlLmFyZ3VtZW50c1xuICAgICAgOiB1bmRlZmluZWRcbiAgICBjb25zdCB2aXNpYmxlVHlwZVBhcmFtZXRlcklkcyA9IG5ldyBTZXQoWy4uLmNvbnRleHQudHlwZVBhcmFtZXRlcnM/LnZhbHVlcygpID8/IFtdXVxuICAgICAgLm1hcCgocGFyYW1ldGVyKSA9PiAvKiogQHR5cGUge3N0cmluZ30gKi8gKHBhcmFtZXRlci5pZCkpKVxuICAgIGNvbnN0IHR5cGVBcmd1bWVudHMgPSBjb250ZXh0dWFsVHlwZUFyZ3VtZW50cyAmJlxuICAgICAgIWNvbnRleHR1YWxUeXBlQXJndW1lbnRzLnNvbWUoKGFyZ3VtZW50KSA9PiB0eXBlQ29udGFpbnNBbnlWYXJpYWJsZShhcmd1bWVudCwgdmlzaWJsZVR5cGVQYXJhbWV0ZXJJZHMpKVxuICAgICAgPyBjb250ZXh0dWFsVHlwZUFyZ3VtZW50c1xuICAgICAgOiB1bmRlZmluZWRcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGFyZ3VtZW50czogY29uc3RydWN0aW9uLmFyZ3VtZW50cy5tYXAoKGFyZ3VtZW50LCBpbmRleCkgPT5cbiAgICAgICAgY29udmVydEV4cHJlc3Npb24oYXJndW1lbnQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsXG4gICAgICAgICAgaW5zdGFudGlhdGVkUmVjb3JkRmllbGRUeXBlKGRlY2xhcmF0aW9uLCB0eXBlQXJndW1lbnRzLCBpbmRleCkpKSxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlJlY29yZENvbnN0cnVjdGlvblwiKSxcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgcmVjb3JkOiByZWNvcmRUeXBlKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBub2RlTG9jYXRpb24oY29uc3RydWN0aW9uLndoYXQsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgICB0eXBlQXJndW1lbnRzKVxuICAgIH0sIHtyZWNvcmQ6IG5vZGVMb2NhdGlvbihjb25zdHJ1Y3Rpb24ud2hhdCwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcInByb3BlcnR5bG9va3VwXCIpIHtcbiAgICBjb25zdCByZWFkID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlByb3BlcnR5TG9va3VwfSAqLyAobm9kZSlcbiAgICBjb25zdCBvZmZzZXQgPSByZWFkLm9mZnNldC5raW5kID09IFwiaWRlbnRpZmllclwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLklkZW50aWZpZXJ9ICovIChyZWFkLm9mZnNldCkgOiB1bmRlZmluZWRcblxuICAgIGlmICghb2Zmc2V0IHx8IHR5cGVvZiBvZmZzZXQubmFtZSAhPSBcInN0cmluZ1wiKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJkeW5hbWljIG9yIGNvbXB1dGVkIG1lbWJlciBhY2Nlc3NcIiwgbm9kZUxvY2F0aW9uKHJlYWQub2Zmc2V0LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgaWYgKHJlYWQud2hhdC5raW5kID09IFwidmFyaWFibGVcIiAmJiAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuVmFyaWFibGV9ICovIChyZWFkLndoYXQpLm5hbWUgPT0gXCJ0aGlzXCIgJiZcbiAgICAgIGNvbnRleHQuY3VycmVudENsYXNzKSB7XG4gICAgICBjb25zdCBmaWVsZCA9IGNvbnRleHQuY3VycmVudENsYXNzLmZpZWxkcy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5uYW1lID09IG9mZnNldC5uYW1lKVxuXG4gICAgICBpZiAoIWZpZWxkKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgYHVua25vd24gcHJpdmF0ZSBmaWVsZCAnJHtvZmZzZXQubmFtZX0nYCwgbm9kZUxvY2F0aW9uKG9mZnNldCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7ZmllbGQ6IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZmllbGQuaWQpLCBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJQcml2YXRlRmllbGRSZWFkXCIpLCBsb2NhdGlvbixcbiAgICAgICAgcmVjZWl2ZXI6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjZWl2ZXJFeHByZXNzaW9ufSAqLyAoXG4gICAgICAgICAgY29udmVydEV4cHJlc3Npb24ocmVhZC53aGF0LCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSl9LCB7bWVtYmVyOiBub2RlTG9jYXRpb24ob2Zmc2V0LCBmaWxlbmFtZSwgc291cmNlKX0pXG4gICAgfVxuICAgIGNvbnN0IHJlY2VpdmVyVHlwZSA9IGtub3duRXhwcmVzc2lvblR5cGUocmVhZC53aGF0LCBjb250ZXh0KVxuICAgIGlmIChyZWNlaXZlclR5cGU/LmtpbmQgPT0gXCJSZWZlcmVuY2VUeXBlXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInByaXZhdGUgcmVmZXJlbmNlLWNsYXNzIGZpZWxkIGFjY2Vzc1wiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgcmVjZWl2ZXJSZWNvcmQgPSByZWNlaXZlclR5cGU/LmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIiA/IHJlY2VpdmVyVHlwZS52YWx1ZVR5cGUgOiByZWNlaXZlclR5cGVcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IHJlY2VpdmVyUmVjb3JkPy5raW5kID09IFwiUmVjb3JkVHlwZVwiID8gY29udGV4dC5yZWNvcmRzLmdldChyZWNlaXZlclJlY29yZC5kZWNsYXJhdGlvbklkKSA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKChkZWNsYXJhdGlvbj8udHlwZVBhcmFtZXRlcnM/Lmxlbmd0aCA/PyAwKSA+IDApIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImdlbmVyaWMgcmVjb3JkIHByb3BlcnR5IGFjY2Vzc1wiLCBub2RlTG9jYXRpb24ocmVhZC5vZmZzZXQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIH1cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBmaWVsZDogb2Zmc2V0Lm5hbWUsXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJNZW1iZXJSZWFkXCIpLFxuICAgICAgbG9jYXRpb24sXG4gICAgICByZWNlaXZlcjogY29udmVydEV4cHJlc3Npb24ocmVhZC53aGF0LCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICAgIH0sIHttZW1iZXI6IG5vZGVMb2NhdGlvbihyZWFkLm9mZnNldCwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcIm9mZnNldGxvb2t1cFwiKSB7XG4gICAgY29uc3QgbG9va3VwID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk9mZnNldExvb2t1cH0gKi8gKG5vZGUpXG5cbiAgICBpZiAoIWxvb2t1cC5vZmZzZXQpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImFwcGVuZCBvciBtaXNzaW5nIGFycmF5IGluZGV4XCIsIGxvY2F0aW9uKVxuICAgIGNvbnN0IHJlY2VpdmVyID0gbG9va3VwLndoYXQua2luZCA9PSBcInZhcmlhYmxlXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuVmFyaWFibGV9ICovIChsb29rdXAud2hhdCkgOiB1bmRlZmluZWRcbiAgICBjb25zdCByZWNlaXZlclR5cGUgPSByZWNlaXZlciAmJiB0eXBlb2YgcmVjZWl2ZXIubmFtZSA9PSBcInN0cmluZ1wiID8gY29udGV4dC5iaW5kaW5ncy5nZXQocmVjZWl2ZXIubmFtZSkgOiB1bmRlZmluZWRcbiAgICBjb25zdCBhY2Nlc3NLaW5kID0gcmVjZWl2ZXJUeXBlPy5raW5kID09IFwiTGlzdFR5cGVcIiA/IFwibGlzdFwiIDpcbiAgICAgIHJlY2VpdmVyVHlwZT8ua2luZCA9PSBcIk1hcFR5cGVcIiB8fCByZWNlaXZlclR5cGU/LmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiID8gXCJtYXBcIiA6XG4gICAgICBsb29rdXAub2Zmc2V0LmtpbmQgPT0gXCJudW1iZXJcIiA/IFwibGlzdFwiIDogbG9va3VwLm9mZnNldC5raW5kID09IFwic3RyaW5nXCIgPyBcIm1hcFwiIDogdW5kZWZpbmVkXG5cbiAgICBpZiAoYWNjZXNzS2luZCA9PSBcImxpc3RcIiAmJiBbXCJudW1iZXJcIiwgXCJzdHJpbmdcIiwgXCJ2YXJpYWJsZVwiXS5pbmNsdWRlcyhsb29rdXAub2Zmc2V0LmtpbmQpKSB7XG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICAgIGNvbGxlY3Rpb246IGNvbnZlcnRFeHByZXNzaW9uKGxvb2t1cC53aGF0LCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSxcbiAgICAgICAgaW5kZXg6IGNvbnZlcnRFeHByZXNzaW9uKGxvb2t1cC5vZmZzZXQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpLFxuICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJMaXN0SW5kZXhFeHByZXNzaW9uXCIpLFxuICAgICAgICBsb2NhdGlvbixcbiAgICAgICAgdG90YWxpdHk6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcInByb3ZlblwiKVxuICAgICAgfSwge29wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKFwiW1wiLCBsb29rdXAud2hhdC5sb2M/LmVuZC5vZmZzZXQgPz8gMCwgbG9va3VwLm9mZnNldC5sb2M/LnN0YXJ0Lm9mZnNldCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKX0pXG4gICAgfVxuICAgIGlmIChhY2Nlc3NLaW5kID09IFwibWFwXCIgJiYgW1wibnVtYmVyXCIsIFwic3RyaW5nXCIsIFwidmFyaWFibGVcIl0uaW5jbHVkZXMobG9va3VwLm9mZnNldC5raW5kKSkge1xuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgICBjb2xsZWN0aW9uOiBjb252ZXJ0RXhwcmVzc2lvbihsb29rdXAud2hhdCwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCksXG4gICAgICAgIGtleTogY29udmVydEV4cHJlc3Npb24obG9va3VwLm9mZnNldCwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCksXG4gICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIk1hcExvb2t1cEV4cHJlc3Npb25cIiksXG4gICAgICAgIGxvY2F0aW9uLFxuICAgICAgICB0b3RhbGl0eTogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwicHJvdmVuXCIpXG4gICAgICB9LCB7b3BlcmF0b3I6IHRva2VuTG9jYXRpb24oXCJbXCIsIGxvb2t1cC53aGF0LmxvYz8uZW5kLm9mZnNldCA/PyAwLCBsb29rdXAub2Zmc2V0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgICB9XG5cbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJub25saXRlcmFsIGFycmF5IGFjY2Vzc1wiLCBub2RlTG9jYXRpb24obG9va3VwLm9mZnNldCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cblxuICBpZiAobm9kZS5raW5kID09IFwidW5hcnlcIikge1xuICAgIGNvbnN0IHVuYXJ5ID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlVuYXJ5fSAqLyAobm9kZSlcblxuICAgIGlmICghW1wiIVwiLCBcIi1cIl0uaW5jbHVkZXModW5hcnkudHlwZSkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBgdW5hcnkgJHt1bmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuXG4gICAgY29uc3Qgc2VtYW50aWMgPSB3aXRoQWRhcHRlZE9wZXJhdGlvbih3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IFwiVW5hcnlFeHByZXNzaW9uXCIsXG4gICAgICBsb2NhdGlvbixcbiAgICAgIG9wZXJhbmQ6IGNvbnZlcnRFeHByZXNzaW9uKHVuYXJ5LndoYXQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpXG4gICAgfSwge1xuICAgICAgb3BlcmF0b3I6IHRva2VuTG9jYXRpb24odW5hcnkudHlwZSwgdW5hcnkubG9jPy5zdGFydC5vZmZzZXQgPz8gMCwgdW5hcnkud2hhdC5sb2M/LnN0YXJ0Lm9mZnNldCA/PyB1bmFyeS5sb2M/LmVuZC5vZmZzZXQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9KSwgdW5hcnkudHlwZSA9PSBcIiFcIiA/IFwiTm90XCIgOiBcIk5lZ2F0ZVwiKVxuXG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKHNlbWFudGljKSlcbiAgfVxuXG4gIGlmIChub2RlLmtpbmQgPT0gXCJiaW5cIikge1xuICAgIGNvbnN0IGJpbmFyeSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5CaW59ICovIChub2RlKVxuICAgIGlmIChiaW5hcnkudHlwZSA9PSBcIiE9PVwiICYmIGJpbmFyeS5sZWZ0LmtpbmQgPT0gXCJ2YXJpYWJsZVwiICYmIGJpbmFyeS5yaWdodC5raW5kID09IFwibnVsbGtleXdvcmRcIikge1xuICAgICAgY29uc3Qgb3BlcmFuZCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuSWRlbnRpZmllckV4cHJlc3Npb259ICovIChcbiAgICAgICAgY29udmVydEV4cHJlc3Npb24oYmluYXJ5LmxlZnQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIHVuZGVmaW5lZCwgdHJ1ZSlcbiAgICAgIClcblxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIk9wdGlvbmFsSXNQcmVzZW50XCIpLCBsb2NhdGlvbiwgb3BlcmFuZH0sIHtcbiAgICAgICAgb3BlcmF0b3I6IHRva2VuTG9jYXRpb24oYmluYXJ5LnR5cGUsIGJpbmFyeS5sZWZ0LmxvYz8uZW5kLm9mZnNldCA/PyAwLCBiaW5hcnkucmlnaHQubG9jPy5zdGFydC5vZmZzZXQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICAgIH0pXG4gICAgfVxuICAgIGlmIChbXCI9PVwiLCBcIiE9XCJdLmluY2x1ZGVzKGJpbmFyeS50eXBlKSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGBjb2VyY2l2ZSBlcXVhbGl0eSAke2JpbmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuICAgIGlmIChbXCJhbmRcIiwgXCJvclwiXS5pbmNsdWRlcyhiaW5hcnkudHlwZSkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBgcHJlY2VkZW5jZS1zZW5zaXRpdmUgYm9vbGVhbiAke2JpbmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuICAgIGlmICghcGhwQmluYXJ5T3BlcmF0aW9ucy5oYXMoYmluYXJ5LnR5cGUpKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgYGJpbmFyeSAke2JpbmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuXG4gICAgY29uc3Qgc2VtYW50aWMgPSB3aXRoQWRhcHRlZE9wZXJhdGlvbih7XG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJCaW5hcnlFeHByZXNzaW9uXCIpLFxuICAgICAgbGVmdDogY29udmVydEV4cHJlc3Npb24oYmluYXJ5LmxlZnQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpLFxuICAgICAgbG9jYXRpb24sXG4gICAgICByaWdodDogY29udmVydEV4cHJlc3Npb24oYmluYXJ5LnJpZ2h0LCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICAgIH0sIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCIpLkFkYXB0ZWRPcGVyYXRpb259ICovIChwaHBCaW5hcnlPcGVyYXRpb25zLmdldChiaW5hcnkudHlwZSkpKVxuXG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKHdpdGhQYXJzZXJSYW5nZXMoc2VtYW50aWMsIHtcbiAgICAgIG9wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKGJpbmFyeS50eXBlLCBiaW5hcnkubGVmdC5sb2M/LmVuZC5vZmZzZXQgPz8gMCwgYmluYXJ5LnJpZ2h0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSkpKVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcImNhbGxcIikge1xuICAgIGNvbnN0IGNhbGwgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuQ2FsbH0gKi8gKG5vZGUpXG5cbiAgICBpZiAoY2FsbC53aGF0LmtpbmQgPT0gXCJwcm9wZXJ0eWxvb2t1cFwiKSB7XG4gICAgICBjb25zdCBsb29rdXAgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuUHJvcGVydHlMb29rdXB9ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChjYWxsLndoYXQpKVxuICAgICAgY29uc3QgbWVtYmVyID0gbG9va3VwLm9mZnNldC5raW5kID09IFwiaWRlbnRpZmllclwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLklkZW50aWZpZXJ9ICovIChsb29rdXAub2Zmc2V0KSA6IHVuZGVmaW5lZFxuICAgICAgY29uc3QgcmVjZWl2ZXJUeXBlID0ga25vd25FeHByZXNzaW9uVHlwZShsb29rdXAud2hhdCwgY29udGV4dClcblxuICAgICAgaWYgKG1lbWJlciAmJiB0eXBlb2YgbWVtYmVyLm5hbWUgPT0gXCJzdHJpbmdcIiAmJiByZWNlaXZlclR5cGU/LmtpbmQgPT0gXCJSZWZlcmVuY2VUeXBlXCIpIHtcbiAgICAgICAgY29uc3QgbWV0aG9kID0gY29udGV4dC5jbGFzc2VzLmdldChyZWNlaXZlclR5cGUuZGVjbGFyYXRpb25JZCk/Lm1ldGhvZHMuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUubmFtZSA9PSBtZW1iZXIubmFtZSlcbiAgICAgICAgY29uc3QgdW5zdXBwb3J0ZWRBcmd1bWVudCA9IGNhbGwuYXJndW1lbnRzLmZpbmQoKGFyZ3VtZW50KSA9PlxuICAgICAgICAgIGFyZ3VtZW50LmtpbmQgPT0gXCJuYW1lZGFyZ3VtZW50XCIgfHwgYXJndW1lbnQua2luZCA9PSBcInZhcmlhZGljXCIgfHwgUmVmbGVjdC5nZXQoYXJndW1lbnQsIFwiYnlyZWZcIikgPT09IHRydWUpXG5cbiAgICAgICAgaWYgKHVuc3VwcG9ydGVkQXJndW1lbnQpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm5vbi1wb3NpdGlvbmFsIG1ldGhvZCBhcmd1bWVudFwiLFxuICAgICAgICAgIG5vZGVMb2NhdGlvbih1bnN1cHBvcnRlZEFyZ3VtZW50LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2FyZ3VtZW50czogY2FsbC5hcmd1bWVudHMubWFwKChhcmd1bWVudCwgaW5kZXgpID0+XG4gICAgICAgICAgY29udmVydEV4cHJlc3Npb24oYXJndW1lbnQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIG1ldGhvZD8ucGFyYW1ldGVyc1tpbmRleF0/LnR5cGUpKSxcbiAgICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiTWV0aG9kQ2FsbEV4cHJlc3Npb25cIiksIGxvY2F0aW9uLCBtZXRob2Q6IG1ldGhvZD8uaWQgPz8gbWVtYmVyLm5hbWUsXG4gICAgICAgIHJlY2VpdmVyOiBjb252ZXJ0RXhwcmVzc2lvbihsb29rdXAud2hhdCwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCl9LCB7bWVtYmVyOiBub2RlTG9jYXRpb24obWVtYmVyLCBmaWxlbmFtZSwgc291cmNlKX0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNhbGwud2hhdC5raW5kID09IFwicHJvcGVydHlsb29rdXBcIiAmJiBjYWxsLmFyZ3VtZW50cy5sZW5ndGggPT0gMCkge1xuICAgICAgY29uc3QgbG9va3VwID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlByb3BlcnR5TG9va3VwfSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAoY2FsbC53aGF0KSlcbiAgICAgIGNvbnN0IHJlY2VpdmVyID0gbG9va3VwLndoYXQua2luZCA9PSBcInZhcmlhYmxlXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuVmFyaWFibGV9ICovIChsb29rdXAud2hhdCkgOiB1bmRlZmluZWRcbiAgICAgIGNvbnN0IG1lbWJlciA9IGxvb2t1cC5vZmZzZXQua2luZCA9PSBcImlkZW50aWZpZXJcIiA/IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZGVudGlmaWVyfSAqLyAobG9va3VwLm9mZnNldCkgOiB1bmRlZmluZWRcblxuICAgICAgaWYgKHJlY2VpdmVyICYmIHR5cGVvZiByZWNlaXZlci5uYW1lID09IFwic3RyaW5nXCIgJiYgbWVtYmVyPy5uYW1lID09IFwiZ2V0TWVzc2FnZVwiICYmIGNvbnRleHQuYmluZGluZ3MuZ2V0KHJlY2VpdmVyLm5hbWUpPy5raW5kID09IFwiRXJyb3JUeXBlXCIpIHtcbiAgICAgICAgY29uc3QgcmVjZWl2ZXJMb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihyZWNlaXZlciwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICAgICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRXJyb3JNZXNzYWdlUmVhZFwiKSxcbiAgICAgICAgICBsb2NhdGlvbixcbiAgICAgICAgICByZWNlaXZlcjogd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiSWRlbnRpZmllckV4cHJlc3Npb25cIiksIGxvY2F0aW9uOiByZWNlaXZlckxvY2F0aW9uLCBuYW1lOiByZWNlaXZlci5uYW1lfSwge1xuICAgICAgICAgICAgbmFtZTogcmVjZWl2ZXJMb2NhdGlvblxuICAgICAgICAgIH0pXG4gICAgICAgIH0sIHttZW1iZXI6IG5vZGVMb2NhdGlvbihtZW1iZXIsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgICAgIH1cbiAgICAgIGlmIChtZW1iZXIgJiYgdHlwZW9mIG1lbWJlci5uYW1lID09IFwic3RyaW5nXCIgJiYga25vd25HZW5lcmljUmVjb3JkQWNjZXNzb3JUeXBlKGxvb2t1cCwgY29udGV4dCkpIHtcbiAgICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgICAgIGZpZWxkOiBtZW1iZXIubmFtZSxcbiAgICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJNZW1iZXJSZWFkXCIpLFxuICAgICAgICAgIGxvY2F0aW9uLFxuICAgICAgICAgIHJlY2VpdmVyOiBjb252ZXJ0RXhwcmVzc2lvbihsb29rdXAud2hhdCwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgICAgICAgfSwge21lbWJlcjogbm9kZUxvY2F0aW9uKG1lbWJlciwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjYWxsLndoYXQua2luZCA9PSBcIm5hbWVcIiAmJiBjYWxsLndoYXQubmFtZSA9PSBcImNvdW50XCIgJiYgY2FsbC5hcmd1bWVudHMubGVuZ3RoID09IDEpIHtcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgICAgY29sbGVjdGlvbjogY29udmVydEV4cHJlc3Npb24oY2FsbC5hcmd1bWVudHNbMF0sIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpLFxuICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJDb2xsZWN0aW9uU2l6ZUV4cHJlc3Npb25cIiksXG4gICAgICAgIGxvY2F0aW9uXG4gICAgICB9LCB7b3BlcmF0b3I6IG5vZGVMb2NhdGlvbihjYWxsLndoYXQsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgICB9XG5cbiAgICBpZiAoY2FsbC53aGF0LmtpbmQgIT0gXCJuYW1lXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImR5bmFtaWMgY2FsbFwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgY2FsbGVkTmFtZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5OYW1lfSAqLyAoY2FsbC53aGF0KVxuXG4gICAgaWYgKGNhbGxlZE5hbWUucmVzb2x1dGlvbiAhPSBcInVxblwiIHx8IGNhbGxlZE5hbWUubmFtZS5pbmNsdWRlcyhcIlxcXFxcIikpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInF1YWxpZmllZCBjYWxsXCIsIG5vZGVMb2NhdGlvbihjYWxsLndoYXQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIH1cbiAgICBjb25zdCB1bnN1cHBvcnRlZEFyZ3VtZW50ID0gY2FsbC5hcmd1bWVudHMuZmluZCgoYXJndW1lbnQpID0+XG4gICAgICBhcmd1bWVudC5raW5kID09IFwibmFtZWRhcmd1bWVudFwiIHx8IGFyZ3VtZW50LmtpbmQgPT0gXCJ2YXJpYWRpY1wiIHx8IFJlZmxlY3QuZ2V0KGFyZ3VtZW50LCBcImJ5cmVmXCIpID09PSB0cnVlKVxuXG4gICAgaWYgKHVuc3VwcG9ydGVkQXJndW1lbnQpIHtcbiAgICAgIGNvbnN0IGRldGFpbCA9IHVuc3VwcG9ydGVkQXJndW1lbnQua2luZCA9PSBcIm5hbWVkYXJndW1lbnRcIiA/IFwibmFtZWQgYXJndW1lbnRcIiA6XG4gICAgICAgIHVuc3VwcG9ydGVkQXJndW1lbnQua2luZCA9PSBcInZhcmlhZGljXCIgPyBcInVucGFja2VkIGFyZ3VtZW50XCIgOiBcImJ5LXJlZmVyZW5jZSBhcmd1bWVudFwiXG5cbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBkZXRhaWwsIG5vZGVMb2NhdGlvbih1bnN1cHBvcnRlZEFyZ3VtZW50LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG5cbiAgICBjb25zdCBjYWxsZWUgPSBjYWxsZWROYW1lLm5hbWVcblxuICAgIGNvbnN0IHNpZ25hdHVyZSA9IGNvbnRleHQuZnVuY3Rpb25zLmdldChjYWxsZWUpXG4gICAgY29uc3Qga25vd25Bcmd1bWVudHMgPSBjYWxsLmFyZ3VtZW50cy5tYXAoKGFyZ3VtZW50KSA9PiBrbm93bkNhbGxBcmd1bWVudFR5cGUoYXJndW1lbnQsIGNvbnRleHQpKVxuICAgIGNvbnN0IHBhcmFtZXRlclR5cGVzID0gc2lnbmF0dXJlID8ga25vd25DYWxsUGFyYW1ldGVyVHlwZXMoc2lnbmF0dXJlLCBrbm93bkFyZ3VtZW50cykgOiB1bmRlZmluZWRcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGFyZ3VtZW50czogY2FsbC5hcmd1bWVudHMubWFwKChhcmd1bWVudCwgaW5kZXgpID0+XG4gICAgICAgIGNvbnZlcnRFeHByZXNzaW9uKGFyZ3VtZW50LCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0LFxuICAgICAgICAgIHBhcmFtZXRlclR5cGVzPy5baW5kZXhdID8/IHNpZ25hdHVyZT8ucGFyYW1ldGVyc1tpbmRleF0/LnR5cGUsXG4gICAgICAgICAgcHJlc2VydmVzR2VuZXJpY09wdGlvbmFsRXZpZGVuY2Uoc2lnbmF0dXJlLCBpbmRleCkpKSxcbiAgICAgIGNhbGxlZSxcbiAgICAgIGtpbmQ6IFwiQ2FsbEV4cHJlc3Npb25cIixcbiAgICAgIGxvY2F0aW9uXG4gICAgfSwge2NhbGxlZTogbm9kZUxvY2F0aW9uKGNhbGwud2hhdCwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICB9XG5cbiAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIG5vZGUua2luZCwgbG9jYXRpb24pXG59XG5cbi8qKlxuICogUmVzb2x2ZXMgb25seSByZXN1bHQgdHlwZXMgZXN0YWJsaXNoZWQgYnkgZXhwbGljaXQgc2lnbmF0dXJlcyBhbmQgYmluZGluZ3MuXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuRXhwcmVzc2lvbn0gbm9kZSAtIFBhcnNlci1vd25lZCBleHByZXNzaW9uLlxuICogQHBhcmFtIHtQaHBDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZSB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yVHlwZSB8IHVuZGVmaW5lZH0gS25vd24gcmVzdWx0IHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGtub3duRXhwcmVzc2lvblR5cGUobm9kZSwgY29udGV4dCkge1xuICBpZiAobm9kZS5raW5kID09IFwidmFyaWFibGVcIikge1xuICAgIGNvbnN0IHZhcmlhYmxlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlZhcmlhYmxlfSAqLyAobm9kZSlcblxuICAgIGlmICh2YXJpYWJsZS5uYW1lID09IFwidGhpc1wiICYmIGNvbnRleHQuY3VycmVudENsYXNzPy5pZCkge1xuICAgICAgcmV0dXJuIHtkZWNsYXJhdGlvbklkOiBjb250ZXh0LmN1cnJlbnRDbGFzcy5pZCwga2luZDogXCJSZWZlcmVuY2VUeXBlXCJ9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFyaWFibGUubmFtZSA9PSBcInN0cmluZ1wiKSByZXR1cm4gY29udGV4dC5iaW5kaW5ncy5nZXQodmFyaWFibGUubmFtZSlcbiAgfVxuICBpZiAobm9kZS5raW5kID09IFwiY2FsbFwiKSB7XG4gICAgY29uc3QgY2FsbCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5DYWxsfSAqLyAobm9kZSlcbiAgICBjb25zdCBuYW1lID0gY2FsbC53aGF0LmtpbmQgPT0gXCJuYW1lXCIgJiYgdHlwZW9mIGNhbGwud2hhdC5uYW1lID09IFwic3RyaW5nXCIgPyBjYWxsLndoYXQubmFtZSA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKG5hbWUpIHtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IGNvbnRleHQuZnVuY3Rpb25zLmdldChuYW1lKVxuXG4gICAgICBpZiAoc2lnbmF0dXJlKSByZXR1cm4ga25vd25DYWxsUmV0dXJuVHlwZShzaWduYXR1cmUsIGNhbGwuYXJndW1lbnRzLm1hcCgoYXJndW1lbnQpID0+IGtub3duRXhwcmVzc2lvblR5cGUoYXJndW1lbnQsIGNvbnRleHQpKSlcbiAgICB9XG4gICAgaWYgKGNhbGwud2hhdC5raW5kID09IFwicHJvcGVydHlsb29rdXBcIiAmJiBjYWxsLmFyZ3VtZW50cy5sZW5ndGggPT0gMCkge1xuICAgICAgcmV0dXJuIGtub3duR2VuZXJpY1JlY29yZEFjY2Vzc29yVHlwZShcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlByb3BlcnR5TG9va3VwfSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAoY2FsbC53aGF0KSksIGNvbnRleHQpXG4gICAgfVxuICAgIGlmIChjYWxsLndoYXQua2luZCA9PSBcInByb3BlcnR5bG9va3VwXCIpIHtcbiAgICAgIGNvbnN0IGxvb2t1cCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Qcm9wZXJ0eUxvb2t1cH0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKGNhbGwud2hhdCkpXG4gICAgICBjb25zdCByZWNlaXZlciA9IGtub3duRXhwcmVzc2lvblR5cGUobG9va3VwLndoYXQsIGNvbnRleHQpXG4gICAgICBjb25zdCBtZW1iZXIgPSBsb29rdXAub2Zmc2V0LmtpbmQgPT0gXCJpZGVudGlmaWVyXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuSWRlbnRpZmllcn0gKi8gKGxvb2t1cC5vZmZzZXQpIDogdW5kZWZpbmVkXG5cbiAgICAgIGlmIChyZWNlaXZlcj8ua2luZCA9PSBcIlJlZmVyZW5jZVR5cGVcIiAmJiBtZW1iZXIgJiYgdHlwZW9mIG1lbWJlci5uYW1lID09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuIGNvbnRleHQuY2xhc3Nlcy5nZXQocmVjZWl2ZXIuZGVjbGFyYXRpb25JZCk/Lm1ldGhvZHMuZmluZCgobWV0aG9kKSA9PiBtZXRob2QubmFtZSA9PSBtZW1iZXIubmFtZSk/LnJldHVyblR5cGVcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKG5vZGUua2luZCA9PSBcIm9mZnNldGxvb2t1cFwiKSB7XG4gICAgY29uc3QgbG9va3VwID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk9mZnNldExvb2t1cH0gKi8gKG5vZGUpXG4gICAgY29uc3QgY29sbGVjdGlvblR5cGUgPSBrbm93bkV4cHJlc3Npb25UeXBlKGxvb2t1cC53aGF0LCBjb250ZXh0KVxuXG4gICAgaWYgKGNvbGxlY3Rpb25UeXBlPy5raW5kID09IFwiTGlzdFR5cGVcIikgcmV0dXJuIGNvbGxlY3Rpb25UeXBlLmVsZW1lbnRUeXBlXG4gICAgaWYgKGNvbGxlY3Rpb25UeXBlPy5raW5kID09IFwiTWFwVHlwZVwiIHx8IGNvbGxlY3Rpb25UeXBlPy5raW5kID09IFwiT3JkZXJlZE1hcFR5cGVcIikgcmV0dXJuIGNvbGxlY3Rpb25UeXBlLnZhbHVlVHlwZVxuICB9XG4gIGlmIChub2RlLmtpbmQgPT0gXCJuZXdcIikge1xuICAgIGNvbnN0IGNvbnN0cnVjdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5OZXd9ICovIChub2RlKVxuICAgIGNvbnN0IG5hbWUgPSBjb25zdHJ1Y3Rpb24ud2hhdC5raW5kID09IFwibmFtZVwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5hbWV9ICovIChjb25zdHJ1Y3Rpb24ud2hhdCkgOiB1bmRlZmluZWRcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IG5hbWUgJiYgdHlwZW9mIG5hbWUubmFtZSA9PSBcInN0cmluZ1wiID8gY29udGV4dC5yZWNvcmROYW1lcy5nZXQobmFtZS5uYW1lKSA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKGRlY2xhcmF0aW9uPy5pZCkgcmV0dXJuIGRlY2xhcmF0aW9uLmtpbmQgPT0gXCJDbGFzc0RlY2xhcmF0aW9uXCJcbiAgICAgID8ge2RlY2xhcmF0aW9uSWQ6IGRlY2xhcmF0aW9uLmlkLCBraW5kOiBcIlJlZmVyZW5jZVR5cGVcIn1cbiAgICAgIDoge2RlY2xhcmF0aW9uSWQ6IGRlY2xhcmF0aW9uLmlkLCBraW5kOiBcIlJlY29yZFR5cGVcIn1cbiAgfVxuICBpZiAobm9kZS5raW5kID09IFwicHJvcGVydHlsb29rdXBcIikge1xuICAgIGNvbnN0IHJlYWQgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuUHJvcGVydHlMb29rdXB9ICovIChub2RlKVxuICAgIGNvbnN0IHJlY2VpdmVyID0ga25vd25FeHByZXNzaW9uVHlwZShyZWFkLndoYXQsIGNvbnRleHQpXG5cbiAgICBpZiAocmVhZC53aGF0LmtpbmQgPT0gXCJ2YXJpYWJsZVwiICYmIC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5WYXJpYWJsZX0gKi8gKHJlYWQud2hhdCkubmFtZSA9PSBcInRoaXNcIiAmJlxuICAgICAgY29udGV4dC5jdXJyZW50Q2xhc3MpIHtcbiAgICAgIGNvbnN0IG9mZnNldCA9IHJlYWQub2Zmc2V0LmtpbmQgPT0gXCJpZGVudGlmaWVyXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuSWRlbnRpZmllcn0gKi8gKHJlYWQub2Zmc2V0KSA6IHVuZGVmaW5lZFxuXG4gICAgICByZXR1cm4gY29udGV4dC5jdXJyZW50Q2xhc3MuZmllbGRzLmZpbmQoKGZpZWxkKSA9PiBmaWVsZC5uYW1lID09IG9mZnNldD8ubmFtZSk/LnR5cGVcbiAgICB9XG5cbiAgICBpZiAocmVjZWl2ZXI/LmtpbmQgIT0gXCJSZWNvcmRUeXBlXCIpIHJldHVybiB1bmRlZmluZWRcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGNvbnRleHQucmVjb3Jkcy5nZXQocmVjZWl2ZXIuZGVjbGFyYXRpb25JZClcbiAgICBjb25zdCBvZmZzZXQgPSByZWFkLm9mZnNldC5raW5kID09IFwiaWRlbnRpZmllclwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLklkZW50aWZpZXJ9ICovIChyZWFkLm9mZnNldCkgOiB1bmRlZmluZWRcblxuICAgIGNvbnN0IG1lbWJlck5hbWUgPSBvZmZzZXQgJiYgdHlwZW9mIG9mZnNldC5uYW1lID09IFwic3RyaW5nXCIgPyBvZmZzZXQubmFtZSA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKG1lbWJlck5hbWUgJiYgZGVjbGFyYXRpb24pIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gZGVjbGFyYXRpb24uZmllbGRzLmZpbmRJbmRleCgoZmllbGQpID0+IGZpZWxkLm5hbWUgPT0gbWVtYmVyTmFtZSlcblxuICAgICAgcmV0dXJuIGluc3RhbnRpYXRlZFJlY29yZEZpZWxkVHlwZShkZWNsYXJhdGlvbiwgcmVjZWl2ZXIuYXJndW1lbnRzLCBpbmRleClcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogUmVzb2x2ZXMgZXhhY3QgcGFyc2VyLWtub3duIGFyZ3VtZW50IGV2aWRlbmNlIHdpdGhvdXQgY2hhbmdpbmcgdGhlIGVzdGFibGlzaGVkXG4gKiBleHByZXNzaW9uLXJlc3VsdCBjbGFzc2lmaWVyIHVzZWQgZm9yIG9wdGlvbmFsIGNvbnZlcnNpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuRXhwcmVzc2lvbn0gbm9kZSAtIFBhcnNlci1vd25lZCBjYWxsIGFyZ3VtZW50LlxuICogQHBhcmFtIHtQaHBDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZSB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yVHlwZSB8IHVuZGVmaW5lZH0gS25vd24gYXJndW1lbnQgdHlwZS5cbiAqL1xuZnVuY3Rpb24ga25vd25DYWxsQXJndW1lbnRUeXBlKG5vZGUsIGNvbnRleHQpIHtcbiAgY29uc3Qga25vd24gPSBrbm93bkV4cHJlc3Npb25UeXBlKG5vZGUsIGNvbnRleHQpXG5cbiAgaWYgKGtub3duKSByZXR1cm4ga25vd25cbiAgaWYgKG5vZGUua2luZCA9PSBcIm51bWJlclwiICYmIE51bWJlci5pc1NhZmVJbnRlZ2VyKE51bWJlcigvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTnVtYmVyfSAqLyAobm9kZSkudmFsdWUpKSkge1xuICAgIHJldHVybiBzY2FsYXJUeXBlKFwiaW50ZWdlclwiKVxuICB9XG4gIGlmIChub2RlLmtpbmQgPT0gXCJib29sZWFuXCIgJiYgdHlwZW9mIC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Cb29sZWFufSAqLyAobm9kZSkudmFsdWUgPT0gXCJib29sZWFuXCIpIHtcbiAgICByZXR1cm4gc2NhbGFyVHlwZShcImJvb2xlYW5cIilcbiAgfVxuICBpZiAobm9kZS5raW5kID09IFwic3RyaW5nXCIgJiYgdHlwZW9mIC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5TdHJpbmd9ICovIChub2RlKS52YWx1ZSA9PSBcInN0cmluZ1wiICYmXG4gICAgaGFzT25seVVuaWNvZGVTY2FsYXJzKC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5TdHJpbmd9ICovIChub2RlKS52YWx1ZSkpIHtcbiAgICByZXR1cm4gc2NhbGFyVHlwZShcInN0cmluZ1wiKVxuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIFJlc29sdmVzIFBIUCdzIGV4YWN0IHplcm8tYXJndW1lbnQgYWNjZXNzb3IgY2FycmllciBhZ2FpbnN0IGl0cyByZWNlaXZlcidzXG4gKiBnZW5lcmljIHJlY29yZCBkZWNsYXJhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Qcm9wZXJ0eUxvb2t1cH0gbG9va3VwIC0gUGFyc2VyLW93bmVkIG1ldGhvZCBsb29rdXAuXG4gKiBAcGFyYW0ge1BocENvbnZlcnNpb25Db250ZXh0fSBjb250ZXh0IC0gVHlwZWQgY29udmVyc2lvbiBjb250ZXh0LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljVmFsdWVUeXBlIHwgdW5kZWZpbmVkfSBJbnN0YW50aWF0ZWQgZmllbGQgdHlwZS5cbiAqL1xuZnVuY3Rpb24ga25vd25HZW5lcmljUmVjb3JkQWNjZXNzb3JUeXBlKGxvb2t1cCwgY29udGV4dCkge1xuICBjb25zdCByZWNlaXZlciA9IGtub3duRXhwcmVzc2lvblR5cGUobG9va3VwLndoYXQsIGNvbnRleHQpXG4gIGNvbnN0IHJlY2VpdmVyUmVjb3JkID0gcmVjZWl2ZXI/LmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIiA/IHJlY2VpdmVyLnZhbHVlVHlwZSA6IHJlY2VpdmVyXG5cbiAgaWYgKHJlY2VpdmVyUmVjb3JkPy5raW5kICE9IFwiUmVjb3JkVHlwZVwiKSByZXR1cm4gdW5kZWZpbmVkXG4gIGNvbnN0IGRlY2xhcmF0aW9uID0gY29udGV4dC5yZWNvcmRzLmdldChyZWNlaXZlclJlY29yZC5kZWNsYXJhdGlvbklkKVxuICBjb25zdCBtZW1iZXIgPSBsb29rdXAub2Zmc2V0LmtpbmQgPT0gXCJpZGVudGlmaWVyXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuSWRlbnRpZmllcn0gKi8gKGxvb2t1cC5vZmZzZXQpIDogdW5kZWZpbmVkXG4gIGNvbnN0IGluZGV4ID0gbWVtYmVyICYmIHR5cGVvZiBtZW1iZXIubmFtZSA9PSBcInN0cmluZ1wiXG4gICAgPyBkZWNsYXJhdGlvbj8uZmllbGRzLmZpbmRJbmRleCgoZmllbGQpID0+IGZpZWxkLm5hbWUgPT0gbWVtYmVyLm5hbWUpID8/IC0xXG4gICAgOiAtMVxuXG4gIGlmICghZGVjbGFyYXRpb24gfHwgKGRlY2xhcmF0aW9uLnR5cGVQYXJhbWV0ZXJzPy5sZW5ndGggPz8gMCkgPT0gMCB8fCBpbmRleCA8IDApIHJldHVybiB1bmRlZmluZWRcblxuICByZXR1cm4gaW5zdGFudGlhdGVkUmVjb3JkRmllbGRUeXBlKGRlY2xhcmF0aW9uLCByZWNlaXZlclJlY29yZC5hcmd1bWVudHMsIGluZGV4KVxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBleHBsaWNpdCBQSFAgcmV0dXJuLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGV9IG5vZGUgLSBQSFAgbm9kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge1BocENvbnZlcnNpb25Db250ZXh0fSBjb250ZXh0IC0gVHlwZWQgY29udmVyc2lvbiBjb250ZXh0LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJldHVyblN0YXRlbWVudH0gU2VtYW50aWMgcmV0dXJuLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UmV0dXJuKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS5raW5kICE9IFwicmV0dXJuXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBub2RlLmtpbmQsIGxvY2F0aW9uKVxuXG4gIGNvbnN0IHJldHVybk5vZGUgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuUmV0dXJufSAqLyAobm9kZSlcbiAgY29uc3QgZXhwZWN0ZWRUeXBlID0gY29udGV4dC5yZXR1cm5UeXBlPy5raW5kID09IFwiVHlwZVJlZmVyZW5jZVwiICYmIGNvbnRleHQucmV0dXJuVHlwZS5uYW1lID09IFwidm9pZFwiXG4gICAgPyB1bmRlZmluZWRcbiAgICA6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGUgfCB1bmRlZmluZWR9ICovIChjb250ZXh0LnJldHVyblR5cGUpXG5cbiAgcmV0dXJuIHtcbiAgICAuLi4ocmV0dXJuTm9kZS5leHByID8ge2V4cHJlc3Npb246IGNvbnZlcnRFeHByZXNzaW9uKHJldHVybk5vZGUuZXhwciwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCwgZXhwZWN0ZWRUeXBlKX0gOiB7fSksXG4gICAga2luZDogXCJSZXR1cm5TdGF0ZW1lbnRcIixcbiAgICBsb2NhdGlvblxuICB9XG59XG5cbi8qKlxuICogUmVhZHMgb25lIGV4YWN0IFBIUCBsb2NhbCBgQHZhcmAgY2FycmllciBhbmQgaW1tdXRhYmlsaXR5IG1hcmtlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlfSBub2RlIC0gQXNzaWdubWVudC1vd25pbmcgc3RhdGVtZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBMb2NhbCBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IHJlY29yZE5hbWVzIC0gTm9taW5hbCBkZWNsYXJhdGlvbnMgYnkgc291cmNlIG5hbWUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVQYXJhbWV0ZXI+fSBbdHlwZVBhcmFtZXRlcnNdIC0gRGVjbGFyYXRpb24tc2NvcGVkIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyB7e2ltbXV0YWJsZTogYm9vbGVhbiwgdHlwZTogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9IHwgdW5kZWZpbmVkfSBNZXRhZGF0YSB3aGVuIHByZXNlbnQuXG4gKi9cbmZ1bmN0aW9uIGxvY2FsTWV0YWRhdGEobm9kZSwgbmFtZSwgZmlsZW5hbWUsIHNvdXJjZSwgcmVjb3JkTmFtZXMsIHR5cGVQYXJhbWV0ZXJzID0gbmV3IE1hcCgpKSB7XG4gIGNvbnN0IGNvbW1lbnRzID0gbm9kZS5sZWFkaW5nQ29tbWVudHMgPz8gW11cbiAgY29uc3QgY29tbWVudCA9IGNvbW1lbnRzLmF0KC0xKVxuXG4gIGlmICghY29tbWVudCB8fCBjb21tZW50LmtpbmQgIT0gXCJjb21tZW50YmxvY2tcIiB8fCAhY29tbWVudC5sb2MgfHwgIW5vZGUubG9jKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgY29uc3QgZ2FwID0gc291cmNlLnNsaWNlKGNvbW1lbnQubG9jLmVuZC5vZmZzZXQsIG5vZGUubG9jLnN0YXJ0Lm9mZnNldClcblxuICBpZiAoIS9eXFxzKiQvdS50ZXN0KGdhcCkgfHwgKGdhcC5tYXRjaCgvXFxuL2d1KT8ubGVuZ3RoID8/IDApID4gMSkgcmV0dXJuIHVuZGVmaW5lZFxuXG4gIGNvbnN0IGJsb2NrID0gcGFyc2VDb21tZW50KGNvbW1lbnQudmFsdWUpWzBdXG4gIGNvbnN0IHRhZ3MgPSBibG9jaz8udGFncyA/PyBbXVxuICBjb25zdCB2YXJpYWJsZXMgPSB0YWdzLmZpbHRlcigodGFnKSA9PiB0YWcudGFnID09IFwidmFyXCIpXG4gIGNvbnN0IGltbXV0YWJsZSA9IHRhZ3MuZmlsdGVyKCh0YWcpID0+IHRhZy50YWcgPT0gXCJzZW1hbnRpZm9sZC1pbW11dGFibGVcIilcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAodmFyaWFibGVzLmxlbmd0aCA9PSAwICYmIGltbXV0YWJsZS5sZW5ndGggPT0gMCkgcmV0dXJuIHVuZGVmaW5lZFxuXG4gIGNvbnN0IGV4YWN0VmFyaWFibGUgPSB2YXJpYWJsZXMubGVuZ3RoID09IDEgJiYgdmFyaWFibGVzWzBdLnR5cGUgPT0gXCJcIiAmJiB2YXJpYWJsZXNbMF0uZGVzY3JpcHRpb24gPT0gYCQke25hbWV9YFxuICBjb25zdCBleGFjdEltbXV0YWJsZSA9IGltbXV0YWJsZS5sZW5ndGggPD0gMSAmJiBpbW11dGFibGUuZXZlcnkoKHRhZykgPT4gdGFnLm5hbWUgPT0gXCJcIiAmJiB0YWcudHlwZSA9PSBcIlwiICYmIHRhZy5kZXNjcmlwdGlvbiA9PSBcIlwiKVxuICBjb25zdCBrbm93blRhZ3MgPSB0YWdzLmV2ZXJ5KCh0YWcpID0+IHRhZy50YWcgPT0gXCJ2YXJcIiB8fCB0YWcudGFnID09IFwic2VtYW50aWZvbGQtaW1tdXRhYmxlXCIpXG5cbiAgaWYgKCFleGFjdFZhcmlhYmxlIHx8ICFleGFjdEltbXV0YWJsZSB8fCAha25vd25UYWdzKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibWFsZm9ybWVkIGxvY2FsIHR5cGUgbWV0YWRhdGFcIiwgbG9jYXRpb24pXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGltbXV0YWJsZTogaW1tdXRhYmxlLmxlbmd0aCA9PSAxLFxuICAgIHR5cGU6IGRvY3VtZW50ZWRWYWx1ZVR5cGUoe1xuICAgICAgbGFuZ3VhZ2U6IFwicGhwXCIsXG4gICAgICBsb2NhdGlvbjogY29tbWVudFRhZ0xvY2F0aW9uKGNvbW1lbnQsIHZhcmlhYmxlc1swXSwgXCJuYW1lXCIsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgb3duZXJMb2NhdGlvbjogbG9jYXRpb24sXG4gICAgICByZWNvcmRzOiByZWNvcmROYW1lcyxcbiAgICAgIHNvdXJjZSxcbiAgICAgIHNvdXJjZVR5cGU6IHZhcmlhYmxlc1swXS5uYW1lLFxuICAgICAgc3ViamVjdDogYExvY2FsICcke25hbWV9J2AsXG4gICAgICB0eXBlUGFyYW1ldGVyc1xuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgUEhQIGxvY2FsIGRlY2xhcmF0aW9uIG9yIGFzc2lnbm1lbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuTm9kZX0gbm9kZSAtIFBIUCBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtQaHBDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Mb2NhbFN0YXRlbWVudCB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlByaXZhdGVGaWVsZFdyaXRlU3RhdGVtZW50fSBTZW1hbnRpYyBsb2NhbCBvciBwcml2YXRlLWZpZWxkIHN0YXRlbWVudC5cbiAqL1xuZnVuY3Rpb24gY29udmVydExvY2FsU3RhdGVtZW50KG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS5raW5kICE9IFwiZXhwcmVzc2lvbnN0YXRlbWVudFwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgbm9kZS5raW5kLCBsb2NhdGlvbilcblxuICBjb25zdCBleHByZXNzaW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkV4cHJlc3Npb25TdGF0ZW1lbnR9ICovIChub2RlKS5leHByZXNzaW9uXG5cbiAgaWYgKGV4cHJlc3Npb24ua2luZCAhPSBcImFzc2lnblwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgZXhwcmVzc2lvbi5raW5kLCBub2RlTG9jYXRpb24oZXhwcmVzc2lvbiwgZmlsZW5hbWUsIHNvdXJjZSkpXG5cbiAgY29uc3QgYXNzaWdubWVudCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Bc3NpZ259ICovIChleHByZXNzaW9uKVxuXG4gIGlmIChhc3NpZ25tZW50Lm9wZXJhdG9yICE9IFwiPVwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgYGFzc2lnbm1lbnQgJHthc3NpZ25tZW50Lm9wZXJhdG9yfWAsIGxvY2F0aW9uKVxuICBpZiAoYXNzaWdubWVudC5sZWZ0LmtpbmQgPT0gXCJwcm9wZXJ0eWxvb2t1cFwiICYmIGNvbnRleHQuY3VycmVudENsYXNzKSB7XG4gICAgY29uc3QgbG9va3VwID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlByb3BlcnR5TG9va3VwfSAqLyAoYXNzaWdubWVudC5sZWZ0KVxuICAgIGNvbnN0IHJlY2VpdmVyID0gbG9va3VwLndoYXQua2luZCA9PSBcInZhcmlhYmxlXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuVmFyaWFibGV9ICovIChsb29rdXAud2hhdCkgOiB1bmRlZmluZWRcbiAgICBjb25zdCBtZW1iZXIgPSBsb29rdXAub2Zmc2V0LmtpbmQgPT0gXCJpZGVudGlmaWVyXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuSWRlbnRpZmllcn0gKi8gKGxvb2t1cC5vZmZzZXQpIDogdW5kZWZpbmVkXG4gICAgY29uc3QgZmllbGQgPSByZWNlaXZlcj8ubmFtZSA9PSBcInRoaXNcIiAmJiBtZW1iZXIgJiYgdHlwZW9mIG1lbWJlci5uYW1lID09IFwic3RyaW5nXCJcbiAgICAgID8gY29udGV4dC5jdXJyZW50Q2xhc3MuZmllbGRzLmZpbmQoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLm5hbWUgPT0gbWVtYmVyLm5hbWUpXG4gICAgICA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKCFmaWVsZCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwicHJpdmF0ZSBmaWVsZCB3cml0ZSBvdXRzaWRlIHRoZSBkZWNsYXJpbmcgcmVjZWl2ZXJcIiwgbm9kZUxvY2F0aW9uKGFzc2lnbm1lbnQubGVmdCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2V4cHJlc3Npb246IGNvbnZlcnRFeHByZXNzaW9uKGFzc2lnbm1lbnQucmlnaHQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIGZpZWxkLnR5cGUpLFxuICAgICAgZmllbGQ6IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZmllbGQuaWQpLCBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJQcml2YXRlRmllbGRXcml0ZVN0YXRlbWVudFwiKSwgbG9jYXRpb24sXG4gICAgICByZWNlaXZlcjogLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNlaXZlckV4cHJlc3Npb259ICovIChcbiAgICAgICAgY29udmVydEV4cHJlc3Npb24obG9va3VwLndoYXQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpKX0sXG4gICAge21lbWJlcjogbm9kZUxvY2F0aW9uKC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZGVudGlmaWVyfSAqLyAobWVtYmVyKSwgZmlsZW5hbWUsIHNvdXJjZSksIG9wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKFwiPVwiLCBhc3NpZ25tZW50LmxlZnQubG9jPy5lbmQub2Zmc2V0ID8/IDAsXG4gICAgICBhc3NpZ25tZW50LnJpZ2h0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgfVxuICBpZiAoYXNzaWdubWVudC5sZWZ0LmtpbmQgIT0gXCJ2YXJpYWJsZVwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgYXNzaWdubWVudC5sZWZ0LmtpbmQsIG5vZGVMb2NhdGlvbihhc3NpZ25tZW50LmxlZnQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICBpZiAoYXNzaWdubWVudC5yaWdodC5raW5kID09IFwidGhyb3dcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInRocm93IGV4cHJlc3Npb24gaW4gYSB2YWx1ZSBjb250ZXh0XCIsIG5vZGVMb2NhdGlvbihhc3NpZ25tZW50LnJpZ2h0LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIGNvbnN0IHZhcmlhYmxlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlZhcmlhYmxlfSAqLyAoYXNzaWdubWVudC5sZWZ0KVxuICBjb25zdCB0YXJnZXRMb2NhdGlvbiA9IG5vZGVMb2NhdGlvbih2YXJpYWJsZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAodHlwZW9mIHZhcmlhYmxlLm5hbWUgIT0gXCJzdHJpbmdcIiB8fCB2YXJpYWJsZS5jdXJseSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZHluYW1pYyB2YXJpYWJsZVwiLCB0YXJnZXRMb2NhdGlvbilcblxuICBjb25zdCBtZXRhZGF0YSA9IGxvY2FsTWV0YWRhdGEobm9kZSwgdmFyaWFibGUubmFtZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dC5yZWNvcmROYW1lcywgY29udGV4dC50eXBlUGFyYW1ldGVycylcblxuICBpZiAobWV0YWRhdGEpIHtcbiAgICBsZXQgZGVjbGFyZWRUeXBlID0gbWV0YWRhdGEudHlwZVxuICAgIGxldCBvcmRlcmVkID0gZmFsc2VcblxuICAgIGlmIChkZWNsYXJlZFR5cGUua2luZCA9PSBcIk1hcFR5cGVcIiAmJiBjb250ZXh0Lm9yZGVyZWRNYXBEZWNsYXJhdGlvbnM/Lmhhcyhhc3NpZ25tZW50KSAmJiBhc3NpZ25tZW50LnJpZ2h0LmtpbmQgPT0gXCJhcnJheVwiKSB7XG4gICAgICBkZWNsYXJlZFR5cGUgPSBvcmRlcmVkTWFwVHlwZUZyb21NYXAoZGVjbGFyZWRUeXBlLCBsb2NhdGlvbilcbiAgICAgIG9yZGVyZWQgPSB0cnVlXG4gICAgfVxuICAgIGNvbnN0IGluaXRpYWxpemVyID0gY29udmVydEV4cHJlc3Npb24oYXNzaWdubWVudC5yaWdodCwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCwgZGVjbGFyZWRUeXBlKVxuXG4gICAgY29udGV4dC5iaW5kaW5ncy5zZXQodmFyaWFibGUubmFtZSwgZGVjbGFyZWRUeXBlKVxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGluaXRpYWxpemVyLFxuICAgICAga2luZDogXCJMb2NhbERlY2xhcmF0aW9uXCIsXG4gICAgICBsb2NhdGlvbixcbiAgICAgIG11dGFibGU6IG9yZGVyZWQgPyBmYWxzZSA6ICFtZXRhZGF0YS5pbW11dGFibGUsXG4gICAgICBuYW1lOiB2YXJpYWJsZS5uYW1lLFxuICAgICAgdHlwZTogZGVjbGFyZWRUeXBlXG4gICAgfSwge1xuICAgICAgbmFtZTogdGFyZ2V0TG9jYXRpb24sXG4gICAgICBvcGVyYXRvcjogdG9rZW5Mb2NhdGlvbihcIj1cIiwgYXNzaWdubWVudC5sZWZ0LmxvYz8uZW5kLm9mZnNldCA/PyAwLCBhc3NpZ25tZW50LnJpZ2h0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSlcbiAgfVxuXG4gIGNvbnN0IGluZmVycmVkVHlwZSA9IGtub3duRXhwcmVzc2lvblR5cGUoYXNzaWdubWVudC5yaWdodCwgY29udGV4dClcblxuICBpZiAoaW5mZXJyZWRUeXBlPy5raW5kID09IFwiUmVjb3JkVHlwZVwiIHx8IGluZmVycmVkVHlwZT8ua2luZCA9PSBcIlJlZmVyZW5jZVR5cGVcIiB8fFxuICAgIGluZmVycmVkVHlwZT8ua2luZCA9PSBcIk93bmVkUmVzb3VyY2VUeXBlXCIpIHtcbiAgICBjb25zdCBpbml0aWFsaXplciA9IGNvbnZlcnRFeHByZXNzaW9uKGFzc2lnbm1lbnQucmlnaHQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIGluZmVycmVkVHlwZSlcblxuICAgIGNvbnRleHQuYmluZGluZ3Muc2V0KHZhcmlhYmxlLm5hbWUsIGluZmVycmVkVHlwZSlcbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBpbml0aWFsaXplcixcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkxvY2FsRGVjbGFyYXRpb25cIiksXG4gICAgICBsb2NhdGlvbixcbiAgICAgIG11dGFibGU6IGZhbHNlLFxuICAgICAgbmFtZTogdmFyaWFibGUubmFtZSxcbiAgICAgIHR5cGU6IGluZmVycmVkVHlwZVxuICAgIH0sIHtcbiAgICAgIG5hbWU6IHRhcmdldExvY2F0aW9uLFxuICAgICAgb3BlcmF0b3I6IHRva2VuTG9jYXRpb24oXCI9XCIsIGFzc2lnbm1lbnQubGVmdC5sb2M/LmVuZC5vZmZzZXQgPz8gMCwgYXNzaWdubWVudC5yaWdodC5sb2M/LnN0YXJ0Lm9mZnNldCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0pXG4gIH1cblxuICBjb25zdCBiaW5kaW5nVHlwZSA9IGNvbnRleHQuYmluZGluZ3MuZ2V0KHZhcmlhYmxlLm5hbWUpXG5cbiAgaWYgKCFiaW5kaW5nVHlwZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwicGhwXCIsIGBMb2NhbCAnJHt2YXJpYWJsZS5uYW1lfSdgLCBsb2NhdGlvbilcblxuICBjb25zdCB0YXJnZXQgPSB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb246IHRhcmdldExvY2F0aW9uLCBuYW1lOiB2YXJpYWJsZS5uYW1lfSwge1xuICAgIG5hbWU6IHRhcmdldExvY2F0aW9uXG4gIH0pXG4gIGNvbnN0IHZhbHVlID0gY29udmVydEV4cHJlc3Npb24oYXNzaWdubWVudC5yaWdodCwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCxcbiAgICBiaW5kaW5nVHlwZS5raW5kID09IFwiRXJyb3JUeXBlXCIgPyB1bmRlZmluZWQgOiBiaW5kaW5nVHlwZSlcblxuICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgZXhwcmVzc2lvbjogdmFsdWUsXG4gICAga2luZDogXCJBc3NpZ25tZW50U3RhdGVtZW50XCIsXG4gICAgbG9jYXRpb24sXG4gICAgdGFyZ2V0XG4gIH0sIHtcbiAgICBvcGVyYXRvcjogdG9rZW5Mb2NhdGlvbihcIj1cIiwgYXNzaWdubWVudC5sZWZ0LmxvYz8uZW5kLm9mZnNldCA/PyAwLCBhc3NpZ25tZW50LnJpZ2h0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIH0pXG59XG5cbi8qKlxuICogQ29udmVydHMgb25lIGV4aGF1c3RpdmUgUEhQIHN0YXRlbWVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlfSBub2RlIC0gUEhQIHN0YXRlbWVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge1BocENvbnZlcnNpb25Db250ZXh0fSBjb250ZXh0IC0gVHlwZWQgY29udmVyc2lvbiBjb250ZXh0LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0YXRlbWVudH0gU2VtYW50aWMgc3RhdGVtZW50LlxuICovXG5mdW5jdGlvbiBjb252ZXJ0U3RhdGVtZW50KG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpIHtcbiAgaWYgKG5vZGUua2luZCA9PSBcInJldHVyblwiKSByZXR1cm4gY29udmVydFJldHVybihub2RlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICBpZiAobm9kZS5raW5kID09IFwiaWZcIikgcmV0dXJuIGNvbnZlcnRJZigvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuSWZ9ICovIChub2RlKSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgaWYgKG5vZGUua2luZCA9PSBcInRocm93XCIpIHJldHVybiBjb252ZXJ0UGhwUmFpc2Uobm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgaWYgKG5vZGUua2luZCA9PSBcInRyeVwiKSByZXR1cm4gY29udmVydFBocFRyeShub2RlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICBpZiAobm9kZS5raW5kID09IFwid2hpbGVcIikgcmV0dXJuIGNvbnZlcnRXaGlsZSgvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuV2hpbGV9ICovIChub2RlKSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgaWYgKG5vZGUua2luZCA9PSBcImZvcmVhY2hcIikgcmV0dXJuIGNvbnZlcnRGb3JFYWNoKC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Gb3JlYWNofSAqLyAobm9kZSksIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpXG4gIGlmIChub2RlLmtpbmQgPT0gXCJicmVha1wiIHx8IG5vZGUua2luZCA9PSBcImNvbnRpbnVlXCIpIHtcbiAgICBjb25zdCBjb250cm9sID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkJyZWFrIHwgaW1wb3J0KFwicGhwLXBhcnNlclwiKS5Db250aW51ZX0gKi8gKG5vZGUpXG5cbiAgICBpZiAoY29udHJvbC5sZXZlbCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGAke25vZGUua2luZH0gbGV2ZWxgLCBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgY29uc3QgbG9jYXRpb24gPSB0b2tlbkxvY2F0aW9uKG5vZGUua2luZCwgbm9kZS5sb2M/LnN0YXJ0Lm9mZnNldCA/PyAwLCBub2RlLmxvYz8uZW5kLm9mZnNldCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAga2luZDogLyoqIEB0eXBlIHtcIkJyZWFrU3RhdGVtZW50XCIgfCBcIkNvbnRpbnVlU3RhdGVtZW50XCJ9ICovIChub2RlLmtpbmQgPT0gXCJicmVha1wiID8gXCJCcmVha1N0YXRlbWVudFwiIDogXCJDb250aW51ZVN0YXRlbWVudFwiKSxcbiAgICAgIGxvY2F0aW9uXG4gICAgfSwge2tleXdvcmQ6IGxvY2F0aW9ufSlcbiAgfVxuICBpZiAobm9kZS5raW5kID09IFwiZWNob1wiKSByZXR1cm4gY29udmVydFByaW50KC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5FY2hvfSAqLyAobm9kZSksIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpXG4gIGlmIChub2RlLmtpbmQgPT0gXCJleHByZXNzaW9uc3RhdGVtZW50XCIpIHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkV4cHJlc3Npb25TdGF0ZW1lbnR9ICovIChub2RlKS5leHByZXNzaW9uXG5cbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiY2FsbFwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBleHByZXNzaW9uOiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNhbGxFeHByZXNzaW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuTWV0aG9kQ2FsbEV4cHJlc3Npb259ICovIChcbiAgICAgICAgICBjb252ZXJ0RXhwcmVzc2lvbihleHByZXNzaW9uLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICAgICAgICApLFxuICAgICAgICBraW5kOiBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIixcbiAgICAgICAgbG9jYXRpb246IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjb252ZXJ0TG9jYWxTdGF0ZW1lbnQobm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgfVxuXG4gIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBub2RlLmtpbmQsIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBleGFjdCBgdGhyb3cgbmV3IERlY2xhcmVkRXJyb3IobWVzc2FnZSlgLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGV9IG5vZGUgLSBQSFAgdGhyb3cgbm9kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge1BocENvbnZlcnNpb25Db250ZXh0fSBjb250ZXh0IC0gVHlwZWQgbGV4aWNhbCBjb250ZXh0LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJhaXNlU3RhdGVtZW50fSBTZW1hbnRpYyByYWlzZS5cbiAqL1xuZnVuY3Rpb24gY29udmVydFBocFJhaXNlKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgY29uc3RydWN0aW9uID0gUmVmbGVjdC5nZXQobm9kZSwgXCJ3aGF0XCIpXG5cbiAgaWYgKCFjb25zdHJ1Y3Rpb24gfHwgY29uc3RydWN0aW9uLmtpbmQgIT0gXCJuZXdcIiB8fCBjb25zdHJ1Y3Rpb24ud2hhdD8ua2luZCAhPSBcIm5hbWVcIiB8fFxuICAgIGNvbnN0cnVjdGlvbi53aGF0LnJlc29sdXRpb24gIT0gXCJ1cW5cIiB8fCAhY29udGV4dC5lcnJvck5hbWVzLmhhcyhjb25zdHJ1Y3Rpb24ud2hhdC5uYW1lKSB8fFxuICAgICFBcnJheS5pc0FycmF5KGNvbnN0cnVjdGlvbi5hcmd1bWVudHMpIHx8IGNvbnN0cnVjdGlvbi5hcmd1bWVudHMubGVuZ3RoICE9IDEgfHxcbiAgICBjb25zdHJ1Y3Rpb24uYXJndW1lbnRzWzBdLmtpbmQgPT0gXCJuYW1lZGFyZ3VtZW50XCIgfHwgY29uc3RydWN0aW9uLmFyZ3VtZW50c1swXS5raW5kID09IFwidmFyaWFkaWNcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInRocm93IG90aGVyIHRoYW4gZXhhY3QgZGVjbGFyZWQgZXJyb3IgY29uc3RydWN0aW9uXCIsIGxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IGRlY2xhcmF0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9ufSAqLyAoY29udGV4dC5lcnJvck5hbWVzLmdldChjb25zdHJ1Y3Rpb24ud2hhdC5uYW1lKSlcbiAgY29uc3QgdHlwZUxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKGNvbnN0cnVjdGlvbi53aGF0LCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICBlcnJvcjogd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBlcnJvcjogd2l0aFBhcnNlclJhbmdlcyh7ZGVjbGFyYXRpb25JZDogLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZWNsYXJhdGlvbi5pZCksIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkVycm9yVHlwZVwiKX0sIHt0eXBlOiB0eXBlTG9jYXRpb259KSxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkVycm9yQ29uc3RydWN0aW9uXCIpLFxuICAgICAgbG9jYXRpb246IG5vZGVMb2NhdGlvbihjb25zdHJ1Y3Rpb24sIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgbWVzc2FnZTogY29udmVydEV4cHJlc3Npb24oY29uc3RydWN0aW9uLmFyZ3VtZW50c1swXSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgICB9LCB7dHlwZTogdHlwZUxvY2F0aW9ufSksXG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUmFpc2VTdGF0ZW1lbnRcIiksXG4gICAgbG9jYXRpb25cbiAgfSwge2tleXdvcmQ6IHRva2VuTG9jYXRpb24oXCJ0aHJvd1wiLCBub2RlLmxvYz8uc3RhcnQub2Zmc2V0ID8/IDAsIGNvbnN0cnVjdGlvbi5sb2M/LnN0YXJ0Lm9mZnNldCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKX0pXG59XG5cbi8qKlxuICogQ29udmVydHMgb25lIGV4YWN0IHR5cGVkIGNhdGNoIHdpdGggbm8gZmluYWxseS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlfSBub2RlIC0gUEhQIHRyeSBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7UGhwQ29udmVyc2lvbkNvbnRleHR9IGNvbnRleHQgLSBUeXBlZCBsZXhpY2FsIGNvbnRleHQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHJ5U3RhdGVtZW50fSBTZW1hbnRpYyBleGFjdCBoYW5kbGVyLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UGhwVHJ5KG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgY2F0Y2hlcyA9IFJlZmxlY3QuZ2V0KG5vZGUsIFwiY2F0Y2hlc1wiKVxuICBjb25zdCBib2R5ID0gUmVmbGVjdC5nZXQobm9kZSwgXCJib2R5XCIpXG5cbiAgaWYgKFJlZmxlY3QuZ2V0KG5vZGUsIFwiYWx3YXlzXCIpIHx8ICFBcnJheS5pc0FycmF5KGNhdGNoZXMpIHx8IGNhdGNoZXMubGVuZ3RoICE9IDEgfHwgYm9keT8ua2luZCAhPSBcImJsb2NrXCIpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJ0cnkgd2l0aG91dCBvbmUgdHlwZWQgY2F0Y2ggYW5kIG5vIGZpbmFsbHlcIiwgbG9jYXRpb24pXG4gIH1cbiAgY29uc3QgaGFuZGxlciA9IGNhdGNoZXNbMF1cbiAgY29uc3QgY2F1Z2h0ID0gaGFuZGxlci53aGF0Py5bMF1cbiAgY29uc3QgYmluZGluZyA9IGhhbmRsZXIudmFyaWFibGVcblxuICBpZiAoaGFuZGxlci53aGF0Py5sZW5ndGggIT0gMSB8fCBjYXVnaHQ/LmtpbmQgIT0gXCJuYW1lXCIgfHwgY2F1Z2h0LnJlc29sdXRpb24gIT0gXCJ1cW5cIiB8fFxuICAgICFjb250ZXh0LmVycm9yTmFtZXMuaGFzKGNhdWdodC5uYW1lKSB8fCBiaW5kaW5nPy5raW5kICE9IFwidmFyaWFibGVcIiB8fCB0eXBlb2YgYmluZGluZy5uYW1lICE9IFwic3RyaW5nXCIgfHxcbiAgICBiaW5kaW5nLmN1cmx5IHx8IGhhbmRsZXIuYm9keT8ua2luZCAhPSBcImJsb2NrXCIpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJicm9hZCwgbXVsdGlwbGUsIG9yIG1hbGZvcm1lZCBjYXRjaFwiLCBub2RlTG9jYXRpb24oaGFuZGxlciwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgY29uc3QgZGVjbGFyYXRpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb259ICovIChjb250ZXh0LmVycm9yTmFtZXMuZ2V0KGNhdWdodC5uYW1lKSlcbiAgY29uc3QgY2F1Z2h0TG9jYXRpb24gPSBub2RlTG9jYXRpb24oY2F1Z2h0LCBmaWxlbmFtZSwgc291cmNlKVxuICBjb25zdCBjYXRjaFR5cGUgPSB3aXRoUGFyc2VyUmFuZ2VzKHtkZWNsYXJhdGlvbklkOiAvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRXJyb3JUeXBlXCIpfSwge1xuICAgIHR5cGU6IGNhdWdodExvY2F0aW9uXG4gIH0pXG4gIGNvbnN0IGJvZHlDb250ZXh0ID0gey4uLmNvbnRleHQsIGJpbmRpbmdzOiBuZXcgTWFwKGNvbnRleHQuYmluZGluZ3MpfVxuICBjb25zdCBjYXRjaENvbnRleHQgPSB7Li4uY29udGV4dCwgYmluZGluZ3M6IG5ldyBNYXAoY29udGV4dC5iaW5kaW5ncyl9XG5cbiAgY2F0Y2hDb250ZXh0LmJpbmRpbmdzLnNldChiaW5kaW5nLm5hbWUsIGNhdGNoVHlwZSlcbiAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgIGJvZHk6IGNvbnZlcnRCbG9jayhib2R5LCBmaWxlbmFtZSwgc291cmNlLCBib2R5Q29udGV4dCksXG4gICAgY2F0Y2hCaW5kaW5nOiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkNhdGNoQmluZGluZ1wiKSxcbiAgICAgIGxvY2F0aW9uOiBub2RlTG9jYXRpb24oYmluZGluZywgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBtdXRhYmxlOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoZmFsc2UpLFxuICAgICAgbmFtZTogYmluZGluZy5uYW1lLFxuICAgICAgdHlwZTogY2F0Y2hUeXBlXG4gICAgfSwge25hbWU6IG5vZGVMb2NhdGlvbihiaW5kaW5nLCBmaWxlbmFtZSwgc291cmNlKX0pLFxuICAgIGNhdGNoQm9keTogY29udmVydEJsb2NrKGhhbmRsZXIuYm9keSwgZmlsZW5hbWUsIHNvdXJjZSwgY2F0Y2hDb250ZXh0KSxcbiAgICBjYXRjaFR5cGUsXG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiVHJ5U3RhdGVtZW50XCIpLFxuICAgIGxvY2F0aW9uXG4gIH0sIHtjYXRjaDogbm9kZUxvY2F0aW9uKGhhbmRsZXIsIGZpbGVuYW1lLCBzb3VyY2UpLCB0cnk6IHRva2VuTG9jYXRpb24oXCJ0cnlcIiwgbm9kZS5sb2M/LnN0YXJ0Lm9mZnNldCA/PyAwLCBib2R5LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBleGFjdCBibG9jay1mb3JtIFBIUCBgZm9yZWFjaCAoJGxpc3QgYXMgJHZhbHVlKWAuXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuRm9yZWFjaH0gbm9kZSAtIFBIUCBmb3JlYWNoIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtQaHBDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Gb3JFYWNoU3RhdGVtZW50IHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRm9yRWFjaE1hcFN0YXRlbWVudH0gU2VtYW50aWMgbG9vcC5cbiAqL1xuZnVuY3Rpb24gY29udmVydEZvckVhY2gobm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChub2RlLnNob3J0Rm9ybSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiYWx0ZXJuYXRpdmUgZm9yZWFjaCBzeW50YXhcIiwgbG9jYXRpb24pXG4gIGlmIChub2RlLnZhbHVlLmtpbmQgIT0gXCJ2YXJpYWJsZVwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJmb3JlYWNoIGRlc3RydWN0dXJpbmdcIiwgbm9kZUxvY2F0aW9uKG5vZGUudmFsdWUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICBjb25zdCB2YXJpYWJsZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5WYXJpYWJsZX0gKi8gKG5vZGUudmFsdWUpXG5cbiAgaWYgKFJlZmxlY3QuZ2V0KHZhcmlhYmxlLCBcImJ5cmVmXCIpID09PSB0cnVlKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJieS1yZWZlcmVuY2UgZm9yZWFjaFwiLCBub2RlTG9jYXRpb24odmFyaWFibGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICBpZiAodHlwZW9mIHZhcmlhYmxlLm5hbWUgIT0gXCJzdHJpbmdcIiB8fCB2YXJpYWJsZS5jdXJseSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZHluYW1pYyBmb3JlYWNoIGJpbmRpbmdcIiwgbm9kZUxvY2F0aW9uKHZhcmlhYmxlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgaWYgKCFub2RlLmJvZHkgfHwgbm9kZS5ib2R5LmtpbmQgIT0gXCJibG9ja1wiKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZm9yZWFjaCB3aXRob3V0IGJsb2NrIGJvZHlcIiwgbm9kZS5ib2R5ID8gbm9kZUxvY2F0aW9uKG5vZGUuYm9keSwgZmlsZW5hbWUsIHNvdXJjZSkgOiBsb2NhdGlvbilcbiAgfVxuICBjb25zdCBib2R5ID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkJsb2NrfSAqLyAobm9kZS5ib2R5KVxuICBjb25zdCBjb2xsZWN0aW9uVHlwZSA9IGl0ZXJhdGlvbk9wZXJhbmRUeXBlKGtub3duRXhwcmVzc2lvblR5cGUobm9kZS5zb3VyY2UsIGNvbnRleHQpKVxuXG4gIGlmIChub2RlLmtleSkge1xuICAgIGlmIChub2RlLmtleS5raW5kICE9IFwidmFyaWFibGVcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZm9yZWFjaCBrZXkgYmluZGluZyBzaGFwZVwiLCBub2RlTG9jYXRpb24obm9kZS5rZXksIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIGNvbnN0IGtleVZhcmlhYmxlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlZhcmlhYmxlfSAqLyAobm9kZS5rZXkpXG5cbiAgICBpZiAoUmVmbGVjdC5nZXQoa2V5VmFyaWFibGUsIFwiYnlyZWZcIikgPT09IHRydWUgfHwgdHlwZW9mIGtleVZhcmlhYmxlLm5hbWUgIT0gXCJzdHJpbmdcIiB8fCBrZXlWYXJpYWJsZS5jdXJseSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiaW52YWxpZCBmb3JlYWNoIGtleSBiaW5kaW5nXCIsIG5vZGVMb2NhdGlvbihrZXlWYXJpYWJsZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgfVxuICAgIGlmIChjb2xsZWN0aW9uVHlwZT8ua2luZCA9PSBcIk1hcFR5cGVcIikge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwidW5vcmRlcmVkIG1hcCBpdGVyYXRpb25cIiwgbm9kZUxvY2F0aW9uKG5vZGUuc291cmNlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgaWYgKCFjb2xsZWN0aW9uVHlwZSB8fCBjb2xsZWN0aW9uVHlwZS5raW5kICE9IFwiT3JkZXJlZE1hcFR5cGVcIikge1xuICAgICAgcmV0dXJuIG1pc3NpbmdUeXBlKFwicGhwXCIsIFwiT3JkZXJlZCBtYXAgaXRlcmF0aW9uIGNvbGxlY3Rpb25cIiwgbm9kZUxvY2F0aW9uKG5vZGUuc291cmNlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgY29uc3Qga2V5TG9jYXRpb24gPSBub2RlTG9jYXRpb24oa2V5VmFyaWFibGUsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgY29uc3QgdmFsdWVMb2NhdGlvbiA9IG5vZGVMb2NhdGlvbih2YXJpYWJsZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICBjb25zdCBrZXlUeXBlID0gaXRlcmF0aW9uQmluZGluZ1R5cGUoY29sbGVjdGlvblR5cGUua2V5VHlwZSwga2V5TG9jYXRpb24pXG4gICAgY29uc3QgdmFsdWVUeXBlID0gaXRlcmF0aW9uQmluZGluZ1R5cGUoY29sbGVjdGlvblR5cGUudmFsdWVUeXBlLCB2YWx1ZUxvY2F0aW9uKVxuICAgIGNvbnN0IGtleUJpbmRpbmcgPSB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlZhbHVlQmluZGluZ1wiKSwgbG9jYXRpb246IGtleUxvY2F0aW9uLCBtdXRhYmxlOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoZmFsc2UpLFxuICAgICAgbmFtZToga2V5VmFyaWFibGUubmFtZSwgdHlwZToga2V5VHlwZVxuICAgIH0sIHtuYW1lOiBrZXlMb2NhdGlvbn0pXG4gICAgY29uc3QgdmFsdWVCaW5kaW5nID0gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJWYWx1ZUJpbmRpbmdcIiksIGxvY2F0aW9uOiB2YWx1ZUxvY2F0aW9uLCBtdXRhYmxlOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoZmFsc2UpLFxuICAgICAgbmFtZTogdmFyaWFibGUubmFtZSwgdHlwZTogdmFsdWVUeXBlXG4gICAgfSwge25hbWU6IHZhbHVlTG9jYXRpb259KVxuICAgIGNvbnN0IGJvZHlDb250ZXh0ID0gey4uLmNvbnRleHQsIGJpbmRpbmdzOiBuZXcgTWFwKGNvbnRleHQuYmluZGluZ3MpfVxuXG4gICAgYm9keUNvbnRleHQuYmluZGluZ3Muc2V0KGtleVZhcmlhYmxlLm5hbWUsIGtleVR5cGUpXG4gICAgYm9keUNvbnRleHQuYmluZGluZ3Muc2V0KHZhcmlhYmxlLm5hbWUsIHZhbHVlVHlwZSlcbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBib2R5OiBjb252ZXJ0QmxvY2soYm9keSwgZmlsZW5hbWUsIHNvdXJjZSwgYm9keUNvbnRleHQpLFxuICAgICAga2V5QmluZGluZyxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkZvckVhY2hNYXBTdGF0ZW1lbnRcIiksXG4gICAgICBsb2NhdGlvbixcbiAgICAgIG1hcDogY29udmVydEV4cHJlc3Npb24obm9kZS5zb3VyY2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpLFxuICAgICAgdmFsdWVCaW5kaW5nXG4gICAgfSwge29wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKFwiZm9yZWFjaFwiLCBub2RlLmxvYz8uc3RhcnQub2Zmc2V0ID8/IDAsIG5vZGUuc291cmNlLmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsXG4gICAgICBmaWxlbmFtZSwgc291cmNlKX0pXG4gIH1cblxuICBpZiAoY29sbGVjdGlvblR5cGU/LmtpbmQgPT0gXCJNYXBUeXBlXCIgfHwgY29sbGVjdGlvblR5cGU/LmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibWFwIGl0ZXJhdGlvbiB3aXRob3V0IGtleS92YWx1ZSBwYWlyIGJpbmRpbmdcIiwgbm9kZUxvY2F0aW9uKG5vZGUuc291cmNlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuICBpZiAoIWNvbGxlY3Rpb25UeXBlIHx8IGNvbGxlY3Rpb25UeXBlLmtpbmQgIT0gXCJMaXN0VHlwZVwiKSB7XG4gICAgcmV0dXJuIG1pc3NpbmdUeXBlKFwicGhwXCIsIFwiSXRlcmF0aW9uIGNvbGxlY3Rpb25cIiwgbm9kZUxvY2F0aW9uKG5vZGUuc291cmNlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuICBjb25zdCBiaW5kaW5nTG9jYXRpb24gPSBub2RlTG9jYXRpb24odmFyaWFibGUsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGNvbnN0IGluZmVycmVkVHlwZSA9IGNvbGxlY3Rpb25UeXBlLmVsZW1lbnRUeXBlXG4gIGNvbnN0IGJpbmRpbmdUeXBlID0gaXRlcmF0aW9uQmluZGluZ1R5cGUoaW5mZXJyZWRUeXBlLCBiaW5kaW5nTG9jYXRpb24pXG4gIGNvbnN0IHZhbHVlQmluZGluZyA9IHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlZhbHVlQmluZGluZ1wiKSxcbiAgICBsb2NhdGlvbjogYmluZGluZ0xvY2F0aW9uLFxuICAgIG11dGFibGU6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChmYWxzZSksXG4gICAgbmFtZTogdmFyaWFibGUubmFtZSxcbiAgICB0eXBlOiBiaW5kaW5nVHlwZVxuICB9LCB7bmFtZTogYmluZGluZ0xvY2F0aW9ufSlcbiAgY29uc3QgYm9keUNvbnRleHQgPSB7Li4uY29udGV4dCwgYmluZGluZ3M6IG5ldyBNYXAoY29udGV4dC5iaW5kaW5ncyl9XG5cbiAgYm9keUNvbnRleHQuYmluZGluZ3Muc2V0KHZhcmlhYmxlLm5hbWUsIGJpbmRpbmdUeXBlKVxuICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgYm9keTogY29udmVydEJsb2NrKGJvZHksIGZpbGVuYW1lLCBzb3VyY2UsIGJvZHlDb250ZXh0KSxcbiAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJGb3JFYWNoU3RhdGVtZW50XCIpLFxuICAgIGxpc3Q6IGNvbnZlcnRFeHByZXNzaW9uKG5vZGUuc291cmNlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSxcbiAgICBsb2NhdGlvbixcbiAgICB2YWx1ZUJpbmRpbmdcbiAgfSwge29wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKFwiZm9yZWFjaFwiLCBub2RlLmxvYz8uc3RhcnQub2Zmc2V0ID8/IDAsIG5vZGUuc291cmNlLmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhbiBvcmRlcmVkIFBIUCBibG9jayB3aXRoIGl0cyBvd24gYWRhcHRhdGlvbiBzY29wZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5CbG9ja30gbm9kZSAtIFBIUCBwYXJzZXIgYmxvY2suXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtQaHBDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gU2VtYW50aWMgYmxvY2suXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRCbG9jayhub2RlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSB7XG4gIHJldHVybiB7XG4gICAga2luZDogXCJCbG9ja1wiLFxuICAgIGxvY2F0aW9uOiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgc3RhdGVtZW50czogbm9kZS5jaGlsZHJlbi5tYXAoKHN0YXRlbWVudCkgPT4gY29udmVydFN0YXRlbWVudChzdGF0ZW1lbnQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpKVxuICB9XG59XG5cbi8qKlxuICogUmVxdWlyZXMgYW4gZXhhY3QgUEhQIHNjYWxhciBkZWNsYXJhdGlvbiB0eXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGUgfCBudWxsfSBzb3VyY2VUeXBlIC0gUEhQIHR5cGUgbm9kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdWJqZWN0IC0gVHlwZWQgc3ViamVjdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gU291cmNlIGxvY2F0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IFtyZWNvcmROYW1lc10gLSBOb21pbmFsIGRlY2xhcmF0aW9ucyBieSBzb3VyY2UgbmFtZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZX0gU2VtYW50aWMgdHlwZS5cbiAqL1xuZnVuY3Rpb24gY29udmVydFR5cGUoc291cmNlVHlwZSwgc3ViamVjdCwgbG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIHJlY29yZE5hbWVzID0gbmV3IE1hcCgpKSB7XG4gIGlmICghc291cmNlVHlwZSkgcmV0dXJuIHJlcXVpcmVTb3VyY2VTY2FsYXJUeXBlKFwicGhwXCIsIHVuZGVmaW5lZCwgc3ViamVjdCwgbG9jYXRpb24pXG4gIGlmIChzb3VyY2VUeXBlLmtpbmQgIT0gXCJ0eXBlcmVmZXJlbmNlXCIgJiYgc291cmNlVHlwZS5raW5kICE9IFwibmFtZVwiICYmIHNvdXJjZVR5cGUua2luZCAhPSBcImlkZW50aWZpZXJcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInVuc3VwcG9ydGVkIHNjYWxhciB0eXBlXCIsIG5vZGVMb2NhdGlvbihzb3VyY2VUeXBlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIGNvbnN0IHR5cGVOYW1lID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlR5cGVSZWZlcmVuY2UgfCBpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5hbWUgfCBpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLklkZW50aWZpZXJ9ICovIChzb3VyY2VUeXBlKS5uYW1lXG5cbiAgY29uc3QgdHlwZUxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKHNvdXJjZVR5cGUsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGNvbnN0IGRlY2xhcmF0aW9uID0gcmVjb3JkTmFtZXMuZ2V0KHR5cGVOYW1lKVxuXG4gIGlmIChkZWNsYXJhdGlvbj8uaWQpIHJldHVybiBkZWNsYXJhdGlvbi5raW5kID09IFwiQ2xhc3NEZWNsYXJhdGlvblwiXG4gICAgPyByZWZlcmVuY2VUeXBlKGRlY2xhcmF0aW9uLmlkLCB0eXBlTG9jYXRpb24pXG4gICAgOiBkZWNsYXJhdGlvbi5raW5kID09IFwiRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvblwiXG4gICAgICA/IG93bmVkUmVzb3VyY2VUeXBlKGRlY2xhcmF0aW9uLmlkLCB0eXBlTG9jYXRpb24pXG4gICAgICA6IHJlY29yZFR5cGUoZGVjbGFyYXRpb24uaWQsIHR5cGVMb2NhdGlvbilcblxuICByZXR1cm4gcmVxdWlyZVNvdXJjZVNjYWxhclR5cGUoXCJwaHBcIiwgdHlwZU5hbWUsIHN1YmplY3QsIGxvY2F0aW9uLCB0eXBlTG9jYXRpb24pXG59XG5cbi8qKlxuICogUmVhZHMgdGhlIGV4YWN0IFBIUERvYyBjb250YWluZXIgc2lnbmF0dXJlIGF0dGFjaGVkIHRvIG9uZSBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5GdW5jdGlvbn0gbm9kZSAtIEZ1bmN0aW9uIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbb3duZXJJZF0gLSBTdGFibGUgZGVjbGFyYXRpb24gaWRlbnRpdHkuXG4gKiBAcmV0dXJucyB7e3BhcmFtZXRlcnM6IE1hcDxzdHJpbmcsIHtsb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIHNvdXJjZVR5cGU6IHN0cmluZ30+LCByZXR1cm5UeXBlOiB7bG9jYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBzb3VyY2VUeXBlOiBzdHJpbmd9IHwgdW5kZWZpbmVkLCB0eXBlUGFyYW1ldGVycz86IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVQYXJhbWV0ZXJbXX19IERvY3VtZW50ZWQgdHlwZXMuXG4gKi9cbmZ1bmN0aW9uIGZ1bmN0aW9uRG9jdW1lbnRlZFR5cGVzKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIG93bmVySWQpIHtcbiAgY29uc3QgY29tbWVudCA9IG5vZGUubGVhZGluZ0NvbW1lbnRzPy5hdCgtMSlcblxuICBpZiAoIWNvbW1lbnQgfHwgY29tbWVudC5raW5kICE9IFwiY29tbWVudGJsb2NrXCIgfHwgIWNvbW1lbnQubG9jIHx8ICFub2RlLmxvYyB8fFxuICAgICEvXlxccyokL3UudGVzdChzb3VyY2Uuc2xpY2UoY29tbWVudC5sb2MuZW5kLm9mZnNldCwgbm9kZS5sb2Muc3RhcnQub2Zmc2V0KSkpIHJldHVybiB7cGFyYW1ldGVyczogbmV3IE1hcCgpLCByZXR1cm5UeXBlOiB1bmRlZmluZWR9XG4gIGNvbnN0IGJsb2NrID0gcGFyc2VDb21tZW50KGNvbW1lbnQudmFsdWUpWzBdXG4gIGNvbnN0IHRhZ3MgPSBibG9jaz8udGFncyA/PyBbXVxuICBjb25zdCBwYXJhbWV0ZXJUYWdzID0gdGFncy5maWx0ZXIoKHRhZykgPT4gdGFnLnRhZyA9PSBcInBhcmFtXCIpXG4gIGNvbnN0IHJldHVyblRhZ3MgPSB0YWdzLmZpbHRlcigodGFnKSA9PiB0YWcudGFnID09IFwicmV0dXJuXCIgfHwgdGFnLnRhZyA9PSBcInJldHVybnNcIilcbiAgY29uc3QgdGVtcGxhdGVUYWdzID0gdGFncy5maWx0ZXIoKHRhZykgPT4gdGFnLnRhZyA9PSBcInRlbXBsYXRlXCIpXG4gIGNvbnN0IG1hbGZvcm1lZFRlbXBsYXRlID0gdGFncy5maW5kKCh0YWcpID0+IHRhZy50YWcuc3RhcnRzV2l0aChcInRlbXBsYXRlXCIpICYmIHRhZy50YWcgIT0gXCJ0ZW1wbGF0ZVwiKVxuICBjb25zdCBtYWxmb3JtZWQgPSB0YWdzLnNvbWUoKHRhZykgPT4gIVtcInBhcmFtXCIsIFwicmV0dXJuXCIsIFwicmV0dXJuc1wiLCBcInRlbXBsYXRlXCJdLmluY2x1ZGVzKHRhZy50YWcpKSB8fCByZXR1cm5UYWdzLmxlbmd0aCA+IDEgfHxcbiAgICBwYXJhbWV0ZXJUYWdzLnNvbWUoKHRhZykgPT4gdGFnLnR5cGUgIT0gXCJcIiB8fCAhL15cXCRbQS1aYS16X11bQS1aYS16MC05X10qJC91LnRlc3QodGFnLmRlc2NyaXB0aW9uKSkgfHxcbiAgICByZXR1cm5UYWdzLnNvbWUoKHRhZykgPT4gdGFnLnR5cGUgIT0gXCJcIiB8fCB0YWcuZGVzY3JpcHRpb24gIT0gXCJcIikgfHwgbWFsZm9ybWVkVGVtcGxhdGUgfHxcbiAgICB0ZW1wbGF0ZVRhZ3Muc29tZSgodGFnKSA9PiAhL15bQS1aYS16X11bQS1aYS16MC05X10qJC91LnRlc3QodGFnLm5hbWUpIHx8IHRhZy50eXBlICE9IFwiXCIgfHwgdGFnLmRlc2NyaXB0aW9uICE9IFwiXCIpIHx8XG4gICAgdGVtcGxhdGVUYWdzLmxlbmd0aCA+IDAgJiYgIW93bmVySWRcblxuICBpZiAobWFsZm9ybWVkKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJtYWxmb3JtZWQgZnVuY3Rpb24gdHlwZSBhbm5vdGF0aW9uXCIsIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgY29uc3QgcGFyYW1ldGVycyA9IG5ldyBNYXAocGFyYW1ldGVyVGFncy5tYXAoKHRhZykgPT4gW3RhZy5kZXNjcmlwdGlvbi5zbGljZSgxKSwge1xuICAgIGxvY2F0aW9uOiBjb21tZW50VGFnTG9jYXRpb24oY29tbWVudCwgdGFnLCBcIm5hbWVcIiwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgc291cmNlVHlwZTogdGFnLm5hbWVcbiAgfV0pKVxuXG4gIGlmIChwYXJhbWV0ZXJzLnNpemUgIT0gcGFyYW1ldGVyVGFncy5sZW5ndGgpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJkdXBsaWNhdGUgcGFyYW1ldGVyIGFubm90YXRpb25cIiwgbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGNvbnN0IHJldHVyblRhZyA9IHJldHVyblRhZ3NbMF1cbiAgY29uc3QgdHlwZVBhcmFtZXRlcnMgPSB0ZW1wbGF0ZVRhZ3MubWFwKCh0YWcsIGluZGV4KSA9PiB7XG4gICAgY29uc3QgbG9jYXRpb24gPSBjb21tZW50VGFnTG9jYXRpb24oY29tbWVudCwgdGFnLCBcIm5hbWVcIiwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtpZDogYCR7b3duZXJJZH06dHlwZToke2luZGV4fWAsIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlR5cGVQYXJhbWV0ZXJcIiksIGxvY2F0aW9uLCBuYW1lOiB0YWcubmFtZX0sIHtuYW1lOiBsb2NhdGlvbn0pXG4gIH0pXG5cbiAgcmV0dXJuIHtcbiAgICBwYXJhbWV0ZXJzLFxuICAgIHJldHVyblR5cGU6IHJldHVyblRhZyA/IHtcbiAgICAgIGxvY2F0aW9uOiBjb21tZW50VGFnTG9jYXRpb24oY29tbWVudCwgcmV0dXJuVGFnLCBcIm5hbWVcIiwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBzb3VyY2VUeXBlOiByZXR1cm5UYWcubmFtZVxuICAgIH0gOiB1bmRlZmluZWQsXG4gICAgLi4uKHR5cGVQYXJhbWV0ZXJzLmxlbmd0aCA+IDAgPyB7dHlwZVBhcmFtZXRlcnN9IDoge30pXG4gIH1cbn1cblxuLyoqXG4gKiBSZWFkcyBhbiBvcHRpb25hbCBleGFjdCBjbGFzcy1sZXZlbCBQSFBEb2MgdGVtcGxhdGUgbGlzdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5DbGFzc30gbm9kZSAtIENsYXNzIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IG93bmVySWQgLSBTdGFibGUgcmVjb3JkIGlkZW50aXR5LlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUGFyYW1ldGVyW10gfCB1bmRlZmluZWR9IE9yZGVyZWQgcGFyYW1ldGVycy5cbiAqL1xuZnVuY3Rpb24gY2xhc3NEb2N1bWVudGVkVHlwZVBhcmFtZXRlcnMobm9kZSwgb3duZXJJZCwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBjb25zdCBkb2N1bWVudGVkID0gZnVuY3Rpb25Eb2N1bWVudGVkVHlwZXMoXG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkZ1bmN0aW9ufSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAobm9kZSkpLCBmaWxlbmFtZSwgc291cmNlLCBvd25lcklkKVxuXG4gIGlmIChkb2N1bWVudGVkLnBhcmFtZXRlcnMuc2l6ZSB8fCBkb2N1bWVudGVkLnJldHVyblR5cGUpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJmdW5jdGlvbiB0eXBlIGFubm90YXRpb24gb24gcmVjb3JkIGRlY2xhcmF0aW9uXCIsIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIHJldHVybiBkb2N1bWVudGVkLnR5cGVQYXJhbWV0ZXJzXG59XG5cbi8qKlxuICogUmV0dXJucyBhIG5hdGl2ZSBQSFAgdHlwZSBuYW1lIGZyb20gb25lIHN1cHBvcnRlZCBwYXJzZXIgbm9kZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlIHwgbnVsbH0gdHlwZSAtIE5hdGl2ZSB0eXBlIG5vZGUuXG4gKiBAcmV0dXJucyB7c3RyaW5nIHwgdW5kZWZpbmVkfSBUeXBlIG5hbWUuXG4gKi9cbmZ1bmN0aW9uIHBocFR5cGVOYW1lKHR5cGUpIHtcbiAgaWYgKCF0eXBlIHx8ICFbXCJ0eXBlcmVmZXJlbmNlXCIsIFwibmFtZVwiLCBcImlkZW50aWZpZXJcIl0uaW5jbHVkZXModHlwZS5raW5kKSkgcmV0dXJuIHVuZGVmaW5lZFxuXG4gIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuVHlwZVJlZmVyZW5jZSB8IGltcG9ydChcInBocC1wYXJzZXJcIikuTmFtZSB8IGltcG9ydChcInBocC1wYXJzZXJcIikuSWRlbnRpZmllcn0gKi8gKHR5cGUpLm5hbWVcbn1cblxuLyoqXG4gKiBXcmFwcyBvbmUgcGFyc2VyLWRlY2xhcmVkIGNhbm9uaWNhbCBQSFAgbnVsbGFibGUgdHlwZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9IHZhbHVlVHlwZSAtIFByZXNlbnQtdmFsdWUgc2VtYW50aWMgdHlwZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlfSBzb3VyY2VUeXBlIC0gTmF0aXZlIHBhcnNlciB0eXBlIG5vZGUuXG4gKiBAcGFyYW0ge251bWJlcn0gb3duZXJTdGFydCAtIEVhcmxpZXN0IG93bmluZyBwYXJzZXIgb2Zmc2V0LlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5PcHRpb25hbFR5cGV9IE9wdGlvbmFsIHNlbWFudGljIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIG51bGxhYmxlVHlwZSh2YWx1ZVR5cGUsIHNvdXJjZVR5cGUsIG93bmVyU3RhcnQsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgaWYgKCFzb3VyY2VUeXBlLmxvYykgdGhyb3cgbmV3IEVycm9yKFwiUEhQIHBhcnNlciBvbWl0dGVkIG51bGxhYmxlIHR5cGUgbG9jYXRpb24uXCIpXG4gIGNvbnN0IHZhbHVlTG9jYXRpb24gPSBub2RlTG9jYXRpb24oc291cmNlVHlwZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgbWFya2VyID0gdG9rZW5Mb2NhdGlvbihcIj9cIiwgb3duZXJTdGFydCwgc291cmNlVHlwZS5sb2Muc3RhcnQub2Zmc2V0LCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChtYXJrZXIuZW5kLm9mZnNldCAhPSB2YWx1ZUxvY2F0aW9uLnN0YXJ0Lm9mZnNldCkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm5vbmNhbm9uaWNhbCBudWxsYWJsZSB0eXBlXCIsIG1hcmtlcilcbiAgfVxuXG4gIHJldHVybiBvcHRpb25hbFR5cGUoXG4gICAgdmFsdWVUeXBlLFxuICAgIGxvY2F0aW9uRnJvbU9mZnNldHMoZmlsZW5hbWUsIHNvdXJjZSwgbWFya2VyLnN0YXJ0Lm9mZnNldCwgdmFsdWVMb2NhdGlvbi5lbmQub2Zmc2V0KSxcbiAgICB2YWx1ZUxvY2F0aW9uXG4gIClcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgZXhwbGljaXQgUEhQIGZ1bmN0aW9uIHJldHVybiB0eXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGUgfCBudWxsfSBzb3VyY2VUeXBlIC0gUEhQIHJldHVybiB0eXBlIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3ViamVjdCAtIFR5cGVkIGZ1bmN0aW9uIHJldHVybi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gRnVuY3Rpb24gbG9jYXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FZmZlY3RSZXNvdXJjZURlY2xhcmF0aW9uPn0gW3JlY29yZE5hbWVzXSAtIE5vbWluYWwgZGVjbGFyYXRpb25zIGJ5IHNvdXJjZSBuYW1lLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlfSBTZW1hbnRpYyByZXR1cm4gdHlwZS5cbiAqL1xuZnVuY3Rpb24gY29udmVydFJldHVyblR5cGUoc291cmNlVHlwZSwgc3ViamVjdCwgbG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIHJlY29yZE5hbWVzID0gbmV3IE1hcCgpKSB7XG4gIGlmICghc291cmNlVHlwZSkgcmV0dXJuIHJlcXVpcmVTb3VyY2VSZXR1cm5UeXBlKFwicGhwXCIsIHVuZGVmaW5lZCwgc3ViamVjdCwgbG9jYXRpb24pXG4gIGlmIChzb3VyY2VUeXBlLmtpbmQgIT0gXCJ0eXBlcmVmZXJlbmNlXCIgJiYgc291cmNlVHlwZS5raW5kICE9IFwibmFtZVwiICYmIHNvdXJjZVR5cGUua2luZCAhPSBcImlkZW50aWZpZXJcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInVuc3VwcG9ydGVkIHJldHVybiB0eXBlXCIsIG5vZGVMb2NhdGlvbihzb3VyY2VUeXBlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuICBjb25zdCB0eXBlTmFtZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5UeXBlUmVmZXJlbmNlIHwgaW1wb3J0KFwicGhwLXBhcnNlclwiKS5OYW1lIHwgaW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZGVudGlmaWVyfSAqLyAoc291cmNlVHlwZSkubmFtZVxuICBjb25zdCBkZWNsYXJhdGlvbiA9IHJlY29yZE5hbWVzLmdldCh0eXBlTmFtZSlcblxuICBpZiAoZGVjbGFyYXRpb24/LmlkKSByZXR1cm4gZGVjbGFyYXRpb24ua2luZCA9PSBcIkNsYXNzRGVjbGFyYXRpb25cIlxuICAgID8gcmVmZXJlbmNlVHlwZShkZWNsYXJhdGlvbi5pZCwgbm9kZUxvY2F0aW9uKHNvdXJjZVR5cGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIDogZGVjbGFyYXRpb24ua2luZCA9PSBcIkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb25cIlxuICAgICAgPyBvd25lZFJlc291cmNlVHlwZShkZWNsYXJhdGlvbi5pZCwgbm9kZUxvY2F0aW9uKHNvdXJjZVR5cGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgICAgOiByZWNvcmRUeXBlKGRlY2xhcmF0aW9uLmlkLCBub2RlTG9jYXRpb24oc291cmNlVHlwZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG5cbiAgcmV0dXJuIHJlcXVpcmVTb3VyY2VSZXR1cm5UeXBlKFwicGhwXCIsIHR5cGVOYW1lLCBzdWJqZWN0LCBsb2NhdGlvbiwgbm9kZUxvY2F0aW9uKHNvdXJjZVR5cGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBleHBsaWNpdCB0eXBlIHNpZ25hdHVyZSBvZiBvbmUgUEhQIGZ1bmN0aW9uIGJlZm9yZSBhbnkgYm9keSBleHByZXNzaW9ucy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5GdW5jdGlvbn0gbm9kZSAtIFBIUCBmdW5jdGlvbiBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IHJlY29yZE5hbWVzIC0gTm9taW5hbCBkZWNsYXJhdGlvbnMgYnkgc291cmNlIG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gb3duZXJJZCAtIFN0YWJsZSBmdW5jdGlvbiBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHtQaHBGdW5jdGlvblNpZ25hdHVyZX0gVHlwZWQgZnVuY3Rpb24gc2lnbmF0dXJlLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0RnVuY3Rpb25TaWduYXR1cmUobm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgcmVjb3JkTmFtZXMsIG93bmVySWQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgbmFtZSA9IHR5cGVvZiBub2RlLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG5vZGUubmFtZSA6IG5vZGUubmFtZS5uYW1lXG5cbiAgaWYgKCFub2RlLmJvZHkpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJmdW5jdGlvbiBib2R5XCIsIGxvY2F0aW9uKVxuICB9XG5cbiAgY29uc3QgZG9jdW1lbnRlZCA9IGZ1bmN0aW9uRG9jdW1lbnRlZFR5cGVzKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIG93bmVySWQpXG4gIGNvbnN0IHR5cGVQYXJhbWV0ZXJOYW1lcyA9IG5ldyBNYXAoKGRvY3VtZW50ZWQudHlwZVBhcmFtZXRlcnMgPz8gW10pLm1hcCgocGFyYW1ldGVyKSA9PiBbcGFyYW1ldGVyLm5hbWUsIHBhcmFtZXRlcl0pKVxuICBjb25zdCBwYXJhbWV0ZXJzID0gbm9kZS5hcmd1bWVudHMubWFwKChwYXJhbWV0ZXIpID0+IHtcbiAgICBjb25zdCBwYXJhbWV0ZXJMb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihwYXJhbWV0ZXIsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgY29uc3QgcGFyYW1ldGVyTmFtZSA9IHR5cGVvZiBwYXJhbWV0ZXIubmFtZSA9PSBcInN0cmluZ1wiID8gcGFyYW1ldGVyLm5hbWUgOiBwYXJhbWV0ZXIubmFtZS5uYW1lXG5cbiAgICBpZiAocGFyYW1ldGVyLmJ5cmVmKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJieS1yZWZlcmVuY2UgcGFyYW1ldGVyXCIsIHBhcmFtZXRlckxvY2F0aW9uKVxuICAgIGlmIChwYXJhbWV0ZXIudmFyaWFkaWMpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInZhcmlhZGljIHBhcmFtZXRlclwiLCBwYXJhbWV0ZXJMb2NhdGlvbilcbiAgICBpZiAocGFyYW1ldGVyLnZhbHVlKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJkZWZhdWx0IHBhcmFtZXRlclwiLCBwYXJhbWV0ZXJMb2NhdGlvbilcbiAgICBjb25zdCBwYXJhbWV0ZXJOb2RlID0gdHlwZW9mIHBhcmFtZXRlci5uYW1lID09IFwic3RyaW5nXCIgPyBwYXJhbWV0ZXIgOiBwYXJhbWV0ZXIubmFtZVxuICAgIGNvbnN0IGRvY3VtZW50ZWRUeXBlID0gZG9jdW1lbnRlZC5wYXJhbWV0ZXJzLmdldChwYXJhbWV0ZXJOYW1lKVxuICAgIGNvbnN0IG5hdGl2ZVR5cGUgPSBwaHBUeXBlTmFtZShwYXJhbWV0ZXIudHlwZSlcblxuICAgIGxldCBwYXJhbWV0ZXJUeXBlID0gZG9jdW1lbnRlZFR5cGVcbiAgICAgID8gZG9jdW1lbnRlZFZhbHVlVHlwZSh7bGFuZ3VhZ2U6IFwicGhwXCIsIGxvY2F0aW9uOiBkb2N1bWVudGVkVHlwZS5sb2NhdGlvbiwgb3duZXJMb2NhdGlvbjogcGFyYW1ldGVyTG9jYXRpb24sIHNvdXJjZSxcbiAgICAgICAgcmVjb3JkczogcmVjb3JkTmFtZXMsIHNvdXJjZVR5cGU6IGRvY3VtZW50ZWRUeXBlLnNvdXJjZVR5cGUsIHN1YmplY3Q6IGBQYXJhbWV0ZXIgJyR7cGFyYW1ldGVyTmFtZX0nYCwgdHlwZVBhcmFtZXRlcnM6IHR5cGVQYXJhbWV0ZXJOYW1lc30pXG4gICAgICA6IGNvbnZlcnRUeXBlKHBhcmFtZXRlci50eXBlLCBgUGFyYW1ldGVyICcke3BhcmFtZXRlck5hbWV9J2AsIHBhcmFtZXRlckxvY2F0aW9uLCBmaWxlbmFtZSwgc291cmNlLCByZWNvcmROYW1lcylcblxuICAgIGlmIChuYXRpdmVUeXBlID09IFwiYXJyYXlcIiAmJiAhZG9jdW1lbnRlZFR5cGUpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgUGFyYW1ldGVyICcke3BhcmFtZXRlck5hbWV9J2AsIHBhcmFtZXRlckxvY2F0aW9uKVxuICAgIGlmIChkb2N1bWVudGVkVHlwZSAmJiAhcGhwRG9jdW1lbnRlZE5hdGl2ZVR5cGVNYXRjaGVzKG5hdGl2ZVR5cGUsIHBhcmFtZXRlci5udWxsYWJsZSwgcGFyYW1ldGVyVHlwZSwgcmVjb3JkTmFtZXMpKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJkb2N1bWVudGVkIHBhcmFtZXRlciB0eXBlIGluY29tcGF0aWJsZSB3aXRoIG5hdGl2ZSB0eXBlXCIsIGRvY3VtZW50ZWRUeXBlLmxvY2F0aW9uKVxuICAgIH1cblxuICAgIGlmIChwYXJhbWV0ZXIubnVsbGFibGUgJiYgcGFyYW1ldGVyVHlwZS5raW5kICE9IFwiT3B0aW9uYWxUeXBlXCIpIHtcbiAgICAgIGlmICghcGFyYW1ldGVyLnR5cGUpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgUGFyYW1ldGVyICcke3BhcmFtZXRlck5hbWV9J2AsIHBhcmFtZXRlckxvY2F0aW9uKVxuICAgICAgcGFyYW1ldGVyVHlwZSA9IG51bGxhYmxlVHlwZShwYXJhbWV0ZXJUeXBlLCBwYXJhbWV0ZXIudHlwZSwgcGFyYW1ldGVyLmxvYz8uc3RhcnQub2Zmc2V0ID8/IDAsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSBlbHNlIGlmICghcGFyYW1ldGVyLm51bGxhYmxlICYmIHBhcmFtZXRlclR5cGUua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiICYmXG4gICAgICBwYXJhbWV0ZXJUeXBlLnZhbHVlVHlwZS5raW5kICE9IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm9wdGlvbmFsIGFubm90YXRpb24gd2l0aG91dCBudWxsYWJsZSBuYXRpdmUgdHlwZVwiLCBkb2N1bWVudGVkVHlwZT8ubG9jYXRpb24gPz8gcGFyYW1ldGVyTG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IHNlbWFudGljUGFyYW1ldGVyID0ge1xuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUGFyYW1ldGVyXCIpLFxuICAgICAgbG9jYXRpb246IHBhcmFtZXRlckxvY2F0aW9uLFxuICAgICAgbmFtZTogcGFyYW1ldGVyTmFtZSxcbiAgICAgIHR5cGU6IHBhcmFtZXRlclR5cGVcbiAgICB9XG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyhzZW1hbnRpY1BhcmFtZXRlciwge25hbWU6IG5vZGVMb2NhdGlvbihwYXJhbWV0ZXJOb2RlLCBmaWxlbmFtZSwgc291cmNlKX0pXG4gIH0pXG4gIGNvbnN0IGV4dHJhRG9jdW1lbnRlZFBhcmFtZXRlciA9IFsuLi5kb2N1bWVudGVkLnBhcmFtZXRlcnMua2V5cygpXS5maW5kKChuYW1lKSA9PlxuICAgICFub2RlLmFyZ3VtZW50cy5zb21lKChwYXJhbWV0ZXIpID0+ICh0eXBlb2YgcGFyYW1ldGVyLm5hbWUgPT0gXCJzdHJpbmdcIiA/IHBhcmFtZXRlci5uYW1lIDogcGFyYW1ldGVyLm5hbWUubmFtZSkgPT0gbmFtZSkpXG5cbiAgaWYgKGV4dHJhRG9jdW1lbnRlZFBhcmFtZXRlcikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGBhbm5vdGF0aW9uIGZvciB1bmtub3duIHBhcmFtZXRlciAnJHtleHRyYURvY3VtZW50ZWRQYXJhbWV0ZXJ9J2AsIGxvY2F0aW9uKVxuICBpZiAobm9kZS5ieXJlZikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiYnktcmVmZXJlbmNlIHJldHVyblwiLCBsb2NhdGlvbilcbiAgY29uc3QgbmFtZU5vZGUgPSB0eXBlb2Ygbm9kZS5uYW1lID09IFwic3RyaW5nXCIgPyBub2RlIDogbm9kZS5uYW1lXG4gIGNvbnN0IG5hdGl2ZVJldHVyblR5cGUgPSBwaHBUeXBlTmFtZShub2RlLnR5cGUpXG4gIGxldCByZXR1cm5UeXBlXG5cbiAgaWYgKGRvY3VtZW50ZWQucmV0dXJuVHlwZSkge1xuICAgIHJldHVyblR5cGUgPSBkb2N1bWVudGVkVmFsdWVUeXBlKHtsYW5ndWFnZTogXCJwaHBcIiwgbG9jYXRpb246IGRvY3VtZW50ZWQucmV0dXJuVHlwZS5sb2NhdGlvbiwgb3duZXJMb2NhdGlvbjogbG9jYXRpb24sIHNvdXJjZSxcbiAgICAgIHJlY29yZHM6IHJlY29yZE5hbWVzLCBzb3VyY2VUeXBlOiBkb2N1bWVudGVkLnJldHVyblR5cGUuc291cmNlVHlwZSwgc3ViamVjdDogYEZ1bmN0aW9uICcke25hbWV9JyByZXR1cm5gLCB0eXBlUGFyYW1ldGVyczogdHlwZVBhcmFtZXRlck5hbWVzfSlcbiAgICBpZiAoIXBocERvY3VtZW50ZWROYXRpdmVUeXBlTWF0Y2hlcyhuYXRpdmVSZXR1cm5UeXBlLCBub2RlLm51bGxhYmxlLCByZXR1cm5UeXBlLCByZWNvcmROYW1lcykpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImRvY3VtZW50ZWQgcmV0dXJuIHR5cGUgaW5jb21wYXRpYmxlIHdpdGggbmF0aXZlIHR5cGVcIiwgZG9jdW1lbnRlZC5yZXR1cm5UeXBlLmxvY2F0aW9uKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAobmF0aXZlUmV0dXJuVHlwZSA9PSBcImFycmF5XCIpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgRnVuY3Rpb24gJyR7bmFtZX0nIHJldHVybmAsIGxvY2F0aW9uKVxuICAgIHJldHVyblR5cGUgPSBjb252ZXJ0UmV0dXJuVHlwZShub2RlLnR5cGUsIGBGdW5jdGlvbiAnJHtuYW1lfScgcmV0dXJuYCwgbG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIHJlY29yZE5hbWVzKVxuICB9XG4gIGlmIChub2RlLm51bGxhYmxlICYmIHJldHVyblR5cGUua2luZCAhPSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgaWYgKCFub2RlLnR5cGUpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgRnVuY3Rpb24gJyR7bmFtZX0nIHJldHVybmAsIGxvY2F0aW9uKVxuICAgIGNvbnN0IHR5cGVTdGFydCA9IG5vZGUudHlwZS5sb2M/LnN0YXJ0Lm9mZnNldCA/PyAwXG5cbiAgICByZXR1cm5UeXBlID0gbnVsbGFibGVUeXBlKFxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZX0gKi8gKHJldHVyblR5cGUpLFxuICAgICAgbm9kZS50eXBlLFxuICAgICAgTWF0aC5tYXgobm9kZS5sb2M/LnN0YXJ0Lm9mZnNldCA/PyAwLCB0eXBlU3RhcnQgLSAyKSxcbiAgICAgIGZpbGVuYW1lLFxuICAgICAgc291cmNlXG4gICAgKVxuICB9IGVsc2UgaWYgKCFub2RlLm51bGxhYmxlICYmIHJldHVyblR5cGUua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiICYmXG4gICAgcmV0dXJuVHlwZS52YWx1ZVR5cGUua2luZCAhPSBcIlR5cGVWYXJpYWJsZVJlZmVyZW5jZVwiKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwib3B0aW9uYWwgYW5ub3RhdGlvbiB3aXRob3V0IG51bGxhYmxlIG5hdGl2ZSByZXR1cm4gdHlwZVwiLCBkb2N1bWVudGVkLnJldHVyblR5cGU/LmxvY2F0aW9uID8/IGxvY2F0aW9uKVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBsb2NhdGlvbixcbiAgICBuYW1lLFxuICAgIG5hbWVMb2NhdGlvbjogbm9kZUxvY2F0aW9uKG5hbWVOb2RlLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICBwYXJhbWV0ZXJzLFxuICAgIHJldHVyblR5cGUsXG4gICAgLi4uKGRvY3VtZW50ZWQudHlwZVBhcmFtZXRlcnMgPyB7dHlwZVBhcmFtZXRlcnM6IGRvY3VtZW50ZWQudHlwZVBhcmFtZXRlcnN9IDoge30pXG4gIH1cbn1cblxuLyoqXG4gKiBDaGVja3MgdGhlIGV4YWN0IHJ1bnRpbWUgY2FycmllciBwZXJtaXR0ZWQgYmVzaWRlIGEgcHJlY2lzZSBQSFBEb2MgdHlwZS5cbiAqIEBwYXJhbSB7c3RyaW5nIHwgdW5kZWZpbmVkfSBuYXRpdmVUeXBlIC0gTmF0aXZlIFBIUCB0eXBlIG5hbWUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG5hdGl2ZU51bGxhYmxlIC0gV2hldGhlciB0aGUgbmF0aXZlIGNhcnJpZXIgaGFzIFBIUCdzIG51bGxhYmxlIG1hcmtlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9IGRvY3VtZW50ZWRUeXBlIC0gRXhhY3Qgc2VtYW50aWMgZG9jdW1lbnQgdHlwZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IHJlY29yZHMgLSBWaXNpYmxlIG5vbWluYWwgZGVjbGFyYXRpb25zIGJ5IG5hbWUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgbmF0aXZlIGNhcnJpZXIgYWdyZWVzIHdpdGhvdXQgY2hhbmdpbmcgbWVhbmluZy5cbiAqL1xuZnVuY3Rpb24gcGhwRG9jdW1lbnRlZE5hdGl2ZVR5cGVNYXRjaGVzKG5hdGl2ZVR5cGUsIG5hdGl2ZU51bGxhYmxlLCBkb2N1bWVudGVkVHlwZSwgcmVjb3Jkcykge1xuICBpZiAoZG9jdW1lbnRlZFR5cGUua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgaWYgKGRvY3VtZW50ZWRUeXBlLnZhbHVlVHlwZS5raW5kID09IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIpIHtcbiAgICAgIHJldHVybiBuYXRpdmVUeXBlID09PSB1bmRlZmluZWQgJiYgIW5hdGl2ZU51bGxhYmxlXG4gICAgfVxuXG4gICAgcmV0dXJuIG5hdGl2ZU51bGxhYmxlICYmIHBocERvY3VtZW50ZWROYXRpdmVUeXBlTWF0Y2hlcyhuYXRpdmVUeXBlLCBmYWxzZSwgZG9jdW1lbnRlZFR5cGUudmFsdWVUeXBlLCByZWNvcmRzKVxuICB9XG4gIGlmIChuYXRpdmVOdWxsYWJsZSkgcmV0dXJuIGZhbHNlXG4gIGlmIChkb2N1bWVudGVkVHlwZS5raW5kID09IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIpIHJldHVybiBuYXRpdmVUeXBlID09PSB1bmRlZmluZWRcbiAgaWYgKGRvY3VtZW50ZWRUeXBlLmtpbmQgPT0gXCJUeXBlUmVmZXJlbmNlXCIpIHtcbiAgICByZXR1cm4gbmF0aXZlVHlwZSAhPT0gdW5kZWZpbmVkICYmIHNvdXJjZVNjYWxhclR5cGUoXCJwaHBcIiwgbmF0aXZlVHlwZSk/Lm5hbWUgPT0gZG9jdW1lbnRlZFR5cGUubmFtZVxuICB9XG4gIGlmIChkb2N1bWVudGVkVHlwZS5raW5kID09IFwiTGlzdFR5cGVcIiB8fCBkb2N1bWVudGVkVHlwZS5raW5kID09IFwiTWFwVHlwZVwiIHx8IGRvY3VtZW50ZWRUeXBlLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiKSB7XG4gICAgcmV0dXJuIG5hdGl2ZVR5cGUgPT0gXCJhcnJheVwiXG4gIH1cbiAgaWYgKGRvY3VtZW50ZWRUeXBlLmtpbmQgPT0gXCJSZWNvcmRUeXBlXCIpIHtcbiAgICByZXR1cm4gbmF0aXZlVHlwZSAhPT0gdW5kZWZpbmVkICYmIHJlY29yZHMuZ2V0KG5hdGl2ZVR5cGUpPy5pZCA9PSBkb2N1bWVudGVkVHlwZS5kZWNsYXJhdGlvbklkXG4gIH1cbiAgaWYgKGRvY3VtZW50ZWRUeXBlLmtpbmQgPT0gXCJSZWZlcmVuY2VUeXBlXCIpIHtcbiAgICByZXR1cm4gbmF0aXZlVHlwZSAhPT0gdW5kZWZpbmVkICYmIHJlY29yZHMuZ2V0KG5hdGl2ZVR5cGUpPy5pZCA9PSBkb2N1bWVudGVkVHlwZS5kZWNsYXJhdGlvbklkXG4gIH1cblxuICByZXR1cm4gZmFsc2Vcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIFBIUCBmdW5jdGlvbiBib2R5IHVzaW5nIHRoZSBhbHJlYWR5LXByb3ZlZCBtb2R1bGUgc2lnbmF0dXJlcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5GdW5jdGlvbn0gbm9kZSAtIFBIUCBmdW5jdGlvbiBub2RlLlxuICogQHBhcmFtIHtQaHBGdW5jdGlvblNpZ25hdHVyZX0gc2lnbmF0dXJlIC0gUHJlY29udmVydGVkIGV4cGxpY2l0IHNpZ25hdHVyZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgUGhwRnVuY3Rpb25TaWduYXR1cmU+fSBmdW5jdGlvbnMgLSBNb2R1bGUgZnVuY3Rpb24gc2lnbmF0dXJlcy5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IHJlY29yZE5hbWVzIC0gTm9taW5hbCBkZWNsYXJhdGlvbnMgYnkgc291cmNlIG5hbWUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uPn0gcmVjb3JkcyAtIFJlY29yZCBkZWNsYXJhdGlvbnMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24+fSBjbGFzc2VzIC0gUmVmZXJlbmNlIGNsYXNzZXMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24+fSBlcnJvck5hbWVzIC0gRXJyb3IgZGVjbGFyYXRpb25zIGJ5IHNvdXJjZSBuYW1lLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9uPn0gZXJyb3JzIC0gRXJyb3IgZGVjbGFyYXRpb25zIGJ5IGlkZW50aXR5LlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9ufSBTZW1hbnRpYyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY29udmVydEZ1bmN0aW9uKG5vZGUsIHNpZ25hdHVyZSwgZnVuY3Rpb25zLCByZWNvcmROYW1lcywgcmVjb3JkcywgY2xhc3NlcywgZXJyb3JOYW1lcywgZXJyb3JzLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGlmICghbm9kZS5ib2R5KSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJmdW5jdGlvbiBib2R5XCIsIHNpZ25hdHVyZS5sb2NhdGlvbilcbiAgY29uc3QgY29udGV4dCA9IHtcbiAgICBiaW5kaW5nczogbmV3IE1hcChzaWduYXR1cmUucGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlcikgPT4gW3BhcmFtZXRlci5uYW1lLCBwYXJhbWV0ZXIudHlwZV0pKSxcbiAgICBjbGFzc2VzLFxuICAgIGVycm9yTmFtZXMsXG4gICAgZXJyb3JzLFxuICAgIGZ1bmN0aW9ucyxcbiAgICBvcmRlcmVkTWFwRGVjbGFyYXRpb25zOiBvcmRlcmVkTWFwRGVjbGFyYXRpb25zRm9yUGhwKG5vZGUuYm9keSksXG4gICAgcmVjb3JkTmFtZXMsXG4gICAgcmVjb3JkcyxcbiAgICByZXR1cm5UeXBlOiBzaWduYXR1cmUucmV0dXJuVHlwZSxcbiAgICB0eXBlUGFyYW1ldGVyczogbmV3IE1hcCgoc2lnbmF0dXJlLnR5cGVQYXJhbWV0ZXJzID8/IFtdKS5tYXAoKHBhcmFtZXRlcikgPT4gW3BhcmFtZXRlci5uYW1lLCBwYXJhbWV0ZXJdKSlcbiAgfVxuXG4gIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICBib2R5OiBjb252ZXJ0QmxvY2sobm9kZS5ib2R5LCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSxcbiAgICBraW5kOiBcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIixcbiAgICBsb2NhdGlvbjogc2lnbmF0dXJlLmxvY2F0aW9uLFxuICAgIG5hbWU6IHNpZ25hdHVyZS5uYW1lLFxuICAgIHBhcmFtZXRlcnM6IHNpZ25hdHVyZS5wYXJhbWV0ZXJzLFxuICAgIHJldHVyblR5cGU6IHNpZ25hdHVyZS5yZXR1cm5UeXBlLFxuICAgIC4uLihzaWduYXR1cmUudHlwZVBhcmFtZXRlcnMgPyB7dHlwZVBhcmFtZXRlcnM6IHNpZ25hdHVyZS50eXBlUGFyYW1ldGVyc30gOiB7fSlcbiAgfSwge25hbWU6IHNpZ25hdHVyZS5uYW1lTG9jYXRpb259KVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHBhcnNlci1vd25lZCBrZXkvdmFsdWUgbG9vcHMgdG8gZXhhY3QgZGVjbGFyYXRpb25zIGluc2lkZSBvbmUgbGV4aWNhbCBvd25lci5cbiAqIEFtYmlndW91cyBzYW1lLW5hbWUgZGVjbGFyYXRpb25zIHByb2R1Y2Ugbm8gZXZpZGVuY2UgYW5kIGZhaWwgZHVyaW5nIGxvb3AgY29udmVyc2lvbi5cbiAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBGdW5jdGlvbiBib2R5IG9yIGVudHJ5LXBvaW50IHN1YnRyZWUuXG4gKiBAcmV0dXJucyB7U2V0PG9iamVjdD59IEV4YWN0IHBhaXItaXRlcmF0ZWQgcGFyc2VyIGRlY2xhcmF0aW9ucy5cbiAqL1xuZnVuY3Rpb24gb3JkZXJlZE1hcERlY2xhcmF0aW9uc0ZvclBocCh2YWx1ZSkge1xuICAvKiogQHR5cGUge3tkZWNsYXJhdGlvbjogb2JqZWN0LCBuYW1lOiBzdHJpbmcsIG9mZnNldDogbnVtYmVyfVtdfSAqL1xuICBjb25zdCBkZWNsYXJhdGlvbnMgPSBbXVxuICAvKiogQHR5cGUge3tuYW1lOiBzdHJpbmcsIG9mZnNldDogbnVtYmVyfVtdfSAqL1xuICBjb25zdCByZWNlaXZlcnMgPSBbXVxuICBjb25zdCBzZWVuID0gbmV3IFdlYWtTZXQoKVxuICAvKipcbiAgICogVmlzaXRzIG9uZSBwYXJzZXIgY2FuZGlkYXRlLlxuICAgKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIFBhcnNlciBjYW5kaWRhdGUuXG4gICAqL1xuICBjb25zdCB2aXNpdCA9IChjYW5kaWRhdGUpID0+IHtcbiAgICBpZiAoIWNhbmRpZGF0ZSB8fCB0eXBlb2YgY2FuZGlkYXRlICE9IFwib2JqZWN0XCIgfHwgc2Vlbi5oYXMoY2FuZGlkYXRlKSkgcmV0dXJuXG4gICAgc2Vlbi5hZGQoY2FuZGlkYXRlKVxuICAgIGNvbnN0IGtpbmQgPSBSZWZsZWN0LmdldChjYW5kaWRhdGUsIFwia2luZFwiKVxuXG4gICAgaWYgKGtpbmQgPT0gXCJmdW5jdGlvblwiIHx8IGtpbmQgPT0gXCJjbGFzc1wiKSByZXR1cm5cbiAgICBpZiAoa2luZCA9PSBcImFzc2lnblwiKSB7XG4gICAgICBjb25zdCB2YXJpYWJsZSA9IFJlZmxlY3QuZ2V0KGNhbmRpZGF0ZSwgXCJsZWZ0XCIpXG5cbiAgICAgIGlmIChSZWZsZWN0LmdldCh2YXJpYWJsZSwgXCJraW5kXCIpID09IFwidmFyaWFibGVcIiAmJiB0eXBlb2YgUmVmbGVjdC5nZXQodmFyaWFibGUsIFwibmFtZVwiKSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGRlY2xhcmF0aW9ucy5wdXNoKHtcbiAgICAgICAgICBkZWNsYXJhdGlvbjogY2FuZGlkYXRlLFxuICAgICAgICAgIG5hbWU6IFJlZmxlY3QuZ2V0KHZhcmlhYmxlLCBcIm5hbWVcIiksXG4gICAgICAgICAgb2Zmc2V0OiBSZWZsZWN0LmdldCh2YXJpYWJsZSwgXCJsb2NcIik/LnN0YXJ0Lm9mZnNldFxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoa2luZCA9PSBcImZvcmVhY2hcIikge1xuICAgICAgY29uc3QgcmVjZWl2ZXIgPSBSZWZsZWN0LmdldChjYW5kaWRhdGUsIFwic291cmNlXCIpXG5cbiAgICAgIGlmIChSZWZsZWN0LmdldChyZWNlaXZlciwgXCJraW5kXCIpID09IFwidmFyaWFibGVcIiAmJiB0eXBlb2YgUmVmbGVjdC5nZXQocmVjZWl2ZXIsIFwibmFtZVwiKSA9PSBcInN0cmluZ1wiICYmXG4gICAgICAgIFJlZmxlY3QuZ2V0KGNhbmRpZGF0ZSwgXCJrZXlcIikpIHJlY2VpdmVycy5wdXNoKHtcbiAgICAgICAgbmFtZTogUmVmbGVjdC5nZXQocmVjZWl2ZXIsIFwibmFtZVwiKSxcbiAgICAgICAgb2Zmc2V0OiBSZWZsZWN0LmdldChjYW5kaWRhdGUsIFwibG9jXCIpPy5zdGFydC5vZmZzZXRcbiAgICAgIH0pXG4gICAgfVxuICAgIGZvciAoY29uc3QgW2tleSwgY2hpbGRdIG9mIE9iamVjdC5lbnRyaWVzKGNhbmRpZGF0ZSkpIHtcbiAgICAgIGlmIChbXCJsb2NcIiwgXCJsZWFkaW5nQ29tbWVudHNcIiwgXCJ0cmFpbGluZ0NvbW1lbnRzXCJdLmluY2x1ZGVzKGtleSkpIGNvbnRpbnVlXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShjaGlsZCkpIHtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGNoaWxkKSB2aXNpdChpdGVtKVxuICAgICAgfSBlbHNlIHZpc2l0KGNoaWxkKVxuICAgIH1cbiAgfVxuXG4gIHZpc2l0KHZhbHVlKVxuICBjb25zdCBzZWxlY3RlZCA9IG5ldyBTZXQoKVxuICBmb3IgKGNvbnN0IHJlY2VpdmVyIG9mIHJlY2VpdmVycykge1xuICAgIGNvbnN0IG1hdGNoZXMgPSBkZWNsYXJhdGlvbnMuZmlsdGVyKCh7bmFtZSwgb2Zmc2V0fSkgPT4gbmFtZSA9PSByZWNlaXZlci5uYW1lICYmIG9mZnNldCA8IHJlY2VpdmVyLm9mZnNldClcblxuICAgIGlmIChtYXRjaGVzLmxlbmd0aCA9PSAxKSBzZWxlY3RlZC5hZGQobWF0Y2hlc1swXS5kZWNsYXJhdGlvbilcbiAgfVxuXG4gIHJldHVybiBzZWxlY3RlZFxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBleGFjdCBmaW5hbCBSdW50aW1lRXhjZXB0aW9uIHN1YmNsYXNzLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkNsYXNzfSBub2RlIC0gUEhQIGNsYXNzIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9ufSBkZWNsYXJhdGlvbiAtIFByZWRlY2xhcmVkIHNlbWFudGljIGVycm9yLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9ufSBTZW1hbnRpYyBlcnJvciBkZWNsYXJhdGlvbi5cbiAqL1xuZnVuY3Rpb24gY29udmVydFBocEVycm9yKG5vZGUsIGRlY2xhcmF0aW9uLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGNvbnN0IHBhcmVudCA9IG5vZGUuZXh0ZW5kc1xuICBjb25zdCBwYXJlbnROYW1lID0gcGFyZW50Py5raW5kID09IFwibmFtZVwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5hbWV9ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChwYXJlbnQpKSA6IHVuZGVmaW5lZFxuXG4gIGlmIChub2RlLmlzQW5vbnltb3VzIHx8ICFub2RlLmlzRmluYWwgfHwgbm9kZS5pc1JlYWRvbmx5IHx8IG5vZGUuaXNBYnN0cmFjdCB8fCBub2RlLmltcGxlbWVudHM/Lmxlbmd0aCB8fFxuICAgIG5vZGUuYXR0ckdyb3Vwcy5sZW5ndGggfHwgbm9kZS5ib2R5Lmxlbmd0aCAhPSAwIHx8ICFwYXJlbnROYW1lIHx8XG4gICAgIShwYXJlbnROYW1lLm5hbWUgPT0gXCJSdW50aW1lRXhjZXB0aW9uXCIgJiYgcGFyZW50TmFtZS5yZXNvbHV0aW9uID09IFwidXFuXCIgfHxcbiAgICAgIHBhcmVudE5hbWUubmFtZSA9PSBcIlxcXFxSdW50aW1lRXhjZXB0aW9uXCIgJiYgcGFyZW50TmFtZS5yZXNvbHV0aW9uID09IFwiZnFuXCIpKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibm9uY2Fub25pY2FsIHR5cGVkIGVycm9yIGRlY2xhcmF0aW9uXCIsIGxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IG5hbWVOb2RlID0gdHlwZW9mIG5vZGUubmFtZSA9PSBcInN0cmluZ1wiID8gbm9kZSA6IG5vZGUubmFtZVxuXG4gIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKGRlY2xhcmF0aW9uLCB7bmFtZTogbm9kZUxvY2F0aW9uKG5hbWVOb2RlLCBmaWxlbmFtZSwgc291cmNlKSwgdHlwZTogbm9kZUxvY2F0aW9uKHBhcmVudE5hbWUsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbn1cblxuLyoqXG4gKiBSZWFkcyBvbmUgZXhhY3QgcHVibGljIFBIUCBjb25zdHJ1Y3RvciBvciBpbnN0YW5jZS1tZXRob2Qgc2lnbmF0dXJlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk1ldGhvZH0gbm9kZSAtIFBhcnNlci1vd25lZCBtZXRob2QuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb24+fSBub21pbmFsTmFtZXMgLSBWaXNpYmxlIG5vbWluYWwgZGVjbGFyYXRpb25zLlxuICogQHBhcmFtIHtzdHJpbmd9IG93bmVySWQgLSBTdGFibGUgY2FsbGFibGUgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGNvbnN0cnVjdG9yIC0gV2hldGhlciB0aGlzIGlzIHRoZSBzb2xlIGNvbnN0cnVjdG9yLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHt7bG9jYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBuYW1lOiBzdHJpbmcsIG5hbWVMb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIHBhcmFtZXRlcnM6IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlBhcmFtZXRlcltdLCByZXR1cm5UeXBlPzogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9fSBFeGFjdCBzaWduYXR1cmUuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRQaHBDbGFzc0NhbGxhYmxlU2lnbmF0dXJlKG5vZGUsIG5vbWluYWxOYW1lcywgb3duZXJJZCwgY29uc3RydWN0b3IsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgbmFtZSA9IHR5cGVvZiBub2RlLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG5vZGUubmFtZSA6IG5vZGUubmFtZS5uYW1lXG5cbiAgaWYgKCFjb25zdHJ1Y3RvciAmJiAvXl9fL3UudGVzdChuYW1lKSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGByZXNlcnZlZCByZWZlcmVuY2UgbWV0aG9kICcke25hbWV9J2AsIGxvY2F0aW9uKVxuICBpZiAobm9kZS52aXNpYmlsaXR5ICE9IFwicHVibGljXCIgfHwgbm9kZS5pc1N0YXRpYyB8fCBub2RlLmlzQWJzdHJhY3QgfHwgbm9kZS5pc0ZpbmFsIHx8IFJlZmxlY3QuZ2V0KG5vZGUsIFwiaXNSZWFkb25seVwiKSB8fCBub2RlLmJ5cmVmIHx8XG4gICAgbm9kZS5hdHRyR3JvdXBzLmxlbmd0aCB8fCAhbm9kZS5ib2R5IHx8IGNvbnN0cnVjdG9yICE9IChuYW1lID09IFwiX19jb25zdHJ1Y3RcIikpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJub25jYW5vbmljYWwgcmVmZXJlbmNlIGNsYXNzIGNhbGxhYmxlXCIsIGxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IGRvY3VtZW50ZWQgPSBmdW5jdGlvbkRvY3VtZW50ZWRUeXBlcygvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuRnVuY3Rpb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChub2RlKSksXG4gICAgZmlsZW5hbWUsIHNvdXJjZSwgb3duZXJJZClcbiAgaWYgKGRvY3VtZW50ZWQudHlwZVBhcmFtZXRlcnM/Lmxlbmd0aCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZ2VuZXJpYyByZWZlcmVuY2UgY2xhc3MgY2FsbGFibGVcIiwgbG9jYXRpb24pXG4gIGlmIChjb25zdHJ1Y3RvciAmJiAobm9kZS50eXBlIHx8IG5vZGUubnVsbGFibGUgfHwgZG9jdW1lbnRlZC5yZXR1cm5UeXBlKSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImNvbnN0cnVjdG9yIHJldHVybiBhbm5vdGF0aW9uXCIsIGxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IHBhcmFtZXRlcnMgPSBub2RlLmFyZ3VtZW50cy5tYXAoKHBhcmFtZXRlcikgPT4ge1xuICAgIGNvbnN0IHBhcmFtZXRlckxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKHBhcmFtZXRlciwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICBjb25zdCBwYXJhbWV0ZXJOYW1lID0gdHlwZW9mIHBhcmFtZXRlci5uYW1lID09IFwic3RyaW5nXCIgPyBwYXJhbWV0ZXIubmFtZSA6IHBhcmFtZXRlci5uYW1lLm5hbWVcblxuICAgIGlmIChwYXJhbWV0ZXIuYnlyZWYgfHwgcGFyYW1ldGVyLnZhcmlhZGljIHx8IHBhcmFtZXRlci52YWx1ZSB8fCBwYXJhbWV0ZXIuZmxhZ3MgfHwgcGFyYW1ldGVyLnJlYWRvbmx5IHx8XG4gICAgICBwYXJhbWV0ZXIuaG9va3MubGVuZ3RoIHx8IHBhcmFtZXRlci5hdHRyR3JvdXBzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibm9uY2Fub25pY2FsIHJlZmVyZW5jZSBjbGFzcyBwYXJhbWV0ZXJcIiwgcGFyYW1ldGVyTG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IGRvY3VtZW50ZWRUeXBlID0gZG9jdW1lbnRlZC5wYXJhbWV0ZXJzLmdldChwYXJhbWV0ZXJOYW1lKVxuICAgIGNvbnN0IG5hdGl2ZVR5cGUgPSBwaHBUeXBlTmFtZShwYXJhbWV0ZXIudHlwZSlcbiAgICBsZXQgdHlwZSA9IGRvY3VtZW50ZWRUeXBlXG4gICAgICA/IGRvY3VtZW50ZWRWYWx1ZVR5cGUoe2xhbmd1YWdlOiBcInBocFwiLCBsb2NhdGlvbjogZG9jdW1lbnRlZFR5cGUubG9jYXRpb24sIG93bmVyTG9jYXRpb246IHBhcmFtZXRlckxvY2F0aW9uLFxuICAgICAgICByZWNvcmRzOiBub21pbmFsTmFtZXMsIHNvdXJjZSwgc291cmNlVHlwZTogZG9jdW1lbnRlZFR5cGUuc291cmNlVHlwZSwgc3ViamVjdDogYFBhcmFtZXRlciAnJHtwYXJhbWV0ZXJOYW1lfSdgfSlcbiAgICAgIDogY29udmVydFR5cGUocGFyYW1ldGVyLnR5cGUsIGBQYXJhbWV0ZXIgJyR7cGFyYW1ldGVyTmFtZX0nYCwgcGFyYW1ldGVyTG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIG5vbWluYWxOYW1lcylcblxuICAgIGlmIChuYXRpdmVUeXBlID09IFwiYXJyYXlcIiAmJiAhZG9jdW1lbnRlZFR5cGUpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgUGFyYW1ldGVyICcke3BhcmFtZXRlck5hbWV9J2AsIHBhcmFtZXRlckxvY2F0aW9uKVxuICAgIGlmIChkb2N1bWVudGVkVHlwZSAmJiAhcGhwRG9jdW1lbnRlZE5hdGl2ZVR5cGVNYXRjaGVzKG5hdGl2ZVR5cGUsIHBhcmFtZXRlci5udWxsYWJsZSwgdHlwZSwgbm9taW5hbE5hbWVzKSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZG9jdW1lbnRlZCBwYXJhbWV0ZXIgdHlwZSBpbmNvbXBhdGlibGUgd2l0aCBuYXRpdmUgdHlwZVwiLCBkb2N1bWVudGVkVHlwZS5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKHBhcmFtZXRlci5udWxsYWJsZSAmJiB0eXBlLmtpbmQgIT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgICAgaWYgKCFwYXJhbWV0ZXIudHlwZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwicGhwXCIsIGBQYXJhbWV0ZXIgJyR7cGFyYW1ldGVyTmFtZX0nYCwgcGFyYW1ldGVyTG9jYXRpb24pXG4gICAgICB0eXBlID0gbnVsbGFibGVUeXBlKHR5cGUsIHBhcmFtZXRlci50eXBlLCBwYXJhbWV0ZXIubG9jPy5zdGFydC5vZmZzZXQgPz8gMCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9IGVsc2UgaWYgKCFwYXJhbWV0ZXIubnVsbGFibGUgJiYgdHlwZS5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm9wdGlvbmFsIGFubm90YXRpb24gd2l0aG91dCBudWxsYWJsZSBuYXRpdmUgdHlwZVwiLCBkb2N1bWVudGVkVHlwZT8ubG9jYXRpb24gPz8gcGFyYW1ldGVyTG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IG5hbWVOb2RlID0gdHlwZW9mIHBhcmFtZXRlci5uYW1lID09IFwic3RyaW5nXCIgPyBwYXJhbWV0ZXIgOiBwYXJhbWV0ZXIubmFtZVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlBhcmFtZXRlclwiKSwgbG9jYXRpb246IHBhcmFtZXRlckxvY2F0aW9uLFxuICAgICAgbmFtZTogcGFyYW1ldGVyTmFtZSwgdHlwZX0sIHtuYW1lOiBub2RlTG9jYXRpb24obmFtZU5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgfSlcbiAgaWYgKFsuLi5kb2N1bWVudGVkLnBhcmFtZXRlcnMua2V5cygpXS5zb21lKChwYXJhbWV0ZXJOYW1lKSA9PlxuICAgICFub2RlLmFyZ3VtZW50cy5zb21lKChwYXJhbWV0ZXIpID0+ICh0eXBlb2YgcGFyYW1ldGVyLm5hbWUgPT0gXCJzdHJpbmdcIiA/IHBhcmFtZXRlci5uYW1lIDogcGFyYW1ldGVyLm5hbWUubmFtZSkgPT0gcGFyYW1ldGVyTmFtZSkpKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibWV0aG9kIFBIUERvYyBwYXJhbWV0ZXIgbWlzbWF0Y2hcIiwgbG9jYXRpb24pXG4gIH1cbiAgY29uc3QgbmFtZU5vZGUgPSB0eXBlb2Ygbm9kZS5uYW1lID09IFwic3RyaW5nXCIgPyBub2RlIDogbm9kZS5uYW1lXG5cbiAgaWYgKGNvbnN0cnVjdG9yKSByZXR1cm4ge2xvY2F0aW9uLCBuYW1lOiBcImNvbnN0cnVjdG9yXCIsIG5hbWVMb2NhdGlvbjogbm9kZUxvY2F0aW9uKG5hbWVOb2RlLCBmaWxlbmFtZSwgc291cmNlKSwgcGFyYW1ldGVyc31cbiAgbGV0IHJldHVyblR5cGVcbiAgY29uc3QgbmF0aXZlUmV0dXJuVHlwZSA9IHBocFR5cGVOYW1lKG5vZGUudHlwZSlcblxuICBpZiAoZG9jdW1lbnRlZC5yZXR1cm5UeXBlKSB7XG4gICAgcmV0dXJuVHlwZSA9IGRvY3VtZW50ZWRWYWx1ZVR5cGUoe2xhbmd1YWdlOiBcInBocFwiLCBsb2NhdGlvbjogZG9jdW1lbnRlZC5yZXR1cm5UeXBlLmxvY2F0aW9uLCBvd25lckxvY2F0aW9uOiBsb2NhdGlvbixcbiAgICAgIHJlY29yZHM6IG5vbWluYWxOYW1lcywgc291cmNlLCBzb3VyY2VUeXBlOiBkb2N1bWVudGVkLnJldHVyblR5cGUuc291cmNlVHlwZSwgc3ViamVjdDogYE1ldGhvZCAnJHtuYW1lfScgcmV0dXJuYH0pXG4gICAgaWYgKCFwaHBEb2N1bWVudGVkTmF0aXZlVHlwZU1hdGNoZXMobmF0aXZlUmV0dXJuVHlwZSwgbm9kZS5udWxsYWJsZSwgcmV0dXJuVHlwZSwgbm9taW5hbE5hbWVzKSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZG9jdW1lbnRlZCBtZXRob2QgcmV0dXJuIHR5cGUgaW5jb21wYXRpYmxlIHdpdGggbmF0aXZlIHR5cGVcIiwgZG9jdW1lbnRlZC5yZXR1cm5UeXBlLmxvY2F0aW9uKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAobmF0aXZlUmV0dXJuVHlwZSA9PSBcImFycmF5XCIpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgTWV0aG9kICcke25hbWV9JyByZXR1cm5gLCBsb2NhdGlvbilcbiAgICByZXR1cm5UeXBlID0gY29udmVydFJldHVyblR5cGUobm9kZS50eXBlLCBgTWV0aG9kICcke25hbWV9JyByZXR1cm5gLCBsb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSwgbm9taW5hbE5hbWVzKVxuICB9XG4gIGlmIChub2RlLm51bGxhYmxlICYmIHJldHVyblR5cGUua2luZCAhPSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgaWYgKCFub2RlLnR5cGUpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgTWV0aG9kICcke25hbWV9JyByZXR1cm5gLCBsb2NhdGlvbilcbiAgICByZXR1cm5UeXBlID0gbnVsbGFibGVUeXBlKC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9ICovIChyZXR1cm5UeXBlKSwgbm9kZS50eXBlLFxuICAgICAgbm9kZS50eXBlLmxvYz8uc3RhcnQub2Zmc2V0ID8/IDAsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIH0gZWxzZSBpZiAoIW5vZGUubnVsbGFibGUgJiYgcmV0dXJuVHlwZS5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJvcHRpb25hbCBhbm5vdGF0aW9uIHdpdGhvdXQgbnVsbGFibGUgbmF0aXZlIHJldHVybiB0eXBlXCIsIGRvY3VtZW50ZWQucmV0dXJuVHlwZT8ubG9jYXRpb24gPz8gbG9jYXRpb24pXG4gIH1cblxuICByZXR1cm4ge2xvY2F0aW9uLCBuYW1lLCBuYW1lTG9jYXRpb246IG5vZGVMb2NhdGlvbihuYW1lTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksIHBhcmFtZXRlcnMsIHJldHVyblR5cGV9XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGJvdW5kZWQgZmluYWwvcHJpdmF0ZS1maWVsZCBQSFAgcmVmZXJlbmNlLWNsYXNzIHByb2ZpbGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuQ2xhc3N9IG5vZGUgLSBQYXJzZXIgY2xhc3MuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb259IGRlY2xhcmF0aW9uIC0gUHJlZGVjbGFyZWQgY2xhc3MgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb24+fSBub21pbmFsTmFtZXMgLSBWaXNpYmxlIG5vbWluYWwgZGVjbGFyYXRpb25zLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbj59IHJlY29yZHMgLSBSZWNvcmRzIGJ5IGlkZW50aXR5LlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uPn0gY2xhc3NlcyAtIENsYXNzZXMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIFBocEZ1bmN0aW9uU2lnbmF0dXJlPn0gZnVuY3Rpb25zIC0gVG9wLWxldmVsIHNpZ25hdHVyZXMuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24+fSBlcnJvck5hbWVzIC0gRXJyb3JzIGJ5IG5hbWUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24+fSBlcnJvcnMgLSBFcnJvcnMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb259IFNlbWFudGljIGNsYXNzLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UGhwUmVmZXJlbmNlQ2xhc3Mobm9kZSwgZGVjbGFyYXRpb24sIG5vbWluYWxOYW1lcywgcmVjb3JkcywgY2xhc3NlcywgZnVuY3Rpb25zLCBlcnJvck5hbWVzLCBlcnJvcnMsXG4gIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS5pc0Fub255bW91cyB8fCAhbm9kZS5pc0ZpbmFsIHx8IG5vZGUuaXNSZWFkb25seSB8fCBub2RlLmlzQWJzdHJhY3QgfHwgbm9kZS5leHRlbmRzIHx8IG5vZGUuaW1wbGVtZW50cz8ubGVuZ3RoIHx8XG4gICAgbm9kZS5hdHRyR3JvdXBzLmxlbmd0aCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwicmVmZXJlbmNlIGNsYXNzIGluaGVyaXRhbmNlIG9yIG5vbmNhbm9uaWNhbCBtb2RpZmllclwiLCBsb2NhdGlvbilcbiAgY29uc3QgZmllbGRTdGF0ZW1lbnRzID0gbm9kZS5ib2R5LmZpbHRlcigobWVtYmVyKSA9PiBtZW1iZXIua2luZCA9PSBcInByb3BlcnR5c3RhdGVtZW50XCIpXG4gIGNvbnN0IG1ldGhvZE5vZGVzID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk1ldGhvZFtdfSAqLyAobm9kZS5ib2R5LmZpbHRlcigobWVtYmVyKSA9PiBtZW1iZXIua2luZCA9PSBcIm1ldGhvZFwiKSlcbiAgY29uc3QgY29uc3RydWN0b3JzID0gbWV0aG9kTm9kZXMuZmlsdGVyKChtZXRob2QpID0+ICh0eXBlb2YgbWV0aG9kLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG1ldGhvZC5uYW1lIDogbWV0aG9kLm5hbWUubmFtZSkgPT0gXCJfX2NvbnN0cnVjdFwiKVxuICBjb25zdCBvcmRpbmFyeU1ldGhvZHMgPSBtZXRob2ROb2Rlcy5maWx0ZXIoKG1ldGhvZCkgPT4gIWNvbnN0cnVjdG9ycy5pbmNsdWRlcyhtZXRob2QpKVxuXG4gIGlmIChjb25zdHJ1Y3RvcnMubGVuZ3RoICE9IDEgfHwgZmllbGRTdGF0ZW1lbnRzLmxlbmd0aCA9PSAwIHx8IGZpZWxkU3RhdGVtZW50cy5sZW5ndGggKyBtZXRob2ROb2Rlcy5sZW5ndGggIT0gbm9kZS5ib2R5Lmxlbmd0aCkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInJlZmVyZW5jZSBjbGFzcyByZXF1aXJlcyBwcml2YXRlIGZpZWxkcywgb25lIGNvbnN0cnVjdG9yLCBhbmQgb3JkaW5hcnkgbWV0aG9kc1wiLCBsb2NhdGlvbilcbiAgfVxuICBkZWNsYXJhdGlvbi5maWVsZHMgPSBmaWVsZFN0YXRlbWVudHMubWFwKChzdGF0ZW1lbnQsIGluZGV4KSA9PiB7XG4gICAgY29uc3QgZmllbGRMb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihzdGF0ZW1lbnQsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgY29uc3QgcHJvcGVydGllcyA9IFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJwcm9wZXJ0aWVzXCIpXG4gICAgY29uc3QgcHJvcGVydHkgPSBBcnJheS5pc0FycmF5KHByb3BlcnRpZXMpICYmIHByb3BlcnRpZXMubGVuZ3RoID09IDEgPyBwcm9wZXJ0aWVzWzBdIDogdW5kZWZpbmVkXG4gICAgY29uc3QgbmFtZU5vZGUgPSBwcm9wZXJ0eT8ubmFtZVxuICAgIGNvbnN0IG5hbWUgPSB0eXBlb2YgbmFtZU5vZGUgPT0gXCJzdHJpbmdcIiA/IG5hbWVOb2RlIDogbmFtZU5vZGU/Lm5hbWVcblxuICAgIGlmIChSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwidmlzaWJpbGl0eVwiKSAhPSBcInByaXZhdGVcIiB8fCBSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwiaXNTdGF0aWNcIikgfHxcbiAgICAgIFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJpc0Fic3RyYWN0XCIpIHx8IFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJpc0ZpbmFsXCIpIHx8ICFwcm9wZXJ0eSB8fFxuICAgICAgdHlwZW9mIG5hbWUgIT0gXCJzdHJpbmdcIiB8fCBwcm9wZXJ0eS52YWx1ZSB8fCBwcm9wZXJ0eS5yZWFkb25seSB8fCBwcm9wZXJ0eS5udWxsYWJsZSB8fCBwcm9wZXJ0eS5hdHRyR3JvdXBzPy5sZW5ndGggfHxcbiAgICAgIHByb3BlcnR5Lmhvb2tzPy5sZW5ndGgpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm5vbmNhbm9uaWNhbCBwcml2YXRlIGluc3RhbmNlIGZpZWxkXCIsIGZpZWxkTG9jYXRpb24pXG4gICAgY29uc3QgdHlwZSA9IGNvbnZlcnRUeXBlKHByb3BlcnR5LnR5cGUsIGBQcml2YXRlIGZpZWxkICcke25hbWV9J2AsIGZpZWxkTG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIG5vbWluYWxOYW1lcylcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtpZDogYCR7ZGVjbGFyYXRpb24uaWR9OmZpZWxkOiR7aW5kZXh9YCwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUHJpdmF0ZUZpZWxkXCIpLFxuICAgICAgbG9jYXRpb246IGZpZWxkTG9jYXRpb24sIG5hbWUsIHR5cGV9LCB7bmFtZTogbm9kZUxvY2F0aW9uKHR5cGVvZiBuYW1lTm9kZSA9PSBcInN0cmluZ1wiID8gcHJvcGVydHkgOiBuYW1lTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICB9KVxuICBjb25zdCBjb25zdHJ1Y3Rvck5vZGUgPSBjb25zdHJ1Y3RvcnNbMF1cbiAgY29uc3QgY29uc3RydWN0b3JTaWduYXR1cmUgPSBjb252ZXJ0UGhwQ2xhc3NDYWxsYWJsZVNpZ25hdHVyZShjb25zdHJ1Y3Rvck5vZGUsIG5vbWluYWxOYW1lcyxcbiAgICBgJHtkZWNsYXJhdGlvbi5pZH06Y29uc3RydWN0b3JgLCB0cnVlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGRlY2xhcmF0aW9uLmNvbnN0cnVjdG9yID0gd2l0aFBhcnNlclJhbmdlcyh7Ym9keTogLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gKi8gKHt9KSxcbiAgICBpZDogYCR7ZGVjbGFyYXRpb24uaWR9OmNvbnN0cnVjdG9yYCwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQ29uc3RydWN0b3JEZWNsYXJhdGlvblwiKSxcbiAgICBsb2NhdGlvbjogY29uc3RydWN0b3JTaWduYXR1cmUubG9jYXRpb24sIHBhcmFtZXRlcnM6IGNvbnN0cnVjdG9yU2lnbmF0dXJlLnBhcmFtZXRlcnN9LCB7Y29uc3RydWN0b3I6IGNvbnN0cnVjdG9yU2lnbmF0dXJlLm5hbWVMb2NhdGlvbn0pXG4gIGNvbnN0IG1ldGhvZFNpZ25hdHVyZXMgPSBvcmRpbmFyeU1ldGhvZHMubWFwKChtZXRob2QsIGluZGV4KSA9PiBjb252ZXJ0UGhwQ2xhc3NDYWxsYWJsZVNpZ25hdHVyZShtZXRob2QsIG5vbWluYWxOYW1lcyxcbiAgICBgJHtkZWNsYXJhdGlvbi5pZH06bWV0aG9kOiR7aW5kZXh9YCwgZmFsc2UsIGZpbGVuYW1lLCBzb3VyY2UpKVxuXG4gIGRlY2xhcmF0aW9uLm1ldGhvZHMgPSBtZXRob2RTaWduYXR1cmVzLm1hcCgoc2lnbmF0dXJlLCBpbmRleCkgPT4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgYm9keTogLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gKi8gKHt9KSwgaWQ6IGAke2RlY2xhcmF0aW9uLmlkfTptZXRob2Q6JHtpbmRleH1gLFxuICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIk1ldGhvZERlY2xhcmF0aW9uXCIpLCBsb2NhdGlvbjogc2lnbmF0dXJlLmxvY2F0aW9uLCBuYW1lOiBzaWduYXR1cmUubmFtZSxcbiAgICBwYXJhbWV0ZXJzOiBzaWduYXR1cmUucGFyYW1ldGVycyxcbiAgICByZXR1cm5UeXBlOiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlfSAqLyAoc2lnbmF0dXJlLnJldHVyblR5cGUpXG4gIH0sIHtuYW1lOiBzaWduYXR1cmUubmFtZUxvY2F0aW9ufSkpXG4gIGNvbnN0IGJhc2UgPSB7YmluZGluZ3M6IG5ldyBNYXAoKSwgY2xhc3NlcywgY3VycmVudENsYXNzOiBkZWNsYXJhdGlvbiwgZXJyb3JOYW1lcywgZXJyb3JzLCBmdW5jdGlvbnMsXG4gICAgcmVjb3JkTmFtZXM6IG5vbWluYWxOYW1lcywgcmVjb3Jkc31cblxuICBkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5ib2R5ID0gY29udmVydEJsb2NrKC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5CbG9ja30gKi8gKGNvbnN0cnVjdG9yTm9kZS5ib2R5KSwgZmlsZW5hbWUsIHNvdXJjZSxcbiAgICB7Li4uYmFzZSwgYmluZGluZ3M6IG5ldyBNYXAoZGVjbGFyYXRpb24uY29uc3RydWN0b3IucGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlcikgPT4gW3BhcmFtZXRlci5uYW1lLCBwYXJhbWV0ZXIudHlwZV0pKSxcbiAgICAgIHJldHVyblR5cGU6IHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJUeXBlUmVmZXJlbmNlXCIpLCBuYW1lOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJ2b2lkXCIpfX0pXG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBvcmRpbmFyeU1ldGhvZHMubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgY29uc3QgbWV0aG9kID0gZGVjbGFyYXRpb24ubWV0aG9kc1tpbmRleF1cblxuICAgIG1ldGhvZC5ib2R5ID0gY29udmVydEJsb2NrKC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5CbG9ja30gKi8gKG9yZGluYXJ5TWV0aG9kc1tpbmRleF0uYm9keSksIGZpbGVuYW1lLCBzb3VyY2UsXG4gICAgICB7Li4uYmFzZSwgYmluZGluZ3M6IG5ldyBNYXAobWV0aG9kLnBhcmFtZXRlcnMubWFwKChwYXJhbWV0ZXIpID0+IFtwYXJhbWV0ZXIubmFtZSwgcGFyYW1ldGVyLnR5cGVdKSksIHJldHVyblR5cGU6IG1ldGhvZC5yZXR1cm5UeXBlfSlcbiAgfVxuICBjb25zdCBuYW1lTm9kZSA9IHR5cGVvZiBub2RlLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG5vZGUgOiBub2RlLm5hbWVcblxuICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyhkZWNsYXJhdGlvbiwge25hbWU6IG5vZGVMb2NhdGlvbihuYW1lTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSl9KVxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBleGFjdCBmaW5hbCByZWFkb25seSBwcm9tb3RlZC1wcm9wZXJ0eSBQSFAgcmVjb3JkLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkNsYXNzfSBub2RlIC0gUEhQIGNsYXNzIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbn0gZGVjbGFyYXRpb24gLSBQcmVkZWNsYXJlZCBub21pbmFsIGlkZW50aXR5LlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbj59IHJlY29yZE5hbWVzIC0gUmVjb3JkIGRlY2xhcmF0aW9ucyBieSBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbn0gU2VtYW50aWMgcmVjb3JkLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UGhwUmVjb3JkKG5vZGUsIGRlY2xhcmF0aW9uLCByZWNvcmROYW1lcywgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuICBjb25zdCBnZW5lcmljID0gKGRlY2xhcmF0aW9uLnR5cGVQYXJhbWV0ZXJzPy5sZW5ndGggPz8gMCkgPiAwXG5cbiAgaWYgKG5vZGUuaXNBbm9ueW1vdXMgfHwgIW5vZGUuaXNGaW5hbCB8fCBub2RlLmlzUmVhZG9ubHkgPT0gZ2VuZXJpYyB8fCBub2RlLmlzQWJzdHJhY3QgfHwgbm9kZS5leHRlbmRzIHx8IG5vZGUuaW1wbGVtZW50cz8ubGVuZ3RoIHx8XG4gICAgbm9kZS5hdHRyR3JvdXBzLmxlbmd0aCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibm9uY2Fub25pY2FsIHJlY29yZCBjbGFzcyBtb2RpZmllcnNcIiwgbG9jYXRpb24pXG4gIGlmIChub2RlLmJvZHkubGVuZ3RoIDwgMSB8fCBub2RlLmJvZHlbMF0ua2luZCAhPSBcIm1ldGhvZFwiIHx8ICFnZW5lcmljICYmIG5vZGUuYm9keS5sZW5ndGggIT0gMSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInJlY29yZCBjbGFzcyBib2R5IG91dHNpZGUgb25lIGNvbnN0cnVjdG9yXCIsIG5vZGVMb2NhdGlvbihub2RlLmJvZHlbMV0gPz8gbm9kZS5ib2R5WzBdID8/IG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGNvbnN0IGNvbnN0cnVjdG9yID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk1ldGhvZH0gKi8gKG5vZGUuYm9keVswXSlcbiAgY29uc3QgdHlwZVBhcmFtZXRlck5hbWVzID0gbmV3IE1hcCgoZGVjbGFyYXRpb24udHlwZVBhcmFtZXRlcnMgPz8gW10pLm1hcCgocGFyYW1ldGVyKSA9PiBbcGFyYW1ldGVyLm5hbWUsIHBhcmFtZXRlcl0pKVxuICBjb25zdCBjb25zdHJ1Y3Rvck5hbWUgPSB0eXBlb2YgY29uc3RydWN0b3IubmFtZSA9PSBcInN0cmluZ1wiID8gY29uc3RydWN0b3IubmFtZSA6IGNvbnN0cnVjdG9yLm5hbWUubmFtZVxuXG4gIGlmIChjb25zdHJ1Y3Rvck5hbWUgIT0gXCJfX2NvbnN0cnVjdFwiIHx8IGNvbnN0cnVjdG9yLnZpc2liaWxpdHkgIT0gXCJwdWJsaWNcIiB8fCBjb25zdHJ1Y3Rvci5pc1N0YXRpYyB8fCBjb25zdHJ1Y3Rvci5pc0Fic3RyYWN0IHx8XG4gICAgY29uc3RydWN0b3IuaXNGaW5hbCB8fCBSZWZsZWN0LmdldChjb25zdHJ1Y3RvciwgXCJpc1JlYWRvbmx5XCIpIHx8IGNvbnN0cnVjdG9yLmJ5cmVmIHx8IGNvbnN0cnVjdG9yLnR5cGUgfHwgY29uc3RydWN0b3IubnVsbGFibGUgfHxcbiAgICBjb25zdHJ1Y3Rvci5hdHRyR3JvdXBzLmxlbmd0aCB8fCAhY29uc3RydWN0b3IuYm9keSB8fCBjb25zdHJ1Y3Rvci5ib2R5LmNoaWxkcmVuLmxlbmd0aCAhPSAwKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibm9uY2Fub25pY2FsIHJlY29yZCBjb25zdHJ1Y3RvclwiLCBub2RlTG9jYXRpb24oY29uc3RydWN0b3IsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGNvbnN0IGRvY3VtZW50ZWQgPSBmdW5jdGlvbkRvY3VtZW50ZWRUeXBlcygvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuRnVuY3Rpb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChjb25zdHJ1Y3RvcikpLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGRlY2xhcmF0aW9uLmZpZWxkcyA9IGNvbnN0cnVjdG9yLmFyZ3VtZW50cy5tYXAoKHBhcmFtZXRlcikgPT4ge1xuICAgIGNvbnN0IGZpZWxkTG9jYXRpb24gPSBub2RlTG9jYXRpb24ocGFyYW1ldGVyLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIGNvbnN0IG5hbWUgPSB0eXBlb2YgcGFyYW1ldGVyLm5hbWUgPT0gXCJzdHJpbmdcIiA/IHBhcmFtZXRlci5uYW1lIDogcGFyYW1ldGVyLm5hbWUubmFtZVxuICAgIGNvbnN0IGRvY3VtZW50ZWRUeXBlID0gZG9jdW1lbnRlZC5wYXJhbWV0ZXJzLmdldChuYW1lKVxuICAgIGNvbnN0IG5hdGl2ZVR5cGUgPSBwaHBUeXBlTmFtZShwYXJhbWV0ZXIudHlwZSlcblxuICAgIGlmIChwYXJhbWV0ZXIuZmxhZ3MgIT0gKGdlbmVyaWMgPyA0IDogMSkgfHwgcGFyYW1ldGVyLmJ5cmVmIHx8IHBhcmFtZXRlci52YXJpYWRpYyB8fCBwYXJhbWV0ZXIudmFsdWUgfHwgcGFyYW1ldGVyLnJlYWRvbmx5IHx8XG4gICAgICBwYXJhbWV0ZXIuaG9va3MubGVuZ3RoIHx8IHBhcmFtZXRlci5hdHRyR3JvdXBzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwicmVjb3JkIGZpZWxkIG91dHNpZGUgcHVibGljIHByb21vdGVkLXByb3BlcnR5IHByb2ZpbGVcIiwgZmllbGRMb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKG5hdGl2ZVR5cGUgPT0gXCJhcnJheVwiICYmICFkb2N1bWVudGVkVHlwZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwicGhwXCIsIGBSZWNvcmQgZmllbGQgJyR7bmFtZX0nYCwgZmllbGRMb2NhdGlvbilcbiAgICBsZXQgdHlwZSA9IGRvY3VtZW50ZWRUeXBlXG4gICAgICA/IGRvY3VtZW50ZWRWYWx1ZVR5cGUoe2xhbmd1YWdlOiBcInBocFwiLCBsb2NhdGlvbjogZG9jdW1lbnRlZFR5cGUubG9jYXRpb24sIG93bmVyTG9jYXRpb246IGZpZWxkTG9jYXRpb24sIHJlY29yZHM6IHJlY29yZE5hbWVzLFxuICAgICAgICBzb3VyY2UsIHNvdXJjZVR5cGU6IGRvY3VtZW50ZWRUeXBlLnNvdXJjZVR5cGUsIHN1YmplY3Q6IGBSZWNvcmQgZmllbGQgJyR7bmFtZX0nYCwgdHlwZVBhcmFtZXRlcnM6IHR5cGVQYXJhbWV0ZXJOYW1lc30pXG4gICAgICA6IGNvbnZlcnRUeXBlKHBhcmFtZXRlci50eXBlLCBgUmVjb3JkIGZpZWxkICcke25hbWV9J2AsIGZpZWxkTG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIHJlY29yZE5hbWVzKVxuXG4gICAgaWYgKGRvY3VtZW50ZWRUeXBlICYmICFwaHBEb2N1bWVudGVkTmF0aXZlVHlwZU1hdGNoZXMobmF0aXZlVHlwZSwgcGFyYW1ldGVyLm51bGxhYmxlLCB0eXBlLCByZWNvcmROYW1lcykpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImRvY3VtZW50ZWQgcmVjb3JkIGZpZWxkIHR5cGUgaW5jb21wYXRpYmxlIHdpdGggbmF0aXZlIHR5cGVcIiwgZG9jdW1lbnRlZFR5cGUubG9jYXRpb24pXG4gICAgfVxuXG4gICAgaWYgKHBhcmFtZXRlci5udWxsYWJsZSAmJiB0eXBlLmtpbmQgIT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgICAgaWYgKCFwYXJhbWV0ZXIudHlwZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwicGhwXCIsIGBSZWNvcmQgZmllbGQgJyR7bmFtZX0nYCwgZmllbGRMb2NhdGlvbilcbiAgICAgIHR5cGUgPSBudWxsYWJsZVR5cGUodHlwZSwgcGFyYW1ldGVyLnR5cGUsIHBhcmFtZXRlci5sb2M/LnN0YXJ0Lm9mZnNldCA/PyAwLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0gZWxzZSBpZiAoIXBhcmFtZXRlci5udWxsYWJsZSAmJiB0eXBlLmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIiAmJiB0eXBlLnZhbHVlVHlwZS5raW5kICE9IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm9wdGlvbmFsIGFubm90YXRpb24gd2l0aG91dCBudWxsYWJsZSBuYXRpdmUgcmVjb3JkIGZpZWxkXCIsIGRvY3VtZW50ZWRUeXBlPy5sb2NhdGlvbiA/PyBmaWVsZExvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBmaWVsZCA9IHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJSZWNvcmRGaWVsZFwiKSwgbG9jYXRpb246IGZpZWxkTG9jYXRpb24sIG5hbWUsIHR5cGV9XG4gICAgY29uc3QgbmFtZU5vZGUgPSB0eXBlb2YgcGFyYW1ldGVyLm5hbWUgPT0gXCJzdHJpbmdcIiA/IHBhcmFtZXRlciA6IHBhcmFtZXRlci5uYW1lXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyhmaWVsZCwge25hbWU6IG5vZGVMb2NhdGlvbihuYW1lTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICB9KVxuICBjb25zdCBleHRyYURvY3VtZW50ZWQgPSBbLi4uZG9jdW1lbnRlZC5wYXJhbWV0ZXJzLmtleXMoKV0uZmluZCgobmFtZSkgPT5cbiAgICAhY29uc3RydWN0b3IuYXJndW1lbnRzLnNvbWUoKHBhcmFtZXRlcikgPT4gKHR5cGVvZiBwYXJhbWV0ZXIubmFtZSA9PSBcInN0cmluZ1wiID8gcGFyYW1ldGVyLm5hbWUgOiBwYXJhbWV0ZXIubmFtZS5uYW1lKSA9PSBuYW1lKSlcblxuICBpZiAoZXh0cmFEb2N1bWVudGVkIHx8IGRvY3VtZW50ZWQucmV0dXJuVHlwZSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiaW52YWxpZCByZWNvcmQgY29uc3RydWN0b3IgYW5ub3RhdGlvblwiLCBsb2NhdGlvbilcbiAgaWYgKGdlbmVyaWMpIHZhbGlkYXRlUGhwR2VuZXJpY1JlY29yZEdldHRlcnMobm9kZSwgZGVjbGFyYXRpb24sIHJlY29yZE5hbWVzLCBmaWxlbmFtZSwgc291cmNlKVxuICBjb25zdCBuYW1lTm9kZSA9IHR5cGVvZiBub2RlLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG5vZGUgOiBub2RlLm5hbWVcblxuICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyhkZWNsYXJhdGlvbiwge25hbWU6IG5vZGVMb2NhdGlvbihuYW1lTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSl9KVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyB0aGUgZXhhY3QgYWNjZXNzb3IgaGFsZiBvZiBQSFAncyBkb2N1bWVudGVkIGdlbmVyaWMtcmVjb3JkIHByb2ZpbGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuQ2xhc3N9IG5vZGUgLSBQSFAgY2xhc3MgZGVjbGFyYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9ufSBkZWNsYXJhdGlvbiAtIENvbnZlcnRlZCByZWNvcmQuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uPn0gcmVjb3JkTmFtZXMgLSBWaXNpYmxlIHJlY29yZHMuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlUGhwR2VuZXJpY1JlY29yZEdldHRlcnMobm9kZSwgZGVjbGFyYXRpb24sIHJlY29yZE5hbWVzLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGdldHRlcnMgPSBub2RlLmJvZHkuc2xpY2UoMSlcbiAgY29uc3QgdHlwZVBhcmFtZXRlcnMgPSBuZXcgTWFwKChkZWNsYXJhdGlvbi50eXBlUGFyYW1ldGVycyA/PyBbXSkubWFwKChwYXJhbWV0ZXIpID0+IFtwYXJhbWV0ZXIubmFtZSwgcGFyYW1ldGVyXSkpXG5cbiAgaWYgKGdldHRlcnMubGVuZ3RoICE9IGRlY2xhcmF0aW9uLmZpZWxkcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJnZW5lcmljIHJlY29yZCBnZXR0ZXIgY291bnRcIiwgbm9kZUxvY2F0aW9uKGdldHRlcnNbZGVjbGFyYXRpb24uZmllbGRzLmxlbmd0aF0gPz8gbm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgZ2V0dGVycy5mb3JFYWNoKChjYW5kaWRhdGUsIGluZGV4KSA9PiB7XG4gICAgY29uc3QgZmllbGQgPSBkZWNsYXJhdGlvbi5maWVsZHNbaW5kZXhdXG5cbiAgICBpZiAoY2FuZGlkYXRlLmtpbmQgIT0gXCJtZXRob2RcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibm9uY2Fub25pY2FsIGdlbmVyaWMgcmVjb3JkIGdldHRlclwiLCBub2RlTG9jYXRpb24oY2FuZGlkYXRlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICBjb25zdCBnZXR0ZXIgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTWV0aG9kfSAqLyAoY2FuZGlkYXRlKVxuICAgIGNvbnN0IG5hbWUgPSB0eXBlb2YgZ2V0dGVyLm5hbWUgPT0gXCJzdHJpbmdcIiA/IGdldHRlci5uYW1lIDogZ2V0dGVyLm5hbWUubmFtZVxuICAgIGNvbnN0IHN0YXRlbWVudCA9IGdldHRlci5ib2R5Py5jaGlsZHJlblswXVxuICAgIGNvbnN0IHJldHVybmVkID0gc3RhdGVtZW50Py5raW5kID09IFwicmV0dXJuXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuUmV0dXJufSAqLyAoc3RhdGVtZW50KS5leHByIDogdW5kZWZpbmVkXG4gICAgY29uc3QgbG9va3VwID0gcmV0dXJuZWQ/LmtpbmQgPT0gXCJwcm9wZXJ0eWxvb2t1cFwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlByb3BlcnR5TG9va3VwfSAqLyAocmV0dXJuZWQpIDogdW5kZWZpbmVkXG4gICAgY29uc3QgcmVjZWl2ZXIgPSBsb29rdXA/LndoYXQua2luZCA9PSBcInZhcmlhYmxlXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuVmFyaWFibGV9ICovIChsb29rdXAud2hhdCkgOiB1bmRlZmluZWRcbiAgICBjb25zdCBtZW1iZXIgPSBsb29rdXA/Lm9mZnNldC5raW5kID09IFwiaWRlbnRpZmllclwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLklkZW50aWZpZXJ9ICovIChsb29rdXAub2Zmc2V0KSA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKG5hbWUgIT0gZmllbGQubmFtZSB8fCBnZXR0ZXIudmlzaWJpbGl0eSAhPSBcInB1YmxpY1wiIHx8IGdldHRlci5pc1N0YXRpYyB8fCBnZXR0ZXIuaXNBYnN0cmFjdCB8fCBnZXR0ZXIuaXNGaW5hbCB8fFxuICAgICAgUmVmbGVjdC5nZXQoZ2V0dGVyLCBcImlzUmVhZG9ubHlcIikgfHwgZ2V0dGVyLmJ5cmVmIHx8IGdldHRlci5hcmd1bWVudHMubGVuZ3RoIHx8IGdldHRlci5hdHRyR3JvdXBzLmxlbmd0aCB8fFxuICAgICAgIWdldHRlci5ib2R5IHx8IGdldHRlci5ib2R5LmNoaWxkcmVuLmxlbmd0aCAhPSAxIHx8IHJlY2VpdmVyPy5uYW1lICE9IFwidGhpc1wiIHx8IG1lbWJlcj8ubmFtZSAhPSBmaWVsZC5uYW1lKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJub25jYW5vbmljYWwgZ2VuZXJpYyByZWNvcmQgZ2V0dGVyXCIsIG5vZGVMb2NhdGlvbihnZXR0ZXIsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIH1cbiAgICBjb25zdCBkb2N1bWVudGVkID0gZnVuY3Rpb25Eb2N1bWVudGVkVHlwZXMoXG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuRnVuY3Rpb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChnZXR0ZXIpKSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICAgIGlmIChkb2N1bWVudGVkLnBhcmFtZXRlcnMuc2l6ZSB8fCBkb2N1bWVudGVkLnR5cGVQYXJhbWV0ZXJzIHx8ICFkb2N1bWVudGVkLnJldHVyblR5cGUpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBnZW5lcmljIHJlY29yZCBnZXR0ZXIgdHlwZVwiLCBub2RlTG9jYXRpb24oZ2V0dGVyLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgY29uc3QgcmV0dXJuVHlwZSA9IGRvY3VtZW50ZWRWYWx1ZVR5cGUoe2xhbmd1YWdlOiBcInBocFwiLCBsb2NhdGlvbjogZG9jdW1lbnRlZC5yZXR1cm5UeXBlLmxvY2F0aW9uLFxuICAgICAgb3duZXJMb2NhdGlvbjogbm9kZUxvY2F0aW9uKGdldHRlciwgZmlsZW5hbWUsIHNvdXJjZSksIHJlY29yZHM6IHJlY29yZE5hbWVzLCBzb3VyY2UsXG4gICAgICBzb3VyY2VUeXBlOiBkb2N1bWVudGVkLnJldHVyblR5cGUuc291cmNlVHlwZSwgc3ViamVjdDogYFJlY29yZCBnZXR0ZXIgJyR7bmFtZX0nYCwgdHlwZVBhcmFtZXRlcnN9KVxuICAgIGNvbnN0IG5hdGl2ZVR5cGUgPSBwaHBUeXBlTmFtZShnZXR0ZXIudHlwZSlcblxuICAgIGlmICghcGhwRG9jdW1lbnRlZE5hdGl2ZVR5cGVNYXRjaGVzKG5hdGl2ZVR5cGUsIGdldHRlci5udWxsYWJsZSwgcmV0dXJuVHlwZSwgcmVjb3JkTmFtZXMpIHx8XG4gICAgICAhc2FtZVZhbHVlVHlwZShyZXR1cm5UeXBlLCBmaWVsZC50eXBlKSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZ2VuZXJpYyByZWNvcmQgZ2V0dGVyIHR5cGUgbWlzbWF0Y2hcIiwgZG9jdW1lbnRlZC5yZXR1cm5UeXBlLmxvY2F0aW9uKVxuICAgIH1cbiAgfSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZXhpc3RpbmcgUEhQIGlmL2Vsc2UgdGVybWluYWwgd2l0aCByZXN0cmljdGVkIGJyYW5jaCBwcmVmaXhlcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZn0gbm9kZSAtIFBIUCBpZiBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7UGhwQ29udmVyc2lvbkNvbnRleHR9IGNvbnRleHQgLSBUeXBlZCBjb252ZXJzaW9uIGNvbnRleHQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuSWZTdGF0ZW1lbnR9IFNlbWFudGljIGJyYW5jaC5cbiAqL1xuZnVuY3Rpb24gY29udmVydElmKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS5zaG9ydEZvcm0pIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImFsdGVybmF0aXZlIGlmIHN5bnRheFwiLCBsb2NhdGlvbilcbiAgaWYgKG5vZGUuYm9keS5raW5kICE9IFwiYmxvY2tcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiaWYgd2l0aG91dCBibG9jayBjb25zZXF1ZW50XCIsIGxvY2F0aW9uKVxuICBpZiAobm9kZS50ZXN0LmtpbmQgPT0gXCJ2YXJpYWJsZVwiKSB7XG4gICAgY29uc3QgdGVzdGVkID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlZhcmlhYmxlfSAqLyAobm9kZS50ZXN0KVxuXG4gICAgaWYgKHR5cGVvZiB0ZXN0ZWQubmFtZSA9PSBcInN0cmluZ1wiICYmIGNvbnRleHQuYmluZGluZ3MuZ2V0KHRlc3RlZC5uYW1lKT8ua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJvcHRpb25hbCB0cnV0aGluZXNzIGNvbmRpdGlvblwiLCBub2RlTG9jYXRpb24odGVzdGVkLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gIH1cblxuICBjb25zdCBjb25kaXRpb24gPSBjb252ZXJ0RXhwcmVzc2lvbihub2RlLnRlc3QsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpXG4gIGNvbnN0IGNvbnNlcXVlbnRDb250ZXh0ID0gey4uLmNvbnRleHQsIGJpbmRpbmdzOiBuZXcgTWFwKGNvbnRleHQuYmluZGluZ3MpfVxuICBjb25zdCBhbHRlcm5hdGVDb250ZXh0ID0gey4uLmNvbnRleHQsIGJpbmRpbmdzOiBuZXcgTWFwKGNvbnRleHQuYmluZGluZ3MpfVxuICBsZXQgYWx0ZXJuYXRlXG5cbiAgaWYgKG5vZGUuYWx0ZXJuYXRlKSB7XG4gICAgaWYgKG5vZGUuYWx0ZXJuYXRlLmtpbmQgPT0gXCJibG9ja1wiKSB7XG4gICAgICBhbHRlcm5hdGUgPSBjb252ZXJ0QmxvY2soLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkJsb2NrfSAqLyAobm9kZS5hbHRlcm5hdGUpLCBmaWxlbmFtZSwgc291cmNlLCBhbHRlcm5hdGVDb250ZXh0KVxuICAgIH0gZWxzZSBpZiAobm9kZS5hbHRlcm5hdGUua2luZCA9PSBcImlmXCIpIHtcbiAgICAgIGNvbnN0IG5lc3RlZCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZn0gKi8gKG5vZGUuYWx0ZXJuYXRlKVxuXG4gICAgICBhbHRlcm5hdGUgPSB7XG4gICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkJsb2NrXCIpLFxuICAgICAgICBsb2NhdGlvbjogbm9kZUxvY2F0aW9uKG5lc3RlZCwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICAgIHN0YXRlbWVudHM6IFtjb252ZXJ0SWYobmVzdGVkLCBmaWxlbmFtZSwgc291cmNlLCBhbHRlcm5hdGVDb250ZXh0KV1cbiAgICAgIH1cbiAgICB9IGVsc2UgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGBpZiBhbHRlcm5hdGUgJHtub2RlLmFsdGVybmF0ZS5raW5kfWAsIG5vZGVMb2NhdGlvbihub2RlLmFsdGVybmF0ZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLihhbHRlcm5hdGUgPyB7YWx0ZXJuYXRlfSA6IHt9KSxcbiAgICBjb25kaXRpb24sXG4gICAgY29uc2VxdWVudDogY29udmVydEJsb2NrKG5vZGUuYm9keSwgZmlsZW5hbWUsIHNvdXJjZSwgY29uc2VxdWVudENvbnRleHQpLFxuICAgIGtpbmQ6IFwiSWZTdGF0ZW1lbnRcIixcbiAgICBsb2NhdGlvblxuICB9XG59XG5cbi8qKlxuICogQ29udmVydHMgZXhhY3QgYnJhY2VkIFBIUCBgd2hpbGUgKCRjb25kaXRpb24pIHsgLi4uIH1gIHN5bnRheC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5XaGlsZX0gbm9kZSAtIFBIUCB3aGlsZSBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7UGhwQ29udmVyc2lvbkNvbnRleHR9IGNvbnRleHQgLSBUeXBlZCBjb252ZXJzaW9uIGNvbnRleHQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuV2hpbGVTdGF0ZW1lbnR9IFNlbWFudGljIGxvb3AuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRXaGlsZShub2RlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG5vZGUuc2hvcnRGb3JtKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJhbHRlcm5hdGl2ZSB3aGlsZSBzeW50YXhcIiwgbG9jYXRpb24pXG4gIGlmICghbm9kZS5ib2R5IHx8IG5vZGUuYm9keS5raW5kICE9IFwiYmxvY2tcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIndoaWxlIHdpdGhvdXQgYmxvY2sgYm9keVwiLCBub2RlLmJvZHkgPyBub2RlTG9jYXRpb24obm9kZS5ib2R5LCBmaWxlbmFtZSwgc291cmNlKSA6IGxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IGJvZHlDb250ZXh0ID0gey4uLmNvbnRleHQsIGJpbmRpbmdzOiBuZXcgTWFwKGNvbnRleHQuYmluZGluZ3MpfVxuXG4gIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICBib2R5OiBjb252ZXJ0QmxvY2soLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkJsb2NrfSAqLyAobm9kZS5ib2R5KSwgZmlsZW5hbWUsIHNvdXJjZSwgYm9keUNvbnRleHQpLFxuICAgIGNvbmRpdGlvbjogY29udmVydEV4cHJlc3Npb24obm9kZS50ZXN0LCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0LCB1bmRlZmluZWQsIHRydWUpLFxuICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIldoaWxlU3RhdGVtZW50XCIpLFxuICAgIGxvY2F0aW9uXG4gIH0sIHtrZXl3b3JkOiB0b2tlbkxvY2F0aW9uKFwid2hpbGVcIiwgbm9kZS5sb2M/LnN0YXJ0Lm9mZnNldCA/PyAwLCBub2RlLnRlc3QubG9jPy5zdGFydC5vZmZzZXQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSl9KVxufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgUEhQIGVjaG8gZW50cnkgcG9pbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuRWNob30gbm9kZSAtIFBIUCBlY2hvIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtQaHBDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5QcmludFN0YXRlbWVudH0gUHJpbnQgc3RhdGVtZW50LlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UHJpbnQobm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChub2RlLmV4cHJlc3Npb25zLmxlbmd0aCAhPSAyIHx8IG5vZGUuZXhwcmVzc2lvbnNbMV0ua2luZCAhPSBcIm5hbWVcIiB8fFxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5OYW1lfSAqLyAobm9kZS5leHByZXNzaW9uc1sxXSkubmFtZSAhPSBcIlBIUF9FT0xcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImVjaG8gd2l0aG91dCBvbmUgZXhwcmVzc2lvbiBhbmQgUEhQX0VPTFwiLCBsb2NhdGlvbilcbiAgfVxuXG4gIHJldHVybiB7ZXhwcmVzc2lvbjogY29udmVydEV4cHJlc3Npb24obm9kZS5leHByZXNzaW9uc1swXSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCksIGtpbmQ6IFwiUHJpbnRTdGF0ZW1lbnRcIiwgbG9jYXRpb259XG59XG5cbi8qKlxuICogUGFyc2VzIFBIUCBpbnRvIHRoZSBzaGFyZWQgc2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHtvYmplY3R9IGlucHV0IC0gUGFyc2VyIGlucHV0LlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0LmZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0LnNvdXJjZSAtIFNvdXJjZSB0ZXh0LlxuICogQHBhcmFtIHtyZWFkb25seSBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FZmZlY3RDYXBhYmlsaXR5RGVjbGFyYXRpb25bXX0gW2lucHV0LmNhcGFiaWxpdGllc10gLSBDb21waWxlci1hdXRob3JpemVkIGRlY2xhcmF0aW9ucy5cbiAqIEBwYXJhbSB7e2lzRW50cnk6IGJvb2xlYW4sIGZ1bmN0aW9uczogTWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbj4sIHJlY29yZHM6IE1hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uPiwgZXJyb3JzPzogTWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXJyb3JEZWNsYXJhdGlvbj59fSBbaW5wdXQucHJvZ3JhbV0gLSBSZXNvbHZlZCBwcm9ncmFtIGltcG9ydHMgYW5kIGVudHJ5IHJvbGUuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IFNlbWFudGljIG1vZHVsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUGhwKHtjYXBhYmlsaXRpZXMgPSBbXSwgZmlsZW5hbWUsIHNvdXJjZSwgcHJvZ3JhbTogcHJvZ3JhbUNvbnRleHR9KSB7XG4gIGNvbnN0IHByb2dyYW0gPSBwYXJzZVBocFByb2dyYW0oZmlsZW5hbWUsIHNvdXJjZSlcbiAgdmFsaWRhdGVEZWNsYXJlTm9kZXMocHJvZ3JhbS5jaGlsZHJlbiwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgbGV0IGJvZHkgPSB0YXNrMDM0UGhwQm9keShwcm9ncmFtLmNoaWxkcmVuLCBjYXBhYmlsaXRpZXMsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKHByb2dyYW1Db250ZXh0KSB7XG4gICAgaW5zcGVjdFBocE1vZHVsZSh7ZmlsZW5hbWUsIHNvdXJjZX0pXG4gICAgY29uc3QgbmFtZXNwYWNlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5hbWVzcGFjZX0gKi8gKGJvZHkuZmluZCgobm9kZSkgPT4gbm9kZS5raW5kID09IFwibmFtZXNwYWNlXCIpKVxuXG4gICAgYm9keSA9IG5hbWVzcGFjZS5jaGlsZHJlbi5maWx0ZXIoKG5vZGUpID0+IG5vZGUua2luZCAhPSBcInVzZWdyb3VwXCIgJiYgIWlzUGhwUmVxdWlyZU9uY2Uobm9kZSkpXG4gIH1cbiAgY29uc3QgY2xhc3NOb2RlcyA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5DbGFzc1tdfSAqLyAoYm9keS5maWx0ZXIoKG5vZGUpID0+IG5vZGUua2luZCA9PSBcImNsYXNzXCIpKVxuICBjb25zdCBlcnJvck5vZGVzID0gY2xhc3NOb2Rlcy5maWx0ZXIoKG5vZGUpID0+IG5vZGUuZXh0ZW5kcz8ua2luZCA9PSBcIm5hbWVcIiAmJlxuICAgIFtcIlJ1bnRpbWVFeGNlcHRpb25cIiwgXCJcXFxcUnVudGltZUV4Y2VwdGlvblwiXS5pbmNsdWRlcyhub2RlLmV4dGVuZHMubmFtZSkpXG4gIGNvbnN0IHJlZmVyZW5jZUNsYXNzTm9kZXMgPSBjbGFzc05vZGVzLmZpbHRlcigobm9kZSkgPT4gIWVycm9yTm9kZXMuaW5jbHVkZXMobm9kZSkgJiZcbiAgICBub2RlLmJvZHkuc29tZSgobWVtYmVyKSA9PiBtZW1iZXIua2luZCA9PSBcInByb3BlcnR5c3RhdGVtZW50XCIpKVxuICBjb25zdCByZWNvcmROb2RlcyA9IGNsYXNzTm9kZXMuZmlsdGVyKChub2RlKSA9PiAhZXJyb3JOb2Rlcy5pbmNsdWRlcyhub2RlKSAmJiAhcmVmZXJlbmNlQ2xhc3NOb2Rlcy5pbmNsdWRlcyhub2RlKSlcbiAgY29uc3QgZXJyb3JEZWNsYXJhdGlvbnMgPSBlcnJvck5vZGVzLm1hcCgobm9kZSwgaW5kZXgpID0+ICh7XG4gICAgaWQ6IGBlcnJvcjoke2luZGV4fWAsXG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRXJyb3JEZWNsYXJhdGlvblwiKSxcbiAgICBsb2NhdGlvbjogbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgIG5hbWU6IHR5cGVvZiBub2RlLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG5vZGUubmFtZSA6IG5vZGUubmFtZS5uYW1lXG4gIH0pKVxuICBjb25zdCByZWNvcmREZWNsYXJhdGlvbnMgPSByZWNvcmROb2Rlcy5tYXAoKG5vZGUsIGluZGV4KSA9PiB7XG4gICAgY29uc3QgaWQgPSBgcmVjb3JkOiR7aW5kZXh9YFxuICAgIGNvbnN0IHR5cGVQYXJhbWV0ZXJzID0gY2xhc3NEb2N1bWVudGVkVHlwZVBhcmFtZXRlcnMobm9kZSwgaWQsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICByZXR1cm4ge1xuICAgICAgZmllbGRzOiBbXSxcbiAgICAgIGlkLFxuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUmVjb3JkRGVjbGFyYXRpb25cIiksXG4gICAgICBsb2NhdGlvbjogbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgbmFtZTogdHlwZW9mIG5vZGUubmFtZSA9PSBcInN0cmluZ1wiID8gbm9kZS5uYW1lIDogbm9kZS5uYW1lLm5hbWUsXG4gICAgICAuLi4odHlwZVBhcmFtZXRlcnMgPyB7dHlwZVBhcmFtZXRlcnN9IDoge30pXG4gICAgfVxuICB9KVxuICBjb25zdCBjbGFzc0RlY2xhcmF0aW9ucyA9IHJlZmVyZW5jZUNsYXNzTm9kZXMubWFwKChub2RlLCBpbmRleCkgPT4gKHtcbiAgICBjb25zdHJ1Y3RvcjogLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Db25zdHJ1Y3RvckRlY2xhcmF0aW9ufSAqLyAoe30pLFxuICAgIGZpZWxkczogW10sIGlkOiBgY2xhc3M6JHtpbmRleH1gLCBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJDbGFzc0RlY2xhcmF0aW9uXCIpLFxuICAgIGxvY2F0aW9uOiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksIG1ldGhvZHM6IFtdLFxuICAgIG5hbWU6IHR5cGVvZiBub2RlLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG5vZGUubmFtZSA6IG5vZGUubmFtZS5uYW1lXG4gIH0pKVxuICBjb25zdCByZWNvcmROYW1lcyA9IC8qKiBAdHlwZSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59ICovIChcbiAgICBuZXcgTWFwKHByb2dyYW1Db250ZXh0Py5yZWNvcmRzID8/IFtdKSlcbiAgZm9yIChjb25zdCByZXNvdXJjZSBvZiBjYXBhYmlsaXRpZXMuZmxhdE1hcCgoe3Jlc291cmNlc30pID0+IHJlc291cmNlcykpIHJlY29yZE5hbWVzLnNldChyZXNvdXJjZS5uYW1lLCByZXNvdXJjZSlcbiAgY29uc3QgZXJyb3JOYW1lcyA9IG5ldyBNYXAocHJvZ3JhbUNvbnRleHQ/LmVycm9ycyA/PyBbXSlcbiAgZm9yIChjb25zdCBmYWlsdXJlIG9mIGNhcGFiaWxpdGllcy5mbGF0TWFwKCh7ZmFpbHVyZXN9KSA9PiBmYWlsdXJlcykpIHtcbiAgICBlcnJvck5hbWVzLnNldChmYWlsdXJlLm5hbWUsIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXJyb3JEZWNsYXJhdGlvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKGZhaWx1cmUpKSlcbiAgfVxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIGVycm9yRGVjbGFyYXRpb25zKSBlcnJvck5hbWVzLnNldChkZWNsYXJhdGlvbi5uYW1lLCBkZWNsYXJhdGlvbilcbiAgY29uc3QgZXJyb3JzQnlJZCA9IG5ldyBNYXAoWy4uLmVycm9yTmFtZXMudmFsdWVzKCldLm1hcCgoZGVjbGFyYXRpb24pID0+IFsvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSwgZGVjbGFyYXRpb25dKSlcbiAgY29uc3QgZXJyb3JzID0gZXJyb3JOb2Rlcy5tYXAoKG5vZGUsIGluZGV4KSA9PiBjb252ZXJ0UGhwRXJyb3Iobm9kZSwgZXJyb3JEZWNsYXJhdGlvbnNbaW5kZXhdLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiByZWNvcmREZWNsYXJhdGlvbnMpIHJlY29yZE5hbWVzLnNldChkZWNsYXJhdGlvbi5uYW1lLCBkZWNsYXJhdGlvbilcbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBjbGFzc0RlY2xhcmF0aW9ucykgcmVjb3JkTmFtZXMuc2V0KGRlY2xhcmF0aW9uLm5hbWUsIGRlY2xhcmF0aW9uKVxuICBjb25zdCByZWNvcmRzQnlJZCA9IG5ldyBNYXAoWy4uLnJlY29yZE5hbWVzLnZhbHVlcygpXVxuICAgIC5maWx0ZXIoKGRlY2xhcmF0aW9uKSA9PiBkZWNsYXJhdGlvbi5raW5kID09IFwiUmVjb3JkRGVjbGFyYXRpb25cIilcbiAgICAubWFwKChkZWNsYXJhdGlvbikgPT4gWy8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBkZWNsYXJhdGlvbl0pKVxuICBjb25zdCBjbGFzc2VzQnlJZCA9IG5ldyBNYXAoY2xhc3NEZWNsYXJhdGlvbnMubWFwKChkZWNsYXJhdGlvbikgPT4gWy8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBkZWNsYXJhdGlvbl0pKVxuICBjb25zdCByZWNvcmRzID0gcmVjb3JkTm9kZXMubWFwKChub2RlLCBpbmRleCkgPT4gY29udmVydFBocFJlY29yZChub2RlLCByZWNvcmREZWNsYXJhdGlvbnNbaW5kZXhdLFxuICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24+fSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAocmVjb3JkTmFtZXMpKSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIGNvbnN0IGZ1bmN0aW9uTm9kZXMgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuRnVuY3Rpb25bXX0gKi8gKGJvZHkuZmlsdGVyKChub2RlKSA9PiBub2RlLmtpbmQgPT0gXCJmdW5jdGlvblwiKSlcbiAgY29uc3Qgc2lnbmF0dXJlcyA9IGZ1bmN0aW9uTm9kZXMubWFwKChub2RlLCBpbmRleCkgPT4gY29udmVydEZ1bmN0aW9uU2lnbmF0dXJlKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIHJlY29yZE5hbWVzLCBgZnVuY3Rpb246JHtpbmRleH1gKSlcbiAgY29uc3QgZnVuY3Rpb25TaWduYXR1cmVzID0gbmV3IE1hcChbLi4uY2FwYWJpbGl0eUZ1bmN0aW9uU2lnbmF0dXJlcyhjYXBhYmlsaXRpZXMsIG1vZHVsZUxvY2F0aW9uKGZpbGVuYW1lLCBzb3VyY2UpKSxcbiAgICAuLi4ocHJvZ3JhbUNvbnRleHQ/LmZ1bmN0aW9ucyA/PyBbXSldLm1hcCgoW2xvY2FsTmFtZSwgZGVjbGFyYXRpb25dKSA9PiBbbG9jYWxOYW1lLCB7XG4gICAgbG9jYXRpb246IGRlY2xhcmF0aW9uLmxvY2F0aW9uLFxuICAgIG5hbWU6IGxvY2FsTmFtZSxcbiAgICBuYW1lTG9jYXRpb246IGRlY2xhcmF0aW9uLmxvY2F0aW9uLFxuICAgIHBhcmFtZXRlcnM6IGRlY2xhcmF0aW9uLnBhcmFtZXRlcnMsXG4gICAgcmV0dXJuVHlwZTogZGVjbGFyYXRpb24ucmV0dXJuVHlwZSxcbiAgICAuLi4oZGVjbGFyYXRpb24udHlwZVBhcmFtZXRlcnMgPyB7dHlwZVBhcmFtZXRlcnM6IGRlY2xhcmF0aW9uLnR5cGVQYXJhbWV0ZXJzfSA6IHt9KVxuICB9XSkpXG4gIGZvciAoY29uc3Qgc2lnbmF0dXJlIG9mIHNpZ25hdHVyZXMpIGZ1bmN0aW9uU2lnbmF0dXJlcy5zZXQoc2lnbmF0dXJlLm5hbWUsIHNpZ25hdHVyZSlcbiAgY29uc3QgY2xhc3NlcyA9IHJlZmVyZW5jZUNsYXNzTm9kZXMubWFwKChub2RlLCBpbmRleCkgPT4gY29udmVydFBocFJlZmVyZW5jZUNsYXNzKG5vZGUsIGNsYXNzRGVjbGFyYXRpb25zW2luZGV4XSxcbiAgICByZWNvcmROYW1lcywgcmVjb3Jkc0J5SWQsIGNsYXNzZXNCeUlkLCBmdW5jdGlvblNpZ25hdHVyZXMsIGVycm9yTmFtZXMsIGVycm9yc0J5SWQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICBjb25zdCBmdW5jdGlvbnMgPSBmdW5jdGlvbk5vZGVzLm1hcCgobm9kZSwgaW5kZXgpID0+XG4gICAgY29udmVydEZ1bmN0aW9uKG5vZGUsIHNpZ25hdHVyZXNbaW5kZXhdLCBmdW5jdGlvblNpZ25hdHVyZXMsIHJlY29yZE5hbWVzLCByZWNvcmRzQnlJZCwgY2xhc3Nlc0J5SWQsIGVycm9yTmFtZXMsIGVycm9yc0J5SWQsXG4gICAgICBmaWxlbmFtZSwgc291cmNlKSlcbiAgY29uc3QgZXhlY3V0YWJsZU5vZGVzID0gYm9keS5maWx0ZXIoKG5vZGUpID0+ICFbXCJjbGFzc1wiLCBcImZ1bmN0aW9uXCIsIFwiZGVjbGFyZVwiLCBcIm5vb3BcIl0uaW5jbHVkZXMobm9kZS5raW5kKSlcbiAgY29uc3QgbG9jYXRpb24gPSBtb2R1bGVMb2NhdGlvbihmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChwcm9ncmFtQ29udGV4dCAmJiAhcHJvZ3JhbUNvbnRleHQuaXNFbnRyeSAmJiBleGVjdXRhYmxlTm9kZXMubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInRvcC1sZXZlbCBzaWRlIGVmZmVjdCBvdXRzaWRlIHRoZSBzZWxlY3RlZCBlbnRyeSBtb2R1bGVcIiwgbm9kZUxvY2F0aW9uKGV4ZWN1dGFibGVOb2Rlc1swXSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgY29uc3QgZmlyc3QgPSBleGVjdXRhYmxlTm9kZXNbMF1cbiAgY29uc3QgbGFzdCA9IGV4ZWN1dGFibGVOb2Rlcy5hdCgtMSkgPz8gZmlyc3RcbiAgY29uc3QgZW50cnlMb2NhdGlvbiA9IGZpcnN0XG4gICAgPyBsb2NhdGlvbkZyb21PZmZzZXRzKGZpbGVuYW1lLCBzb3VyY2UsIGZpcnN0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IDAsIGxhc3Q/LmxvYz8uZW5kLm9mZnNldCA/PyBzb3VyY2UubGVuZ3RoKVxuICAgIDogbG9jYXRpb25cbiAgY29uc3QgZW50cnlDb250ZXh0ID0ge1xuICAgIGJpbmRpbmdzOiBuZXcgTWFwKCksXG4gICAgY2xhc3NlczogY2xhc3Nlc0J5SWQsXG4gICAgZXJyb3JOYW1lcyxcbiAgICBlcnJvcnM6IGVycm9yc0J5SWQsXG4gICAgZnVuY3Rpb25zOiBmdW5jdGlvblNpZ25hdHVyZXMsXG4gICAgb3JkZXJlZE1hcERlY2xhcmF0aW9uczogb3JkZXJlZE1hcERlY2xhcmF0aW9uc0ZvclBocChleGVjdXRhYmxlTm9kZXMpLFxuICAgIHJlY29yZE5hbWVzLFxuICAgIHJlY29yZHM6IHJlY29yZHNCeUlkLFxuICAgIHJldHVyblR5cGU6IHVuZGVmaW5lZFxuICB9XG4gIGNvbnN0IGVudHJ5QmxvY2sgPSB7XG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQmxvY2tcIiksXG4gICAgbG9jYXRpb246IGVudHJ5TG9jYXRpb24sXG4gICAgc3RhdGVtZW50czogZXhlY3V0YWJsZU5vZGVzLm1hcCgobm9kZSkgPT4gY29udmVydFN0YXRlbWVudChub2RlLCBmaWxlbmFtZSwgc291cmNlLCBlbnRyeUNvbnRleHQpKVxuICB9XG5cbiAgaWYgKCFwcm9ncmFtQ29udGV4dCAmJiBmdW5jdGlvbnMubGVuZ3RoID09IDAgJiYgY2FwYWJpbGl0aWVzLmxlbmd0aCA9PSAwICYmICFibG9ja1JlZmVyZW5jZXNQcm90ZWN0ZWRFbnRyeShlbnRyeUJsb2NrKSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm1vZHVsZSB3aXRob3V0IGEgZnVuY3Rpb25cIiwgbG9jYXRpb24pXG4gIH1cbiAgcmV0dXJuIHtcbiAgICBlbnRyeVBvaW50OiB7XG4gICAgICBib2R5OiBlbnRyeUJsb2NrLFxuICAgICAga2luZDogXCJFbnRyeVBvaW50XCIsXG4gICAgICBsb2NhdGlvbjogZW50cnlMb2NhdGlvblxuICAgIH0sXG4gICAgZnVuY3Rpb25zLFxuICAgIGtpbmQ6IFwiTW9kdWxlXCIsXG4gICAgbG9jYXRpb24sXG4gICAgLi4uKGVycm9ycy5sZW5ndGggPiAwID8ge2Vycm9yc30gOiB7fSksXG4gICAgLi4uKGNsYXNzZXMubGVuZ3RoID4gMCA/IHtjbGFzc2VzfSA6IHt9KSxcbiAgICAuLi4ocmVjb3Jkcy5sZW5ndGggPiAwID8ge3JlY29yZHN9IDoge30pXG4gIH1cbn1cblxuLyoqXG4gKiBSZW1vdmVzIGV4YWN0IHByb3RlY3RlZCBQSFAgcHJvYmUgc3VwcG9ydCBiZWZvcmUgcG9ydGFibGUgY29udmVyc2lvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5TdGF0ZW1lbnRbXX0gYm9keSAtIFBhcnNlZCB0b3AtbGV2ZWwgc3RhdGVtZW50cy5cbiAqIEBwYXJhbSB7cmVhZG9ubHkgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0Q2FwYWJpbGl0eURlY2xhcmF0aW9uW119IGNhcGFiaWxpdGllcyAtIEF1dGhvcml6ZWQgZGVjbGFyYXRpb25zLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlN0YXRlbWVudFtdfSBQb3J0YWJsZSBzdGF0ZW1lbnRzLlxuICovXG5mdW5jdGlvbiB0YXNrMDM0UGhwQm9keShib2R5LCBjYXBhYmlsaXRpZXMsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgaWYgKCFpc1Rhc2swMzRSZXNvdXJjZVByb2JlKGNhcGFiaWxpdGllcykpIHJldHVybiBib2R5XG4gIGNvbnN0IHN0YXJ0ID0gYm9keS5maW5kSW5kZXgoKG5vZGUpID0+IG5vZGUubGVhZGluZ0NvbW1lbnRzPy5zb21lKCh7dmFsdWV9KSA9PiB2YWx1ZSA9PSBcIi8qIHNlbWFudGlmb2xkLXRhc2swMzQtc3VwcG9ydCAqL1wiKSlcblxuICBpZiAoc3RhcnQgPCAwKSByZXR1cm4gYm9keVxuICBpZiAoIWhhc0V4YWN0RWZmZWN0U3VwcG9ydChzb3VyY2UsIFwicGhwXCIpKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibWFsZm9ybWVkIHByb3RlY3RlZCBUYXNrIDAzNCBzdXBwb3J0XCIsIG5vZGVMb2NhdGlvbihib2R5W3N0YXJ0XSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgY29uc3QgZXhwZWN0ZWQgPSBbXG4gICAgW1wiY2xhc3NcIiwgXCJQcm9iZU9wZXJhdGlvbkZhaWx1cmVcIl0sIFtcImNsYXNzXCIsIFwiUHJvYmVBY3F1aXJlRmFpbHVyZVwiXSwgW1wiY2xhc3NcIiwgXCJQcm9iZVJlYWRGYWlsdXJlXCJdLFxuICAgIFtcImNsYXNzXCIsIFwiUHJvYmVDbG9zZUZhaWx1cmVcIl0sIFtcImNsYXNzXCIsIFwiUHJvYmVSZXNvdXJjZUNsb3NlZFwiXSwgW1wiY2xhc3NcIiwgXCJQcm9iZVJlc291cmNlXCJdLFxuICAgIFtcImV4cHJlc3Npb25zdGF0ZW1lbnRcIiwgdW5kZWZpbmVkXSwgW1wiZnVuY3Rpb25cIiwgXCJwcm9iZUVmZmVjdFwiXSwgW1wiZnVuY3Rpb25cIiwgXCJwcm9iZUFjcXVpcmVcIl0sXG4gICAgW1wiZnVuY3Rpb25cIiwgXCJwcm9iZVJlYWRcIl0sIFtcImZ1bmN0aW9uXCIsIFwicHJvYmVDbG9zZVwiXSwgW1wiZnVuY3Rpb25cIiwgXCJwcm9iZVRyYWNlXCJdXG4gIF1cbiAgY29uc3QgbWF0Y2hlcyA9IGV4cGVjdGVkLmV2ZXJ5KChba2luZCwgbmFtZV0sIGluZGV4KSA9PiB7XG4gICAgY29uc3Qgbm9kZSA9IGJvZHlbc3RhcnQgKyBpbmRleF1cbiAgICBjb25zdCByYXdOYW1lID0gbm9kZSA/IFJlZmxlY3QuZ2V0KG5vZGUsIFwibmFtZVwiKSA6IHVuZGVmaW5lZFxuICAgIGNvbnN0IGFjdHVhbE5hbWUgPSB0eXBlb2YgcmF3TmFtZSA9PSBcInN0cmluZ1wiID8gcmF3TmFtZSA6IHJhd05hbWUgJiYgdHlwZW9mIHJhd05hbWUgPT0gXCJvYmplY3RcIiA/IFJlZmxlY3QuZ2V0KHJhd05hbWUsIFwibmFtZVwiKSA6IHVuZGVmaW5lZFxuICAgIHJldHVybiBub2RlPy5raW5kID09IGtpbmQgJiYgYWN0dWFsTmFtZSA9PSBuYW1lXG4gIH0pXG4gIGNvbnN0IG5leHQgPSBib2R5W3N0YXJ0ICsgZXhwZWN0ZWQubGVuZ3RoXVxuXG4gIGlmICghbWF0Y2hlcyB8fCBuZXh0ICYmICFuZXh0LmxlYWRpbmdDb21tZW50cz8uc29tZSgoe3ZhbHVlfSkgPT4gdmFsdWUgPT0gXCIvKiBzZW1hbnRpZm9sZC10YXNrMDM0LXN1cHBvcnQtZW5kICovXCIpKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibWFsZm9ybWVkIHByb3RlY3RlZCBUYXNrIDAzNCBzdXBwb3J0XCIsIG5vZGVMb2NhdGlvbihib2R5W3N0YXJ0XSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgcmV0dXJuIFsuLi5ib2R5LnNsaWNlKDAsIHN0YXJ0KSwgLi4uYm9keS5zbGljZShzdGFydCArIGV4cGVjdGVkLmxlbmd0aCldXG59XG5cbi8qKlxuICogUmVhZHMgdGhlIGNhbm9uaWNhbCBwYXJzZXItb3duZWQgUEhQIG5hbWVzcGFjZSwgdXNlIGJpbmRpbmdzLCBhbmQgbGl0ZXJhbCByZXF1aXJlX29uY2UgZWRnZXMuXG4gKiBAcGFyYW0ge29iamVjdH0gaW5wdXQgLSBQYXJzZXIgaW5wdXQuXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQuZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQuc291cmNlIC0gU291cmNlIHRleHQuXG4gKiBAcmV0dXJucyB7e2JpbmRpbmdzOiB7aW1wb3J0ZWROYW1lOiBzdHJpbmcsIGxvY2FsTmFtZTogc3RyaW5nLCBsb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIG5hdGl2ZU5hbWU6IHN0cmluZywgc3ltYm9sS2luZDogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNEZWNsYXJhdGlvbktpbmQsIHR5cGVPbmx5OiBmYWxzZX1bXSwgaW1wb3J0czoge2ltcG9ydGVkTmFtZTogc3RyaW5nLCBsb2NhbE5hbWU6IHN0cmluZywgbG9jYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBuYW1lc3BhY2U6IHRydWUsIHBhdGhMb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIHNwZWNpZmllcjogc3RyaW5nLCB0eXBlT25seTogZmFsc2V9W10sIGV4cG9ydHM6IHtleHBvcnRlZE5hbWU6IHN0cmluZywgbG9jYWxOYW1lOiBzdHJpbmcsIGxvY2F0aW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbiwgdHlwZU9ubHk6IGZhbHNlfVtdLCBuYXRpdmVOYW1lOiBzdHJpbmd9fSBQYXJzZXItb3duZWQgUEhQIG1vZHVsZSBoZWFkZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnNwZWN0UGhwTW9kdWxlKHtmaWxlbmFtZSwgc291cmNlfSkge1xuICBjb25zdCBwcm9ncmFtID0gcGFyc2VQaHBQcm9ncmFtKGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgdmFsaWRhdGVEZWNsYXJlTm9kZXMocHJvZ3JhbS5jaGlsZHJlbiwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgbmFtZXNwYWNlcyA9IHByb2dyYW0uY2hpbGRyZW4uZmlsdGVyKChub2RlKSA9PiBub2RlLmtpbmQgPT0gXCJuYW1lc3BhY2VcIilcbiAgY29uc3QgaW52YWxpZE91dGVyID0gcHJvZ3JhbS5jaGlsZHJlbi5maW5kKChub2RlKSA9PiAhW1wiZGVjbGFyZVwiLCBcIm5hbWVzcGFjZVwiLCBcIm5vb3BcIl0uaW5jbHVkZXMobm9kZS5raW5kKSlcbiAgY29uc3QgbmFtZXNwYWNlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5hbWVzcGFjZSB8IHVuZGVmaW5lZH0gKi8gKG5hbWVzcGFjZXNbMF0pXG5cbiAgaWYgKCFuYW1lc3BhY2UgfHwgbmFtZXNwYWNlcy5sZW5ndGggIT0gMSB8fCBuYW1lc3BhY2Uud2l0aEJyYWNrZXRzIHx8IHR5cGVvZiBuYW1lc3BhY2UubmFtZSAhPSBcInN0cmluZ1wiIHx8IGludmFsaWRPdXRlcikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm9uZSBjYW5vbmljYWwgdW5icmFja2V0ZWQgbmFtZXNwYWNlXCIsXG4gICAgICBub2RlTG9jYXRpb24oaW52YWxpZE91dGVyID8/IG5hbWVzcGFjZXNbMV0gPz8gbmFtZXNwYWNlID8/IHByb2dyYW0sIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGNvbnN0IGJpbmRpbmdzID0gW11cblxuICBmb3IgKGNvbnN0IG5vZGUgb2YgbmFtZXNwYWNlLmNoaWxkcmVuLmZpbHRlcigoY2hpbGQpID0+IGNoaWxkLmtpbmQgPT0gXCJ1c2Vncm91cFwiKSkge1xuICAgIGNvbnN0IGdyb3VwID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlVzZUdyb3VwfSAqLyAobm9kZSlcblxuICAgIGlmIChncm91cC5uYW1lICE9PSBudWxsIHx8ICFbbnVsbCwgXCJmdW5jdGlvblwiXS5pbmNsdWRlcyhncm91cC50eXBlKSB8fCBncm91cC5pdGVtcy5sZW5ndGggPT0gMCkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZ3JvdXBlZCwgY29uc3RhbnQsIG9yIGVtcHR5IHVzZSBkZWNsYXJhdGlvblwiLCBub2RlTG9jYXRpb24oZ3JvdXAsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgZ3JvdXAuaXRlbXMpIHtcbiAgICAgIGlmIChpdGVtLnR5cGUgIT09IG51bGwgfHwgdHlwZW9mIGl0ZW0ubmFtZSAhPSBcInN0cmluZ1wiIHx8ICFpdGVtLm5hbWUuaW5jbHVkZXMoXCJcXFxcXCIpKSB7XG4gICAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImdyb3VwZWQgb3IgdW5xdWFsaWZpZWQgdXNlIGl0ZW1cIiwgbm9kZUxvY2F0aW9uKGl0ZW0sIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgICAgfVxuICAgICAgY29uc3QgaW1wb3J0ZWROYW1lID0gaXRlbS5uYW1lLnNwbGl0KFwiXFxcXFwiKS5hdCgtMSlcbiAgICAgIGNvbnN0IGFsaWFzID0gaXRlbS5hbGlhc1xuXG4gICAgICBpZiAoIWltcG9ydGVkTmFtZSB8fCBhbGlhcyAmJiBhbGlhcy5raW5kICE9IFwiaWRlbnRpZmllclwiKSB7XG4gICAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImludmFsaWQgdXNlIGFsaWFzXCIsIG5vZGVMb2NhdGlvbihpdGVtLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgIH1cbiAgICAgIGJpbmRpbmdzLnB1c2goe1xuICAgICAgICBpbXBvcnRlZE5hbWUsXG4gICAgICAgIGxvY2FsTmFtZTogYWxpYXMgPyBhbGlhcy5uYW1lIDogaW1wb3J0ZWROYW1lLFxuICAgICAgICBsb2NhdGlvbjogbm9kZUxvY2F0aW9uKGl0ZW0sIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgICBuYXRpdmVOYW1lOiBpdGVtLm5hbWUsXG4gICAgICAgIHN5bWJvbEtpbmQ6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNEZWNsYXJhdGlvbktpbmR9ICovIChncm91cC50eXBlID09IFwiZnVuY3Rpb25cIiA/IFwiZnVuY3Rpb25cIiA6IFwicmVjb3JkXCIpLFxuICAgICAgICB0eXBlT25seTogLyoqIEB0eXBlIHtjb25zdH0gKi8gKGZhbHNlKVxuICAgICAgfSlcbiAgICB9XG4gIH1cbiAgY29uc3QgaW1wb3J0cyA9IG5hbWVzcGFjZS5jaGlsZHJlbi5maWx0ZXIoaXNQaHBJbmNsdWRlU3RhdGVtZW50KS5tYXAoKG5vZGUpID0+IHtcbiAgICBpZiAoIWlzUGhwUmVxdWlyZU9uY2Uobm9kZSkpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImluY2x1ZGUvcmVxdWlyZSBvdXRzaWRlIGxpdGVyYWwgcmVxdWlyZV9vbmNlIF9fRElSX18gcHJvZmlsZVwiLCBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgfVxuICAgIGNvbnN0IHN0YXRlbWVudCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5FeHByZXNzaW9uU3RhdGVtZW50fSAqLyAobm9kZSlcbiAgICBjb25zdCBpbmNsdWRlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkluY2x1ZGV9ICovIChzdGF0ZW1lbnQuZXhwcmVzc2lvbilcbiAgICBjb25zdCB0YXJnZXQgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuQmlufSAqLyAoaW5jbHVkZS50YXJnZXQpXG4gICAgY29uc3QgcGF0aCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5TdHJpbmd9ICovICh0YXJnZXQucmlnaHQpXG5cbiAgICBpZiAoIXBhdGgudmFsdWUuc3RhcnRzV2l0aChcIi9cIikgfHwgcGF0aC52YWx1ZS5pbmNsdWRlcyhcIlxcMFwiKSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwidW5zYWZlIHJlcXVpcmVfb25jZSBwYXRoXCIsIG5vZGVMb2NhdGlvbihwYXRoLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgaW1wb3J0ZWROYW1lOiBcIipcIixcbiAgICAgIGxvY2FsTmFtZTogXCJcIixcbiAgICAgIGxvY2F0aW9uOiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBuYW1lc3BhY2U6IC8qKiBAdHlwZSB7Y29uc3R9ICovICh0cnVlKSxcbiAgICAgIHBhdGhMb2NhdGlvbjogbm9kZUxvY2F0aW9uKHBhdGgsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgc3BlY2lmaWVyOiBgLiR7cGF0aC52YWx1ZX1gLFxuICAgICAgdHlwZU9ubHk6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChmYWxzZSlcbiAgICB9XG4gIH0pXG4gIGNvbnN0IGV4cG9ydHMgPSBuYW1lc3BhY2UuY2hpbGRyZW4uZmxhdE1hcCgobm9kZSkgPT4ge1xuICAgIGlmIChub2RlLmtpbmQgIT0gXCJjbGFzc1wiICYmIG5vZGUua2luZCAhPSBcImZ1bmN0aW9uXCIpIHJldHVybiBbXVxuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkNsYXNzIHwgaW1wb3J0KFwicGhwLXBhcnNlclwiKS5GdW5jdGlvbn0gKi8gKG5vZGUpXG4gICAgY29uc3QgbmFtZSA9IHR5cGVvZiBkZWNsYXJhdGlvbi5uYW1lID09IFwic3RyaW5nXCIgPyBkZWNsYXJhdGlvbi5uYW1lIDogZGVjbGFyYXRpb24ubmFtZS5uYW1lXG5cbiAgICByZXR1cm4gW3tleHBvcnRlZE5hbWU6IG5hbWUsIGxvY2FsTmFtZTogbmFtZSwgbG9jYXRpb246IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSwgdHlwZU9ubHk6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChmYWxzZSl9XVxuICB9KVxuXG4gIHJldHVybiB7YmluZGluZ3MsIGV4cG9ydHMsIGltcG9ydHMsIG5hdGl2ZU5hbWU6IG5hbWVzcGFjZS5uYW1lfVxufVxuXG4vKipcbiAqIFJlcG9ydHMgd2hldGhlciBhIFBIUCBzdGF0ZW1lbnQgaXMgYW55IGluY2x1ZGUvcmVxdWlyZSBleHByZXNzaW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGV9IG5vZGUgLSBDYW5kaWRhdGUgc3RhdGVtZW50LlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIG5vZGUgaXMgYW4gaW5jbHVkZSBleHByZXNzaW9uIHN0YXRlbWVudC5cbiAqL1xuZnVuY3Rpb24gaXNQaHBJbmNsdWRlU3RhdGVtZW50KG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUua2luZCA9PSBcImV4cHJlc3Npb25zdGF0ZW1lbnRcIiAmJlxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5FeHByZXNzaW9uU3RhdGVtZW50fSAqLyAobm9kZSkuZXhwcmVzc2lvbi5raW5kID09IFwiaW5jbHVkZVwiXG59XG5cbi8qKlxuICogUmVwb3J0cyB3aGV0aGVyIGEgUEhQIHN0YXRlbWVudCBpcyB0aGUgY2Fub25pY2FsIGxpdGVyYWwgcHJvamVjdCBsb2FkIGVkZ2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuTm9kZX0gbm9kZSAtIENhbmRpZGF0ZSBzdGF0ZW1lbnQuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgbm9kZSBpcyBhIHN1cHBvcnRlZCByZXF1aXJlLW9uY2Ugc3RhdGVtZW50LlxuICovXG5mdW5jdGlvbiBpc1BocFJlcXVpcmVPbmNlKG5vZGUpIHtcbiAgaWYgKCFpc1BocEluY2x1ZGVTdGF0ZW1lbnQobm9kZSkpIHJldHVybiBmYWxzZVxuICBjb25zdCBzdGF0ZW1lbnQgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuRXhwcmVzc2lvblN0YXRlbWVudH0gKi8gKG5vZGUpXG4gIGNvbnN0IGluY2x1ZGUgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuSW5jbHVkZX0gKi8gKHN0YXRlbWVudC5leHByZXNzaW9uKVxuICBjb25zdCB0YXJnZXQgPSBpbmNsdWRlLnRhcmdldC5raW5kID09IFwiYmluXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuQmlufSAqLyAoaW5jbHVkZS50YXJnZXQpIDogdW5kZWZpbmVkXG4gIGNvbnN0IGxlZnQgPSB0YXJnZXQ/LmxlZnQua2luZCA9PSBcIm1hZ2ljXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTWFnaWN9ICovICh0YXJnZXQubGVmdCkgOiB1bmRlZmluZWRcblxuICByZXR1cm4gaW5jbHVkZS5vbmNlICYmIGluY2x1ZGUucmVxdWlyZSAmJiB0YXJnZXQ/LnR5cGUgPT0gXCIuXCIgJiZcbiAgICBsZWZ0Py52YWx1ZSA9PSBcIl9fRElSX19cIiAmJiB0YXJnZXQucmlnaHQua2luZCA9PSBcInN0cmluZ1wiXG59XG5cbi8qKlxuICogQWNjZXB0cyBvbmx5IGFuIG9wdGlvbmFsIHNpbmdsZSBgZGVjbGFyZShzdHJpY3RfdHlwZXM9MSlgIGRpcmVjdGl2ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlW119IG5vZGVzIC0gVG9wLWxldmVsIFBIUCBub2Rlcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVEZWNsYXJlTm9kZXMobm9kZXMsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgZGVjbGFyYXRpb25zID0gbm9kZXMuZmlsdGVyKChub2RlKSA9PiBub2RlLmtpbmQgPT0gXCJkZWNsYXJlXCIpXG5cbiAgaWYgKGRlY2xhcmF0aW9ucy5sZW5ndGggPiAxKSB7XG4gICAgdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJtdWx0aXBsZSBkZWNsYXJlIGRpcmVjdGl2ZXNcIiwgbm9kZUxvY2F0aW9uKGRlY2xhcmF0aW9uc1sxXSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cblxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uTm9kZSBvZiBkZWNsYXJhdGlvbnMpIHtcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5EZWNsYXJlfSAqLyAoZGVjbGFyYXRpb25Ob2RlKVxuICAgIGNvbnN0IGRpcmVjdGl2ZSA9IGRlY2xhcmF0aW9uLmRpcmVjdGl2ZXNbMF1cbiAgICBjb25zdCBrZXkgPSBkaXJlY3RpdmU/LmtleVxuICAgIGNvbnN0IHZhbHVlID0gZGlyZWN0aXZlPy52YWx1ZVxuICAgIGNvbnN0IG51bWVyaWNWYWx1ZSA9IHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PSBcIm9iamVjdFwiICYmIHZhbHVlLmtpbmQgPT0gXCJudW1iZXJcIlxuICAgICAgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTnVtYmVyfSAqLyAodmFsdWUpXG4gICAgICA6IHVuZGVmaW5lZFxuICAgIGNvbnN0IHZhbHVlSXNPbmUgPSBudW1lcmljVmFsdWU/LmxvYyAmJiBzb3VyY2Uuc2xpY2UobnVtZXJpY1ZhbHVlLmxvYy5zdGFydC5vZmZzZXQsIG51bWVyaWNWYWx1ZS5sb2MuZW5kLm9mZnNldCkgPT0gXCIxXCJcbiAgICBjb25zdCB2YWxpZCA9IGRlY2xhcmF0aW9uLm1vZGUgPT0gXCJub25lXCIgJiYgZGVjbGFyYXRpb24uY2hpbGRyZW4ubGVuZ3RoID09IDAgJiYgZGVjbGFyYXRpb24uZGlyZWN0aXZlcy5sZW5ndGggPT0gMSAmJlxuICAgICAga2V5LmtpbmQgPT0gXCJpZGVudGlmaWVyXCIgJiYga2V5Lm5hbWUgPT0gXCJzdHJpY3RfdHlwZXNcIiAmJiB2YWx1ZUlzT25lXG5cbiAgICBpZiAoIXZhbGlkKSB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImRlY2xhcmUgb3RoZXIgdGhhbiBzdHJpY3RfdHlwZXM9MVwiLCBub2RlTG9jYXRpb24oZGVjbGFyYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG59XG5cbi8qKlxuICogSW52b2tlcyBwaHAtcGFyc2VyIGFuZCBub3JtYWxpemVzIHN5bnRheCBmYWlsdXJlcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBTb3VyY2UgdGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlByb2dyYW19IFBIUCBwcm9ncmFtLlxuICovXG5mdW5jdGlvbiBwYXJzZVBocFByb2dyYW0oZmlsZW5hbWUsIHNvdXJjZSkge1xuICB0cnkge1xuICAgIHJldHVybiBwYXJzZXIucGFyc2VDb2RlKHNvdXJjZSwgZmlsZW5hbWUpXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIHBhcnNlRmFpbHVyZShcInBocFwiLCBlcnJvciwgcGhwUGFyc2VyRmFpbHVyZUxvY2F0aW9uKGVycm9yLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxufVxuXG4vKipcbiAqIE5vcm1hbGl6ZXMgcGhwLXBhcnNlcidzIG9uZS1iYXNlZCBsaW5lIGFuZCB6ZXJvLWJhc2VkIGNvbHVtbiB3aGVuIHByZXNlbnQuXG4gKiBBIG1vZHVsZSByYW5nZSByZW1haW5zIHRoZSBkZXRlcm1pbmlzdGljIGZhbGxiYWNrIGZvciBvcGFxdWUgcGFyc2VyIGVycm9ycy5cbiAqIEBwYXJhbSB7dW5rbm93bn0gZXJyb3IgLSBOYXRpdmUgcGFyc2VyIGVycm9yLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gUmVxdWVzdGVkIHNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IEZhaWx1cmUgcmFuZ2UuXG4gKi9cbmZ1bmN0aW9uIHBocFBhcnNlckZhaWx1cmVMb2NhdGlvbihlcnJvciwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAoIWVycm9yIHx8IHR5cGVvZiBlcnJvciAhPSBcIm9iamVjdFwiKSByZXR1cm4gbW9kdWxlTG9jYXRpb24oZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgbGluZSA9IFJlZmxlY3QuZ2V0KGVycm9yLCBcImxpbmVOdW1iZXJcIilcbiAgY29uc3QgY29sdW1uID0gUmVmbGVjdC5nZXQoZXJyb3IsIFwiY29sdW1uTnVtYmVyXCIpXG5cbiAgaWYgKHR5cGVvZiBsaW5lICE9IFwibnVtYmVyXCIgfHwgIU51bWJlci5pc1NhZmVJbnRlZ2VyKGxpbmUpIHx8IGxpbmUgPCAxIHx8XG4gICAgdHlwZW9mIGNvbHVtbiAhPSBcIm51bWJlclwiIHx8ICFOdW1iZXIuaXNTYWZlSW50ZWdlcihjb2x1bW4pIHx8IGNvbHVtbiA8IDApIHtcbiAgICByZXR1cm4gbW9kdWxlTG9jYXRpb24oZmlsZW5hbWUsIHNvdXJjZSlcbiAgfVxuICBsZXQgbGluZVN0YXJ0ID0gMFxuXG4gIGZvciAobGV0IGN1cnJlbnQgPSAxOyBjdXJyZW50IDwgbGluZTsgY3VycmVudCsrKSB7XG4gICAgY29uc3QgbmV3bGluZSA9IHNvdXJjZS5pbmRleE9mKFwiXFxuXCIsIGxpbmVTdGFydClcblxuICAgIGlmIChuZXdsaW5lIDwgMCkgcmV0dXJuIG1vZHVsZUxvY2F0aW9uKGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgbGluZVN0YXJ0ID0gbmV3bGluZSArIDFcbiAgfVxuICBjb25zdCBsaW5lRW5kID0gc291cmNlLmluZGV4T2YoXCJcXG5cIiwgbGluZVN0YXJ0KVxuICBjb25zdCBib3VuZGVkRW5kID0gbGluZUVuZCA8IDAgPyBzb3VyY2UubGVuZ3RoIDogbGluZUVuZFxuICBjb25zdCBvZmZzZXQgPSBNYXRoLm1pbihsaW5lU3RhcnQgKyBjb2x1bW4sIGJvdW5kZWRFbmQpXG5cbiAgcmV0dXJuIGxvY2F0aW9uRnJvbU9mZnNldHMoZmlsZW5hbWUsIHNvdXJjZSwgb2Zmc2V0LCBNYXRoLm1pbihvZmZzZXQgKyAxLCBzb3VyY2UubGVuZ3RoKSlcbn1cbiJdfQ==