semantifold 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. package/README.md +58 -15
  2. package/build/index.d.ts +48 -2
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +57 -8
  5. package/build/src/artifact-path.d.ts +23 -1
  6. package/build/src/artifact-path.d.ts.map +1 -1
  7. package/build/src/artifact-path.js +45 -3
  8. package/build/src/artifacts.d.ts.map +1 -1
  9. package/build/src/artifacts.js +66 -1
  10. package/build/src/backends/c-validation.d.ts.map +1 -1
  11. package/build/src/backends/c-validation.js +7 -3
  12. package/build/src/backends/cpp-validation.d.ts.map +1 -1
  13. package/build/src/backends/cpp-validation.js +7 -3
  14. package/build/src/backends/csharp.js +7 -1
  15. package/build/src/backends/dart-runtime.d.ts +2 -0
  16. package/build/src/backends/dart-runtime.d.ts.map +1 -0
  17. package/build/src/backends/dart-runtime.js +41 -0
  18. package/build/src/backends/dart.d.ts +20 -0
  19. package/build/src/backends/dart.d.ts.map +1 -0
  20. package/build/src/backends/dart.js +321 -0
  21. package/build/src/backends/effects.d.ts +60 -0
  22. package/build/src/backends/effects.d.ts.map +1 -0
  23. package/build/src/backends/effects.js +746 -0
  24. package/build/src/backends/go.js +18 -4
  25. package/build/src/backends/identifiers.d.ts +36 -4
  26. package/build/src/backends/identifiers.d.ts.map +1 -1
  27. package/build/src/backends/identifiers.js +154 -10
  28. package/build/src/backends/index.d.ts.map +1 -1
  29. package/build/src/backends/index.js +27 -4
  30. package/build/src/backends/ios.d.ts +68 -0
  31. package/build/src/backends/ios.d.ts.map +1 -0
  32. package/build/src/backends/ios.js +1503 -0
  33. package/build/src/backends/java.d.ts.map +1 -1
  34. package/build/src/backends/java.js +429 -36
  35. package/build/src/backends/javascript.d.ts +6 -0
  36. package/build/src/backends/javascript.d.ts.map +1 -1
  37. package/build/src/backends/javascript.js +380 -24
  38. package/build/src/backends/kotlin-runtime.d.ts +3 -0
  39. package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
  40. package/build/src/backends/kotlin-runtime.js +29 -0
  41. package/build/src/backends/kotlin.d.ts +23 -0
  42. package/build/src/backends/kotlin.d.ts.map +1 -0
  43. package/build/src/backends/kotlin.js +136 -0
  44. package/build/src/backends/native-validation.d.ts +2 -2
  45. package/build/src/backends/native-validation.d.ts.map +1 -1
  46. package/build/src/backends/native-validation.js +2 -2
  47. package/build/src/backends/ordered-expressions.d.ts.map +1 -1
  48. package/build/src/backends/ordered-expressions.js +39 -7
  49. package/build/src/backends/php-stdlib-support.d.ts +19 -0
  50. package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
  51. package/build/src/backends/php-stdlib-support.js +227 -0
  52. package/build/src/backends/php.d.ts.map +1 -1
  53. package/build/src/backends/php.js +448 -33
  54. package/build/src/backends/program.d.ts +81 -0
  55. package/build/src/backends/program.d.ts.map +1 -0
  56. package/build/src/backends/program.js +1308 -0
  57. package/build/src/backends/python.js +7 -1
  58. package/build/src/backends/ruby.d.ts.map +1 -1
  59. package/build/src/backends/ruby.js +310 -24
  60. package/build/src/backends/rust-runtime.d.ts +7 -0
  61. package/build/src/backends/rust-runtime.d.ts.map +1 -0
  62. package/build/src/backends/rust-runtime.js +32 -0
  63. package/build/src/backends/rust-validation.d.ts +9 -0
  64. package/build/src/backends/rust-validation.d.ts.map +1 -0
  65. package/build/src/backends/rust-validation.js +78 -0
  66. package/build/src/backends/rust.d.ts +24 -0
  67. package/build/src/backends/rust.d.ts.map +1 -0
  68. package/build/src/backends/rust.js +344 -0
  69. package/build/src/backends/scalars.d.ts +14 -6
  70. package/build/src/backends/scalars.d.ts.map +1 -1
  71. package/build/src/backends/scalars.js +167 -17
  72. package/build/src/backends/shared.d.ts +23 -4
  73. package/build/src/backends/shared.d.ts.map +1 -1
  74. package/build/src/backends/shared.js +2158 -62
  75. package/build/src/backends/stdlib-support.d.ts +14 -0
  76. package/build/src/backends/stdlib-support.d.ts.map +1 -0
  77. package/build/src/backends/stdlib-support.js +237 -0
  78. package/build/src/backends/swift-runtime.d.ts +3 -0
  79. package/build/src/backends/swift-runtime.d.ts.map +1 -0
  80. package/build/src/backends/swift-runtime.js +14 -0
  81. package/build/src/backends/swift.d.ts +8 -0
  82. package/build/src/backends/swift.d.ts.map +1 -0
  83. package/build/src/backends/swift.js +127 -0
  84. package/build/src/backends/typescript.d.ts.map +1 -1
  85. package/build/src/backends/typescript.js +344 -24
  86. package/build/src/backends/wasm.d.ts +43 -0
  87. package/build/src/backends/wasm.d.ts.map +1 -0
  88. package/build/src/backends/wasm.js +2164 -0
  89. package/build/src/backends/writer.d.ts +235 -4
  90. package/build/src/backends/writer.d.ts.map +1 -1
  91. package/build/src/backends/writer.js +468 -3
  92. package/build/src/diagnostic.d.ts +4 -3
  93. package/build/src/diagnostic.d.ts.map +1 -1
  94. package/build/src/diagnostic.js +5 -3
  95. package/build/src/frontends/c.d.ts.map +1 -1
  96. package/build/src/frontends/c.js +5 -3
  97. package/build/src/frontends/cpp.d.ts.map +1 -1
  98. package/build/src/frontends/cpp.js +5 -3
  99. package/build/src/frontends/csharp.d.ts.map +1 -1
  100. package/build/src/frontends/csharp.js +7 -3
  101. package/build/src/frontends/dart.d.ts +10 -0
  102. package/build/src/frontends/dart.d.ts.map +1 -0
  103. package/build/src/frontends/dart.js +913 -0
  104. package/build/src/frontends/index.d.ts +3 -1
  105. package/build/src/frontends/index.d.ts.map +1 -1
  106. package/build/src/frontends/index.js +15 -5
  107. package/build/src/frontends/java.d.ts +110 -1
  108. package/build/src/frontends/java.d.ts.map +1 -1
  109. package/build/src/frontends/java.js +1725 -70
  110. package/build/src/frontends/javascript-typescript.d.ts +69 -1
  111. package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
  112. package/build/src/frontends/javascript-typescript.js +1825 -93
  113. package/build/src/frontends/kotlin.d.ts +10 -0
  114. package/build/src/frontends/kotlin.d.ts.map +1 -0
  115. package/build/src/frontends/kotlin.js +685 -0
  116. package/build/src/frontends/php.d.ts +118 -1
  117. package/build/src/frontends/php.d.ts.map +1 -1
  118. package/build/src/frontends/php.js +1583 -76
  119. package/build/src/frontends/program.d.ts +74 -0
  120. package/build/src/frontends/program.d.ts.map +1 -0
  121. package/build/src/frontends/program.js +989 -0
  122. package/build/src/frontends/ruby.d.ts +68 -1
  123. package/build/src/frontends/ruby.d.ts.map +1 -1
  124. package/build/src/frontends/ruby.js +1446 -101
  125. package/build/src/frontends/rust-parser.d.ts +11 -0
  126. package/build/src/frontends/rust-parser.d.ts.map +1 -0
  127. package/build/src/frontends/rust-parser.js +15 -0
  128. package/build/src/frontends/rust.d.ts +14 -0
  129. package/build/src/frontends/rust.d.ts.map +1 -0
  130. package/build/src/frontends/rust.js +715 -0
  131. package/build/src/frontends/scalars.d.ts +10 -0
  132. package/build/src/frontends/scalars.d.ts.map +1 -1
  133. package/build/src/frontends/scalars.js +28 -2
  134. package/build/src/frontends/swift.d.ts +10 -0
  135. package/build/src/frontends/swift.d.ts.map +1 -0
  136. package/build/src/frontends/swift.js +860 -0
  137. package/build/src/frontends/types.d.ts +186 -0
  138. package/build/src/frontends/types.d.ts.map +1 -0
  139. package/build/src/frontends/types.js +634 -0
  140. package/build/src/language-registry.d.ts +46 -4
  141. package/build/src/language-registry.d.ts.map +1 -1
  142. package/build/src/language-registry.js +167 -13
  143. package/build/src/mapping.d.ts +2 -2
  144. package/build/src/mapping.d.ts.map +1 -1
  145. package/build/src/mapping.js +31 -10
  146. package/build/src/semantic/capabilities.d.ts +66 -0
  147. package/build/src/semantic/capabilities.d.ts.map +1 -0
  148. package/build/src/semantic/capabilities.js +649 -0
  149. package/build/src/semantic/effects.d.ts +26 -0
  150. package/build/src/semantic/effects.d.ts.map +1 -0
  151. package/build/src/semantic/effects.js +764 -0
  152. package/build/src/semantic/generics.d.ts +23 -0
  153. package/build/src/semantic/generics.d.ts.map +1 -0
  154. package/build/src/semantic/generics.js +61 -0
  155. package/build/src/semantic/lifetime.d.ts +37 -0
  156. package/build/src/semantic/lifetime.d.ts.map +1 -0
  157. package/build/src/semantic/lifetime.js +527 -0
  158. package/build/src/semantic/provenance.d.ts +9 -2
  159. package/build/src/semantic/provenance.d.ts.map +1 -1
  160. package/build/src/semantic/provenance.js +462 -20
  161. package/build/src/semantic/scalars.d.ts +11 -0
  162. package/build/src/semantic/scalars.d.ts.map +1 -1
  163. package/build/src/semantic/scalars.js +16 -1
  164. package/build/src/semantic/stdlib.d.ts +254 -0
  165. package/build/src/semantic/stdlib.d.ts.map +1 -0
  166. package/build/src/semantic/stdlib.js +880 -0
  167. package/build/src/semantic/types.d.ts +2952 -202
  168. package/build/src/semantic/types.d.ts.map +1 -1
  169. package/build/src/semantic/types.js +688 -15
  170. package/build/src/semantic/validate.d.ts +85 -5
  171. package/build/src/semantic/validate.d.ts.map +1 -1
  172. package/build/src/semantic/validate.js +2576 -98
  173. package/build/src/stdlib-facades.d.ts +304 -0
  174. package/build/src/stdlib-facades.d.ts.map +1 -0
  175. package/build/src/stdlib-facades.js +1167 -0
  176. package/build/src/stdlib-negotiation.d.ts +69 -0
  177. package/build/src/stdlib-negotiation.d.ts.map +1 -0
  178. package/build/src/stdlib-negotiation.js +403 -0
  179. package/build/src/stdlib-providers.d.ts +72 -0
  180. package/build/src/stdlib-providers.d.ts.map +1 -0
  181. package/build/src/stdlib-providers.js +339 -0
  182. package/build/src/toolchains.d.ts +55 -1
  183. package/build/src/toolchains.d.ts.map +1 -1
  184. package/build/src/toolchains.js +15 -4
  185. package/docs/architecture.md +45 -13
  186. package/docs/dart.md +60 -0
  187. package/docs/goals.md +3 -3
  188. package/docs/ios.md +121 -0
  189. package/docs/kotlin.md +42 -0
  190. package/docs/language-support.md +231 -26
  191. package/docs/multi-file-modules.md +52 -0
  192. package/docs/parser-qualification.md +121 -8
  193. package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
  194. package/docs/rust.md +88 -0
  195. package/docs/source-maps.md +15 -7
  196. package/docs/standard-library-portability.md +39 -8
  197. package/docs/swift.md +44 -0
  198. package/docs/testing.md +366 -4
  199. package/docs/webassembly.md +52 -0
  200. package/index.js +63 -8
  201. package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
  202. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
  203. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
  204. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
  205. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
  206. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
  207. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
  208. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
  209. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
  210. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
  211. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
  212. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
  213. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
  214. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
  215. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
  216. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
  217. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
  218. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
  219. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
  220. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
  221. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
  222. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
  223. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
  224. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
  225. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
  226. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
  227. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
  228. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
  229. package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
  230. package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
  231. package/package.json +5 -2
  232. package/src/artifact-path.js +47 -2
  233. package/src/artifacts.js +67 -0
  234. package/src/backends/c-validation.js +6 -1
  235. package/src/backends/cpp-validation.js +6 -1
  236. package/src/backends/csharp.js +3 -0
  237. package/src/backends/dart-runtime.js +41 -0
  238. package/src/backends/dart.js +326 -0
  239. package/src/backends/effects.js +705 -0
  240. package/src/backends/go.js +14 -2
  241. package/src/backends/identifiers.js +160 -9
  242. package/src/backends/index.js +27 -2
  243. package/src/backends/ios.js +1612 -0
  244. package/src/backends/java.js +454 -36
  245. package/src/backends/javascript.js +389 -23
  246. package/src/backends/kotlin-runtime.js +29 -0
  247. package/src/backends/kotlin.js +141 -0
  248. package/src/backends/native-validation.js +1 -1
  249. package/src/backends/ordered-expressions.js +40 -6
  250. package/src/backends/php-stdlib-support.js +239 -0
  251. package/src/backends/php.js +469 -32
  252. package/src/backends/program.js +1407 -0
  253. package/src/backends/python.js +3 -0
  254. package/src/backends/ruby.js +326 -23
  255. package/src/backends/rust-runtime.js +34 -0
  256. package/src/backends/rust-validation.js +75 -0
  257. package/src/backends/rust.js +335 -0
  258. package/src/backends/scalars.js +141 -16
  259. package/src/backends/shared.js +2304 -124
  260. package/src/backends/stdlib-support.js +234 -0
  261. package/src/backends/swift-runtime.js +14 -0
  262. package/src/backends/swift.js +132 -0
  263. package/src/backends/typescript.js +349 -23
  264. package/src/backends/wasm.js +2208 -0
  265. package/src/backends/writer.js +520 -2
  266. package/src/diagnostic.js +4 -2
  267. package/src/frontends/c.js +4 -2
  268. package/src/frontends/cpp.js +4 -2
  269. package/src/frontends/csharp.js +4 -2
  270. package/src/frontends/dart.js +963 -0
  271. package/src/frontends/index.js +14 -4
  272. package/src/frontends/java.js +1977 -69
  273. package/src/frontends/javascript-typescript.js +2046 -102
  274. package/src/frontends/kotlin.js +713 -0
  275. package/src/frontends/php.js +1725 -79
  276. package/src/frontends/program.js +1062 -0
  277. package/src/frontends/ruby.js +1624 -98
  278. package/src/frontends/rust-parser.js +18 -0
  279. package/src/frontends/rust.js +714 -0
  280. package/src/frontends/scalars.js +31 -1
  281. package/src/frontends/swift.js +893 -0
  282. package/src/frontends/types.js +750 -0
  283. package/src/language-registry.js +172 -12
  284. package/src/mapping.js +33 -9
  285. package/src/semantic/capabilities.js +671 -0
  286. package/src/semantic/effects.js +737 -0
  287. package/src/semantic/generics.js +58 -0
  288. package/src/semantic/lifetime.js +517 -0
  289. package/src/semantic/provenance.js +412 -19
  290. package/src/semantic/scalars.js +17 -0
  291. package/src/semantic/stdlib.js +921 -0
  292. package/src/semantic/types.js +765 -14
  293. package/src/semantic/validate.js +2934 -209
  294. package/src/stdlib-facades.js +1211 -0
  295. package/src/stdlib-negotiation.js +446 -0
  296. package/src/stdlib-providers.js +377 -0
  297. package/src/toolchains.js +16 -3
@@ -0,0 +1,527 @@
1
+ // @ts-check
2
+ /** @typedef {(code: string, detail: string, location: import("./types.js").SourceLocation) => never} LifetimeFail */
3
+ /** @typedef {{kind: "open", originId: string, origin: import("./types.js").SourceLocation} | {kind: "moved", originId: string, origin: import("./types.js").SourceLocation, destination: string} | {kind: "terminal", originId: string, origin: import("./types.js").SourceLocation, closeSiteId: string | import("./types.js").SourceLocation}} OwnerState */
4
+ /** @typedef {{kind: "normal" | "return" | "raise" | "break" | "continue", state: Map<string, OwnerState>, location?: import("./types.js").SourceLocation, errorId?: string}} LifetimeExit */
5
+ /**
6
+ * Performs path-sensitive structured lifetime validation for Task 034 owned values.
7
+ * @param {import("./types.js").SemanticModule} module - Fully type-resolved module.
8
+ * @param {{functions: Map<string, Set<string>>, methods: Map<string, Set<string>>}} errorEffects - Complete escaping error sets per function and method.
9
+ * @param {LifetimeFail} fail - Located failure.
10
+ * @returns {void}
11
+ */
12
+ export function validateResourceLifetimes(module, errorEffects, fail) {
13
+ if (!(module.capabilities ?? []).some(({ resources }) => resources.length > 0) && !moduleContainsOwnedType(module))
14
+ return;
15
+ for (const declaration of module.classes ?? []) {
16
+ analyzeOwner(declaration.constructor.parameters, declaration.constructor.body, fail, undefined, errorEffects);
17
+ for (const method of declaration.methods)
18
+ analyzeOwner(method.parameters, method.body, fail, declaration.ownership?.kind == "ownedResource" ? declaration.ownership.fieldId : undefined, errorEffects);
19
+ }
20
+ for (const declaration of module.functions)
21
+ analyzeOwner(declaration.parameters, declaration.body, fail, undefined, errorEffects);
22
+ analyzeOwner([], module.entryPoint.body, fail, undefined, errorEffects);
23
+ }
24
+ /**
25
+ * Analyzes one function, constructor, method, or entry-point owner.
26
+ * @param {import("./types.js").Parameter[]} parameters - Owned parameters.
27
+ * @param {import("./types.js").Block} body - Structured body.
28
+ * @param {LifetimeFail} fail - Located failure.
29
+ * @param {string | undefined} borrowedFieldId - Owned receiver field, when present.
30
+ * @param {{functions: Map<string, Set<string>>, methods: Map<string, Set<string>>}} errorEffects - Complete escaping error sets per function and method.
31
+ * @returns {void}
32
+ */
33
+ function analyzeOwner(parameters, body, fail, borrowedFieldId, errorEffects) {
34
+ /** @type {Map<string, OwnerState>} */
35
+ const initial = new Map();
36
+ const obligations = new Set(parameters.filter(({ type }) => isOwned(type)).map(({ name }) => name));
37
+ for (const parameter of parameters) {
38
+ if (isOwned(parameter.type))
39
+ initial.set(parameter.name, openState(`parameter:${parameter.name}`, parameter.location));
40
+ }
41
+ if (borrowedFieldId)
42
+ initial.set(`this.${borrowedFieldId}`, openState(`receiver:${borrowedFieldId}`, body.location));
43
+ const exits = analyzeBlock(body, [{ kind: "normal", state: initial }], fail, errorEffects);
44
+ for (const exit of exits)
45
+ checkLeaks(exit.state, obligations, exit.location ?? body.location, fail);
46
+ }
47
+ /**
48
+ * Evaluates one lexical block while retaining every abrupt exit separately.
49
+ * @param {import("./types.js").Block} block - Structured block.
50
+ * @param {LifetimeExit[]} incoming - Incoming control-flow states.
51
+ * @param {LifetimeFail} fail - Located failure.
52
+ * @param {{functions: Map<string, Set<string>>, methods: Map<string, Set<string>>}} errorEffects - Complete escaping error sets per function and method.
53
+ * @returns {LifetimeExit[]} Reachable exits.
54
+ */
55
+ function analyzeBlock(block, incoming, fail, errorEffects) {
56
+ let active = incoming.filter(({ kind }) => kind == "normal");
57
+ const departed = incoming.filter(({ kind }) => kind != "normal");
58
+ /** @type {Set<string>} */
59
+ const locals = new Set();
60
+ for (const statement of block.statements) {
61
+ if (active.length == 0)
62
+ break;
63
+ const next = [];
64
+ for (const flow of active)
65
+ next.push(...analyzeStatement(statement, flow.state, fail, locals, errorEffects));
66
+ departed.push(...next.filter(({ kind }) => kind != "normal"));
67
+ active = mergeEquivalentNormals(next.filter(({ kind }) => kind == "normal"), statement.location, fail);
68
+ }
69
+ const exits = [...departed, ...active.map((flow) => ({ ...flow, location: flow.location ?? block.location }))];
70
+ for (const exit of exits) {
71
+ checkLeaks(exit.state, locals, exit.location ?? block.location, fail);
72
+ for (const name of locals)
73
+ exit.state.delete(name);
74
+ }
75
+ return exits;
76
+ }
77
+ /**
78
+ * Evaluates one statement from one normal state.
79
+ * @param {import("./types.js").Statement} statement - Statement.
80
+ * @param {Map<string, OwnerState>} state - Incoming ownership state.
81
+ * @param {LifetimeFail} fail - Located failure.
82
+ * @param {Set<string>} locals - Locals introduced in the current block.
83
+ * @param {{functions: Map<string, Set<string>>, methods: Map<string, Set<string>>}} errorEffects - Complete escaping error sets per function and method.
84
+ * @returns {LifetimeExit[]} Reachable exits.
85
+ */
86
+ function analyzeStatement(statement, state, fail, locals, errorEffects) {
87
+ if (statement.kind == "LocalDeclaration") {
88
+ const flows = evaluateExpression(statement.initializer, cloneState(state), fail, errorEffects);
89
+ if (isOwned(statement.type)) {
90
+ locals.add(statement.name);
91
+ for (const flow of flows) {
92
+ if (flow.kind != "normal")
93
+ continue;
94
+ const origin = statement.initializer.kind == "OwnedMoveExpression"
95
+ ? flow.state.get(statement.initializer.expression.name)?.origin ?? statement.initializer.location
96
+ : statement.initializer.location;
97
+ flow.state.set(statement.name, openState(`local:${statement.name}`, origin));
98
+ }
99
+ }
100
+ return flows.map((flow) => ({ ...flow, location: statement.location }));
101
+ }
102
+ if (statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement") {
103
+ return evaluateExpression(statement.expression, cloneState(state), fail, errorEffects)
104
+ .map((flow) => ({ ...flow, location: statement.location }));
105
+ }
106
+ if (statement.kind == "AssignmentStatement" || statement.kind == "PrivateFieldWriteStatement") {
107
+ return evaluateExpression(statement.expression, cloneState(state), fail, errorEffects)
108
+ .map((flow) => ({ ...flow, location: statement.location }));
109
+ }
110
+ if (statement.kind == "ReturnStatement") {
111
+ const flows = statement.expression ? evaluateExpression(statement.expression, cloneState(state), fail, errorEffects) :
112
+ /** @type {LifetimeExit[]} */ ([{ kind: "normal", state: cloneState(state) }]);
113
+ return flows.map((flow) => flow.kind == "normal"
114
+ ? { kind: "return", location: statement.location, state: flow.state }
115
+ : { ...flow, location: statement.location });
116
+ }
117
+ if (statement.kind == "RaiseStatement") {
118
+ const flows = evaluateExpression(statement.error.message, cloneState(state), fail, errorEffects);
119
+ return flows.map((flow) => flow.kind == "normal"
120
+ ? { errorId: statement.error.error.declarationId, kind: "raise", location: statement.location, state: flow.state }
121
+ : { ...flow, location: statement.location });
122
+ }
123
+ if (statement.kind == "IfStatement") {
124
+ const conditions = evaluateExpression(statement.condition, cloneState(state), fail, errorEffects);
125
+ /** @type {LifetimeExit[]} */
126
+ const result = conditions.filter(({ kind }) => kind != "normal");
127
+ for (const condition of conditions.filter(({ kind }) => kind == "normal")) {
128
+ result.push(...analyzeBlock(statement.consequent, [{ kind: "normal", state: cloneState(condition.state) }], fail, errorEffects));
129
+ const alternate = statement.alternate
130
+ ? analyzeBlock(statement.alternate, [{ kind: "normal", state: cloneState(condition.state) }], fail, errorEffects)
131
+ : /** @type {LifetimeExit[]} */ ([{ kind: "normal", location: statement.location, state: cloneState(condition.state) }]);
132
+ result.push(...alternate);
133
+ }
134
+ return mergeEquivalentNormals(result, statement.location, fail);
135
+ }
136
+ if (statement.kind == "TryStatement") {
137
+ const bodyExits = analyzeBlock(statement.body, [{ kind: "normal", state: cloneState(state) }], fail, errorEffects);
138
+ /** @type {LifetimeExit[]} */
139
+ const result = bodyExits.filter((flow) => flow.kind != "raise" || flow.errorId != statement.catchType.declarationId);
140
+ for (const caught of bodyExits.filter((flow) => flow.kind == "raise" && flow.errorId == statement.catchType.declarationId)) {
141
+ result.push(...analyzeBlock(statement.catchBody, [{ kind: "normal", state: cloneState(caught.state) }], fail, errorEffects));
142
+ }
143
+ return mergeEquivalentNormals(result, statement.location, fail);
144
+ }
145
+ if (statement.kind == "WhileStatement") {
146
+ const conditions = evaluateExpression(statement.condition, cloneState(state), fail, errorEffects);
147
+ /** @type {LifetimeExit[]} */
148
+ const result = conditions.filter(({ kind }) => kind != "normal");
149
+ for (const condition of conditions.filter(({ kind }) => kind == "normal")) {
150
+ const bodyExits = analyzeBlock(statement.body, [{ kind: "normal", state: cloneState(condition.state) }], fail, errorEffects);
151
+ for (const exit of bodyExits) {
152
+ if (exit.kind == "normal" || exit.kind == "continue")
153
+ requireSameState(condition.state, exit.state, statement.location, fail);
154
+ else if (exit.kind == "break") {
155
+ requireSameState(condition.state, exit.state, statement.location, fail);
156
+ result.push({ kind: "normal", location: statement.location, state: exit.state });
157
+ }
158
+ else
159
+ result.push(exit);
160
+ }
161
+ result.push({ kind: "normal", location: statement.location, state: condition.state });
162
+ }
163
+ return mergeEquivalentNormals(result, statement.location, fail);
164
+ }
165
+ if (statement.kind == "ForEachStatement" || statement.kind == "ForEachMapStatement") {
166
+ const operand = statement.kind == "ForEachStatement" ? statement.list : statement.map;
167
+ const operands = evaluateExpression(operand, cloneState(state), fail, errorEffects);
168
+ /** @type {LifetimeExit[]} */
169
+ const result = operands.filter(({ kind }) => kind != "normal");
170
+ for (const evaluated of operands.filter(({ kind }) => kind == "normal")) {
171
+ const bodyExits = analyzeBlock(statement.body, [{ kind: "normal", state: cloneState(evaluated.state) }], fail, errorEffects);
172
+ for (const exit of bodyExits) {
173
+ if (exit.kind == "normal" || exit.kind == "continue")
174
+ requireSameState(evaluated.state, exit.state, statement.location, fail);
175
+ else if (exit.kind == "break") {
176
+ requireSameState(evaluated.state, exit.state, statement.location, fail);
177
+ result.push({ kind: "normal", location: statement.location, state: exit.state });
178
+ }
179
+ else
180
+ result.push(exit);
181
+ }
182
+ result.push({ kind: "normal", location: statement.location, state: evaluated.state });
183
+ }
184
+ return mergeEquivalentNormals(result, statement.location, fail);
185
+ }
186
+ if (statement.kind == "BreakStatement")
187
+ return [{ kind: "break", location: statement.location, state: cloneState(state) }];
188
+ if (statement.kind == "ContinueStatement")
189
+ return [{ kind: "continue", location: statement.location, state: cloneState(state) }];
190
+ return [];
191
+ }
192
+ /**
193
+ * Evaluates one expression with failure states at exact evaluation boundaries.
194
+ * @param {import("./types.js").Expression} expression - Expression.
195
+ * @param {Map<string, OwnerState>} state - Incoming ownership state.
196
+ * @param {LifetimeFail} fail - Located failure.
197
+ * @param {{functions: Map<string, Set<string>>, methods: Map<string, Set<string>>}} errorEffects - Complete escaping error sets per function and method.
198
+ * @returns {LifetimeExit[]} Reachable exits.
199
+ */
200
+ function evaluateExpression(expression, state, fail, errorEffects) {
201
+ if (expression.kind == "OwnedMoveExpression") {
202
+ const owner = requireOwner(expression.expression.name, state, expression.location, fail);
203
+ if (owner.kind == "moved")
204
+ fail("USE_AFTER_MOVE", `Resource '${expression.expression.name}' was already moved.`, expression.location);
205
+ if (owner.kind == "terminal")
206
+ fail("USE_AFTER_CLOSE", `Resource '${expression.expression.name}' is terminal after close.`, expression.location);
207
+ state.set(expression.expression.name, { ...owner, destination: "transfer", kind: "moved" });
208
+ return [{ kind: "normal", state }];
209
+ }
210
+ if (expression.kind == "OwnedBorrowExpression") {
211
+ const name = placeName(expression.expression);
212
+ const owner = requireOwner(name, state, expression.location, fail);
213
+ if (owner.kind == "moved")
214
+ fail("USE_AFTER_MOVE", `Resource '${name}' was moved before this borrow.`, expression.location);
215
+ return [{ kind: "normal", state }];
216
+ }
217
+ if (expression.kind == "EffectCallExpression")
218
+ return evaluateEffectCall(expression, state, fail, errorEffects);
219
+ if (expression.kind == "CallExpression" || expression.kind == "MethodCallExpression" || expression.kind == "ReferenceConstruction") {
220
+ return evaluateOrdinaryCall(expression, state, fail, errorEffects);
221
+ }
222
+ /** @type {LifetimeExit[]} */
223
+ let flows = [{ kind: "normal", state }];
224
+ for (const child of expressionChildren(expression))
225
+ flows = evaluateForFlows(child, flows, fail, errorEffects);
226
+ return flows;
227
+ }
228
+ /**
229
+ * Applies one capability operation's declared ownership and failure flow.
230
+ * @param {import("./types.js").EffectCallExpression} expression - Effect call.
231
+ * @param {Map<string, OwnerState>} state - Incoming ownership state.
232
+ * @param {LifetimeFail} fail - Located failure.
233
+ * @param {{functions: Map<string, Set<string>>, methods: Map<string, Set<string>>}} errorEffects - Complete escaping error sets per function and method.
234
+ * @returns {LifetimeExit[]} Reachable exits.
235
+ */
236
+ function evaluateEffectCall(expression, state, fail, errorEffects) {
237
+ /** @type {LifetimeExit[]} */
238
+ let flows = [{ kind: "normal", state }];
239
+ for (const argument of expression.arguments)
240
+ flows = evaluateForFlows(argument, flows, fail, errorEffects);
241
+ const result = flows.filter(({ kind }) => kind != "normal");
242
+ const resourceFlow = expression.resolution.resourceFlow;
243
+ for (const flow of flows.filter(({ kind }) => kind == "normal")) {
244
+ let operationState = cloneState(flow.state);
245
+ let terminalFailure;
246
+ if (resourceFlow.kind == "borrow" || resourceFlow.kind == "close") {
247
+ const argument = expression.arguments[resourceFlow.parameterIndex];
248
+ if (argument.kind != "OwnedBorrowExpression")
249
+ fail("INVALID_RESOURCE_BORROW", "Resource operation lacks an immediate borrow.", argument.location);
250
+ const name = placeName(argument.expression);
251
+ const owner = requireOwner(name, operationState, argument.location, fail);
252
+ if (owner.kind == "moved")
253
+ fail("USE_AFTER_MOVE", `Resource '${name}' was moved before this operation.`, argument.location);
254
+ if (owner.kind == "terminal")
255
+ terminalFailure = resourceFlow.terminalFailureId;
256
+ else if (resourceFlow.kind == "close")
257
+ operationState.set(name, { ...owner, closeSiteId: expression.effectSiteId, kind: "terminal" });
258
+ }
259
+ if (terminalFailure) {
260
+ result.push({ errorId: terminalFailure, kind: "raise", location: expression.location, state: operationState });
261
+ continue;
262
+ }
263
+ const failureIds = expression.resolution.failureIds.filter((id) => resourceFlow.kind != "borrow" && resourceFlow.kind != "close" || id != resourceFlow.terminalFailureId);
264
+ result.push({ kind: "normal", state: cloneState(operationState) });
265
+ for (const errorId of failureIds) {
266
+ result.push({ errorId, kind: "raise", location: expression.location, state: cloneState(operationState) });
267
+ }
268
+ }
269
+ return result;
270
+ }
271
+ /**
272
+ * Applies call-entry ownership commit semantics after ordered argument evaluation.
273
+ * @param {import("./types.js").CallExpression | import("./types.js").MethodCallExpression | import("./types.js").ReferenceConstruction} expression - Call.
274
+ * @param {Map<string, OwnerState>} state - Incoming ownership state.
275
+ * @param {LifetimeFail} fail - Located failure.
276
+ * @param {{functions: Map<string, Set<string>>, methods: Map<string, Set<string>>}} errorEffects - Complete escaping error sets per function and method.
277
+ * @returns {LifetimeExit[]} Reachable exits.
278
+ */
279
+ function evaluateOrdinaryCall(expression, state, fail, errorEffects) {
280
+ const arguments_ = expression.kind == "MethodCallExpression" ? [expression.receiver, ...expression.arguments] : expression.arguments;
281
+ /** @type {LifetimeExit[]} */
282
+ let flows = [{ kind: "normal", state }];
283
+ /** @type {string[]} */
284
+ const reservedMoves = [];
285
+ for (const argument of arguments_) {
286
+ if (argument.kind == "OwnedMoveExpression") {
287
+ for (const flow of flows.filter(({ kind }) => kind == "normal")) {
288
+ const owner = requireOwner(argument.expression.name, flow.state, argument.location, fail);
289
+ if (owner.kind == "moved")
290
+ fail("USE_AFTER_MOVE", `Resource '${argument.expression.name}' was already moved.`, argument.location);
291
+ if (owner.kind == "terminal")
292
+ fail("USE_AFTER_CLOSE", `Resource '${argument.expression.name}' is terminal after close.`, argument.location);
293
+ }
294
+ if (reservedMoves.includes(argument.expression.name)) {
295
+ fail("RESOURCE_ALIAS", `Resource '${argument.expression.name}' cannot be transferred to two parameters.`, argument.location);
296
+ }
297
+ reservedMoves.push(argument.expression.name);
298
+ }
299
+ else
300
+ flows = evaluateForFlows(argument, flows, fail, errorEffects);
301
+ }
302
+ const result = flows.filter(({ kind }) => kind != "normal");
303
+ for (const flow of flows.filter(({ kind }) => kind == "normal")) {
304
+ const entered = cloneState(flow.state);
305
+ for (const name of reservedMoves) {
306
+ const owner = requireOwner(name, entered, expression.location, fail);
307
+ if (owner.kind == "moved")
308
+ fail("USE_AFTER_MOVE", `Resource '${name}' was already moved.`, expression.location);
309
+ if (owner.kind == "terminal")
310
+ fail("USE_AFTER_CLOSE", `Resource '${name}' is terminal after close.`, expression.location);
311
+ entered.set(name, { ...owner, destination: "callee", kind: "moved" });
312
+ }
313
+ if (expression.kind == "MethodCallExpression" && expression.resolution?.resourceFlow) {
314
+ const receiver = expression.receiver.kind == "OwnedBorrowExpression" ? expression.receiver.expression : expression.receiver;
315
+ if (receiver.kind != "IdentifierExpression" && receiver.kind != "ReceiverExpression" && receiver.kind != "PrivateFieldRead") {
316
+ fail("INVALID_RESOURCE_BORROW", "Owned method receiver must be an immediate borrowed place.", receiver.location);
317
+ }
318
+ const name = placeName(receiver);
319
+ const owner = requireOwner(name, entered, expression.location, fail);
320
+ if (owner.kind == "terminal") {
321
+ if (expression.resolution.resourceFlow.terminalFailureId) {
322
+ result.push({ errorId: expression.resolution.resourceFlow.terminalFailureId, kind: "raise",
323
+ location: expression.location, state: entered });
324
+ continue;
325
+ }
326
+ fail("USE_AFTER_CLOSE", `Resource '${name}' is terminal after close.`, expression.location);
327
+ }
328
+ if (expression.resolution.resourceFlow.kind == "terminal") {
329
+ entered.set(name, { ...owner, closeSiteId: expression.effectSiteId ?? expression.location, kind: "terminal" });
330
+ }
331
+ }
332
+ result.push({ kind: "normal", state: cloneState(entered) });
333
+ const escaping = new Set(expression.failureIds ?? []);
334
+ if (expression.kind == "CallExpression") {
335
+ for (const errorId of errorEffects.functions.get(expression.callee) ?? [])
336
+ escaping.add(errorId);
337
+ }
338
+ else if (expression.kind == "MethodCallExpression") {
339
+ for (const errorId of errorEffects.methods.get(expression.method) ?? [])
340
+ escaping.add(errorId);
341
+ }
342
+ for (const errorId of escaping) {
343
+ result.push({ errorId, kind: "raise", location: expression.location, state: cloneState(entered) });
344
+ }
345
+ }
346
+ return result;
347
+ }
348
+ /**
349
+ * Evaluates a child expression only along normal incoming paths.
350
+ * @param {import("./types.js").Expression} expression - Child expression.
351
+ * @param {LifetimeExit[]} flows - Incoming paths.
352
+ * @param {LifetimeFail} fail - Located failure.
353
+ * @param {{functions: Map<string, Set<string>>, methods: Map<string, Set<string>>}} errorEffects - Complete escaping error sets per function and method.
354
+ * @returns {LifetimeExit[]} Reachable exits.
355
+ */
356
+ function evaluateForFlows(expression, flows, fail, errorEffects) {
357
+ const result = flows.filter(({ kind }) => kind != "normal");
358
+ for (const flow of flows.filter(({ kind }) => kind == "normal")) {
359
+ result.push(...evaluateExpression(expression, cloneState(flow.state), fail, errorEffects));
360
+ }
361
+ return result;
362
+ }
363
+ /**
364
+ * Returns non-call expression children in evaluation order.
365
+ * @param {import("./types.js").Expression} expression - Parent expression.
366
+ * @returns {import("./types.js").Expression[]} Children.
367
+ */
368
+ function expressionChildren(expression) {
369
+ if (expression.kind == "BinaryExpression")
370
+ return [expression.left, expression.right];
371
+ if (expression.kind == "UnaryExpression")
372
+ return [expression.operand];
373
+ if (expression.kind == "OptionalSome")
374
+ return [expression.value];
375
+ if (expression.kind == "OptionalIsPresent" || expression.kind == "OptionalUnwrap")
376
+ return [expression.operand];
377
+ if (expression.kind == "ListLiteral")
378
+ return expression.elements;
379
+ if (expression.kind == "MapLiteral" || expression.kind == "OrderedMapLiteral")
380
+ return expression.entries.map(({ value }) => value);
381
+ if (expression.kind == "ListIndexExpression")
382
+ return [expression.collection, expression.index];
383
+ if (expression.kind == "MapLookupExpression")
384
+ return [expression.collection, expression.key];
385
+ if (expression.kind == "CollectionSizeExpression")
386
+ return [expression.collection];
387
+ if (expression.kind == "RecordConstruction")
388
+ return expression.arguments;
389
+ if (expression.kind == "MemberRead")
390
+ return [expression.receiver];
391
+ if (expression.kind == "PrivateFieldRead")
392
+ return [expression.receiver];
393
+ if (expression.kind == "ErrorMessageRead")
394
+ return [expression.receiver];
395
+ return [];
396
+ }
397
+ /**
398
+ * Merges normal paths only after proving identical ownership states.
399
+ * @param {LifetimeExit[]} flows - Candidate paths.
400
+ * @param {import("./types.js").SourceLocation} location - Join location.
401
+ * @param {LifetimeFail} fail - Located failure.
402
+ * @returns {LifetimeExit[]} Merged paths.
403
+ */
404
+ function mergeEquivalentNormals(flows, location, fail) {
405
+ const normal = flows.filter(({ kind }) => kind == "normal");
406
+ if (normal.length > 1) {
407
+ for (const candidate of normal.slice(1))
408
+ requireSameState(normal[0].state, candidate.state, location, fail);
409
+ }
410
+ return [...flows.filter(({ kind }) => kind != "normal"), ...(normal.length > 0 ? [normal[0]] : [])];
411
+ }
412
+ /**
413
+ * Requires a finite ownership invariant at a branch or loop join.
414
+ * @param {Map<string, OwnerState>} left - First ownership state.
415
+ * @param {Map<string, OwnerState>} right - Second ownership state.
416
+ * @param {import("./types.js").SourceLocation} location - Join location.
417
+ * @param {LifetimeFail} fail - Located failure.
418
+ * @returns {void}
419
+ */
420
+ function requireSameState(left, right, location, fail) {
421
+ const names = new Set([...left.keys(), ...right.keys()]);
422
+ for (const name of names) {
423
+ const leftState = left.get(name);
424
+ const rightState = right.get(name);
425
+ if (leftState?.kind != rightState?.kind || leftState?.originId != rightState?.originId) {
426
+ fail("RESOURCE_STATE_MISMATCH", `Resource '${name}' has different ownership state across reachable paths.`, location);
427
+ }
428
+ }
429
+ }
430
+ /**
431
+ * Rejects every owned value that leaves its introducing scope open.
432
+ * @param {Map<string, OwnerState>} state - Ownership state.
433
+ * @param {Set<string>} names - Owners introduced in the scope.
434
+ * @param {import("./types.js").SourceLocation} location - Exit location.
435
+ * @param {LifetimeFail} fail - Located failure.
436
+ * @returns {void}
437
+ */
438
+ function checkLeaks(state, names, location, fail) {
439
+ for (const name of names) {
440
+ const owner = state.get(name);
441
+ if (owner?.kind == "open") {
442
+ const origin = owner.origin;
443
+ fail("LEAKED_RESOURCE", `Owned resource '${name}' remains open; acquired at ${origin.filename}:${origin.start.line}:${origin.start.column}.`, location);
444
+ }
445
+ }
446
+ }
447
+ /**
448
+ * Resolves an owned place in the current scope.
449
+ * @param {string} name - Stable place name.
450
+ * @param {Map<string, OwnerState>} state - Ownership state.
451
+ * @param {import("./types.js").SourceLocation} location - Use location.
452
+ * @param {LifetimeFail} fail - Located failure.
453
+ * @returns {OwnerState} Owner state.
454
+ */
455
+ function requireOwner(name, state, location, fail) {
456
+ const owner = state.get(name);
457
+ if (!owner)
458
+ return fail("INVALID_RESOURCE_BORROW", `No owned resource place '${name}' is in scope.`, location);
459
+ return owner;
460
+ }
461
+ /**
462
+ * Converts an immediate owned expression to a stable place name.
463
+ * @param {import("./types.js").IdentifierExpression | import("./types.js").ReceiverExpression | import("./types.js").PrivateFieldRead} expression - Owned place.
464
+ * @returns {string} Place identity.
465
+ */
466
+ function placeName(expression) {
467
+ if (expression.kind == "IdentifierExpression")
468
+ return expression.name;
469
+ if (expression.kind == "ReceiverExpression")
470
+ return "this";
471
+ if (expression.kind == "PrivateFieldRead")
472
+ return `this.${expression.field}`;
473
+ return "<invalid>";
474
+ }
475
+ /**
476
+ * Creates one open ownership state.
477
+ * @param {string} originId - Deterministic origin identity.
478
+ * @param {import("./types.js").SourceLocation} origin - Acquisition location.
479
+ * @returns {OwnerState} Open state.
480
+ */
481
+ function openState(originId, origin) {
482
+ return { kind: "open", origin, originId };
483
+ }
484
+ /**
485
+ * Clones an ownership state for a control-flow fork.
486
+ * @param {Map<string, OwnerState>} state - State to clone.
487
+ * @returns {Map<string, OwnerState>} Detached state.
488
+ */
489
+ function cloneState(state) {
490
+ return new Map([...state].map(([name, value]) => [name, { ...value }]));
491
+ }
492
+ /**
493
+ * Checks whether a type carries linear ownership.
494
+ * @param {import("./types.js").SemanticFunctionReturnType} type - Semantic type.
495
+ * @returns {boolean} Whether the type is owned.
496
+ */
497
+ function isOwned(type) {
498
+ return type.kind == "OwnedResourceType" || type.kind == "OwnedReferenceType";
499
+ }
500
+ /**
501
+ * Checks whether the module contains any owned semantic type.
502
+ * @param {import("./types.js").SemanticModule} module - Semantic module.
503
+ * @returns {boolean} Whether lifetime analysis is required.
504
+ */
505
+ function moduleContainsOwnedType(module) {
506
+ const pending = [/** @type {unknown} */ (module)];
507
+ const seen = new Set();
508
+ while (pending.length > 0) {
509
+ const value = pending.pop();
510
+ if (!value || typeof value != "object" || seen.has(value))
511
+ continue;
512
+ seen.add(value);
513
+ if (!Array.isArray(value) && (Reflect.get(value, "kind") == "OwnedResourceType" ||
514
+ Reflect.get(value, "kind") == "OwnedReferenceType"))
515
+ return true;
516
+ for (const [key, child] of Object.entries(value)) {
517
+ if (["location", "provenance", "sourceProvenance"].includes(key))
518
+ continue;
519
+ if (Array.isArray(child))
520
+ pending.push(...child);
521
+ else if (child && typeof child == "object")
522
+ pending.push(child);
523
+ }
524
+ }
525
+ return false;
526
+ }
527
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlmZXRpbWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VtYW50aWMvbGlmZXRpbWUuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLHFIQUFxSDtBQUNySCwrVkFBK1Y7QUFDL1YsNkxBQTZMO0FBRTdMOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSx5QkFBeUIsQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLElBQUk7SUFDbEUsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLFlBQVksSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFDLFNBQVMsRUFBQyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsTUFBTSxDQUFDO1FBQUUsT0FBTTtJQUV4SCxLQUFLLE1BQU0sV0FBVyxJQUFJLE1BQU0sQ0FBQyxPQUFPLElBQUksRUFBRSxFQUFFLENBQUM7UUFDL0MsWUFBWSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUE7UUFDN0csS0FBSyxNQUFNLE1BQU0sSUFBSSxXQUFXLENBQUMsT0FBTztZQUFFLFlBQVksQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUN6RixXQUFXLENBQUMsU0FBUyxFQUFFLElBQUksSUFBSSxlQUFlLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUE7SUFDN0csQ0FBQztJQUNELEtBQUssTUFBTSxXQUFXLElBQUksTUFBTSxDQUFDLFNBQVM7UUFBRSxZQUFZLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxXQUFXLENBQUMs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dHJpbmcsIGRldGFpbDogc3RyaW5nLCBsb2NhdGlvbjogaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbikgPT4gbmV2ZXJ9IExpZmV0aW1lRmFpbCAqL1xuLyoqIEB0eXBlZGVmIHt7a2luZDogXCJvcGVuXCIsIG9yaWdpbklkOiBzdHJpbmcsIG9yaWdpbjogaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gfCB7a2luZDogXCJtb3ZlZFwiLCBvcmlnaW5JZDogc3RyaW5nLCBvcmlnaW46IGltcG9ydChcIi4vdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIGRlc3RpbmF0aW9uOiBzdHJpbmd9IHwge2tpbmQ6IFwidGVybWluYWxcIiwgb3JpZ2luSWQ6IHN0cmluZywgb3JpZ2luOiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBjbG9zZVNpdGVJZDogc3RyaW5nIHwgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn19IE93bmVyU3RhdGUgKi9cbi8qKiBAdHlwZWRlZiB7e2tpbmQ6IFwibm9ybWFsXCIgfCBcInJldHVyblwiIHwgXCJyYWlzZVwiIHwgXCJicmVha1wiIHwgXCJjb250aW51ZVwiLCBzdGF0ZTogTWFwPHN0cmluZywgT3duZXJTdGF0ZT4sIGxvY2F0aW9uPzogaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbiwgZXJyb3JJZD86IHN0cmluZ319IExpZmV0aW1lRXhpdCAqL1xuXG4vKipcbiAqIFBlcmZvcm1zIHBhdGgtc2Vuc2l0aXZlIHN0cnVjdHVyZWQgbGlmZXRpbWUgdmFsaWRhdGlvbiBmb3IgVGFzayAwMzQgb3duZWQgdmFsdWVzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBGdWxseSB0eXBlLXJlc29sdmVkIG1vZHVsZS5cbiAqIEBwYXJhbSB7e2Z1bmN0aW9uczogTWFwPHN0cmluZywgU2V0PHN0cmluZz4+LCBtZXRob2RzOiBNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj59fSBlcnJvckVmZmVjdHMgLSBDb21wbGV0ZSBlc2NhcGluZyBlcnJvciBzZXRzIHBlciBmdW5jdGlvbiBhbmQgbWV0aG9kLlxuICogQHBhcmFtIHtMaWZldGltZUZhaWx9IGZhaWwgLSBMb2NhdGVkIGZhaWx1cmUuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlUmVzb3VyY2VMaWZldGltZXMobW9kdWxlLCBlcnJvckVmZmVjdHMsIGZhaWwpIHtcbiAgaWYgKCEobW9kdWxlLmNhcGFiaWxpdGllcyA/PyBbXSkuc29tZSgoe3Jlc291cmNlc30pID0+IHJlc291cmNlcy5sZW5ndGggPiAwKSAmJiAhbW9kdWxlQ29udGFpbnNPd25lZFR5cGUobW9kdWxlKSkgcmV0dXJuXG5cbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuY2xhc3NlcyA/PyBbXSkge1xuICAgIGFuYWx5emVPd25lcihkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5wYXJhbWV0ZXJzLCBkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5ib2R5LCBmYWlsLCB1bmRlZmluZWQsIGVycm9yRWZmZWN0cylcbiAgICBmb3IgKGNvbnN0IG1ldGhvZCBvZiBkZWNsYXJhdGlvbi5tZXRob2RzKSBhbmFseXplT3duZXIobWV0aG9kLnBhcmFtZXRlcnMsIG1ldGhvZC5ib2R5LCBmYWlsLFxuICAgICAgZGVjbGFyYXRpb24ub3duZXJzaGlwPy5raW5kID09IFwib3duZWRSZXNvdXJjZVwiID8gZGVjbGFyYXRpb24ub3duZXJzaGlwLmZpZWxkSWQgOiB1bmRlZmluZWQsIGVycm9yRWZmZWN0cylcbiAgfVxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5mdW5jdGlvbnMpIGFuYWx5emVPd25lcihkZWNsYXJhdGlvbi5wYXJhbWV0ZXJzLCBkZWNsYXJhdGlvbi5ib2R5LCBmYWlsLCB1bmRlZmluZWQsIGVycm9yRWZmZWN0cylcbiAgYW5hbHl6ZU93bmVyKFtdLCBtb2R1bGUuZW50cnlQb2ludC5ib2R5LCBmYWlsLCB1bmRlZmluZWQsIGVycm9yRWZmZWN0cylcbn1cblxuLyoqXG4gKiBBbmFseXplcyBvbmUgZnVuY3Rpb24sIGNvbnN0cnVjdG9yLCBtZXRob2QsIG9yIGVudHJ5LXBvaW50IG93bmVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlBhcmFtZXRlcltdfSBwYXJhbWV0ZXJzIC0gT3duZWQgcGFyYW1ldGVycy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CbG9ja30gYm9keSAtIFN0cnVjdHVyZWQgYm9keS5cbiAqIEBwYXJhbSB7TGlmZXRpbWVGYWlsfSBmYWlsIC0gTG9jYXRlZCBmYWlsdXJlLlxuICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IGJvcnJvd2VkRmllbGRJZCAtIE93bmVkIHJlY2VpdmVyIGZpZWxkLCB3aGVuIHByZXNlbnQuXG4gKiBAcGFyYW0ge3tmdW5jdGlvbnM6IE1hcDxzdHJpbmcsIFNldDxzdHJpbmc+PiwgbWV0aG9kczogTWFwPHN0cmluZywgU2V0PHN0cmluZz4+fX0gZXJyb3JFZmZlY3RzIC0gQ29tcGxldGUgZXNjYXBpbmcgZXJyb3Igc2V0cyBwZXIgZnVuY3Rpb24gYW5kIG1ldGhvZC5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiBhbmFseXplT3duZXIocGFyYW1ldGVycywgYm9keSwgZmFpbCwgYm9ycm93ZWRGaWVsZElkLCBlcnJvckVmZmVjdHMpIHtcbiAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBPd25lclN0YXRlPn0gKi9cbiAgY29uc3QgaW5pdGlhbCA9IG5ldyBNYXAoKVxuICBjb25zdCBvYmxpZ2F0aW9ucyA9IG5ldyBTZXQocGFyYW1ldGVycy5maWx0ZXIoKHt0eXBlfSkgPT4gaXNPd25lZCh0eXBlKSkubWFwKCh7bmFtZX0pID0+IG5hbWUpKVxuXG4gIGZvciAoY29uc3QgcGFyYW1ldGVyIG9mIHBhcmFtZXRlcnMpIHtcbiAgICBpZiAoaXNPd25lZChwYXJhbWV0ZXIudHlwZSkpIGluaXRpYWwuc2V0KHBhcmFtZXRlci5uYW1lLCBvcGVuU3RhdGUoYHBhcmFtZXRlcjoke3BhcmFtZXRlci5uYW1lfWAsIHBhcmFtZXRlci5sb2NhdGlvbikpXG4gIH1cbiAgaWYgKGJvcnJvd2VkRmllbGRJZCkgaW5pdGlhbC5zZXQoYHRoaXMuJHtib3Jyb3dlZEZpZWxkSWR9YCwgb3BlblN0YXRlKGByZWNlaXZlcjoke2JvcnJvd2VkRmllbGRJZH1gLCBib2R5LmxvY2F0aW9uKSlcbiAgY29uc3QgZXhpdHMgPSBhbmFseXplQmxvY2soYm9keSwgW3traW5kOiBcIm5vcm1hbFwiLCBzdGF0ZTogaW5pdGlhbH1dLCBmYWlsLCBlcnJvckVmZmVjdHMpXG5cbiAgZm9yIChjb25zdCBleGl0IG9mIGV4aXRzKSBjaGVja0xlYWtzKGV4aXQuc3RhdGUsIG9ibGlnYXRpb25zLCBleGl0LmxvY2F0aW9uID8/IGJvZHkubG9jYXRpb24sIGZhaWwpXG59XG5cbi8qKlxuICogRXZhbHVhdGVzIG9uZSBsZXhpY2FsIGJsb2NrIHdoaWxlIHJldGFpbmluZyBldmVyeSBhYnJ1cHQgZXhpdCBzZXBhcmF0ZWx5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkJsb2NrfSBibG9jayAtIFN0cnVjdHVyZWQgYmxvY2suXG4gKiBAcGFyYW0ge0xpZmV0aW1lRXhpdFtdfSBpbmNvbWluZyAtIEluY29taW5nIGNvbnRyb2wtZmxvdyBzdGF0ZXMuXG4gKiBAcGFyYW0ge0xpZmV0aW1lRmFpbH0gZmFpbCAtIExvY2F0ZWQgZmFpbHVyZS5cbiAqIEBwYXJhbSB7e2Z1bmN0aW9uczogTWFwPHN0cmluZywgU2V0PHN0cmluZz4+LCBtZXRob2RzOiBNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj59fSBlcnJvckVmZmVjdHMgLSBDb21wbGV0ZSBlc2NhcGluZyBlcnJvciBzZXRzIHBlciBmdW5jdGlvbiBhbmQgbWV0aG9kLlxuICogQHJldHVybnMge0xpZmV0aW1lRXhpdFtdfSBSZWFjaGFibGUgZXhpdHMuXG4gKi9cbmZ1bmN0aW9uIGFuYWx5emVCbG9jayhibG9jaywgaW5jb21pbmcsIGZhaWwsIGVycm9yRWZmZWN0cykge1xuICBsZXQgYWN0aXZlID0gaW5jb21pbmcuZmlsdGVyKCh7a2luZH0pID0+IGtpbmQgPT0gXCJub3JtYWxcIilcbiAgY29uc3QgZGVwYXJ0ZWQgPSBpbmNvbWluZy5maWx0ZXIoKHtraW5kfSkgPT4ga2luZCAhPSBcIm5vcm1hbFwiKVxuICAvKiogQHR5cGUge1NldDxzdHJpbmc+fSAqL1xuICBjb25zdCBsb2NhbHMgPSBuZXcgU2V0KClcblxuICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBibG9jay5zdGF0ZW1lbnRzKSB7XG4gICAgaWYgKGFjdGl2ZS5sZW5ndGggPT0gMCkgYnJlYWtcbiAgICBjb25zdCBuZXh0ID0gW11cblxuICAgIGZvciAoY29uc3QgZmxvdyBvZiBhY3RpdmUpIG5leHQucHVzaCguLi5hbmFseXplU3RhdGVtZW50KHN0YXRlbWVudCwgZmxvdy5zdGF0ZSwgZmFpbCwgbG9jYWxzLCBlcnJvckVmZmVjdHMpKVxuICAgIGRlcGFydGVkLnB1c2goLi4ubmV4dC5maWx0ZXIoKHtraW5kfSkgPT4ga2luZCAhPSBcIm5vcm1hbFwiKSlcbiAgICBhY3RpdmUgPSBtZXJnZUVxdWl2YWxlbnROb3JtYWxzKG5leHQuZmlsdGVyKCh7a2luZH0pID0+IGtpbmQgPT0gXCJub3JtYWxcIiksIHN0YXRlbWVudC5sb2NhdGlvbiwgZmFpbClcbiAgfVxuICBjb25zdCBleGl0cyA9IFsuLi5kZXBhcnRlZCwgLi4uYWN0aXZlLm1hcCgoZmxvdykgPT4gKHsuLi5mbG93LCBsb2NhdGlvbjogZmxvdy5sb2NhdGlvbiA/PyBibG9jay5sb2NhdGlvbn0pKV1cblxuICBmb3IgKGNvbnN0IGV4aXQgb2YgZXhpdHMpIHtcbiAgICBjaGVja0xlYWtzKGV4aXQuc3RhdGUsIGxvY2FscywgZXhpdC5sb2NhdGlvbiA/PyBibG9jay5sb2NhdGlvbiwgZmFpbClcbiAgICBmb3IgKGNvbnN0IG5hbWUgb2YgbG9jYWxzKSBleGl0LnN0YXRlLmRlbGV0ZShuYW1lKVxuICB9XG4gIHJldHVybiBleGl0c1xufVxuXG4vKipcbiAqIEV2YWx1YXRlcyBvbmUgc3RhdGVtZW50IGZyb20gb25lIG5vcm1hbCBzdGF0ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TdGF0ZW1lbnR9IHN0YXRlbWVudCAtIFN0YXRlbWVudC5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgT3duZXJTdGF0ZT59IHN0YXRlIC0gSW5jb21pbmcgb3duZXJzaGlwIHN0YXRlLlxuICogQHBhcmFtIHtMaWZldGltZUZhaWx9IGZhaWwgLSBMb2NhdGVkIGZhaWx1cmUuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSBsb2NhbHMgLSBMb2NhbHMgaW50cm9kdWNlZCBpbiB0aGUgY3VycmVudCBibG9jay5cbiAqIEBwYXJhbSB7e2Z1bmN0aW9uczogTWFwPHN0cmluZywgU2V0PHN0cmluZz4+LCBtZXRob2RzOiBNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj59fSBlcnJvckVmZmVjdHMgLSBDb21wbGV0ZSBlc2NhcGluZyBlcnJvciBzZXRzIHBlciBmdW5jdGlvbiBhbmQgbWV0aG9kLlxuICogQHJldHVybnMge0xpZmV0aW1lRXhpdFtdfSBSZWFjaGFibGUgZXhpdHMuXG4gKi9cbmZ1bmN0aW9uIGFuYWx5emVTdGF0ZW1lbnQoc3RhdGVtZW50LCBzdGF0ZSwgZmFpbCwgbG9jYWxzLCBlcnJvckVmZmVjdHMpIHtcbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiTG9jYWxEZWNsYXJhdGlvblwiKSB7XG4gICAgY29uc3QgZmxvd3MgPSBldmFsdWF0ZUV4cHJlc3Npb24oc3RhdGVtZW50LmluaXRpYWxpemVyLCBjbG9uZVN0YXRlKHN0YXRlKSwgZmFpbCwgZXJyb3JFZmZlY3RzKVxuXG4gICAgaWYgKGlzT3duZWQoc3RhdGVtZW50LnR5cGUpKSB7XG4gICAgICBsb2NhbHMuYWRkKHN0YXRlbWVudC5uYW1lKVxuICAgICAgZm9yIChjb25zdCBmbG93IG9mIGZsb3dzKSB7XG4gICAgICAgIGlmIChmbG93LmtpbmQgIT0gXCJub3JtYWxcIikgY29udGludWVcbiAgICAgICAgY29uc3Qgb3JpZ2luID0gc3RhdGVtZW50LmluaXRpYWxpemVyLmtpbmQgPT0gXCJPd25lZE1vdmVFeHByZXNzaW9uXCJcbiAgICAgICAgICA/IGZsb3cuc3RhdGUuZ2V0KHN0YXRlbWVudC5pbml0aWFsaXplci5leHByZXNzaW9uLm5hbWUpPy5vcmlnaW4gPz8gc3RhdGVtZW50LmluaXRpYWxpemVyLmxvY2F0aW9uXG4gICAgICAgICAgOiBzdGF0ZW1lbnQuaW5pdGlhbGl6ZXIubG9jYXRpb25cbiAgICAgICAgZmxvdy5zdGF0ZS5zZXQoc3RhdGVtZW50Lm5hbWUsIG9wZW5TdGF0ZShgbG9jYWw6JHtzdGF0ZW1lbnQubmFtZX1gLCBvcmlnaW4pKVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmxvd3MubWFwKChmbG93KSA9PiAoey4uLmZsb3csIGxvY2F0aW9uOiBzdGF0ZW1lbnQubG9jYXRpb259KSlcbiAgfVxuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJFeHByZXNzaW9uU3RhdGVtZW50XCIgfHwgc3RhdGVtZW50LmtpbmQgPT0gXCJQcmludFN0YXRlbWVudFwiKSB7XG4gICAgcmV0dXJuIGV2YWx1YXRlRXhwcmVzc2lvbihzdGF0ZW1lbnQuZXhwcmVzc2lvbiwgY2xvbmVTdGF0ZShzdGF0ZSksIGZhaWwsIGVycm9yRWZmZWN0cylcbiAgICAgIC5tYXAoKGZsb3cpID0+ICh7Li4uZmxvdywgbG9jYXRpb246IHN0YXRlbWVudC5sb2NhdGlvbn0pKVxuICB9XG4gIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIiB8fCBzdGF0ZW1lbnQua2luZCA9PSBcIlByaXZhdGVGaWVsZFdyaXRlU3RhdGVtZW50XCIpIHtcbiAgICByZXR1cm4gZXZhbHVhdGVFeHByZXNzaW9uKHN0YXRlbWVudC5leHByZXNzaW9uLCBjbG9uZVN0YXRlKHN0YXRlKSwgZmFpbCwgZXJyb3JFZmZlY3RzKVxuICAgICAgLm1hcCgoZmxvdykgPT4gKHsuLi5mbG93LCBsb2NhdGlvbjogc3RhdGVtZW50LmxvY2F0aW9ufSkpXG4gIH1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUmV0dXJuU3RhdGVtZW50XCIpIHtcbiAgICBjb25zdCBmbG93cyA9IHN0YXRlbWVudC5leHByZXNzaW9uID8gZXZhbHVhdGVFeHByZXNzaW9uKHN0YXRlbWVudC5leHByZXNzaW9uLCBjbG9uZVN0YXRlKHN0YXRlKSwgZmFpbCwgZXJyb3JFZmZlY3RzKSA6XG4gICAgICAvKiogQHR5cGUge0xpZmV0aW1lRXhpdFtdfSAqLyAoW3traW5kOiBcIm5vcm1hbFwiLCBzdGF0ZTogY2xvbmVTdGF0ZShzdGF0ZSl9XSlcbiAgICByZXR1cm4gZmxvd3MubWFwKChmbG93KSA9PiBmbG93LmtpbmQgPT0gXCJub3JtYWxcIlxuICAgICAgPyB7a2luZDogXCJyZXR1cm5cIiwgbG9jYXRpb246IHN0YXRlbWVudC5sb2NhdGlvbiwgc3RhdGU6IGZsb3cuc3RhdGV9XG4gICAgICA6IHsuLi5mbG93LCBsb2NhdGlvbjogc3RhdGVtZW50LmxvY2F0aW9ufSlcbiAgfVxuICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJSYWlzZVN0YXRlbWVudFwiKSB7XG4gICAgY29uc3QgZmxvd3MgPSBldmFsdWF0ZUV4cHJlc3Npb24oc3RhdGVtZW50LmVycm9yLm1lc3NhZ2UsIGNsb25lU3RhdGUoc3RhdGUpLCBmYWlsLCBlcnJvckVmZmVjdHMpXG4gICAgcmV0dXJuIGZsb3dzLm1hcCgoZmxvdykgPT4gZmxvdy5raW5kID09IFwibm9ybWFsXCJcbiAgICAgID8ge2Vycm9ySWQ6IHN0YXRlbWVudC5lcnJvci5lcnJvci5kZWNsYXJhdGlvbklkLCBraW5kOiBcInJhaXNlXCIsIGxvY2F0aW9uOiBzdGF0ZW1lbnQubG9jYXRpb24sIHN0YXRlOiBmbG93LnN0YXRlfVxuICAgICAgOiB7Li4uZmxvdywgbG9jYXRpb246IHN0YXRlbWVudC5sb2NhdGlvbn0pXG4gIH1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgIGNvbnN0IGNvbmRpdGlvbnMgPSBldmFsdWF0ZUV4cHJlc3Npb24oc3RhdGVtZW50LmNvbmRpdGlvbiwgY2xvbmVTdGF0ZShzdGF0ZSksIGZhaWwsIGVycm9yRWZmZWN0cylcbiAgICAvKiogQHR5cGUge0xpZmV0aW1lRXhpdFtdfSAqL1xuICAgIGNvbnN0IHJlc3VsdCA9IGNvbmRpdGlvbnMuZmlsdGVyKCh7a2luZH0pID0+IGtpbmQgIT0gXCJub3JtYWxcIilcblxuICAgIGZvciAoY29uc3QgY29uZGl0aW9uIG9mIGNvbmRpdGlvbnMuZmlsdGVyKCh7a2luZH0pID0+IGtpbmQgPT0gXCJub3JtYWxcIikpIHtcbiAgICAgIHJlc3VsdC5wdXNoKC4uLmFuYWx5emVCbG9jayhzdGF0ZW1lbnQuY29uc2VxdWVudCwgW3traW5kOiBcIm5vcm1hbFwiLCBzdGF0ZTogY2xvbmVTdGF0ZShjb25kaXRpb24uc3RhdGUpfV0sIGZhaWwsXG4gICAgICAgIGVycm9yRWZmZWN0cykpXG4gICAgICBjb25zdCBhbHRlcm5hdGUgPSBzdGF0ZW1lbnQuYWx0ZXJuYXRlXG4gICAgICAgID8gYW5hbHl6ZUJsb2NrKHN0YXRlbWVudC5hbHRlcm5hdGUsIFt7a2luZDogXCJub3JtYWxcIiwgc3RhdGU6IGNsb25lU3RhdGUoY29uZGl0aW9uLnN0YXRlKX1dLCBmYWlsLCBlcnJvckVmZmVjdHMpXG4gICAgICAgIDogLyoqIEB0eXBlIHtMaWZldGltZUV4aXRbXX0gKi8gKFt7a2luZDogXCJub3JtYWxcIiwgbG9jYXRpb246IHN0YXRlbWVudC5sb2NhdGlvbiwgc3RhdGU6IGNsb25lU3RhdGUoY29uZGl0aW9uLnN0YXRlKX1dKVxuXG4gICAgICByZXN1bHQucHVzaCguLi5hbHRlcm5hdGUpXG4gICAgfVxuICAgIHJldHVybiBtZXJnZUVxdWl2YWxlbnROb3JtYWxzKHJlc3VsdCwgc3RhdGVtZW50LmxvY2F0aW9uLCBmYWlsKVxuICB9XG4gIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlRyeVN0YXRlbWVudFwiKSB7XG4gICAgY29uc3QgYm9keUV4aXRzID0gYW5hbHl6ZUJsb2NrKHN0YXRlbWVudC5ib2R5LCBbe2tpbmQ6IFwibm9ybWFsXCIsIHN0YXRlOiBjbG9uZVN0YXRlKHN0YXRlKX1dLCBmYWlsLCBlcnJvckVmZmVjdHMpXG4gICAgLyoqIEB0eXBlIHtMaWZldGltZUV4aXRbXX0gKi9cbiAgICBjb25zdCByZXN1bHQgPSBib2R5RXhpdHMuZmlsdGVyKChmbG93KSA9PiBmbG93LmtpbmQgIT0gXCJyYWlzZVwiIHx8IGZsb3cuZXJyb3JJZCAhPSBzdGF0ZW1lbnQuY2F0Y2hUeXBlLmRlY2xhcmF0aW9uSWQpXG5cbiAgICBmb3IgKGNvbnN0IGNhdWdodCBvZiBib2R5RXhpdHMuZmlsdGVyKChmbG93KSA9PiBmbG93LmtpbmQgPT0gXCJyYWlzZVwiICYmIGZsb3cuZXJyb3JJZCA9PSBzdGF0ZW1lbnQuY2F0Y2hUeXBlLmRlY2xhcmF0aW9uSWQpKSB7XG4gICAgICByZXN1bHQucHVzaCguLi5hbmFseXplQmxvY2soc3RhdGVtZW50LmNhdGNoQm9keSwgW3traW5kOiBcIm5vcm1hbFwiLCBzdGF0ZTogY2xvbmVTdGF0ZShjYXVnaHQuc3RhdGUpfV0sIGZhaWwsIGVycm9yRWZmZWN0cykpXG4gICAgfVxuICAgIHJldHVybiBtZXJnZUVxdWl2YWxlbnROb3JtYWxzKHJlc3VsdCwgc3RhdGVtZW50LmxvY2F0aW9uLCBmYWlsKVxuICB9XG4gIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIldoaWxlU3RhdGVtZW50XCIpIHtcbiAgICBjb25zdCBjb25kaXRpb25zID0gZXZhbHVhdGVFeHByZXNzaW9uKHN0YXRlbWVudC5jb25kaXRpb24sIGNsb25lU3RhdGUoc3RhdGUpLCBmYWlsLCBlcnJvckVmZmVjdHMpXG4gICAgLyoqIEB0eXBlIHtMaWZldGltZUV4aXRbXX0gKi9cbiAgICBjb25zdCByZXN1bHQgPSBjb25kaXRpb25zLmZpbHRlcigoe2tpbmR9KSA9PiBraW5kICE9IFwibm9ybWFsXCIpXG5cbiAgICBmb3IgKGNvbnN0IGNvbmRpdGlvbiBvZiBjb25kaXRpb25zLmZpbHRlcigoe2tpbmR9KSA9PiBraW5kID09IFwibm9ybWFsXCIpKSB7XG4gICAgICBjb25zdCBib2R5RXhpdHMgPSBhbmFseXplQmxvY2soc3RhdGVtZW50LmJvZHksIFt7a2luZDogXCJub3JtYWxcIiwgc3RhdGU6IGNsb25lU3RhdGUoY29uZGl0aW9uLnN0YXRlKX1dLCBmYWlsLFxuICAgICAgICBlcnJvckVmZmVjdHMpXG4gICAgICBmb3IgKGNvbnN0IGV4aXQgb2YgYm9keUV4aXRzKSB7XG4gICAgICAgIGlmIChleGl0LmtpbmQgPT0gXCJub3JtYWxcIiB8fCBleGl0LmtpbmQgPT0gXCJjb250aW51ZVwiKSByZXF1aXJlU2FtZVN0YXRlKGNvbmRpdGlvbi5zdGF0ZSwgZXhpdC5zdGF0ZSwgc3RhdGVtZW50LmxvY2F0aW9uLCBmYWlsKVxuICAgICAgICBlbHNlIGlmIChleGl0LmtpbmQgPT0gXCJicmVha1wiKSB7XG4gICAgICAgICAgcmVxdWlyZVNhbWVTdGF0ZShjb25kaXRpb24uc3RhdGUsIGV4aXQuc3RhdGUsIHN0YXRlbWVudC5sb2NhdGlvbiwgZmFpbClcbiAgICAgICAgICByZXN1bHQucHVzaCh7a2luZDogXCJub3JtYWxcIiwgbG9jYXRpb246IHN0YXRlbWVudC5sb2NhdGlvbiwgc3RhdGU6IGV4aXQuc3RhdGV9KVxuICAgICAgICB9IGVsc2UgcmVzdWx0LnB1c2goZXhpdClcbiAgICAgIH1cbiAgICAgIHJlc3VsdC5wdXNoKHtraW5kOiBcIm5vcm1hbFwiLCBsb2NhdGlvbjogc3RhdGVtZW50LmxvY2F0aW9uLCBzdGF0ZTogY29uZGl0aW9uLnN0YXRlfSlcbiAgICB9XG4gICAgcmV0dXJuIG1lcmdlRXF1aXZhbGVudE5vcm1hbHMocmVzdWx0LCBzdGF0ZW1lbnQubG9jYXRpb24sIGZhaWwpXG4gIH1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaE1hcFN0YXRlbWVudFwiKSB7XG4gICAgY29uc3Qgb3BlcmFuZCA9IHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaFN0YXRlbWVudFwiID8gc3RhdGVtZW50Lmxpc3QgOiBzdGF0ZW1lbnQubWFwXG4gICAgY29uc3Qgb3BlcmFuZHMgPSBldmFsdWF0ZUV4cHJlc3Npb24ob3BlcmFuZCwgY2xvbmVTdGF0ZShzdGF0ZSksIGZhaWwsIGVycm9yRWZmZWN0cylcbiAgICAvKiogQHR5cGUge0xpZmV0aW1lRXhpdFtdfSAqL1xuICAgIGNvbnN0IHJlc3VsdCA9IG9wZXJhbmRzLmZpbHRlcigoe2tpbmR9KSA9PiBraW5kICE9IFwibm9ybWFsXCIpXG5cbiAgICBmb3IgKGNvbnN0IGV2YWx1YXRlZCBvZiBvcGVyYW5kcy5maWx0ZXIoKHtraW5kfSkgPT4ga2luZCA9PSBcIm5vcm1hbFwiKSkge1xuICAgICAgY29uc3QgYm9keUV4aXRzID0gYW5hbHl6ZUJsb2NrKHN0YXRlbWVudC5ib2R5LCBbe2tpbmQ6IFwibm9ybWFsXCIsIHN0YXRlOiBjbG9uZVN0YXRlKGV2YWx1YXRlZC5zdGF0ZSl9XSwgZmFpbCxcbiAgICAgICAgZXJyb3JFZmZlY3RzKVxuICAgICAgZm9yIChjb25zdCBleGl0IG9mIGJvZHlFeGl0cykge1xuICAgICAgICBpZiAoZXhpdC5raW5kID09IFwibm9ybWFsXCIgfHwgZXhpdC5raW5kID09IFwiY29udGludWVcIikgcmVxdWlyZVNhbWVTdGF0ZShldmFsdWF0ZWQuc3RhdGUsIGV4aXQuc3RhdGUsIHN0YXRlbWVudC5sb2NhdGlvbiwgZmFpbClcbiAgICAgICAgZWxzZSBpZiAoZXhpdC5raW5kID09IFwiYnJlYWtcIikge1xuICAgICAgICAgIHJlcXVpcmVTYW1lU3RhdGUoZXZhbHVhdGVkLnN0YXRlLCBleGl0LnN0YXRlLCBzdGF0ZW1lbnQubG9jYXRpb24sIGZhaWwpXG4gICAgICAgICAgcmVzdWx0LnB1c2goe2tpbmQ6IFwibm9ybWFsXCIsIGxvY2F0aW9uOiBzdGF0ZW1lbnQubG9jYXRpb24sIHN0YXRlOiBleGl0LnN0YXRlfSlcbiAgICAgICAgfSBlbHNlIHJlc3VsdC5wdXNoKGV4aXQpXG4gICAgICB9XG4gICAgICByZXN1bHQucHVzaCh7a2luZDogXCJub3JtYWxcIiwgbG9jYXRpb246IHN0YXRlbWVudC5sb2NhdGlvbiwgc3RhdGU6IGV2YWx1YXRlZC5zdGF0ZX0pXG4gICAgfVxuICAgIHJldHVybiBtZXJnZUVxdWl2YWxlbnROb3JtYWxzKHJlc3VsdCwgc3RhdGVtZW50LmxvY2F0aW9uLCBmYWlsKVxuICB9XG4gIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkJyZWFrU3RhdGVtZW50XCIpIHJldHVybiBbe2tpbmQ6IFwiYnJlYWtcIiwgbG9jYXRpb246IHN0YXRlbWVudC5sb2NhdGlvbiwgc3RhdGU6IGNsb25lU3RhdGUoc3RhdGUpfV1cbiAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiQ29udGludWVTdGF0ZW1lbnRcIikgcmV0dXJuIFt7a2luZDogXCJjb250aW51ZVwiLCBsb2NhdGlvbjogc3RhdGVtZW50LmxvY2F0aW9uLCBzdGF0ZTogY2xvbmVTdGF0ZShzdGF0ZSl9XVxuXG4gIHJldHVybiBbXVxufVxuXG4vKipcbiAqIEV2YWx1YXRlcyBvbmUgZXhwcmVzc2lvbiB3aXRoIGZhaWx1cmUgc3RhdGVzIGF0IGV4YWN0IGV2YWx1YXRpb24gYm91bmRhcmllcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBleHByZXNzaW9uIC0gRXhwcmVzc2lvbi5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgT3duZXJTdGF0ZT59IHN0YXRlIC0gSW5jb21pbmcgb3duZXJzaGlwIHN0YXRlLlxuICogQHBhcmFtIHtMaWZldGltZUZhaWx9IGZhaWwgLSBMb2NhdGVkIGZhaWx1cmUuXG4gKiBAcGFyYW0ge3tmdW5jdGlvbnM6IE1hcDxzdHJpbmcsIFNldDxzdHJpbmc+PiwgbWV0aG9kczogTWFwPHN0cmluZywgU2V0PHN0cmluZz4+fX0gZXJyb3JFZmZlY3RzIC0gQ29tcGxldGUgZXNjYXBpbmcgZXJyb3Igc2V0cyBwZXIgZnVuY3Rpb24gYW5kIG1ldGhvZC5cbiAqIEByZXR1cm5zIHtMaWZldGltZUV4aXRbXX0gUmVhY2hhYmxlIGV4aXRzLlxuICovXG5mdW5jdGlvbiBldmFsdWF0ZUV4cHJlc3Npb24oZXhwcmVzc2lvbiwgc3RhdGUsIGZhaWwsIGVycm9yRWZmZWN0cykge1xuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiT3duZWRNb3ZlRXhwcmVzc2lvblwiKSB7XG4gICAgY29uc3Qgb3duZXIgPSByZXF1aXJlT3duZXIoZXhwcmVzc2lvbi5leHByZXNzaW9uLm5hbWUsIHN0YXRlLCBleHByZXNzaW9uLmxvY2F0aW9uLCBmYWlsKVxuXG4gICAgaWYgKG93bmVyLmtpbmQgPT0gXCJtb3ZlZFwiKSBmYWlsKFwiVVNFX0FGVEVSX01PVkVcIiwgYFJlc291cmNlICcke2V4cHJlc3Npb24uZXhwcmVzc2lvbi5uYW1lfScgd2FzIGFscmVhZHkgbW92ZWQuYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICBpZiAob3duZXIua2luZCA9PSBcInRlcm1pbmFsXCIpIGZhaWwoXCJVU0VfQUZURVJfQ0xPU0VcIiwgYFJlc291cmNlICcke2V4cHJlc3Npb24uZXhwcmVzc2lvbi5uYW1lfScgaXMgdGVybWluYWwgYWZ0ZXIgY2xvc2UuYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICBzdGF0ZS5zZXQoZXhwcmVzc2lvbi5leHByZXNzaW9uLm5hbWUsIHsuLi5vd25lciwgZGVzdGluYXRpb246IFwidHJhbnNmZXJcIiwga2luZDogXCJtb3ZlZFwifSlcbiAgICByZXR1cm4gW3traW5kOiBcIm5vcm1hbFwiLCBzdGF0ZX1dXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk93bmVkQm9ycm93RXhwcmVzc2lvblwiKSB7XG4gICAgY29uc3QgbmFtZSA9IHBsYWNlTmFtZShleHByZXNzaW9uLmV4cHJlc3Npb24pXG4gICAgY29uc3Qgb3duZXIgPSByZXF1aXJlT3duZXIobmFtZSwgc3RhdGUsIGV4cHJlc3Npb24ubG9jYXRpb24sIGZhaWwpXG5cbiAgICBpZiAob3duZXIua2luZCA9PSBcIm1vdmVkXCIpIGZhaWwoXCJVU0VfQUZURVJfTU9WRVwiLCBgUmVzb3VyY2UgJyR7bmFtZX0nIHdhcyBtb3ZlZCBiZWZvcmUgdGhpcyBib3Jyb3cuYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICByZXR1cm4gW3traW5kOiBcIm5vcm1hbFwiLCBzdGF0ZX1dXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCIpIHJldHVybiBldmFsdWF0ZUVmZmVjdENhbGwoZXhwcmVzc2lvbiwgc3RhdGUsIGZhaWwsIGVycm9yRWZmZWN0cylcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkNhbGxFeHByZXNzaW9uXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiTWV0aG9kQ2FsbEV4cHJlc3Npb25cIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJSZWZlcmVuY2VDb25zdHJ1Y3Rpb25cIikge1xuICAgIHJldHVybiBldmFsdWF0ZU9yZGluYXJ5Q2FsbChleHByZXNzaW9uLCBzdGF0ZSwgZmFpbCwgZXJyb3JFZmZlY3RzKVxuICB9XG5cbiAgLyoqIEB0eXBlIHtMaWZldGltZUV4aXRbXX0gKi9cbiAgbGV0IGZsb3dzID0gW3traW5kOiBcIm5vcm1hbFwiLCBzdGF0ZX1dXG4gIGZvciAoY29uc3QgY2hpbGQgb2YgZXhwcmVzc2lvbkNoaWxkcmVuKGV4cHJlc3Npb24pKSBmbG93cyA9IGV2YWx1YXRlRm9yRmxvd3MoY2hpbGQsIGZsb3dzLCBmYWlsLCBlcnJvckVmZmVjdHMpXG4gIHJldHVybiBmbG93c1xufVxuXG4vKipcbiAqIEFwcGxpZXMgb25lIGNhcGFiaWxpdHkgb3BlcmF0aW9uJ3MgZGVjbGFyZWQgb3duZXJzaGlwIGFuZCBmYWlsdXJlIGZsb3cuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRWZmZWN0Q2FsbEV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBFZmZlY3QgY2FsbC5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgT3duZXJTdGF0ZT59IHN0YXRlIC0gSW5jb21pbmcgb3duZXJzaGlwIHN0YXRlLlxuICogQHBhcmFtIHtMaWZldGltZUZhaWx9IGZhaWwgLSBMb2NhdGVkIGZhaWx1cmUuXG4gKiBAcGFyYW0ge3tmdW5jdGlvbnM6IE1hcDxzdHJpbmcsIFNldDxzdHJpbmc+PiwgbWV0aG9kczogTWFwPHN0cmluZywgU2V0PHN0cmluZz4+fX0gZXJyb3JFZmZlY3RzIC0gQ29tcGxldGUgZXNjYXBpbmcgZXJyb3Igc2V0cyBwZXIgZnVuY3Rpb24gYW5kIG1ldGhvZC5cbiAqIEByZXR1cm5zIHtMaWZldGltZUV4aXRbXX0gUmVhY2hhYmxlIGV4aXRzLlxuICovXG5mdW5jdGlvbiBldmFsdWF0ZUVmZmVjdENhbGwoZXhwcmVzc2lvbiwgc3RhdGUsIGZhaWwsIGVycm9yRWZmZWN0cykge1xuICAvKiogQHR5cGUge0xpZmV0aW1lRXhpdFtdfSAqL1xuICBsZXQgZmxvd3MgPSBbe2tpbmQ6IFwibm9ybWFsXCIsIHN0YXRlfV1cblxuICBmb3IgKGNvbnN0IGFyZ3VtZW50IG9mIGV4cHJlc3Npb24uYXJndW1lbnRzKSBmbG93cyA9IGV2YWx1YXRlRm9yRmxvd3MoYXJndW1lbnQsIGZsb3dzLCBmYWlsLCBlcnJvckVmZmVjdHMpXG4gIGNvbnN0IHJlc3VsdCA9IGZsb3dzLmZpbHRlcigoe2tpbmR9KSA9PiBraW5kICE9IFwibm9ybWFsXCIpXG4gIGNvbnN0IHJlc291cmNlRmxvdyA9IGV4cHJlc3Npb24ucmVzb2x1dGlvbi5yZXNvdXJjZUZsb3dcblxuICBmb3IgKGNvbnN0IGZsb3cgb2YgZmxvd3MuZmlsdGVyKCh7a2luZH0pID0+IGtpbmQgPT0gXCJub3JtYWxcIikpIHtcbiAgICBsZXQgb3BlcmF0aW9uU3RhdGUgPSBjbG9uZVN0YXRlKGZsb3cuc3RhdGUpXG4gICAgbGV0IHRlcm1pbmFsRmFpbHVyZVxuXG4gICAgaWYgKHJlc291cmNlRmxvdy5raW5kID09IFwiYm9ycm93XCIgfHwgcmVzb3VyY2VGbG93LmtpbmQgPT0gXCJjbG9zZVwiKSB7XG4gICAgICBjb25zdCBhcmd1bWVudCA9IGV4cHJlc3Npb24uYXJndW1lbnRzW3Jlc291cmNlRmxvdy5wYXJhbWV0ZXJJbmRleF1cbiAgICAgIGlmIChhcmd1bWVudC5raW5kICE9IFwiT3duZWRCb3Jyb3dFeHByZXNzaW9uXCIpIGZhaWwoXCJJTlZBTElEX1JFU09VUkNFX0JPUlJPV1wiLCBcIlJlc291cmNlIG9wZXJhdGlvbiBsYWNrcyBhbiBpbW1lZGlhdGUgYm9ycm93LlwiLCBhcmd1bWVudC5sb2NhdGlvbilcbiAgICAgIGNvbnN0IG5hbWUgPSBwbGFjZU5hbWUoYXJndW1lbnQuZXhwcmVzc2lvbilcbiAgICAgIGNvbnN0IG93bmVyID0gcmVxdWlyZU93bmVyKG5hbWUsIG9wZXJhdGlvblN0YXRlLCBhcmd1bWVudC5sb2NhdGlvbiwgZmFpbClcblxuICAgICAgaWYgKG93bmVyLmtpbmQgPT0gXCJtb3ZlZFwiKSBmYWlsKFwiVVNFX0FGVEVSX01PVkVcIiwgYFJlc291cmNlICcke25hbWV9JyB3YXMgbW92ZWQgYmVmb3JlIHRoaXMgb3BlcmF0aW9uLmAsIGFyZ3VtZW50LmxvY2F0aW9uKVxuICAgICAgaWYgKG93bmVyLmtpbmQgPT0gXCJ0ZXJtaW5hbFwiKSB0ZXJtaW5hbEZhaWx1cmUgPSByZXNvdXJjZUZsb3cudGVybWluYWxGYWlsdXJlSWRcbiAgICAgIGVsc2UgaWYgKHJlc291cmNlRmxvdy5raW5kID09IFwiY2xvc2VcIikgb3BlcmF0aW9uU3RhdGUuc2V0KG5hbWUsIHsuLi5vd25lciwgY2xvc2VTaXRlSWQ6IGV4cHJlc3Npb24uZWZmZWN0U2l0ZUlkLCBraW5kOiBcInRlcm1pbmFsXCJ9KVxuICAgIH1cbiAgICBpZiAodGVybWluYWxGYWlsdXJlKSB7XG4gICAgICByZXN1bHQucHVzaCh7ZXJyb3JJZDogdGVybWluYWxGYWlsdXJlLCBraW5kOiBcInJhaXNlXCIsIGxvY2F0aW9uOiBleHByZXNzaW9uLmxvY2F0aW9uLCBzdGF0ZTogb3BlcmF0aW9uU3RhdGV9KVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgY29uc3QgZmFpbHVyZUlkcyA9IGV4cHJlc3Npb24ucmVzb2x1dGlvbi5mYWlsdXJlSWRzLmZpbHRlcigoaWQpID0+XG4gICAgICByZXNvdXJjZUZsb3cua2luZCAhPSBcImJvcnJvd1wiICYmIHJlc291cmNlRmxvdy5raW5kICE9IFwiY2xvc2VcIiB8fCBpZCAhPSByZXNvdXJjZUZsb3cudGVybWluYWxGYWlsdXJlSWQpXG5cbiAgICByZXN1bHQucHVzaCh7a2luZDogXCJub3JtYWxcIiwgc3RhdGU6IGNsb25lU3RhdGUob3BlcmF0aW9uU3RhdGUpfSlcbiAgICBmb3IgKGNvbnN0IGVycm9ySWQgb2YgZmFpbHVyZUlkcykge1xuICAgICAgcmVzdWx0LnB1c2goe2Vycm9ySWQsIGtpbmQ6IFwicmFpc2VcIiwgbG9jYXRpb246IGV4cHJlc3Npb24ubG9jYXRpb24sIHN0YXRlOiBjbG9uZVN0YXRlKG9wZXJhdGlvblN0YXRlKX0pXG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHRcbn1cblxuLyoqXG4gKiBBcHBsaWVzIGNhbGwtZW50cnkgb3duZXJzaGlwIGNvbW1pdCBzZW1hbnRpY3MgYWZ0ZXIgb3JkZXJlZCBhcmd1bWVudCBldmFsdWF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkNhbGxFeHByZXNzaW9uIHwgaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5NZXRob2RDYWxsRXhwcmVzc2lvbiB8IGltcG9ydChcIi4vdHlwZXMuanNcIikuUmVmZXJlbmNlQ29uc3RydWN0aW9ufSBleHByZXNzaW9uIC0gQ2FsbC5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgT3duZXJTdGF0ZT59IHN0YXRlIC0gSW5jb21pbmcgb3duZXJzaGlwIHN0YXRlLlxuICogQHBhcmFtIHtMaWZldGltZUZhaWx9IGZhaWwgLSBMb2NhdGVkIGZhaWx1cmUuXG4gKiBAcGFyYW0ge3tmdW5jdGlvbnM6IE1hcDxzdHJpbmcsIFNldDxzdHJpbmc+PiwgbWV0aG9kczogTWFwPHN0cmluZywgU2V0PHN0cmluZz4+fX0gZXJyb3JFZmZlY3RzIC0gQ29tcGxldGUgZXNjYXBpbmcgZXJyb3Igc2V0cyBwZXIgZnVuY3Rpb24gYW5kIG1ldGhvZC5cbiAqIEByZXR1cm5zIHtMaWZldGltZUV4aXRbXX0gUmVhY2hhYmxlIGV4aXRzLlxuICovXG5mdW5jdGlvbiBldmFsdWF0ZU9yZGluYXJ5Q2FsbChleHByZXNzaW9uLCBzdGF0ZSwgZmFpbCwgZXJyb3JFZmZlY3RzKSB7XG4gIGNvbnN0IGFyZ3VtZW50c18gPSBleHByZXNzaW9uLmtpbmQgPT0gXCJNZXRob2RDYWxsRXhwcmVzc2lvblwiID8gW2V4cHJlc3Npb24ucmVjZWl2ZXIsIC4uLmV4cHJlc3Npb24uYXJndW1lbnRzXSA6IGV4cHJlc3Npb24uYXJndW1lbnRzXG4gIC8qKiBAdHlwZSB7TGlmZXRpbWVFeGl0W119ICovXG4gIGxldCBmbG93cyA9IFt7a2luZDogXCJub3JtYWxcIiwgc3RhdGV9XVxuICAvKiogQHR5cGUge3N0cmluZ1tdfSAqL1xuICBjb25zdCByZXNlcnZlZE1vdmVzID0gW11cblxuICBmb3IgKGNvbnN0IGFyZ3VtZW50IG9mIGFyZ3VtZW50c18pIHtcbiAgICBpZiAoYXJndW1lbnQua2luZCA9PSBcIk93bmVkTW92ZUV4cHJlc3Npb25cIikge1xuICAgICAgZm9yIChjb25zdCBmbG93IG9mIGZsb3dzLmZpbHRlcigoe2tpbmR9KSA9PiBraW5kID09IFwibm9ybWFsXCIpKSB7XG4gICAgICAgIGNvbnN0IG93bmVyID0gcmVxdWlyZU93bmVyKGFyZ3VtZW50LmV4cHJlc3Npb24ubmFtZSwgZmxvdy5zdGF0ZSwgYXJndW1lbnQubG9jYXRpb24sIGZhaWwpXG4gICAgICAgIGlmIChvd25lci5raW5kID09IFwibW92ZWRcIikgZmFpbChcIlVTRV9BRlRFUl9NT1ZFXCIsIGBSZXNvdXJjZSAnJHthcmd1bWVudC5leHByZXNzaW9uLm5hbWV9JyB3YXMgYWxyZWFkeSBtb3ZlZC5gLCBhcmd1bWVudC5sb2NhdGlvbilcbiAgICAgICAgaWYgKG93bmVyLmtpbmQgPT0gXCJ0ZXJtaW5hbFwiKSBmYWlsKFwiVVNFX0FGVEVSX0NMT1NFXCIsIGBSZXNvdXJjZSAnJHthcmd1bWVudC5leHByZXNzaW9uLm5hbWV9JyBpcyB0ZXJtaW5hbCBhZnRlciBjbG9zZS5gLCBhcmd1bWVudC5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGlmIChyZXNlcnZlZE1vdmVzLmluY2x1ZGVzKGFyZ3VtZW50LmV4cHJlc3Npb24ubmFtZSkpIHtcbiAgICAgICAgZmFpbChcIlJFU09VUkNFX0FMSUFTXCIsIGBSZXNvdXJjZSAnJHthcmd1bWVudC5leHByZXNzaW9uLm5hbWV9JyBjYW5ub3QgYmUgdHJhbnNmZXJyZWQgdG8gdHdvIHBhcmFtZXRlcnMuYCwgYXJndW1lbnQubG9jYXRpb24pXG4gICAgICB9XG4gICAgICByZXNlcnZlZE1vdmVzLnB1c2goYXJndW1lbnQuZXhwcmVzc2lvbi5uYW1lKVxuICAgIH0gZWxzZSBmbG93cyA9IGV2YWx1YXRlRm9yRmxvd3MoYXJndW1lbnQsIGZsb3dzLCBmYWlsLCBlcnJvckVmZmVjdHMpXG4gIH1cbiAgY29uc3QgcmVzdWx0ID0gZmxvd3MuZmlsdGVyKCh7a2luZH0pID0+IGtpbmQgIT0gXCJub3JtYWxcIilcblxuICBmb3IgKGNvbnN0IGZsb3cgb2YgZmxvd3MuZmlsdGVyKCh7a2luZH0pID0+IGtpbmQgPT0gXCJub3JtYWxcIikpIHtcbiAgICBjb25zdCBlbnRlcmVkID0gY2xvbmVTdGF0ZShmbG93LnN0YXRlKVxuICAgIGZvciAoY29uc3QgbmFtZSBvZiByZXNlcnZlZE1vdmVzKSB7XG4gICAgICBjb25zdCBvd25lciA9IHJlcXVpcmVPd25lcihuYW1lLCBlbnRlcmVkLCBleHByZXNzaW9uLmxvY2F0aW9uLCBmYWlsKVxuICAgICAgaWYgKG93bmVyLmtpbmQgPT0gXCJtb3ZlZFwiKSBmYWlsKFwiVVNFX0FGVEVSX01PVkVcIiwgYFJlc291cmNlICcke25hbWV9JyB3YXMgYWxyZWFkeSBtb3ZlZC5gLCBleHByZXNzaW9uLmxvY2F0aW9uKVxuICAgICAgaWYgKG93bmVyLmtpbmQgPT0gXCJ0ZXJtaW5hbFwiKSBmYWlsKFwiVVNFX0FGVEVSX0NMT1NFXCIsIGBSZXNvdXJjZSAnJHtuYW1lfScgaXMgdGVybWluYWwgYWZ0ZXIgY2xvc2UuYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICAgIGVudGVyZWQuc2V0KG5hbWUsIHsuLi5vd25lciwgZGVzdGluYXRpb246IFwiY2FsbGVlXCIsIGtpbmQ6IFwibW92ZWRcIn0pXG4gICAgfVxuICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJNZXRob2RDYWxsRXhwcmVzc2lvblwiICYmIGV4cHJlc3Npb24ucmVzb2x1dGlvbj8ucmVzb3VyY2VGbG93KSB7XG4gICAgICBjb25zdCByZWNlaXZlciA9IGV4cHJlc3Npb24ucmVjZWl2ZXIua2luZCA9PSBcIk93bmVkQm9ycm93RXhwcmVzc2lvblwiID8gZXhwcmVzc2lvbi5yZWNlaXZlci5leHByZXNzaW9uIDogZXhwcmVzc2lvbi5yZWNlaXZlclxuICAgICAgaWYgKHJlY2VpdmVyLmtpbmQgIT0gXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiICYmIHJlY2VpdmVyLmtpbmQgIT0gXCJSZWNlaXZlckV4cHJlc3Npb25cIiAmJiByZWNlaXZlci5raW5kICE9IFwiUHJpdmF0ZUZpZWxkUmVhZFwiKSB7XG4gICAgICAgIGZhaWwoXCJJTlZBTElEX1JFU09VUkNFX0JPUlJPV1wiLCBcIk93bmVkIG1ldGhvZCByZWNlaXZlciBtdXN0IGJlIGFuIGltbWVkaWF0ZSBib3Jyb3dlZCBwbGFjZS5cIiwgcmVjZWl2ZXIubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBjb25zdCBuYW1lID0gcGxhY2VOYW1lKHJlY2VpdmVyKVxuICAgICAgY29uc3Qgb3duZXIgPSByZXF1aXJlT3duZXIobmFtZSwgZW50ZXJlZCwgZXhwcmVzc2lvbi5sb2NhdGlvbiwgZmFpbClcblxuICAgICAgaWYgKG93bmVyLmtpbmQgPT0gXCJ0ZXJtaW5hbFwiKSB7XG4gICAgICAgIGlmIChleHByZXNzaW9uLnJlc29sdXRpb24ucmVzb3VyY2VGbG93LnRlcm1pbmFsRmFpbHVyZUlkKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2goe2Vycm9ySWQ6IGV4cHJlc3Npb24ucmVzb2x1dGlvbi5yZXNvdXJjZUZsb3cudGVybWluYWxGYWlsdXJlSWQsIGtpbmQ6IFwicmFpc2VcIixcbiAgICAgICAgICAgIGxvY2F0aW9uOiBleHByZXNzaW9uLmxvY2F0aW9uLCBzdGF0ZTogZW50ZXJlZH0pXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgICBmYWlsKFwiVVNFX0FGVEVSX0NMT1NFXCIsIGBSZXNvdXJjZSAnJHtuYW1lfScgaXMgdGVybWluYWwgYWZ0ZXIgY2xvc2UuYCwgZXhwcmVzc2lvbi5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGlmIChleHByZXNzaW9uLnJlc29sdXRpb24ucmVzb3VyY2VGbG93LmtpbmQgPT0gXCJ0ZXJtaW5hbFwiKSB7XG4gICAgICAgIGVudGVyZWQuc2V0KG5hbWUsIHsuLi5vd25lciwgY2xvc2VTaXRlSWQ6IGV4cHJlc3Npb24uZWZmZWN0U2l0ZUlkID8/IGV4cHJlc3Npb24ubG9jYXRpb24sIGtpbmQ6IFwidGVybWluYWxcIn0pXG4gICAgICB9XG4gICAgfVxuICAgIHJlc3VsdC5wdXNoKHtraW5kOiBcIm5vcm1hbFwiLCBzdGF0ZTogY2xvbmVTdGF0ZShlbnRlcmVkKX0pXG4gICAgY29uc3QgZXNjYXBpbmcgPSBuZXcgU2V0KGV4cHJlc3Npb24uZmFpbHVyZUlkcyA/PyBbXSlcblxuICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJDYWxsRXhwcmVzc2lvblwiKSB7XG4gICAgICBmb3IgKGNvbnN0IGVycm9ySWQgb2YgZXJyb3JFZmZlY3RzLmZ1bmN0aW9ucy5nZXQoZXhwcmVzc2lvbi5jYWxsZWUpID8/IFtdKSBlc2NhcGluZy5hZGQoZXJyb3JJZClcbiAgICB9IGVsc2UgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1ldGhvZENhbGxFeHByZXNzaW9uXCIpIHtcbiAgICAgIGZvciAoY29uc3QgZXJyb3JJZCBvZiBlcnJvckVmZmVjdHMubWV0aG9kcy5nZXQoZXhwcmVzc2lvbi5tZXRob2QpID8/IFtdKSBlc2NhcGluZy5hZGQoZXJyb3JJZClcbiAgICB9XG4gICAgZm9yIChjb25zdCBlcnJvcklkIG9mIGVzY2FwaW5nKSB7XG4gICAgICByZXN1bHQucHVzaCh7ZXJyb3JJZCwga2luZDogXCJyYWlzZVwiLCBsb2NhdGlvbjogZXhwcmVzc2lvbi5sb2NhdGlvbiwgc3RhdGU6IGNsb25lU3RhdGUoZW50ZXJlZCl9KVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0XG59XG5cbi8qKlxuICogRXZhbHVhdGVzIGEgY2hpbGQgZXhwcmVzc2lvbiBvbmx5IGFsb25nIG5vcm1hbCBpbmNvbWluZyBwYXRocy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBleHByZXNzaW9uIC0gQ2hpbGQgZXhwcmVzc2lvbi5cbiAqIEBwYXJhbSB7TGlmZXRpbWVFeGl0W119IGZsb3dzIC0gSW5jb21pbmcgcGF0aHMuXG4gKiBAcGFyYW0ge0xpZmV0aW1lRmFpbH0gZmFpbCAtIExvY2F0ZWQgZmFpbHVyZS5cbiAqIEBwYXJhbSB7e2Z1bmN0aW9uczogTWFwPHN0cmluZywgU2V0PHN0cmluZz4+LCBtZXRob2RzOiBNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj59fSBlcnJvckVmZmVjdHMgLSBDb21wbGV0ZSBlc2NhcGluZyBlcnJvciBzZXRzIHBlciBmdW5jdGlvbiBhbmQgbWV0aG9kLlxuICogQHJldHVybnMge0xpZmV0aW1lRXhpdFtdfSBSZWFjaGFibGUgZXhpdHMuXG4gKi9cbmZ1bmN0aW9uIGV2YWx1YXRlRm9yRmxvd3MoZXhwcmVzc2lvbiwgZmxvd3MsIGZhaWwsIGVycm9yRWZmZWN0cykge1xuICBjb25zdCByZXN1bHQgPSBmbG93cy5maWx0ZXIoKHtraW5kfSkgPT4ga2luZCAhPSBcIm5vcm1hbFwiKVxuICBmb3IgKGNvbnN0IGZsb3cgb2YgZmxvd3MuZmlsdGVyKCh7a2luZH0pID0+IGtpbmQgPT0gXCJub3JtYWxcIikpIHtcbiAgICByZXN1bHQucHVzaCguLi5ldmFsdWF0ZUV4cHJlc3Npb24oZXhwcmVzc2lvbiwgY2xvbmVTdGF0ZShmbG93LnN0YXRlKSwgZmFpbCwgZXJyb3JFZmZlY3RzKSlcbiAgfVxuICByZXR1cm4gcmVzdWx0XG59XG5cbi8qKlxuICogUmV0dXJucyBub24tY2FsbCBleHByZXNzaW9uIGNoaWxkcmVuIGluIGV2YWx1YXRpb24gb3JkZXIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gZXhwcmVzc2lvbiAtIFBhcmVudCBleHByZXNzaW9uLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRXhwcmVzc2lvbltdfSBDaGlsZHJlbi5cbiAqL1xuZnVuY3Rpb24gZXhwcmVzc2lvbkNoaWxkcmVuKGV4cHJlc3Npb24pIHtcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkJpbmFyeUV4cHJlc3Npb25cIikgcmV0dXJuIFtleHByZXNzaW9uLmxlZnQsIGV4cHJlc3Npb24ucmlnaHRdXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJVbmFyeUV4cHJlc3Npb25cIikgcmV0dXJuIFtleHByZXNzaW9uLm9wZXJhbmRdXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJPcHRpb25hbFNvbWVcIikgcmV0dXJuIFtleHByZXNzaW9uLnZhbHVlXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiT3B0aW9uYWxJc1ByZXNlbnRcIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJPcHRpb25hbFVud3JhcFwiKSByZXR1cm4gW2V4cHJlc3Npb24ub3BlcmFuZF1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkxpc3RMaXRlcmFsXCIpIHJldHVybiBleHByZXNzaW9uLmVsZW1lbnRzXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJNYXBMaXRlcmFsXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiT3JkZXJlZE1hcExpdGVyYWxcIikgcmV0dXJuIGV4cHJlc3Npb24uZW50cmllcy5tYXAoKHt2YWx1ZX0pID0+IHZhbHVlKVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTGlzdEluZGV4RXhwcmVzc2lvblwiKSByZXR1cm4gW2V4cHJlc3Npb24uY29sbGVjdGlvbiwgZXhwcmVzc2lvbi5pbmRleF1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1hcExvb2t1cEV4cHJlc3Npb25cIikgcmV0dXJuIFtleHByZXNzaW9uLmNvbGxlY3Rpb24sIGV4cHJlc3Npb24ua2V5XVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ29sbGVjdGlvblNpemVFeHByZXNzaW9uXCIpIHJldHVybiBbZXhwcmVzc2lvbi5jb2xsZWN0aW9uXVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiUmVjb3JkQ29uc3RydWN0aW9uXCIpIHJldHVybiBleHByZXNzaW9uLmFyZ3VtZW50c1xuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWVtYmVyUmVhZFwiKSByZXR1cm4gW2V4cHJlc3Npb24ucmVjZWl2ZXJdXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJQcml2YXRlRmllbGRSZWFkXCIpIHJldHVybiBbZXhwcmVzc2lvbi5yZWNlaXZlcl1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkVycm9yTWVzc2FnZVJlYWRcIikgcmV0dXJuIFtleHByZXNzaW9uLnJlY2VpdmVyXVxuICByZXR1cm4gW11cbn1cblxuLyoqXG4gKiBNZXJnZXMgbm9ybWFsIHBhdGhzIG9ubHkgYWZ0ZXIgcHJvdmluZyBpZGVudGljYWwgb3duZXJzaGlwIHN0YXRlcy5cbiAqIEBwYXJhbSB7TGlmZXRpbWVFeGl0W119IGZsb3dzIC0gQ2FuZGlkYXRlIHBhdGhzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBsb2NhdGlvbiAtIEpvaW4gbG9jYXRpb24uXG4gKiBAcGFyYW0ge0xpZmV0aW1lRmFpbH0gZmFpbCAtIExvY2F0ZWQgZmFpbHVyZS5cbiAqIEByZXR1cm5zIHtMaWZldGltZUV4aXRbXX0gTWVyZ2VkIHBhdGhzLlxuICovXG5mdW5jdGlvbiBtZXJnZUVxdWl2YWxlbnROb3JtYWxzKGZsb3dzLCBsb2NhdGlvbiwgZmFpbCkge1xuICBjb25zdCBub3JtYWwgPSBmbG93cy5maWx0ZXIoKHtraW5kfSkgPT4ga2luZCA9PSBcIm5vcm1hbFwiKVxuICBpZiAobm9ybWFsLmxlbmd0aCA+IDEpIHtcbiAgICBmb3IgKGNvbnN0IGNhbmRpZGF0ZSBvZiBub3JtYWwuc2xpY2UoMSkpIHJlcXVpcmVTYW1lU3RhdGUobm9ybWFsWzBdLnN0YXRlLCBjYW5kaWRhdGUuc3RhdGUsIGxvY2F0aW9uLCBmYWlsKVxuICB9XG4gIHJldHVybiBbLi4uZmxvd3MuZmlsdGVyKCh7a2luZH0pID0+IGtpbmQgIT0gXCJub3JtYWxcIiksIC4uLihub3JtYWwubGVuZ3RoID4gMCA/IFtub3JtYWxbMF1dIDogW10pXVxufVxuXG4vKipcbiAqIFJlcXVpcmVzIGEgZmluaXRlIG93bmVyc2hpcCBpbnZhcmlhbnQgYXQgYSBicmFuY2ggb3IgbG9vcCBqb2luLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBPd25lclN0YXRlPn0gbGVmdCAtIEZpcnN0IG93bmVyc2hpcCBzdGF0ZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgT3duZXJTdGF0ZT59IHJpZ2h0IC0gU2Vjb25kIG93bmVyc2hpcCBzdGF0ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gbG9jYXRpb24gLSBKb2luIGxvY2F0aW9uLlxuICogQHBhcmFtIHtMaWZldGltZUZhaWx9IGZhaWwgLSBMb2NhdGVkIGZhaWx1cmUuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gcmVxdWlyZVNhbWVTdGF0ZShsZWZ0LCByaWdodCwgbG9jYXRpb24sIGZhaWwpIHtcbiAgY29uc3QgbmFtZXMgPSBuZXcgU2V0KFsuLi5sZWZ0LmtleXMoKSwgLi4ucmlnaHQua2V5cygpXSlcbiAgZm9yIChjb25zdCBuYW1lIG9mIG5hbWVzKSB7XG4gICAgY29uc3QgbGVmdFN0YXRlID0gbGVmdC5nZXQobmFtZSlcbiAgICBjb25zdCByaWdodFN0YXRlID0gcmlnaHQuZ2V0KG5hbWUpXG4gICAgaWYgKGxlZnRTdGF0ZT8ua2luZCAhPSByaWdodFN0YXRlPy5raW5kIHx8IGxlZnRTdGF0ZT8ub3JpZ2luSWQgIT0gcmlnaHRTdGF0ZT8ub3JpZ2luSWQpIHtcbiAgICAgIGZhaWwoXCJSRVNPVVJDRV9TVEFURV9NSVNNQVRDSFwiLCBgUmVzb3VyY2UgJyR7bmFtZX0nIGhhcyBkaWZmZXJlbnQgb3duZXJzaGlwIHN0YXRlIGFjcm9zcyByZWFjaGFibGUgcGF0aHMuYCwgbG9jYXRpb24pXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUmVqZWN0cyBldmVyeSBvd25lZCB2YWx1ZSB0aGF0IGxlYXZlcyBpdHMgaW50cm9kdWNpbmcgc2NvcGUgb3Blbi5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgT3duZXJTdGF0ZT59IHN0YXRlIC0gT3duZXJzaGlwIHN0YXRlLlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gbmFtZXMgLSBPd25lcnMgaW50cm9kdWNlZCBpbiB0aGUgc2NvcGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gRXhpdCBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7TGlmZXRpbWVGYWlsfSBmYWlsIC0gTG9jYXRlZCBmYWlsdXJlLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIGNoZWNrTGVha3Moc3RhdGUsIG5hbWVzLCBsb2NhdGlvbiwgZmFpbCkge1xuICBmb3IgKGNvbnN0IG5hbWUgb2YgbmFtZXMpIHtcbiAgICBjb25zdCBvd25lciA9IHN0YXRlLmdldChuYW1lKVxuICAgIGlmIChvd25lcj8ua2luZCA9PSBcIm9wZW5cIikge1xuICAgICAgY29uc3Qgb3JpZ2luID0gb3duZXIub3JpZ2luXG4gICAgICBmYWlsKFwiTEVBS0VEX1JFU09VUkNFXCIsIGBPd25lZCByZXNvdXJjZSAnJHtuYW1lfScgcmVtYWlucyBvcGVuOyBhY3F1aXJlZCBhdCAke29yaWdpbi5maWxlbmFtZX06JHtvcmlnaW4uc3RhcnQubGluZX06JHtvcmlnaW4uc3RhcnQuY29sdW1ufS5gLCBsb2NhdGlvbilcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBhbiBvd25lZCBwbGFjZSBpbiB0aGUgY3VycmVudCBzY29wZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gU3RhYmxlIHBsYWNlIG5hbWUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIE93bmVyU3RhdGU+fSBzdGF0ZSAtIE93bmVyc2hpcCBzdGF0ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gbG9jYXRpb24gLSBVc2UgbG9jYXRpb24uXG4gKiBAcGFyYW0ge0xpZmV0aW1lRmFpbH0gZmFpbCAtIExvY2F0ZWQgZmFpbHVyZS5cbiAqIEByZXR1cm5zIHtPd25lclN0YXRlfSBPd25lciBzdGF0ZS5cbiAqL1xuZnVuY3Rpb24gcmVxdWlyZU93bmVyKG5hbWUsIHN0YXRlLCBsb2NhdGlvbiwgZmFpbCkge1xuICBjb25zdCBvd25lciA9IHN0YXRlLmdldChuYW1lKVxuICBpZiAoIW93bmVyKSByZXR1cm4gZmFpbChcIklOVkFMSURfUkVTT1VSQ0VfQk9SUk9XXCIsIGBObyBvd25lZCByZXNvdXJjZSBwbGFjZSAnJHtuYW1lfScgaXMgaW4gc2NvcGUuYCwgbG9jYXRpb24pXG4gIHJldHVybiBvd25lclxufVxuXG4vKipcbiAqIENvbnZlcnRzIGFuIGltbWVkaWF0ZSBvd25lZCBleHByZXNzaW9uIHRvIGEgc3RhYmxlIHBsYWNlIG5hbWUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuSWRlbnRpZmllckV4cHJlc3Npb24gfCBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlJlY2VpdmVyRXhwcmVzc2lvbiB8IGltcG9ydChcIi4vdHlwZXMuanNcIikuUHJpdmF0ZUZpZWxkUmVhZH0gZXhwcmVzc2lvbiAtIE93bmVkIHBsYWNlLlxuICogQHJldHVybnMge3N0cmluZ30gUGxhY2UgaWRlbnRpdHkuXG4gKi9cbmZ1bmN0aW9uIHBsYWNlTmFtZShleHByZXNzaW9uKSB7XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSByZXR1cm4gZXhwcmVzc2lvbi5uYW1lXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJSZWNlaXZlckV4cHJlc3Npb25cIikgcmV0dXJuIFwidGhpc1wiXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJQcml2YXRlRmllbGRSZWFkXCIpIHJldHVybiBgdGhpcy4ke2V4cHJlc3Npb24uZmllbGR9YFxuICByZXR1cm4gXCI8aW52YWxpZD5cIlxufVxuXG4vKipcbiAqIENyZWF0ZXMgb25lIG9wZW4gb3duZXJzaGlwIHN0YXRlLlxuICogQHBhcmFtIHtzdHJpbmd9IG9yaWdpbklkIC0gRGV0ZXJtaW5pc3RpYyBvcmlnaW4gaWRlbnRpdHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IG9yaWdpbiAtIEFjcXVpc2l0aW9uIGxvY2F0aW9uLlxuICogQHJldHVybnMge093bmVyU3RhdGV9IE9wZW4gc3RhdGUuXG4gKi9cbmZ1bmN0aW9uIG9wZW5TdGF0ZShvcmlnaW5JZCwgb3JpZ2luKSB7XG4gIHJldHVybiB7a2luZDogXCJvcGVuXCIsIG9yaWdpbiwgb3JpZ2luSWR9XG59XG5cbi8qKlxuICogQ2xvbmVzIGFuIG93bmVyc2hpcCBzdGF0ZSBmb3IgYSBjb250cm9sLWZsb3cgZm9yay5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgT3duZXJTdGF0ZT59IHN0YXRlIC0gU3RhdGUgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7TWFwPHN0cmluZywgT3duZXJTdGF0ZT59IERldGFjaGVkIHN0YXRlLlxuICovXG5mdW5jdGlvbiBjbG9uZVN0YXRlKHN0YXRlKSB7XG4gIHJldHVybiBuZXcgTWFwKFsuLi5zdGF0ZV0ubWFwKChbbmFtZSwgdmFsdWVdKSA9PiBbbmFtZSwgey4uLnZhbHVlfV0pKVxufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgdHlwZSBjYXJyaWVzIGxpbmVhciBvd25lcnNoaXAuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9IHR5cGUgLSBTZW1hbnRpYyB0eXBlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHR5cGUgaXMgb3duZWQuXG4gKi9cbmZ1bmN0aW9uIGlzT3duZWQodHlwZSkge1xuICByZXR1cm4gdHlwZS5raW5kID09IFwiT3duZWRSZXNvdXJjZVR5cGVcIiB8fCB0eXBlLmtpbmQgPT0gXCJPd25lZFJlZmVyZW5jZVR5cGVcIlxufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBtb2R1bGUgY29udGFpbnMgYW55IG93bmVkIHNlbWFudGljIHR5cGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFNlbWFudGljIG1vZHVsZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIGxpZmV0aW1lIGFuYWx5c2lzIGlzIHJlcXVpcmVkLlxuICovXG5mdW5jdGlvbiBtb2R1bGVDb250YWluc093bmVkVHlwZShtb2R1bGUpIHtcbiAgY29uc3QgcGVuZGluZyA9IFsvKiogQHR5cGUge3Vua25vd259ICovIChtb2R1bGUpXVxuICBjb25zdCBzZWVuID0gbmV3IFNldCgpXG5cbiAgd2hpbGUgKHBlbmRpbmcubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IHZhbHVlID0gcGVuZGluZy5wb3AoKVxuXG4gICAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT0gXCJvYmplY3RcIiB8fCBzZWVuLmhhcyh2YWx1ZSkpIGNvbnRpbnVlXG4gICAgc2Vlbi5hZGQodmFsdWUpXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSAmJiAoUmVmbGVjdC5nZXQodmFsdWUsIFwia2luZFwiKSA9PSBcIk93bmVkUmVzb3VyY2VUeXBlXCIgfHxcbiAgICAgIFJlZmxlY3QuZ2V0KHZhbHVlLCBcImtpbmRcIikgPT0gXCJPd25lZFJlZmVyZW5jZVR5cGVcIikpIHJldHVybiB0cnVlXG4gICAgZm9yIChjb25zdCBba2V5LCBjaGlsZF0gb2YgT2JqZWN0LmVudHJpZXModmFsdWUpKSB7XG4gICAgICBpZiAoW1wibG9jYXRpb25cIiwgXCJwcm92ZW5hbmNlXCIsIFwic291cmNlUHJvdmVuYW5jZVwiXS5pbmNsdWRlcyhrZXkpKSBjb250aW51ZVxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY2hpbGQpKSBwZW5kaW5nLnB1c2goLi4uY2hpbGQpXG4gICAgICBlbHNlIGlmIChjaGlsZCAmJiB0eXBlb2YgY2hpbGQgPT0gXCJvYmplY3RcIikgcGVuZGluZy5wdXNoKGNoaWxkKVxuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2Vcbn1cbiJdfQ==