breeze-client 2.1.2 → 2.1.3-mjs

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 (397) hide show
  1. package/LICENSE +1 -1
  2. package/adapter-ajax-angularjs/{breeze-client-adapter-ajax-angularjs.d.ts → index.d.ts} +1 -0
  3. package/adapter-ajax-fetch/{breeze-client-adapter-ajax-fetch.d.ts → index.d.ts} +1 -0
  4. package/adapter-ajax-httpclient/{breeze-client-adapter-ajax-httpclient.d.ts → index.d.ts} +1 -0
  5. package/adapter-ajax-jquery/{breeze-client-adapter-ajax-jquery.d.ts → index.d.ts} +1 -0
  6. package/adapter-ajax-post/{breeze-client-adapter-ajax-post.d.ts → index.d.ts} +1 -0
  7. package/adapter-data-service-odata/{breeze-client-adapter-data-service-odata.d.ts → index.d.ts} +1 -0
  8. package/adapter-data-service-webapi/{breeze-client-adapter-data-service-webapi.d.ts → index.d.ts} +1 -0
  9. package/adapter-model-library-backing-store/{breeze-client-adapter-model-library-backing-store.d.ts → index.d.ts} +1 -0
  10. package/adapter-model-library-ko/{breeze-client-adapter-model-library-ko.d.ts → index.d.ts} +1 -0
  11. package/adapter-uri-builder-json/{breeze-client-adapter-uri-builder-json.d.ts → index.d.ts} +1 -0
  12. package/adapter-uri-builder-odata/{breeze-client-adapter-uri-builder-odata.d.ts → index.d.ts} +1 -0
  13. package/esm2020/adapter-ajax-angularjs/adapter-ajax-angularjs.mjs +130 -0
  14. package/esm2020/adapter-ajax-angularjs/adapter-core.mjs +49 -0
  15. package/esm2020/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.mjs +5 -0
  16. package/esm2020/adapter-ajax-fetch/adapter-ajax-fetch.mjs +132 -0
  17. package/esm2020/adapter-ajax-fetch/adapter-core.mjs +49 -0
  18. package/esm2020/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.mjs +5 -0
  19. package/esm2020/adapter-ajax-httpclient/adapter-ajax-httpclient.mjs +137 -0
  20. package/esm2020/adapter-ajax-httpclient/adapter-core.mjs +49 -0
  21. package/esm2020/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.mjs +5 -0
  22. package/esm2020/adapter-ajax-jquery/adapter-ajax-jquery.mjs +103 -0
  23. package/esm2020/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.mjs +5 -0
  24. package/esm2020/adapter-ajax-post/adapter-ajax-post.mjs +77 -0
  25. package/esm2020/adapter-ajax-post/breeze-client-adapter-ajax-post.mjs +5 -0
  26. package/esm2020/adapter-data-service-odata/adapter-core.mjs +49 -0
  27. package/esm2020/adapter-data-service-odata/adapter-data-service-odata.mjs +456 -0
  28. package/esm2020/adapter-data-service-odata/breeze-client-adapter-data-service-odata.mjs +5 -0
  29. package/esm2020/adapter-data-service-webapi/adapter-data-service-webapi.mjs +93 -0
  30. package/esm2020/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.mjs +5 -0
  31. package/esm2020/adapter-model-library-backing-store/adapter-model-library-backing-store.mjs +268 -0
  32. package/esm2020/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.mjs +5 -0
  33. package/esm2020/adapter-model-library-ko/adapter-model-library-ko.mjs +240 -0
  34. package/esm2020/adapter-model-library-ko/breeze-client-adapter-model-library-ko.mjs +5 -0
  35. package/esm2020/adapter-uri-builder-json/adapter-core.mjs +49 -0
  36. package/esm2020/adapter-uri-builder-json/adapter-uri-builder-json.mjs +36 -0
  37. package/esm2020/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.mjs +5 -0
  38. package/esm2020/adapter-uri-builder-odata/adapter-core.mjs +49 -0
  39. package/esm2020/adapter-uri-builder-odata/adapter-uri-builder-odata.mjs +190 -0
  40. package/esm2020/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.mjs +5 -0
  41. package/esm2020/breeze-client.mjs +5 -0
  42. package/esm2020/index.mjs +2 -0
  43. package/esm2020/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.mjs +5 -0
  44. package/esm2020/mixin-get-entity-graph/mixin-get-entity-graph.mjs +269 -0
  45. package/esm2020/mixin-save-queuing/breeze-client-mixin-save-queuing.mjs +5 -0
  46. package/esm2020/mixin-save-queuing/mixin-save-queuing.mjs +400 -0
  47. package/esm2020/src/abstract-data-service-adapter.mjs +296 -0
  48. package/esm2020/src/array.mjs +4 -0
  49. package/esm2020/src/assert-param.mjs +312 -0
  50. package/esm2020/src/breeze.mjs +85 -0
  51. package/esm2020/src/complex-array.mjs +117 -0
  52. package/esm2020/src/config.mjs +223 -0
  53. package/esm2020/src/core.mjs +707 -0
  54. package/esm2020/src/csdl-metadata-parser.mjs +385 -0
  55. package/esm2020/src/data-service.mjs +203 -0
  56. package/esm2020/src/data-type.mjs +444 -0
  57. package/esm2020/src/default-property-interceptor.mjs +460 -0
  58. package/esm2020/src/entity-action.mjs +45 -0
  59. package/esm2020/src/entity-aspect.mjs +806 -0
  60. package/esm2020/src/entity-group.mjs +187 -0
  61. package/esm2020/src/entity-key.mjs +116 -0
  62. package/esm2020/src/entity-manager.mjs +2094 -0
  63. package/esm2020/src/entity-metadata.mjs +2109 -0
  64. package/esm2020/src/entity-query.mjs +996 -0
  65. package/esm2020/src/entity-state.mjs +99 -0
  66. package/esm2020/src/enum.mjs +141 -0
  67. package/esm2020/src/event.mjs +256 -0
  68. package/esm2020/src/interface-registry.mjs +41 -0
  69. package/esm2020/src/key-generator.mjs +108 -0
  70. package/esm2020/src/local-query-comparison-options.mjs +65 -0
  71. package/esm2020/src/mapping-context.mjs +405 -0
  72. package/esm2020/src/naming-convention.mjs +88 -0
  73. package/esm2020/src/observable-array.mjs +183 -0
  74. package/esm2020/src/predicate.mjs +1232 -0
  75. package/esm2020/src/primitive-array.mjs +85 -0
  76. package/esm2020/src/query-options.mjs +152 -0
  77. package/esm2020/src/relation-array.mjs +173 -0
  78. package/esm2020/src/save-options.mjs +41 -0
  79. package/esm2020/src/unattached-children-map.mjs +58 -0
  80. package/esm2020/src/validate.mjs +988 -0
  81. package/esm2020/src/validation-options.mjs +64 -0
  82. package/fesm2015/{breeze-client-adapter-ajax-angularjs.js → breeze-client-adapter-ajax-angularjs.mjs} +1 -1
  83. package/fesm2015/breeze-client-adapter-ajax-angularjs.mjs.map +1 -0
  84. package/fesm2015/{breeze-client-adapter-ajax-fetch.js → breeze-client-adapter-ajax-fetch.mjs} +5 -3
  85. package/fesm2015/breeze-client-adapter-ajax-fetch.mjs.map +1 -0
  86. package/fesm2015/{breeze-client-adapter-ajax-httpclient.js → breeze-client-adapter-ajax-httpclient.mjs} +1 -1
  87. package/fesm2015/breeze-client-adapter-ajax-httpclient.mjs.map +1 -0
  88. package/fesm2015/{breeze-client-adapter-ajax-jquery.js → breeze-client-adapter-ajax-jquery.mjs} +2 -2
  89. package/fesm2015/breeze-client-adapter-ajax-jquery.mjs.map +1 -0
  90. package/fesm2015/{breeze-client-adapter-ajax-post.js → breeze-client-adapter-ajax-post.mjs} +1 -1
  91. package/fesm2015/breeze-client-adapter-ajax-post.mjs.map +1 -0
  92. package/fesm2015/{breeze-client-adapter-data-service-odata.js → breeze-client-adapter-data-service-odata.mjs} +20 -22
  93. package/fesm2015/breeze-client-adapter-data-service-odata.mjs.map +1 -0
  94. package/fesm2015/{breeze-client-adapter-data-service-webapi.js → breeze-client-adapter-data-service-webapi.mjs} +13 -13
  95. package/fesm2015/breeze-client-adapter-data-service-webapi.mjs.map +1 -0
  96. package/fesm2015/{breeze-client-adapter-model-library-backing-store.js → breeze-client-adapter-model-library-backing-store.mjs} +13 -13
  97. package/fesm2015/breeze-client-adapter-model-library-backing-store.mjs.map +1 -0
  98. package/fesm2015/{breeze-client-adapter-model-library-ko.js → breeze-client-adapter-model-library-ko.mjs} +13 -13
  99. package/fesm2015/breeze-client-adapter-model-library-ko.mjs.map +1 -0
  100. package/fesm2015/{breeze-client-adapter-uri-builder-json.js → breeze-client-adapter-uri-builder-json.mjs} +8 -8
  101. package/fesm2015/breeze-client-adapter-uri-builder-json.mjs.map +1 -0
  102. package/fesm2015/{breeze-client-adapter-uri-builder-odata.js → breeze-client-adapter-uri-builder-odata.mjs} +85 -86
  103. package/fesm2015/breeze-client-adapter-uri-builder-odata.mjs.map +1 -0
  104. package/fesm2015/{breeze-client-mixin-get-entity-graph.js → breeze-client-mixin-get-entity-graph.mjs} +1 -1
  105. package/fesm2015/breeze-client-mixin-get-entity-graph.mjs.map +1 -0
  106. package/fesm2015/{breeze-client-mixin-save-queuing.js → breeze-client-mixin-save-queuing.mjs} +1 -1
  107. package/fesm2015/breeze-client-mixin-save-queuing.mjs.map +1 -0
  108. package/fesm2015/{breeze-client.js → breeze-client.mjs} +417 -422
  109. package/fesm2015/breeze-client.mjs.map +1 -0
  110. package/{fesm5/breeze-client-adapter-ajax-angularjs.js → fesm2020/breeze-client-adapter-ajax-angularjs.mjs} +41 -42
  111. package/fesm2020/breeze-client-adapter-ajax-angularjs.mjs.map +1 -0
  112. package/{fesm5/breeze-client-adapter-ajax-fetch.js → fesm2020/breeze-client-adapter-ajax-fetch.mjs} +44 -43
  113. package/fesm2020/breeze-client-adapter-ajax-fetch.mjs.map +1 -0
  114. package/{fesm5/breeze-client-adapter-ajax-httpclient.js → fesm2020/breeze-client-adapter-ajax-httpclient.mjs} +43 -44
  115. package/fesm2020/breeze-client-adapter-ajax-httpclient.mjs.map +1 -0
  116. package/{fesm5/breeze-client-adapter-ajax-jquery.js → fesm2020/breeze-client-adapter-ajax-jquery.mjs} +18 -19
  117. package/fesm2020/breeze-client-adapter-ajax-jquery.mjs.map +1 -0
  118. package/{fesm5/breeze-client-adapter-ajax-post.js → fesm2020/breeze-client-adapter-ajax-post.mjs} +8 -11
  119. package/fesm2020/breeze-client-adapter-ajax-post.mjs.map +1 -0
  120. package/{fesm5/breeze-client-adapter-data-service-odata.js → fesm2020/breeze-client-adapter-data-service-odata.mjs} +126 -134
  121. package/fesm2020/breeze-client-adapter-data-service-odata.mjs.map +1 -0
  122. package/{fesm5/breeze-client-adapter-data-service-webapi.js → fesm2020/breeze-client-adapter-data-service-webapi.mjs} +38 -42
  123. package/fesm2020/breeze-client-adapter-data-service-webapi.mjs.map +1 -0
  124. package/{fesm5/breeze-client-adapter-model-library-backing-store.js → fesm2020/breeze-client-adapter-model-library-backing-store.mjs} +63 -64
  125. package/fesm2020/breeze-client-adapter-model-library-backing-store.mjs.map +1 -0
  126. package/{fesm5/breeze-client-adapter-model-library-ko.js → fesm2020/breeze-client-adapter-model-library-ko.mjs} +57 -58
  127. package/fesm2020/breeze-client-adapter-model-library-ko.mjs.map +1 -0
  128. package/fesm2020/breeze-client-adapter-uri-builder-json.mjs +91 -0
  129. package/fesm2020/breeze-client-adapter-uri-builder-json.mjs.map +1 -0
  130. package/fesm2020/breeze-client-adapter-uri-builder-odata.mjs +245 -0
  131. package/fesm2020/breeze-client-adapter-uri-builder-odata.mjs.map +1 -0
  132. package/{fesm5/breeze-client-mixin-get-entity-graph.js → fesm2020/breeze-client-mixin-get-entity-graph.mjs} +45 -45
  133. package/fesm2020/breeze-client-mixin-get-entity-graph.mjs.map +1 -0
  134. package/{fesm5/breeze-client-mixin-save-queuing.js → fesm2020/breeze-client-mixin-save-queuing.mjs} +116 -126
  135. package/fesm2020/breeze-client-mixin-save-queuing.mjs.map +1 -0
  136. package/{fesm5/breeze-client.js → fesm2020/breeze-client.mjs} +3403 -3615
  137. package/fesm2020/breeze-client.mjs.map +1 -0
  138. package/mixin-get-entity-graph/{breeze-client-mixin-get-entity-graph.d.ts → index.d.ts} +1 -0
  139. package/mixin-save-queuing/{breeze-client-mixin-save-queuing.d.ts → index.d.ts} +1 -0
  140. package/package.json +126 -12
  141. package/src/entity-metadata.d.ts +6 -4
  142. package/src/entity-query.d.ts +1 -1
  143. package/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.metadata.json +0 -1
  144. package/adapter-ajax-angularjs/package.json +0 -13
  145. package/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.metadata.json +0 -1
  146. package/adapter-ajax-fetch/package.json +0 -13
  147. package/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.metadata.json +0 -1
  148. package/adapter-ajax-httpclient/package.json +0 -17
  149. package/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.metadata.json +0 -1
  150. package/adapter-ajax-jquery/package.json +0 -13
  151. package/adapter-ajax-post/breeze-client-adapter-ajax-post.metadata.json +0 -1
  152. package/adapter-ajax-post/package.json +0 -13
  153. package/adapter-data-service-odata/breeze-client-adapter-data-service-odata.metadata.json +0 -1
  154. package/adapter-data-service-odata/package.json +0 -13
  155. package/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.metadata.json +0 -1
  156. package/adapter-data-service-webapi/package.json +0 -13
  157. package/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.metadata.json +0 -1
  158. package/adapter-model-library-backing-store/package.json +0 -13
  159. package/adapter-model-library-ko/breeze-client-adapter-model-library-ko.metadata.json +0 -1
  160. package/adapter-model-library-ko/package.json +0 -13
  161. package/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.metadata.json +0 -1
  162. package/adapter-uri-builder-json/package.json +0 -13
  163. package/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.metadata.json +0 -1
  164. package/adapter-uri-builder-odata/package.json +0 -13
  165. package/breeze-client.d.ts +0 -8
  166. package/breeze-client.metadata.json +0 -1
  167. package/bundles/breeze-client-adapter-ajax-angularjs.umd.js +0 -190
  168. package/bundles/breeze-client-adapter-ajax-angularjs.umd.js.map +0 -1
  169. package/bundles/breeze-client-adapter-ajax-angularjs.umd.min.js +0 -2
  170. package/bundles/breeze-client-adapter-ajax-angularjs.umd.min.js.map +0 -1
  171. package/bundles/breeze-client-adapter-ajax-fetch.umd.js +0 -190
  172. package/bundles/breeze-client-adapter-ajax-fetch.umd.js.map +0 -1
  173. package/bundles/breeze-client-adapter-ajax-fetch.umd.min.js +0 -2
  174. package/bundles/breeze-client-adapter-ajax-fetch.umd.min.js.map +0 -1
  175. package/bundles/breeze-client-adapter-ajax-httpclient.umd.js +0 -195
  176. package/bundles/breeze-client-adapter-ajax-httpclient.umd.js.map +0 -1
  177. package/bundles/breeze-client-adapter-ajax-httpclient.umd.min.js +0 -2
  178. package/bundles/breeze-client-adapter-ajax-httpclient.umd.min.js.map +0 -1
  179. package/bundles/breeze-client-adapter-ajax-jquery.umd.js +0 -115
  180. package/bundles/breeze-client-adapter-ajax-jquery.umd.js.map +0 -1
  181. package/bundles/breeze-client-adapter-ajax-jquery.umd.min.js +0 -2
  182. package/bundles/breeze-client-adapter-ajax-jquery.umd.min.js.map +0 -1
  183. package/bundles/breeze-client-adapter-ajax-post.umd.js +0 -92
  184. package/bundles/breeze-client-adapter-ajax-post.umd.js.map +0 -1
  185. package/bundles/breeze-client-adapter-ajax-post.umd.min.js +0 -2
  186. package/bundles/breeze-client-adapter-ajax-post.umd.min.js.map +0 -1
  187. package/bundles/breeze-client-adapter-data-service-odata.umd.js +0 -743
  188. package/bundles/breeze-client-adapter-data-service-odata.umd.js.map +0 -1
  189. package/bundles/breeze-client-adapter-data-service-odata.umd.min.js +0 -16
  190. package/bundles/breeze-client-adapter-data-service-odata.umd.min.js.map +0 -1
  191. package/bundles/breeze-client-adapter-data-service-webapi.umd.js +0 -326
  192. package/bundles/breeze-client-adapter-data-service-webapi.umd.js.map +0 -1
  193. package/bundles/breeze-client-adapter-data-service-webapi.umd.min.js +0 -16
  194. package/bundles/breeze-client-adapter-data-service-webapi.umd.min.js.map +0 -1
  195. package/bundles/breeze-client-adapter-model-library-backing-store.umd.js +0 -280
  196. package/bundles/breeze-client-adapter-model-library-backing-store.umd.js.map +0 -1
  197. package/bundles/breeze-client-adapter-model-library-backing-store.umd.min.js +0 -2
  198. package/bundles/breeze-client-adapter-model-library-backing-store.umd.min.js.map +0 -1
  199. package/bundles/breeze-client-adapter-model-library-ko.umd.js +0 -252
  200. package/bundles/breeze-client-adapter-model-library-ko.umd.js.map +0 -1
  201. package/bundles/breeze-client-adapter-model-library-ko.umd.min.js +0 -2
  202. package/bundles/breeze-client-adapter-model-library-ko.umd.min.js.map +0 -1
  203. package/bundles/breeze-client-adapter-uri-builder-json.umd.js +0 -96
  204. package/bundles/breeze-client-adapter-uri-builder-json.umd.js.map +0 -1
  205. package/bundles/breeze-client-adapter-uri-builder-json.umd.min.js +0 -2
  206. package/bundles/breeze-client-adapter-uri-builder-json.umd.min.js.map +0 -1
  207. package/bundles/breeze-client-adapter-uri-builder-odata.umd.js +0 -262
  208. package/bundles/breeze-client-adapter-uri-builder-odata.umd.js.map +0 -1
  209. package/bundles/breeze-client-adapter-uri-builder-odata.umd.min.js +0 -2
  210. package/bundles/breeze-client-adapter-uri-builder-odata.umd.min.js.map +0 -1
  211. package/bundles/breeze-client-mixin-get-entity-graph.umd.js +0 -258
  212. package/bundles/breeze-client-mixin-get-entity-graph.umd.js.map +0 -1
  213. package/bundles/breeze-client-mixin-get-entity-graph.umd.min.js +0 -2
  214. package/bundles/breeze-client-mixin-get-entity-graph.umd.min.js.map +0 -1
  215. package/bundles/breeze-client-mixin-save-queuing.umd.js +0 -579
  216. package/bundles/breeze-client-mixin-save-queuing.umd.js.map +0 -1
  217. package/bundles/breeze-client-mixin-save-queuing.umd.min.js +0 -16
  218. package/bundles/breeze-client-mixin-save-queuing.umd.min.js.map +0 -1
  219. package/bundles/breeze-client.umd.js +0 -14094
  220. package/bundles/breeze-client.umd.js.map +0 -1
  221. package/bundles/breeze-client.umd.min.js +0 -16
  222. package/bundles/breeze-client.umd.min.js.map +0 -1
  223. package/esm2015/adapter-ajax-angularjs/adapter-ajax-angularjs.js +0 -130
  224. package/esm2015/adapter-ajax-angularjs/adapter-core.js +0 -49
  225. package/esm2015/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.js +0 -5
  226. package/esm2015/adapter-ajax-fetch/adapter-ajax-fetch.js +0 -130
  227. package/esm2015/adapter-ajax-fetch/adapter-core.js +0 -49
  228. package/esm2015/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.js +0 -5
  229. package/esm2015/adapter-ajax-httpclient/adapter-ajax-httpclient.js +0 -137
  230. package/esm2015/adapter-ajax-httpclient/adapter-core.js +0 -49
  231. package/esm2015/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.js +0 -5
  232. package/esm2015/adapter-ajax-jquery/adapter-ajax-jquery.js +0 -103
  233. package/esm2015/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.js +0 -5
  234. package/esm2015/adapter-ajax-post/adapter-ajax-post.js +0 -77
  235. package/esm2015/adapter-ajax-post/breeze-client-adapter-ajax-post.js +0 -5
  236. package/esm2015/adapter-data-service-odata/adapter-core.js +0 -49
  237. package/esm2015/adapter-data-service-odata/adapter-data-service-odata.js +0 -459
  238. package/esm2015/adapter-data-service-odata/breeze-client-adapter-data-service-odata.js +0 -5
  239. package/esm2015/adapter-data-service-webapi/adapter-data-service-webapi.js +0 -93
  240. package/esm2015/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.js +0 -5
  241. package/esm2015/adapter-model-library-backing-store/adapter-model-library-backing-store.js +0 -268
  242. package/esm2015/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.js +0 -5
  243. package/esm2015/adapter-model-library-ko/adapter-model-library-ko.js +0 -240
  244. package/esm2015/adapter-model-library-ko/breeze-client-adapter-model-library-ko.js +0 -5
  245. package/esm2015/adapter-uri-builder-json/adapter-core.js +0 -49
  246. package/esm2015/adapter-uri-builder-json/adapter-uri-builder-json.js +0 -36
  247. package/esm2015/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.js +0 -5
  248. package/esm2015/adapter-uri-builder-odata/adapter-core.js +0 -49
  249. package/esm2015/adapter-uri-builder-odata/adapter-uri-builder-odata.js +0 -192
  250. package/esm2015/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.js +0 -5
  251. package/esm2015/breeze-client.js +0 -9
  252. package/esm2015/index.js +0 -2
  253. package/esm2015/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.js +0 -5
  254. package/esm2015/mixin-get-entity-graph/mixin-get-entity-graph.js +0 -269
  255. package/esm2015/mixin-save-queuing/breeze-client-mixin-save-queuing.js +0 -5
  256. package/esm2015/mixin-save-queuing/mixin-save-queuing.js +0 -400
  257. package/esm2015/public_api.js +0 -2
  258. package/esm2015/src/abstract-data-service-adapter.js +0 -296
  259. package/esm2015/src/array.js +0 -4
  260. package/esm2015/src/assert-param.js +0 -312
  261. package/esm2015/src/breeze.js +0 -85
  262. package/esm2015/src/complex-array.js +0 -119
  263. package/esm2015/src/config.js +0 -223
  264. package/esm2015/src/core.js +0 -706
  265. package/esm2015/src/csdl-metadata-parser.js +0 -385
  266. package/esm2015/src/data-service.js +0 -203
  267. package/esm2015/src/data-type.js +0 -444
  268. package/esm2015/src/default-property-interceptor.js +0 -459
  269. package/esm2015/src/entity-action.js +0 -45
  270. package/esm2015/src/entity-aspect.js +0 -806
  271. package/esm2015/src/entity-group.js +0 -187
  272. package/esm2015/src/entity-key.js +0 -116
  273. package/esm2015/src/entity-manager.js +0 -2094
  274. package/esm2015/src/entity-metadata.js +0 -2109
  275. package/esm2015/src/entity-query.js +0 -996
  276. package/esm2015/src/entity-state.js +0 -99
  277. package/esm2015/src/enum.js +0 -141
  278. package/esm2015/src/event.js +0 -256
  279. package/esm2015/src/interface-registry.js +0 -41
  280. package/esm2015/src/key-generator.js +0 -108
  281. package/esm2015/src/local-query-comparison-options.js +0 -65
  282. package/esm2015/src/mapping-context.js +0 -405
  283. package/esm2015/src/naming-convention.js +0 -88
  284. package/esm2015/src/observable-array.js +0 -185
  285. package/esm2015/src/predicate.js +0 -1235
  286. package/esm2015/src/primitive-array.js +0 -87
  287. package/esm2015/src/query-options.js +0 -152
  288. package/esm2015/src/relation-array.js +0 -175
  289. package/esm2015/src/save-options.js +0 -41
  290. package/esm2015/src/unattached-children-map.js +0 -58
  291. package/esm2015/src/validate.js +0 -991
  292. package/esm2015/src/validation-options.js +0 -64
  293. package/esm5/adapter-ajax-angularjs/adapter-ajax-angularjs.js +0 -132
  294. package/esm5/adapter-ajax-angularjs/adapter-core.js +0 -49
  295. package/esm5/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.js +0 -5
  296. package/esm5/adapter-ajax-fetch/adapter-ajax-fetch.js +0 -132
  297. package/esm5/adapter-ajax-fetch/adapter-core.js +0 -49
  298. package/esm5/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.js +0 -5
  299. package/esm5/adapter-ajax-httpclient/adapter-ajax-httpclient.js +0 -139
  300. package/esm5/adapter-ajax-httpclient/adapter-core.js +0 -49
  301. package/esm5/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.js +0 -5
  302. package/esm5/adapter-ajax-jquery/adapter-ajax-jquery.js +0 -105
  303. package/esm5/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.js +0 -5
  304. package/esm5/adapter-ajax-post/adapter-ajax-post.js +0 -81
  305. package/esm5/adapter-ajax-post/breeze-client-adapter-ajax-post.js +0 -5
  306. package/esm5/adapter-data-service-odata/adapter-core.js +0 -49
  307. package/esm5/adapter-data-service-odata/adapter-data-service-odata.js +0 -466
  308. package/esm5/adapter-data-service-odata/breeze-client-adapter-data-service-odata.js +0 -5
  309. package/esm5/adapter-data-service-webapi/adapter-data-service-webapi.js +0 -98
  310. package/esm5/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.js +0 -5
  311. package/esm5/adapter-model-library-backing-store/adapter-model-library-backing-store.js +0 -270
  312. package/esm5/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.js +0 -5
  313. package/esm5/adapter-model-library-ko/adapter-model-library-ko.js +0 -242
  314. package/esm5/adapter-model-library-ko/breeze-client-adapter-model-library-ko.js +0 -5
  315. package/esm5/adapter-uri-builder-json/adapter-core.js +0 -49
  316. package/esm5/adapter-uri-builder-json/adapter-uri-builder-json.js +0 -38
  317. package/esm5/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.js +0 -5
  318. package/esm5/adapter-uri-builder-odata/adapter-core.js +0 -49
  319. package/esm5/adapter-uri-builder-odata/adapter-uri-builder-odata.js +0 -197
  320. package/esm5/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.js +0 -5
  321. package/esm5/breeze-client.js +0 -9
  322. package/esm5/index.js +0 -2
  323. package/esm5/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.js +0 -5
  324. package/esm5/mixin-get-entity-graph/mixin-get-entity-graph.js +0 -269
  325. package/esm5/mixin-save-queuing/breeze-client-mixin-save-queuing.js +0 -5
  326. package/esm5/mixin-save-queuing/mixin-save-queuing.js +0 -412
  327. package/esm5/public_api.js +0 -2
  328. package/esm5/src/abstract-data-service-adapter.js +0 -302
  329. package/esm5/src/array.js +0 -4
  330. package/esm5/src/assert-param.js +0 -317
  331. package/esm5/src/breeze.js +0 -85
  332. package/esm5/src/complex-array.js +0 -119
  333. package/esm5/src/config.js +0 -228
  334. package/esm5/src/core.js +0 -714
  335. package/esm5/src/csdl-metadata-parser.js +0 -385
  336. package/esm5/src/data-service.js +0 -207
  337. package/esm5/src/data-type.js +0 -451
  338. package/esm5/src/default-property-interceptor.js +0 -459
  339. package/esm5/src/entity-action.js +0 -52
  340. package/esm5/src/entity-aspect.js +0 -812
  341. package/esm5/src/entity-group.js +0 -189
  342. package/esm5/src/entity-key.js +0 -118
  343. package/esm5/src/entity-manager.js +0 -2112
  344. package/esm5/src/entity-metadata.js +0 -2144
  345. package/esm5/src/entity-query.js +0 -1023
  346. package/esm5/src/entity-state.js +0 -106
  347. package/esm5/src/enum.js +0 -144
  348. package/esm5/src/event.js +0 -259
  349. package/esm5/src/interface-registry.js +0 -43
  350. package/esm5/src/key-generator.js +0 -111
  351. package/esm5/src/local-query-comparison-options.js +0 -67
  352. package/esm5/src/mapping-context.js +0 -407
  353. package/esm5/src/naming-convention.js +0 -90
  354. package/esm5/src/observable-array.js +0 -201
  355. package/esm5/src/predicate.js +0 -1300
  356. package/esm5/src/primitive-array.js +0 -87
  357. package/esm5/src/query-options.js +0 -167
  358. package/esm5/src/relation-array.js +0 -175
  359. package/esm5/src/save-options.js +0 -43
  360. package/esm5/src/unattached-children-map.js +0 -60
  361. package/esm5/src/validate.js +0 -996
  362. package/esm5/src/validation-options.js +0 -66
  363. package/fesm2015/breeze-client-adapter-ajax-angularjs.js.map +0 -1
  364. package/fesm2015/breeze-client-adapter-ajax-fetch.js.map +0 -1
  365. package/fesm2015/breeze-client-adapter-ajax-httpclient.js.map +0 -1
  366. package/fesm2015/breeze-client-adapter-ajax-jquery.js.map +0 -1
  367. package/fesm2015/breeze-client-adapter-ajax-post.js.map +0 -1
  368. package/fesm2015/breeze-client-adapter-data-service-odata.js.map +0 -1
  369. package/fesm2015/breeze-client-adapter-data-service-webapi.js.map +0 -1
  370. package/fesm2015/breeze-client-adapter-model-library-backing-store.js.map +0 -1
  371. package/fesm2015/breeze-client-adapter-model-library-ko.js.map +0 -1
  372. package/fesm2015/breeze-client-adapter-uri-builder-json.js.map +0 -1
  373. package/fesm2015/breeze-client-adapter-uri-builder-odata.js.map +0 -1
  374. package/fesm2015/breeze-client-mixin-get-entity-graph.js.map +0 -1
  375. package/fesm2015/breeze-client-mixin-save-queuing.js.map +0 -1
  376. package/fesm2015/breeze-client.js.map +0 -1
  377. package/fesm5/breeze-client-adapter-ajax-angularjs.js.map +0 -1
  378. package/fesm5/breeze-client-adapter-ajax-fetch.js.map +0 -1
  379. package/fesm5/breeze-client-adapter-ajax-httpclient.js.map +0 -1
  380. package/fesm5/breeze-client-adapter-ajax-jquery.js.map +0 -1
  381. package/fesm5/breeze-client-adapter-ajax-post.js.map +0 -1
  382. package/fesm5/breeze-client-adapter-data-service-odata.js.map +0 -1
  383. package/fesm5/breeze-client-adapter-data-service-webapi.js.map +0 -1
  384. package/fesm5/breeze-client-adapter-model-library-backing-store.js.map +0 -1
  385. package/fesm5/breeze-client-adapter-model-library-ko.js.map +0 -1
  386. package/fesm5/breeze-client-adapter-uri-builder-json.js +0 -92
  387. package/fesm5/breeze-client-adapter-uri-builder-json.js.map +0 -1
  388. package/fesm5/breeze-client-adapter-uri-builder-odata.js +0 -250
  389. package/fesm5/breeze-client-adapter-uri-builder-odata.js.map +0 -1
  390. package/fesm5/breeze-client-mixin-get-entity-graph.js.map +0 -1
  391. package/fesm5/breeze-client-mixin-save-queuing.js.map +0 -1
  392. package/fesm5/breeze-client.js.map +0 -1
  393. package/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.metadata.json +0 -1
  394. package/mixin-get-entity-graph/package.json +0 -13
  395. package/mixin-save-queuing/breeze-client-mixin-save-queuing.metadata.json +0 -1
  396. package/mixin-save-queuing/package.json +0 -13
  397. package/public_api.d.ts +0 -1
@@ -1,2144 +0,0 @@
1
- import { __extends } from "tslib";
2
- import { core } from './core';
3
- import { config } from './config';
4
- import { BreezeEvent } from './event';
5
- import { assertParam, assertConfig, Param } from './assert-param';
6
- import { DataType } from './data-type';
7
- import { EntityAspect, ComplexAspect } from './entity-aspect';
8
- import { EntityKey } from './entity-key';
9
- import { Validator } from './validate';
10
- import { BreezeEnum } from './enum';
11
- import { DataService } from './data-service';
12
- import { NamingConvention } from './naming-convention';
13
- import { CsdlMetadataParser } from './csdl-metadata-parser'; // TODO isolate this later;
14
- import { LocalQueryComparisonOptions } from './local-query-comparison-options';
15
- import { defaultPropertyInterceptor } from './default-property-interceptor';
16
- /**
17
- An instance of the MetadataStore contains all of the metadata about a collection of [[EntityType]]'s.
18
- MetadataStores may be shared across [[EntityManager]]'s. If an EntityManager is created without an
19
- explicit MetadataStore, the MetadataStore from the MetadataStore.defaultInstance property will be used.
20
- @dynamic
21
- **/
22
- var MetadataStore = /** @class */ (function () {
23
- /**
24
- Constructs a new MetadataStore.
25
-
26
- > let ms = new MetadataStore();
27
-
28
- The store can then be associated with an EntityManager
29
- > let entityManager = new EntityManager( {
30
- > serviceName: "breeze/NorthwindIBModel",
31
- > metadataStore: ms
32
- > });
33
-
34
- or for an existing EntityManager
35
- > // Assume em1 is an existing EntityManager
36
- > em1.setProperties( { metadataStore: ms });
37
-
38
- @param config - Configuration settings .
39
- - namingConvention - (default=NamingConvention.defaultInstance) NamingConvention to be used in mapping property names
40
- between client and server. Uses the NamingConvention.defaultInstance if not specified.
41
- - localQueryComparisonOptions - (default=LocalQueryComparisonOptions.defaultInstance) The LocalQueryComparisonOptions to be
42
- used when performing "local queries" in order to match the semantics of queries against a remote service.
43
- - serializerFn - A function that is used to mediate the serialization of instances of this type.
44
- **/
45
- function MetadataStore(config) {
46
- config = config || {};
47
- assertConfig(config)
48
- .whereParam("namingConvention").isOptional().isInstanceOf(NamingConvention).withDefault(NamingConvention.defaultInstance)
49
- .whereParam("localQueryComparisonOptions").isOptional().isInstanceOf(LocalQueryComparisonOptions).withDefault(LocalQueryComparisonOptions.defaultInstance)
50
- .whereParam("serializerFn").isOptional().isFunction()
51
- .applyAll(this);
52
- this.dataServices = []; // array of dataServices;
53
- this._resourceEntityTypeMap = {}; // key is resource name - value is qualified entityType name
54
- this._structuralTypeMap = {}; // key is qualified structuraltype name - value is structuralType. ( structural = entityType or complexType).
55
- this._shortNameMap = {}; // key is shortName, value is qualified name - does not need to be serialized.
56
- this._ctorRegistry = {}; // key is either short or qual type name - value is ctor;
57
- this._incompleteTypeMap = {}; // key is entityTypeName; value is array of nav props
58
- this._incompleteComplexTypeMap = {}; // key is complexTypeName; value is array of complexType props
59
- this._id = MetadataStore.__id++;
60
- this.metadataFetched = new BreezeEvent("metadataFetched", this);
61
- }
62
- // for debugging use the line below instead.
63
- //ctor.normalizeTypeName = function (rawTypeName) { return parseTypeName(rawTypeName).typeName; };
64
- /**
65
- General purpose property set method
66
-
67
- > // assume em1 is an EntityManager containing a number of existing entities.
68
- > em1.metadataStore.setProperties( {
69
- > version: "6.1.3",
70
- > serializerFn: function(prop, value) {
71
- > return (prop.isUnmapped) ? undefined : value;
72
- > }
73
- > )};
74
- @param config - An object containing the selected properties and values to set.
75
- **/
76
- MetadataStore.prototype.setProperties = function (config) {
77
- assertConfig(config)
78
- .whereParam("name").isString().isOptional()
79
- .whereParam("serializerFn").isFunction().isOptional()
80
- .applyAll(this);
81
- };
82
- /**
83
- Adds a DataService to this MetadataStore. If a DataService with the same serviceName is already
84
- in the MetadataStore an exception will be thrown.
85
- @param dataService - The [[DataService]] to add
86
- @param shouldOverwrite - (default=false) Permit overwrite of existing DataService rather than throw exception
87
- **/
88
- MetadataStore.prototype.addDataService = function (dataService, shouldOverwrite) {
89
- assertParam(dataService, "dataService").isInstanceOf(DataService).check();
90
- assertParam(shouldOverwrite, "shouldOverwrite").isBoolean().isOptional().check();
91
- var ix = this._getDataServiceIndex(dataService.serviceName);
92
- if (ix >= 0) {
93
- if (!!shouldOverwrite) {
94
- this.dataServices[ix] = dataService;
95
- }
96
- else {
97
- throw new Error("A dataService with this name '" + dataService.serviceName + "' already exists in this MetadataStore");
98
- }
99
- }
100
- else {
101
- this.dataServices.push(dataService);
102
- }
103
- };
104
- /** @hidden @internal */
105
- MetadataStore.prototype._getDataServiceIndex = function (serviceName) {
106
- return core.arrayIndexOf(this.dataServices, function (ds) {
107
- return ds.serviceName === serviceName;
108
- });
109
- };
110
- /**
111
- Adds an EntityType to this MetadataStore. No additional properties may be added to the EntityType after its has
112
- been added to the MetadataStore.
113
- @param structuralType - The EntityType or ComplexType to add
114
- **/
115
- MetadataStore.prototype.addEntityType = function (stype) {
116
- var structuralType;
117
- if (stype instanceof EntityType || stype instanceof ComplexType) {
118
- structuralType = stype;
119
- }
120
- else {
121
- structuralType = stype.isComplexType ? new ComplexType(stype) : new EntityType(stype);
122
- }
123
- // if (!structuralType.isComplexType) { // same as below but isn't a 'type guard'
124
- if (structuralType instanceof EntityType) {
125
- if (structuralType.baseTypeName && !structuralType.baseEntityType) {
126
- var baseEntityType = this._getStructuralType(structuralType.baseTypeName, true);
127
- // safe cast because we know that baseEntityType must be an EntityType if the structuralType is an EntityType
128
- structuralType._updateFromBase(baseEntityType);
129
- }
130
- if (structuralType.keyProperties.length === 0 && !structuralType.isAbstract) {
131
- throw new Error("Unable to add " + structuralType.name +
132
- " to this MetadataStore. An EntityType must have at least one property designated as a key property - See the 'DataProperty.isPartOfKey' property.");
133
- }
134
- }
135
- structuralType.metadataStore = this;
136
- // don't register anon types
137
- if (!structuralType.isAnonymous) {
138
- if (this._structuralTypeMap[structuralType.name]) {
139
- throw new Error("Type " + structuralType.name + " already exists in this MetadataStore.");
140
- }
141
- this._structuralTypeMap[structuralType.name] = structuralType;
142
- this._shortNameMap[structuralType.shortName] = structuralType.name;
143
- }
144
- structuralType.getProperties().forEach(function (p) {
145
- structuralType._updateNames(p);
146
- if (!p.isUnmapped) {
147
- structuralType._mappedPropertiesCount++;
148
- }
149
- });
150
- structuralType._updateCps();
151
- // 'isEntityType' is a type guard
152
- if (structuralType instanceof EntityType) {
153
- structuralType._updateNps();
154
- // give the type it's base's resource name if it doesn't have its own.
155
- var defResourceName = structuralType.defaultResourceName || (structuralType.baseEntityType && structuralType.baseEntityType.defaultResourceName);
156
- if (defResourceName && !this.getEntityTypeNameForResourceName(defResourceName)) {
157
- this.setEntityTypeForResourceName(defResourceName, structuralType.name);
158
- }
159
- structuralType.defaultResourceName = defResourceName;
160
- // check if this structural type's name, short version or qualified version has a registered ctor.
161
- structuralType.getEntityCtor();
162
- }
163
- };
164
- /**
165
- Exports this MetadataStore to a serialized string appropriate for local storage. This operation is also called
166
- internally when exporting an EntityManager.
167
- > // assume ms is a previously created MetadataStore
168
- > let metadataAsString = ms.exportMetadata();
169
- > window.localStorage.setItem("metadata", metadataAsString);
170
- > // and later, usually in a different session imported
171
- > let metadataFromStorage = window.localStorage.getItem("metadata");
172
- > let newMetadataStore = new MetadataStore();
173
- > newMetadataStore.importMetadata(metadataFromStorage);
174
- @return A serialized version of this MetadataStore that may be stored locally and later restored.
175
- **/
176
- MetadataStore.prototype.exportMetadata = function () {
177
- var result = JSON.stringify({
178
- "metadataVersion": MetadataStore.metadataVersion,
179
- "name": this.name,
180
- "namingConvention": this.namingConvention.name,
181
- "localQueryComparisonOptions": this.localQueryComparisonOptions.name,
182
- "dataServices": this.dataServices,
183
- "structuralTypes": core.objectMap(this._structuralTypeMap),
184
- "resourceEntityTypeMap": this._resourceEntityTypeMap
185
- }, null, config.stringifyPad);
186
- return result;
187
- };
188
- /**
189
- Imports a previously exported serialized MetadataStore into this MetadataStore.
190
-
191
- > // assume ms is a previously created MetadataStore
192
- > let metadataAsString = ms.exportMetadata();
193
- > window.localStorage.setItem("metadata", metadataAsString);
194
- > // and later, usually in a different session
195
- > let metadataFromStorage = window.localStorage.getItem("metadata");
196
- > let newMetadataStore = new MetadataStore();
197
- > newMetadataStore.importMetadata(metadataFromStorage);
198
- @param exportedMetadata - A previously exported MetadataStore.
199
- @param allowMerge - Allows custom metadata to be merged into existing metadata types.
200
- @return This MetadataStore.
201
- @chainable
202
- **/
203
- MetadataStore.prototype.importMetadata = function (exportedMetadata, allowMerge) {
204
- var _this = this;
205
- if (allowMerge === void 0) { allowMerge = false; }
206
- assertParam(allowMerge, "allowMerge").isOptional().isBoolean().check();
207
- this._deferredTypes = {};
208
- // insure that we don't mutate incoming exportedMetadata ( if its an object)
209
- var metadataAsString = (typeof (exportedMetadata) === "string") ? exportedMetadata : JSON.stringify(exportedMetadata);
210
- var metadataJson = JSON.parse(metadataAsString);
211
- if (metadataJson.schema) {
212
- return CsdlMetadataParser.parse(this, metadataJson.schema, metadataJson.altMetadata);
213
- }
214
- var json = metadataJson;
215
- if (json.metadataVersion && json.metadataVersion !== MetadataStore.metadataVersion) {
216
- var msg = core.formatString("Cannot import metadata with a different 'metadataVersion' (%1) than the current 'MetadataStore.metadataVersion' (%2) ", json.metadataVersion, MetadataStore.metadataVersion);
217
- throw new Error(msg);
218
- }
219
- var ncName = json.namingConvention;
220
- var lqcoName = json.localQueryComparisonOptions;
221
- if (this.isEmpty()) {
222
- this.namingConvention = config._fetchObject(NamingConvention, ncName) || this.namingConvention;
223
- this.localQueryComparisonOptions = config._fetchObject(LocalQueryComparisonOptions, lqcoName) || this.localQueryComparisonOptions;
224
- }
225
- else {
226
- if (ncName && this.namingConvention.name !== ncName) {
227
- throw new Error("Cannot import metadata with a different 'namingConvention' from the current MetadataStore");
228
- }
229
- if (lqcoName && this.localQueryComparisonOptions.name !== lqcoName) {
230
- throw new Error("Cannot import metadata with different 'localQueryComparisonOptions' from the current MetadataStore");
231
- }
232
- }
233
- //noinspection JSHint
234
- json.dataServices && json.dataServices.forEach(function (ds) {
235
- var realDs = DataService.fromJSON(ds);
236
- _this.addDataService(realDs, true);
237
- });
238
- json.structuralTypes && json.structuralTypes.forEach(function (stype) {
239
- structuralTypeFromJson(_this, stype, allowMerge);
240
- });
241
- core.extend(this._resourceEntityTypeMap, json.resourceEntityTypeMap);
242
- core.extend(this._incompleteTypeMap, json.incompleteTypeMap);
243
- return this;
244
- };
245
- /**
246
- Creates a new MetadataStore from a previously exported serialized MetadataStore
247
- > // assume ms is a previously created MetadataStore
248
- > let metadataAsString = ms.exportMetadata();
249
- > window.localStorage.setItem("metadata", metadataAsString);
250
- > // and later, usually in a different session
251
- > let metadataFromStorage = window.localStorage.getItem("metadata");
252
- > let newMetadataStore = MetadataStore.importMetadata(metadataFromStorage);
253
- @param exportedString - A previously exported MetadataStore.
254
- @return A new MetadataStore.
255
- **/
256
- MetadataStore.importMetadata = function (exportedString) {
257
- var ms = new MetadataStore();
258
- ms.importMetadata(exportedString);
259
- return ms;
260
- };
261
- /**
262
- Returns whether Metadata has been retrieved for a specified service name.
263
- > // Assume em1 is an existing EntityManager.
264
- > if (!em1.metadataStore.hasMetadataFor("breeze/NorthwindIBModel"))) {
265
- > // do something interesting
266
- > }
267
- @param serviceName - The service name.
268
- @return Whether metadata has already been retrieved for the specified service name.
269
- **/
270
- MetadataStore.prototype.hasMetadataFor = function (serviceName) {
271
- return !!this.getDataService(serviceName);
272
- };
273
- /**
274
- Returns the DataService for a specified service name
275
- > // Assume em1 is an existing EntityManager.
276
- > let ds = em1.metadataStore.getDataService("breeze/NorthwindIBModel");
277
- > let adapterName = ds.adapterName; // may be null
278
- @param serviceName - The service name.
279
- @return The DataService with the specified name.
280
- **/
281
- MetadataStore.prototype.getDataService = function (serviceName) {
282
- assertParam(serviceName, "serviceName").isString().check();
283
- serviceName = DataService._normalizeServiceName(serviceName);
284
- return core.arrayFirst(this.dataServices, function (ds) {
285
- return ds.serviceName === serviceName;
286
- });
287
- };
288
- /**
289
- Fetches the metadata for a specified 'service'. This method is automatically called
290
- internally by an EntityManager before its first query against a new service. __Async__
291
-
292
- Usually you will not actually process the results of a fetchMetadata call directly, but will instead
293
- ask for the metadata from the EntityManager after the fetchMetadata call returns.
294
- > let ms = new MetadataStore();
295
- > // or more commonly
296
- > // let ms = anEntityManager.metadataStore;
297
- > ms.fetchMetadata("breeze/NorthwindIBModel").then(function(rawMetadata) {
298
- > // do something with the metadata
299
- > }).catch(function(exception) {
300
- > // handle exception here
301
- > });
302
- @param dataService - Either a DataService or just the name of the DataService to fetch metadata for.
303
- @param callback - Function called on success.
304
- @param errorCallback - Function called on failure.
305
- @return Promise
306
- **/
307
- MetadataStore.prototype.fetchMetadata = function (dataService, callback, errorCallback) {
308
- var _this = this;
309
- try {
310
- assertParam(dataService, "dataService").isString().or().isInstanceOf(DataService).check();
311
- assertParam(callback, "callback").isFunction().isOptional().check();
312
- assertParam(errorCallback, "errorCallback").isFunction().isOptional().check();
313
- if (typeof dataService === "string") {
314
- // use the dataService with a matching name or create a new one.
315
- dataService = this.getDataService(dataService) || new DataService({ serviceName: dataService });
316
- }
317
- dataService = DataService.resolve([dataService]);
318
- if (this.hasMetadataFor(dataService.serviceName)) {
319
- throw new Error("Metadata for a specific serviceName may only be fetched once per MetadataStore. ServiceName: " + dataService.serviceName);
320
- }
321
- return dataService.adapterInstance.fetchMetadata(this, dataService).then(function (rawMetadata) {
322
- _this.metadataFetched.publish({ metadataStore: _this, dataService: dataService, rawMetadata: rawMetadata });
323
- if (callback)
324
- callback(rawMetadata);
325
- return Promise.resolve(rawMetadata);
326
- }, function (error) {
327
- if (errorCallback)
328
- errorCallback(error);
329
- return Promise.reject(error);
330
- });
331
- }
332
- catch (e) {
333
- return Promise.reject(e);
334
- }
335
- };
336
- // TODO: strongly type interceptor below.
337
- /**
338
- Used to register a constructor for an EntityType that is not known via standard Metadata discovery;
339
- i.e. an unmapped type.
340
- @param entityCtor - The constructor function for the 'unmapped' type.
341
- @param interceptor - An interceptor function
342
- **/
343
- MetadataStore.prototype.trackUnmappedType = function (entityCtor, interceptor) {
344
- assertParam(entityCtor, "entityCtor").isFunction().check();
345
- assertParam(interceptor, "interceptor").isFunction().isOptional().check();
346
- // TODO: think about adding this to the MetadataStore.
347
- var entityType = new EntityType(this);
348
- entityType._setCtor(entityCtor, interceptor);
349
- };
350
- /**
351
- Provides a mechanism to register a 'custom' constructor to be used when creating new instances
352
- of the specified entity type. If this call is not made, a default constructor is created for
353
- the entity as needed.
354
- This call may be made before or after the corresponding EntityType has been discovered via
355
- Metadata discovery.
356
- > let Customer = function () {
357
- > this.miscData = "asdf";
358
- > };
359
- > Customer.prototype.doFoo() {
360
- > ...
361
- > }
362
- > // assume em1 is a preexisting EntityManager;
363
- > em1.metadataStore.registerEntityTypeCtor("Customer", Customer);
364
- > // any queries or EntityType.create calls from this point on will call the Customer constructor
365
- > // registered above.
366
- @param structuralTypeName - The name of the EntityType or ComplexType.
367
- @param aCtor - The constructor for this EntityType or ComplexType; may be null if all you want to do is set the next parameter.
368
- @param initFn - A function or the name of a function on the entity that is to be executed immediately after the entity has been created
369
- and populated with any initial values. Called with 'initFn(entity)'
370
- @param noTrackingFn - A function that is executed immediately after a noTracking entity has been created and whose return
371
- value will be used in place of the noTracking entity.
372
- **/
373
- MetadataStore.prototype.registerEntityTypeCtor = function (structuralTypeName, aCtor, initFn, noTrackingFn) {
374
- assertParam(structuralTypeName, "structuralTypeName").isString().check();
375
- assertParam(aCtor, "aCtor").isFunction().isOptional().check();
376
- assertParam(initFn, "initFn").isOptional().isFunction().or().isString().check();
377
- assertParam(noTrackingFn, "noTrackingFn").isOptional().isFunction().check();
378
- var qualifiedTypeName = getQualifiedTypeName(this, structuralTypeName, false);
379
- var typeName = qualifiedTypeName || structuralTypeName;
380
- if (aCtor) {
381
- if (aCtor._$typeName && aCtor._$typeName !== typeName) {
382
- // TODO: wrap this - console and especially console.warn does not exist in all browsers.
383
- console.warn("Registering a constructor for " + typeName + " that is already used for " + aCtor._$typeName + ".");
384
- }
385
- aCtor._$typeName = typeName;
386
- }
387
- this._ctorRegistry[typeName] = { ctor: aCtor, initFn: initFn, noTrackingFn: noTrackingFn };
388
- if (qualifiedTypeName) {
389
- var stype = this._structuralTypeMap[qualifiedTypeName];
390
- stype && stype.getCtor(true); // this will complete the registration if avail now.
391
- }
392
- };
393
- /**
394
- Returns whether this MetadataStore contains any metadata yet.
395
- > // assume em1 is a preexisting EntityManager;
396
- > if (em1.metadataStore.isEmpty()) {
397
- > // do something interesting
398
- > }
399
- **/
400
- MetadataStore.prototype.isEmpty = function () {
401
- return core.isEmpty(this._structuralTypeMap);
402
- };
403
- /**
404
- Returns an [[EntityType]] or null given its name.
405
- > // assume em1 is a preexisting EntityManager
406
- > let odType = em1.metadataStore.getAsEntityType("OrderDetail");
407
-
408
- or to throw an error if the type is not found
409
- > let badType = em1.metadataStore.getAsEntityType("Foo", false);
410
- > // badType will not get set and an exception will be thrown.
411
- @param structuralTypeName - Either the fully qualified name or a short name may be used. If a short name is specified and multiple types share
412
- that same short name an exception will be thrown.
413
- @param okIfNotFound - (default=false) Whether to throw an error if the specified EntityType is not found.
414
- @return The EntityType. ComplexType or 'null' if not not found.
415
- **/
416
- MetadataStore.prototype.getAsEntityType = function (typeName, okIfNotFound) {
417
- if (okIfNotFound === void 0) { okIfNotFound = false; }
418
- var st = this.getStructuralType(typeName, okIfNotFound);
419
- if (st instanceof EntityType) {
420
- return st;
421
- }
422
- else if (okIfNotFound) {
423
- return null;
424
- }
425
- else {
426
- var msg = core.formatString("Unable to locate an 'EntityType' by the name: '%1'. Be sure to execute a query or call fetchMetadata first.", typeName);
427
- throw new Error(msg);
428
- }
429
- };
430
- /**
431
- Returns an [[EntityType]] or null given its name.
432
- > // assume em1 is a preexisting EntityManager
433
- > let locType = em1.metadataStore.getAsComplexType("Location");
434
-
435
- or to throw an error if the type is not found
436
- > let badType = em1.metadataStore.getAsComplexType("Foo", false);
437
- > // badType will not get set and an exception will be thrown.
438
- @param structuralTypeName - Either the fully qualified name or a short name may be used. If a short name is specified and multiple types share
439
- that same short name an exception will be thrown.
440
- @param okIfNotFound - (default=false) Whether to throw an error if the specified EntityType is not found.
441
- @return The EntityType. ComplexType or 'null' if not not found.
442
- **/
443
- MetadataStore.prototype.getAsComplexType = function (typeName, okIfNotFound) {
444
- if (okIfNotFound === void 0) { okIfNotFound = false; }
445
- var st = this.getStructuralType(typeName, okIfNotFound);
446
- if (st instanceof ComplexType) {
447
- return st;
448
- }
449
- else if (okIfNotFound) {
450
- return null;
451
- }
452
- else {
453
- var msg = core.formatString("Unable to locate an 'ComplexType' by the name: '%1'. Be sure to execute a query or call fetchMetadata first.", typeName);
454
- throw new Error(msg);
455
- }
456
- };
457
- /**
458
- Returns an [[EntityType]] or a [[ComplexType]] given its name.
459
- @deprecated Replaced by getStructuralType but ... it is probably more usefull to call either getAsEntityType or getAsComplexType instead
460
- @param typeName - Either the fully qualified name or a short name may be used. If a short name is specified and multiple types share
461
- that same short name an exception will be thrown.
462
- @param okIfNotFound - (default=false) Whether to throw an error if the specified EntityType is not found.
463
- @return The EntityType. ComplexType or 'null' if not not found.
464
- **/
465
- MetadataStore.prototype.getEntityType = function (typeName, okIfNotFound) {
466
- if (okIfNotFound === void 0) { okIfNotFound = false; }
467
- return this.getStructuralType(typeName, okIfNotFound);
468
- };
469
- /**
470
- Returns an [[EntityType]] or a [[ComplexType]] given its name.
471
- > // assume em1 is a preexisting EntityManager
472
- > let odType = em1.metadataStore.getStructuralType("OrderDetail");
473
-
474
- or to throw an error if the type is not found
475
- > let badType = em1.metadataStore.getStructuralType("Foo", false);
476
- > // badType will not get set and an exception will be thrown.
477
- @deprecated Preferably use either getAsEntityType or getAsComplexType. Get
478
- @param typeName - Either the fully qualified name or a short name may be used. If a short name is specified and multiple types share
479
- that same short name an exception will be thrown.
480
- @param okIfNotFound - (default=false) Whether to throw an error if the specified EntityType is not found.
481
- @return The EntityType. ComplexType or 'null' if not not found.
482
- **/
483
- MetadataStore.prototype.getStructuralType = function (typeName, okIfNotFound) {
484
- if (okIfNotFound === void 0) { okIfNotFound = false; }
485
- assertParam(typeName, "typeName").isString().check();
486
- assertParam(okIfNotFound, "okIfNotFound").isBoolean().isOptional().check(false);
487
- return this._getStructuralType(typeName, okIfNotFound);
488
- };
489
- /** @hidden @internal */
490
- MetadataStore.prototype._getStructuralType = function (typeName, okIfNotFound) {
491
- if (okIfNotFound === void 0) { okIfNotFound = false; }
492
- var qualTypeName = getQualifiedTypeName(this, typeName, false);
493
- var type = this._structuralTypeMap[qualTypeName];
494
- if (!type) {
495
- if (okIfNotFound)
496
- return null;
497
- var msg = core.formatString("Unable to locate a 'Type' by the name: '%1'. Be sure to execute a query or call fetchMetadata first.", typeName);
498
- throw new Error(msg);
499
- }
500
- return type;
501
- };
502
- /**
503
- Returns an array containing all of the [[EntityType]]s or [[ComplexType]]s in this MetadataStore.
504
- > // assume em1 is a preexisting EntityManager
505
- > let allTypes = em1.metadataStore.getEntityTypes();
506
- **/
507
- MetadataStore.prototype.getEntityTypes = function () {
508
- return getTypesFromMap(this._structuralTypeMap);
509
- };
510
- MetadataStore.prototype.getIncompleteNavigationProperties = function () {
511
- return core.objectMap(this._incompleteTypeMap, function (key, value) {
512
- return value;
513
- });
514
- };
515
- /**
516
- Returns a fully qualified entityTypeName for a specified resource name. The reverse of this operation
517
- can be obtained via the [[EntityType.defaultResourceName]] property
518
- **/
519
- MetadataStore.prototype.getEntityTypeNameForResourceName = function (resourceName) {
520
- assertParam(resourceName, "resourceName").isString().check();
521
- return this._resourceEntityTypeMap[resourceName];
522
- };
523
- /**
524
- Associates a resourceName with an entityType.
525
-
526
- This method is only needed in those cases where multiple resources return the same
527
- entityType. In this case Metadata discovery will only determine a single resource name for
528
- each entityType.
529
- @param resourceName - The resource name
530
- @param entityTypeOrName - If passing a string either the fully qualified name or a short name may be used. If a short name is specified and multiple types share
531
- that same short name an exception will be thrown. If the entityType has not yet been discovered then a fully qualified name must be used.
532
- **/
533
- MetadataStore.prototype.setEntityTypeForResourceName = function (resourceName, entityTypeOrName) {
534
- assertParam(resourceName, "resourceName").isString().check();
535
- assertParam(entityTypeOrName, "entityTypeOrName").isInstanceOf(EntityType).or().isString().check();
536
- var entityTypeName;
537
- if (entityTypeOrName instanceof EntityType) {
538
- entityTypeName = entityTypeOrName.name;
539
- }
540
- else {
541
- entityTypeName = getQualifiedTypeName(this, entityTypeOrName, true);
542
- }
543
- this._resourceEntityTypeMap[resourceName] = entityTypeName;
544
- var entityType = this._getStructuralType(entityTypeName, true);
545
- if (entityType && entityType instanceof EntityType && !entityType.defaultResourceName) {
546
- entityType.defaultResourceName = resourceName;
547
- }
548
- };
549
- /** __Dev Only__ - for use when creating a new MetadataParserAdapter */
550
- MetadataStore.parseTypeName = function (entityTypeName) {
551
- // TODO: removed
552
- // if (!entityTypeName) {
553
- // return null;
554
- // }
555
- var typeParts = entityTypeName.split(":#");
556
- if (typeParts.length > 1) {
557
- return MetadataStore.makeTypeHash(typeParts[0], typeParts[1]);
558
- }
559
- if (core.stringStartsWith(entityTypeName, MetadataStore.ANONTYPE_PREFIX)) {
560
- var typeHash = MetadataStore.makeTypeHash(entityTypeName);
561
- typeHash.isAnonymous = true;
562
- return typeHash;
563
- }
564
- var entityTypeNameNoAssembly = entityTypeName.split(",")[0];
565
- typeParts = entityTypeNameNoAssembly.split(".");
566
- if (typeParts.length > 1) {
567
- var shortName = typeParts[typeParts.length - 1];
568
- var namespaceParts = typeParts.slice(0, typeParts.length - 1);
569
- var ns = namespaceParts.join(".");
570
- return MetadataStore.makeTypeHash(shortName, ns);
571
- }
572
- else {
573
- return MetadataStore.makeTypeHash(entityTypeName);
574
- }
575
- };
576
- /** __Dev Only__ - for use when creating a new MetadataParserAdapter */
577
- MetadataStore.makeTypeHash = function (shortName, ns) {
578
- return {
579
- shortTypeName: shortName,
580
- namespace: ns,
581
- typeName: qualifyTypeName(shortName, ns)
582
- };
583
- };
584
- // protected methods
585
- /** @hidden @internal */
586
- MetadataStore.prototype._checkEntityType = function (entity) {
587
- if (entity.entityType)
588
- return;
589
- var typeName = entity.prototype._$typeName;
590
- if (!typeName) {
591
- throw new Error("This entity has not been registered. See the MetadataStore.registerEntityTypeCtor method");
592
- }
593
- // we know that it is an EntityType ( as opposed to a ComplexType)
594
- var entityType = this._getStructuralType(typeName);
595
- if (entityType) {
596
- entity.entityType = entityType;
597
- }
598
- };
599
- /** @hidden @internal */
600
- MetadataStore.__id = 0;
601
- /** @hidden @internal */
602
- MetadataStore.ANONTYPE_PREFIX = "_IB_";
603
- /** The version of any MetadataStores created by this class */
604
- MetadataStore.metadataVersion = '1.0.5';
605
- // needs to be made avail to dataService.xxx files
606
- MetadataStore.normalizeTypeName = core.memoize(function (rawTypeName) {
607
- return rawTypeName && MetadataStore.parseTypeName(rawTypeName).typeName;
608
- });
609
- return MetadataStore;
610
- }());
611
- export { MetadataStore };
612
- MetadataStore.prototype._$typeName = "MetadataStore";
613
- BreezeEvent.bubbleEvent(MetadataStore.prototype);
614
- function getTypesFromMap(typeMap) {
615
- var types = [];
616
- for (var key in typeMap) {
617
- var value = typeMap[key];
618
- // skip 'shortName' entries
619
- if (key === value.name) {
620
- types.push(typeMap[key]);
621
- }
622
- }
623
- return types;
624
- }
625
- function structuralTypeFromJson(metadataStore, json, allowMerge) {
626
- var typeName = qualifyTypeName(json.shortName, json.namespace);
627
- var stype = metadataStore._getStructuralType(typeName, true);
628
- if (stype) {
629
- if (allowMerge) {
630
- return mergeStructuralType(stype, json);
631
- }
632
- else {
633
- // allow it but don't replace anything.
634
- return stype;
635
- }
636
- }
637
- var config = {
638
- shortName: json.shortName,
639
- namespace: json.namespace,
640
- isAbstract: json.isAbstract,
641
- autoGeneratedKeyType: AutoGeneratedKeyType.fromName(json.autoGeneratedKeyType),
642
- defaultResourceName: json.defaultResourceName,
643
- custom: json.custom
644
- };
645
- stype = json.isComplexType ? new ComplexType(config) : new EntityType(config);
646
- // baseType may not have been imported yet so we need to defer handling this type until later.
647
- if (json.baseTypeName && stype instanceof EntityType) {
648
- stype.baseTypeName = json.baseTypeName;
649
- var baseEntityType = metadataStore._getStructuralType(json.baseTypeName, true);
650
- if (baseEntityType) {
651
- completeStructuralTypeFromJson(metadataStore, json, stype);
652
- }
653
- else {
654
- core.getArray(metadataStore._deferredTypes, json.baseTypeName).push({ json: json, stype: stype });
655
- }
656
- }
657
- else {
658
- completeStructuralTypeFromJson(metadataStore, json, stype);
659
- }
660
- // stype may or may not have been added to the metadataStore at this point.
661
- return stype;
662
- }
663
- function mergeStructuralType(stype, json) {
664
- if (json.custom) {
665
- stype.custom = json.custom;
666
- }
667
- mergeProps(stype, json.dataProperties);
668
- mergeProps(stype, json.navigationProperties);
669
- return stype;
670
- }
671
- function mergeProps(stype, jsonProps) {
672
- if (!jsonProps)
673
- return;
674
- jsonProps.forEach(function (jsonProp) {
675
- var propName = jsonProp.name;
676
- if (!propName) {
677
- if (jsonProp.nameOnServer) {
678
- propName = stype.metadataStore.namingConvention.serverPropertyNameToClient(jsonProp.nameOnServer, {});
679
- }
680
- else {
681
- // backslash-quote works around compiler bug
682
- var msg = "Unable to complete \'importMetadata\' - cannot locate a \'name\' or \'nameOnServer\' for one of the imported property nodes";
683
- throw new Error(msg);
684
- }
685
- }
686
- if (jsonProp.custom) {
687
- var prop = stype.getProperty(propName, true);
688
- prop.custom = jsonProp.custom;
689
- }
690
- });
691
- }
692
- function completeStructuralTypeFromJson(metadataStore, json, stype) {
693
- // validators from baseType work because validation walks thru base types
694
- // so no need to copy down.
695
- if (json.validators) {
696
- stype.validators = json.validators.map(Validator.fromJSON);
697
- }
698
- json.dataProperties.forEach(function (dp) {
699
- stype._addPropertyCore(DataProperty.fromJSON(dp));
700
- });
701
- var isEntityType = !json.isComplexType;
702
- if (isEntityType) {
703
- //noinspection JSHint
704
- json.navigationProperties && json.navigationProperties.forEach(function (np) {
705
- stype._addPropertyCore(NavigationProperty.fromJSON(np));
706
- });
707
- }
708
- metadataStore.addEntityType(stype);
709
- var deferredTypes = metadataStore._deferredTypes;
710
- var deferrals = deferredTypes[stype.name];
711
- if (deferrals) {
712
- deferrals.forEach(function (d) {
713
- completeStructuralTypeFromJson(metadataStore, d.json, d.stype);
714
- });
715
- delete deferredTypes[stype.name];
716
- }
717
- }
718
- function getQualifiedTypeName(metadataStore, structTypeName, throwIfNotFound) {
719
- if (isQualifiedTypeName(structTypeName))
720
- return structTypeName;
721
- var result = metadataStore._shortNameMap[structTypeName];
722
- if (!result && throwIfNotFound) {
723
- throw new Error("Unable to locate 'entityTypeName' of: " + structTypeName);
724
- }
725
- return result;
726
- }
727
- /** Container for all of the metadata about a specific type of Entity.
728
- **/
729
- var EntityType = /** @class */ (function () {
730
- /** EntityType constructor
731
- > let entityType = new EntityType( {
732
- > shortName: "person",
733
- > namespace: "myAppNamespace"
734
- > });
735
- @param config - Configuration settings or a MetadataStore. If this parameter is just a MetadataStore
736
- then what will be created is an 'anonymous' type that will never be communicated to or from the server. It is purely for
737
- client side use and will be given an automatically generated name. Normally, however, you will use a configuration object.
738
- **/
739
- function EntityType(config) {
740
- /** Always false for an EntityType. **/
741
- this.isComplexType = false;
742
- /**
743
- @deprecated Use [[getCtor]] instead.
744
- */
745
- this.getEntityCtor = this.getCtor;
746
- if (arguments.length > 1) {
747
- throw new Error("The EntityType ctor has a single argument that is either a 'MetadataStore' or a configuration object.");
748
- }
749
- // let etConfig = <EntityTypeConfig> <any> undefined;
750
- var etConfig = undefined;
751
- if (config._$typeName === "MetadataStore") {
752
- this.metadataStore = config;
753
- this.shortName = "Anon_" + (++EntityType.__nextAnonIx);
754
- this.namespace = "";
755
- this.isAnonymous = true;
756
- // etConfig = undefined;
757
- }
758
- else {
759
- etConfig = config;
760
- assertConfig(config)
761
- .whereParam("shortName").isNonEmptyString()
762
- .whereParam("namespace").isString().isOptional().withDefault("")
763
- .whereParam("baseTypeName").isString().isOptional()
764
- .whereParam("isAbstract").isBoolean().isOptional().withDefault(false)
765
- .whereParam("autoGeneratedKeyType").isEnumOf(AutoGeneratedKeyType).isOptional().withDefault(AutoGeneratedKeyType.None)
766
- .whereParam("defaultResourceName").isNonEmptyString().isOptional().withDefault(null)
767
- .whereParam("dataProperties").isOptional()
768
- .whereParam("navigationProperties").isOptional()
769
- .whereParam("serializerFn").isOptional().isFunction()
770
- .whereParam("custom").isOptional()
771
- .applyAll(this);
772
- }
773
- this.name = qualifyTypeName(this.shortName, this.namespace);
774
- // the defaultResourceName may also be set up either via metadata lookup or first query or via the 'setProperties' method
775
- this.dataProperties = [];
776
- this.navigationProperties = [];
777
- this.complexProperties = [];
778
- this.keyProperties = [];
779
- this.foreignKeyProperties = [];
780
- this.inverseForeignKeyProperties = [];
781
- this.concurrencyProperties = [];
782
- this.unmappedProperties = []; // will be updated later.
783
- this.validators = [];
784
- this.warnings = [];
785
- this._mappedPropertiesCount = 0;
786
- this.subtypes = [];
787
- // now process any data/nav props
788
- if (etConfig && etConfig.dataProperties) {
789
- addProperties(this, etConfig.dataProperties, DataProperty);
790
- }
791
- if (etConfig && etConfig.navigationProperties) {
792
- addProperties(this, etConfig.navigationProperties, NavigationProperty);
793
- }
794
- }
795
- /**
796
- General purpose property set method
797
- > // assume em1 is an EntityManager containing a number of existing entities.
798
- > let custType = em1.metadataStore.getEntityType("Customer");
799
- > custType.setProperties( {
800
- > autoGeneratedKeyType: AutoGeneratedKeyType.Identity;
801
- > defaultResourceName: "CustomersAndIncludedOrders"
802
- > )};
803
- @param config - a configuration object
804
- **/
805
- EntityType.prototype.setProperties = function (config) {
806
- assertConfig(config)
807
- .whereParam("autoGeneratedKeyType").isEnumOf(AutoGeneratedKeyType).isOptional()
808
- .whereParam("defaultResourceName").isString().isOptional()
809
- .whereParam("serializerFn").isFunction().isOptional()
810
- .whereParam("custom").isOptional()
811
- .applyAll(this);
812
- if (config.defaultResourceName) {
813
- this.defaultResourceName = config.defaultResourceName;
814
- }
815
- };
816
- /**
817
- Returns whether this type is a subtype of a specified type.
818
- **/
819
- EntityType.prototype.isSubtypeOf = function (entityType) {
820
- assertParam(entityType, "entityType").isInstanceOf(EntityType).check();
821
- var baseType = this;
822
- do {
823
- if (baseType === entityType)
824
- return true;
825
- baseType = baseType.baseEntityType;
826
- } while (baseType);
827
- return false;
828
- };
829
- /**
830
- Returns an array containing this type and any/all subtypes of this type down thru the hierarchy.
831
- **/
832
- EntityType.prototype.getSelfAndSubtypes = function () {
833
- var result = [this];
834
- this.subtypes.forEach(function (st) {
835
- var subtypes = st.getSelfAndSubtypes();
836
- result.push.apply(result, subtypes);
837
- });
838
- return result;
839
- };
840
- EntityType.prototype.getAllValidators = function () {
841
- var result = this.validators.slice(0);
842
- var bt = this.baseEntityType;
843
- while (bt) {
844
- result.push.apply(result, bt.validators);
845
- bt = bt.baseEntityType;
846
- }
847
- return result;
848
- };
849
- /**
850
- Adds a [[DataProperty]] or a [[NavigationProperty]] to this EntityType.
851
- > // assume myEntityType is a newly constructed EntityType.
852
- > myEntityType.addProperty(dataProperty1);
853
- > myEntityType.addProperty(dataProperty2);
854
- > myEntityType.addProperty(navigationProperty1);
855
- **/
856
- EntityType.prototype.addProperty = function (property) {
857
- assertParam(property, "property").isInstanceOf(DataProperty).or().isInstanceOf(NavigationProperty).check();
858
- // true is 2nd arg to force resolve of any navigation properties.
859
- var newprop = this._addPropertyCore(property, true);
860
- if (this.subtypes && this.subtypes.length) {
861
- var stype_1 = this;
862
- stype_1.getSelfAndSubtypes().forEach(function (st) {
863
- if (st !== stype_1) {
864
- if (property.isNavigationProperty) {
865
- st._addPropertyCore(new NavigationProperty(property), true);
866
- }
867
- else {
868
- st._addPropertyCore(new DataProperty(property), true);
869
- }
870
- }
871
- });
872
- }
873
- return newprop;
874
- };
875
- /** @hidden @internal */
876
- EntityType.prototype._updateFromBase = function (baseEntityType) {
877
- var _this = this;
878
- this.baseEntityType = baseEntityType;
879
- if (this.autoGeneratedKeyType === AutoGeneratedKeyType.None) {
880
- this.autoGeneratedKeyType = baseEntityType.autoGeneratedKeyType;
881
- }
882
- baseEntityType.dataProperties.forEach(function (dp) {
883
- var newDp = new DataProperty(dp);
884
- // don't need to copy validators becaue we will walk the hierarchy to find them
885
- newDp.validators = [];
886
- newDp.baseProperty = dp;
887
- _this._addPropertyCore(newDp);
888
- }, this);
889
- baseEntityType.navigationProperties.forEach(function (np) {
890
- var newNp = new NavigationProperty(np);
891
- // don't need to copy validators becaue we will walk the hierarchy to find them
892
- newNp.validators = [];
893
- newNp.baseProperty = np;
894
- _this._addPropertyCore(newNp);
895
- }, this);
896
- baseEntityType.subtypes.push(this);
897
- };
898
- /** @hidden @internal */
899
- EntityType.prototype._addPropertyCore = function (property, shouldResolve) {
900
- if (shouldResolve === void 0) { shouldResolve = false; }
901
- if (this.isFrozen) {
902
- throw new Error("The '" + this.name + "' EntityType/ComplexType has been frozen. You can only add properties to an EntityType/ComplexType before any instances of that type have been created and attached to an entityManager.");
903
- }
904
- var parentType = property.parentType;
905
- if (parentType) {
906
- if (parentType !== this) {
907
- throw new Error("This property: " + property.name + " has already been added to " + property.parentType.name);
908
- }
909
- else {
910
- // adding the same property more than once to the same entityType is just ignored.
911
- return;
912
- }
913
- }
914
- property.parentType = this;
915
- var ms = this.metadataStore;
916
- // if (property.isDataProperty) { // modified because doesn't act as a type guard
917
- if (property instanceof DataProperty) {
918
- this._addDataProperty(property);
919
- }
920
- else {
921
- this._addNavigationProperty(property);
922
- // metadataStore can be undefined if this entityType has not yet been added to a MetadataStore.
923
- if (shouldResolve && ms) {
924
- tryResolveNp(property, ms);
925
- }
926
- }
927
- // unmapped properties can be added AFTER entityType has already resolved all property names.
928
- if (ms && !(property.name && property.nameOnServer)) {
929
- updateClientServerNames(ms.namingConvention, property, "name");
930
- }
931
- // props can be added after entity prototype has already been wrapped.
932
- if (ms && this._extra) {
933
- if (this._extra.alreadyWrappedProps) {
934
- var proto_1 = this._ctor.prototype;
935
- config.interfaceRegistry.modelLibrary.getDefaultInstance().initializeEntityPrototype(proto_1);
936
- }
937
- }
938
- };
939
- /**
940
- Create a new entity of this type.
941
- > // assume em1 is an EntityManager containing a number of existing entities.
942
- > let custType = em1.metadataStore.getAsEntityType("Customer");
943
- > let cust1 = custType.createEntity();
944
- > em1.addEntity(cust1);
945
- @param initialValues- Configuration object of the properties to set immediately after creation.
946
- @return The new entity.
947
- **/
948
- EntityType.prototype.createEntity = function (initialValues) {
949
- // ignore the _$eref once the entity is attached to an entityManager.
950
- if (initialValues && initialValues._$eref && !initialValues._$eref.entityAspect.entityManager)
951
- return initialValues._$eref;
952
- var instance = this._createInstanceCore();
953
- if (initialValues) {
954
- // only assign an _eref if the object is fully "keyed"
955
- if (this.keyProperties.every(function (kp) {
956
- return initialValues[kp.name] != null;
957
- })) {
958
- initialValues._$eref = instance;
959
- }
960
- this._updateTargetFromRaw(instance, initialValues, getRawValueFromConfig);
961
- this.navigationProperties.forEach(function (np) {
962
- var relatedEntity;
963
- var val = initialValues[np.name];
964
- if (val != undefined) {
965
- var navEntityType_1 = np.entityType;
966
- if (np.isScalar) {
967
- relatedEntity = val.entityAspect ? val : navEntityType_1.createEntity(val);
968
- instance.setProperty(np.name, relatedEntity);
969
- }
970
- else {
971
- var relatedEntities_1 = instance.getProperty(np.name);
972
- val.forEach(function (v) {
973
- relatedEntity = v.entityAspect ? v : navEntityType_1.createEntity(v);
974
- relatedEntities_1.push(relatedEntity);
975
- });
976
- }
977
- }
978
- });
979
- }
980
- this._initializeInstance(instance);
981
- return instance;
982
- };
983
- /** @hidden @internal */
984
- EntityType.prototype._createInstanceCore = function () {
985
- var aCtor = this.getCtor();
986
- var instance = new aCtor();
987
- new EntityAspect(instance);
988
- return instance;
989
- };
990
- /** @hidden @internal */
991
- EntityType.prototype._initializeInstance = function (instance) {
992
- if (this.baseEntityType) {
993
- this.baseEntityType._initializeInstance(instance);
994
- }
995
- var initFn = this.initFn;
996
- if (initFn) {
997
- var fn = (typeof initFn === "string") ? instance[initFn] : initFn;
998
- fn(instance);
999
- }
1000
- this.complexProperties && this.complexProperties.forEach(function (cp) {
1001
- var complexType = cp.dataType;
1002
- var ctInstance = instance.getProperty(cp.name);
1003
- if (Array.isArray(ctInstance)) {
1004
- ctInstance.forEach(function (ctInst) {
1005
- complexType._initializeInstance(ctInst);
1006
- });
1007
- }
1008
- else {
1009
- complexType._initializeInstance(ctInstance);
1010
- }
1011
- });
1012
- // not needed for complexObjects
1013
- if (instance.entityAspect) {
1014
- instance.entityAspect._initialized = true;
1015
- }
1016
- };
1017
- /**
1018
- Returns the constructor for this EntityType.
1019
- @param forceRefresh - Whether to ignore any cached version of this constructor. (default == false)
1020
- @return The constructor for this EntityType.
1021
- **/
1022
- EntityType.prototype.getCtor = function (forceRefresh) {
1023
- if (forceRefresh === void 0) { forceRefresh = false; }
1024
- if (this._ctor && !forceRefresh)
1025
- return this._ctor;
1026
- var ctorRegistry = this.metadataStore._ctorRegistry;
1027
- var r = ctorRegistry[this.name] || ctorRegistry[this.shortName] || {};
1028
- var aCtor = r.ctor || this._ctor;
1029
- var ctorType = aCtor && aCtor.prototype && (aCtor.prototype.entityType || aCtor.prototype.complexType);
1030
- if (ctorType && ctorType.metadataStore !== this.metadataStore) {
1031
- // We can't risk a mismatch between the ctor and the type info in a specific metadatastore
1032
- // because modelLibraries rely on type info to intercept ctor properties
1033
- throw new Error("Cannot register the same constructor for " + this.name + " in different metadata stores. Please define a separate constructor for each metadata store.");
1034
- }
1035
- if (r.ctor && forceRefresh) {
1036
- this._extra = undefined;
1037
- }
1038
- if (!aCtor) {
1039
- var createCtor = config.interfaceRegistry.modelLibrary.getDefaultInstance().createCtor;
1040
- aCtor = createCtor ? createCtor(this) : createEmptyCtor(this);
1041
- }
1042
- this.initFn = r.initFn;
1043
- this.noTrackingFn = r.noTrackingFn;
1044
- aCtor.prototype._$typeName = this.name;
1045
- this._setCtor(aCtor);
1046
- return aCtor;
1047
- };
1048
- /** @hidden @internal */
1049
- // May make public later.
1050
- EntityType.prototype._setCtor = function (aCtor, interceptor) {
1051
- var instanceProto = aCtor.prototype;
1052
- // place for extra breeze related data
1053
- this._extra = this._extra || {};
1054
- var instance = new aCtor();
1055
- calcUnmappedProperties(this, instance);
1056
- if (this._$typeName === "EntityType") {
1057
- // insure that all of the properties are on the 'template' instance before watching the class.
1058
- instanceProto.entityType = this;
1059
- }
1060
- else {
1061
- instanceProto.complexType = this;
1062
- }
1063
- // defaultPropertyInterceptor is a 'global' (but internal to breeze) function;
1064
- instanceProto._$interceptor = interceptor || defaultPropertyInterceptor;
1065
- config.interfaceRegistry.modelLibrary.getDefaultInstance().initializeEntityPrototype(instanceProto);
1066
- this._ctor = aCtor;
1067
- };
1068
- /**
1069
- Adds either an entity or property level validator to this EntityType.
1070
- > // assume em1 is an EntityManager containing a number of existing entities.
1071
- > let custType = em1.metadataStore.getEntityType("Customer");
1072
- > let countryProp = custType.getProperty("Country");
1073
- > let valFn = function (v) {
1074
- > if (v == null) return true;
1075
- > return (core.stringStartsWith(v, "US"));
1076
- > };
1077
- > let countryValidator = new Validator("countryIsUS", valFn,
1078
- > { displayName: "Country", messageTemplate: "'%displayName%' must start with 'US'" });
1079
- > custType.addValidator(countryValidator, countryProp);
1080
-
1081
- This is the same as adding an entity level validator via the 'validators' property of DataProperty or NavigationProperty
1082
- > countryProp.validators.push(countryValidator);
1083
-
1084
- Entity level validators can also be added by omitting the 'property' parameter.
1085
- > custType.addValidator(someEntityLevelValidator);
1086
-
1087
- or
1088
- > custType.validators.push(someEntityLevelValidator);
1089
- @param validator - Validator to add.
1090
- @param property - Property to add this validator to. If omitted, the validator is assumed to be an
1091
- entity level validator and is added to the EntityType's 'validators'.
1092
- **/
1093
- EntityType.prototype.addValidator = function (validator, property) {
1094
- assertParam(validator, "validator").isInstanceOf(Validator).check();
1095
- assertParam(property, "property").isOptional().isString().or().isEntityProperty().check();
1096
- if (property != null) {
1097
- var prop = (typeof property === 'string') ? this.getProperty(property, true) : property;
1098
- prop.validators.push(validator);
1099
- }
1100
- else {
1101
- this.validators.push(validator);
1102
- }
1103
- };
1104
- /**
1105
- Returns all of the properties ( dataProperties and navigationProperties) for this EntityType.
1106
- > // assume em1 is an EntityManager containing a number of existing entities.
1107
- > let custType = em1.metadataStore.getEntityType("Customer");
1108
- > let arrayOfProps = custType.getProperties();
1109
- @return An array of Data and Navigation properties.
1110
- **/
1111
- EntityType.prototype.getProperties = function () {
1112
- return this.dataProperties.concat(this.navigationProperties);
1113
- };
1114
- /**
1115
- Returns all of the property names ( for both dataProperties and navigationProperties) for this EntityType.
1116
- > // assume em1 is an EntityManager containing a number of existing entities.
1117
- > let custType = em1.metadataStore.getEntityType("Customer");
1118
- > let arrayOfPropNames = custType.getPropertyNames();
1119
- **/
1120
- EntityType.prototype.getPropertyNames = function () {
1121
- return this.getProperties().map(core.pluck('name'));
1122
- };
1123
- /**
1124
- Returns a data property with the specified name or null.
1125
- > // assume em1 is an EntityManager containing a number of existing entities.
1126
- > let custType = em1.metadataStore.getEntityType("Customer");
1127
- > let customerNameDataProp = custType.getDataProperty("CustomerName");
1128
- @return A DataProperty or null if not found.
1129
- **/
1130
- EntityType.prototype.getDataProperty = function (propertyName) {
1131
- return core.arrayFirst(this.dataProperties, core.propEq('name', propertyName));
1132
- };
1133
- /**
1134
- Returns a navigation property with the specified name or null.
1135
- > // assume em1 is an EntityManager containing a number of existing entities.
1136
- > let custType = em1.metadataStore.getEntityType("Customer");
1137
- > let customerOrdersNavProp = custType.getDataProperty("Orders");
1138
- @return A NavigationProperty or null if not found.
1139
- **/
1140
- EntityType.prototype.getNavigationProperty = function (propertyName) {
1141
- return core.arrayFirst(this.navigationProperties, core.propEq('name', propertyName));
1142
- };
1143
- /**
1144
- Returns either a DataProperty or a NavigationProperty with the specified name or null.
1145
-
1146
- This method also accepts a '.' delimited property path and will return the 'property' at the
1147
- end of the path.
1148
- > let custType = em1.metadataStore.getEntityType("Customer");
1149
- > let companyNameProp = custType.getProperty("CompanyName");
1150
-
1151
- This method can also walk a property path to return a property
1152
- > let orderDetailType = em1.metadataStore.getEntityType("OrderDetail");
1153
- > let companyNameProp2 = orderDetailType.getProperty("Order.Customer.CompanyName");
1154
- > // companyNameProp === companyNameProp2
1155
- @param [throwIfNotFound=false] {Boolean} Whether to throw an exception if not found.
1156
- @return A DataProperty or NavigationProperty or null if not found.
1157
- **/
1158
- EntityType.prototype.getProperty = function (propertyPath, throwIfNotFound) {
1159
- if (throwIfNotFound === void 0) { throwIfNotFound = false; }
1160
- var props = this.getPropertiesOnPath(propertyPath, false, throwIfNotFound);
1161
- return (props && props.length > 0) ? props[props.length - 1] : null;
1162
- };
1163
- /** @hidden @internal */
1164
- // TODO: have this return empty array instead of null and fix consumers.
1165
- // TODO: think about renaming with '_' prefix.
1166
- EntityType.prototype.getPropertiesOnPath = function (propertyPath, useServerName, throwIfNotFound) {
1167
- if (throwIfNotFound === void 0) { throwIfNotFound = false; }
1168
- var propertyNames = (Array.isArray(propertyPath)) ? propertyPath : propertyPath.trim().split('.');
1169
- var ok = true;
1170
- var key = useServerName === true ? "nameOnServer" : useServerName === false ? "name" : null;
1171
- var parentType = this;
1172
- var getProps = function (propName) {
1173
- var fn = key === null ? core.propsEq("name", "nameOnServer", propName) : core.propEq(key, propName);
1174
- var prop = core.arrayFirst(parentType.getProperties(), fn);
1175
- if (prop) {
1176
- parentType = (prop instanceof NavigationProperty) ? prop.entityType : prop.dataType;
1177
- // parentType = prop.isNavigationProperty ? prop.entityType : prop.dataType;
1178
- }
1179
- else if (throwIfNotFound) {
1180
- throw new Error("unable to locate property: " + propName + " on entityType: " + parentType.name);
1181
- }
1182
- else {
1183
- ok = false;
1184
- }
1185
- return prop;
1186
- };
1187
- var props = propertyNames.map(getProps);
1188
- return ok ? props : null;
1189
- };
1190
- /** For use in pluggable adapters. */
1191
- // TODO: document use
1192
- EntityType.prototype.clientPropertyPathToServer = function (propertyPath, delimiter) {
1193
- if (delimiter === void 0) { delimiter = '.'; }
1194
- var propNames;
1195
- if (this.isAnonymous) {
1196
- var fn_1 = this.metadataStore.namingConvention.clientPropertyNameToServer;
1197
- propNames = propertyPath.split(".").map(function (propName) {
1198
- return fn_1(propName);
1199
- });
1200
- }
1201
- else {
1202
- var props = this.getPropertiesOnPath(propertyPath, false, true);
1203
- propNames = props.map(function (prop) { return prop.nameOnServer; });
1204
- }
1205
- return propNames.join(delimiter);
1206
- };
1207
- /** For use in pluggable adapters. */
1208
- // TODO: document use
1209
- EntityType.prototype.getEntityKeyFromRawEntity = function (rawEntity, rawValueFn) {
1210
- var keyValues = this.keyProperties.map(function (dp) {
1211
- var val = rawValueFn(rawEntity, dp);
1212
- return DataType.parseRawValue(val, dp.dataType);
1213
- });
1214
- return new EntityKey(this, keyValues);
1215
- };
1216
- /** @hidden @internal */
1217
- EntityType.prototype._updateTargetFromRaw = function (target, raw, rawValueFn) {
1218
- // called recursively for complex properties
1219
- this.dataProperties.forEach(function (dp) {
1220
- if (!dp.isSettable)
1221
- return;
1222
- var rawVal = rawValueFn(raw, dp);
1223
- if (rawVal === undefined)
1224
- return;
1225
- var dataType = dp.dataType; // this will be a complexType when dp is a complexProperty
1226
- var oldVal;
1227
- if (dp.isComplexProperty) {
1228
- var complexType_1 = dp.dataType;
1229
- if (rawVal === null)
1230
- return; // rawVal may be null in nosql dbs where it was never defined for the given row.
1231
- oldVal = target.getProperty(dp.name);
1232
- if (dp.isScalar) {
1233
- complexType_1._updateTargetFromRaw(oldVal, rawVal, rawValueFn);
1234
- }
1235
- else {
1236
- if (Array.isArray(rawVal)) {
1237
- var newVal = rawVal.map(function (rawCo) {
1238
- var newCo = complexType_1._createInstanceCore(target, dp);
1239
- complexType_1._updateTargetFromRaw(newCo, rawCo, rawValueFn);
1240
- complexType_1._initializeInstance(newCo);
1241
- return newCo;
1242
- });
1243
- if (!core.arrayEquals(oldVal, newVal, coEquals)) {
1244
- // clear the old array and push new objects into it.
1245
- oldVal.length = 0;
1246
- newVal.forEach(function (nv) {
1247
- oldVal.push(nv);
1248
- });
1249
- }
1250
- }
1251
- else {
1252
- oldVal.length = 0;
1253
- }
1254
- }
1255
- }
1256
- else {
1257
- if (dp.isScalar) {
1258
- var newVal = DataType.parseRawValue(rawVal, dataType);
1259
- target.setProperty(dp.name, newVal);
1260
- }
1261
- else {
1262
- oldVal = target.getProperty(dp.name);
1263
- if (Array.isArray(rawVal)) {
1264
- // need to compare values
1265
- var newVal = rawVal.map(function (rv) {
1266
- return DataType.parseRawValue(rv, dataType);
1267
- });
1268
- if (!core.arrayEquals(oldVal, newVal)) {
1269
- // clear the old array and push new objects into it.
1270
- oldVal.length = 0;
1271
- newVal.forEach(function (nv) {
1272
- oldVal.push(nv);
1273
- });
1274
- }
1275
- }
1276
- else {
1277
- oldVal.length = 0;
1278
- }
1279
- }
1280
- }
1281
- });
1282
- // if merging from an import then raw will have an entityAspect or a complexAspect
1283
- var rawAspect = raw.entityAspect || raw.complexAspect;
1284
- if (rawAspect) {
1285
- var targetAspect = EntityAspect.isEntity(target) ? target.entityAspect : target.complexAspect;
1286
- if (rawAspect.originalValuesMap) {
1287
- targetAspect.originalValues = rawAspect.originalValuesMap;
1288
- }
1289
- if (rawAspect.extraMetadata) {
1290
- targetAspect.extraMetadata = rawAspect.extraMetadata;
1291
- }
1292
- }
1293
- };
1294
- /**
1295
- Returns a string representation of this EntityType.
1296
- **/
1297
- EntityType.prototype.toString = function () {
1298
- return this.name;
1299
- };
1300
- EntityType.prototype.toJSON = function () {
1301
- return core.toJson(this, {
1302
- shortName: null,
1303
- namespace: null,
1304
- baseTypeName: null,
1305
- isAbstract: false,
1306
- autoGeneratedKeyType: null,
1307
- defaultResourceName: null,
1308
- dataProperties: localPropsOnly,
1309
- navigationProperties: localPropsOnly,
1310
- validators: null,
1311
- custom: null
1312
- });
1313
- };
1314
- /** @hidden @internal */
1315
- EntityType.prototype._updateNames = function (property) {
1316
- var nc = this.metadataStore.namingConvention;
1317
- updateClientServerNames(nc, property, "name");
1318
- if (property.isNavigationProperty) {
1319
- updateClientServerNames(nc, property, "foreignKeyNames");
1320
- updateClientServerNames(nc, property, "invForeignKeyNames");
1321
- // these will get set later via _updateNps
1322
- // this.inverse
1323
- // this.entityType
1324
- // this.relatedDataProperties
1325
- // dataProperty.relatedNavigationProperty
1326
- // dataProperty.inverseNavigationProperty
1327
- }
1328
- };
1329
- /** @hidden @internal */
1330
- EntityType.prototype._checkNavProperty = function (navigationProperty) {
1331
- // if (navigationProperty.isNavigationProperty) {
1332
- if (navigationProperty instanceof NavigationProperty) {
1333
- if (navigationProperty.parentType !== this) {
1334
- throw new Error(core.formatString("The navigationProperty '%1' is not a property of entity type '%2'", navigationProperty.name, this.name));
1335
- }
1336
- return navigationProperty;
1337
- }
1338
- if (typeof (navigationProperty) === 'string') {
1339
- var np = this.getProperty(navigationProperty);
1340
- // if (np && np.isNavigationProperty) return np;
1341
- if (np && np instanceof NavigationProperty)
1342
- return np;
1343
- }
1344
- throw new Error("The 'navigationProperty' parameter must either be a NavigationProperty or the name of a NavigationProperty");
1345
- };
1346
- /** @hidden @internal */
1347
- EntityType.prototype._addDataProperty = function (dp) {
1348
- this.dataProperties.push(dp);
1349
- if (dp.isPartOfKey) {
1350
- this.keyProperties.push(dp);
1351
- }
1352
- if (dp.isComplexProperty) {
1353
- this.complexProperties.push(dp);
1354
- }
1355
- if (dp.concurrencyMode && dp.concurrencyMode !== "None") {
1356
- this.concurrencyProperties.push(dp);
1357
- }
1358
- if (dp.isUnmapped) {
1359
- this.unmappedProperties.push(dp);
1360
- }
1361
- };
1362
- /** @hidden @internal */
1363
- EntityType.prototype._addNavigationProperty = function (np) {
1364
- this.navigationProperties.push(np);
1365
- if (!isQualifiedTypeName(np.entityTypeName)) {
1366
- np.entityTypeName = qualifyTypeName(np.entityTypeName, this.namespace);
1367
- }
1368
- };
1369
- /** @hidden @internal */
1370
- EntityType.prototype._updateCps = function () {
1371
- var metadataStore = this.metadataStore;
1372
- var incompleteTypeMap = metadataStore._incompleteComplexTypeMap;
1373
- this.complexProperties.forEach(function (cp) {
1374
- if (cp.complexType)
1375
- return;
1376
- if (!resolveCp(cp, metadataStore)) {
1377
- core.getArray(incompleteTypeMap, cp.complexTypeName).push(cp);
1378
- }
1379
- });
1380
- if (this.isComplexType) {
1381
- (incompleteTypeMap[this.name] || []).forEach(function (cp) {
1382
- resolveCp(cp, metadataStore);
1383
- });
1384
- delete incompleteTypeMap[this.name];
1385
- }
1386
- };
1387
- /** @hidden @internal */
1388
- EntityType.prototype._updateNps = function () {
1389
- var metadataStore = this.metadataStore;
1390
- // resolve all navProps for this entityType
1391
- this.navigationProperties.forEach(function (np) {
1392
- tryResolveNp(np, metadataStore);
1393
- });
1394
- var incompleteTypeMap = metadataStore._incompleteTypeMap;
1395
- // next resolve all navProp that point to this entityType.
1396
- (incompleteTypeMap[this.name] || []).forEach(function (np) {
1397
- tryResolveNp(np, metadataStore);
1398
- });
1399
- // every navProp that pointed to this type should now be resolved
1400
- delete incompleteTypeMap[this.name];
1401
- };
1402
- /** @hidden @internal */
1403
- EntityType.__nextAnonIx = 0;
1404
- /** @hidden @internal */
1405
- EntityType.qualifyTypeName = qualifyTypeName;
1406
- return EntityType;
1407
- }());
1408
- export { EntityType };
1409
- EntityType.prototype._$typeName = "EntityType";
1410
- function getRawValueFromConfig(rawEntity, dp) {
1411
- // 'true' fork can happen if an initializer contains an actaul instance of an already created complex object.
1412
- return (rawEntity.entityAspect || rawEntity.complexAspect) ? rawEntity.getProperty(dp.name) : rawEntity[dp.name];
1413
- }
1414
- function updateClientServerNames(nc, parent, clientPropName) {
1415
- var serverPropName = clientPropName + "OnServer";
1416
- var clientName = parent[clientPropName];
1417
- if (clientName && clientName.length) {
1418
- // if (parent.isUnmapped) return;
1419
- var serverNames = core.toArray(clientName).map(function (cName) {
1420
- var sName = nc.clientPropertyNameToServer(cName, parent);
1421
- var testName = nc.serverPropertyNameToClient(sName, parent);
1422
- if (cName !== testName) {
1423
- throw new Error("NamingConvention for this client property name does not roundtrip properly:" + cName + "-->" + testName);
1424
- }
1425
- return sName;
1426
- });
1427
- parent[serverPropName] = Array.isArray(clientName) ? serverNames : serverNames[0];
1428
- }
1429
- else {
1430
- var serverName = parent[serverPropName];
1431
- if ((!serverName) || serverName.length === 0)
1432
- return;
1433
- var clientNames = core.toArray(serverName).map(function (sName) {
1434
- var cName = nc.serverPropertyNameToClient(sName, parent);
1435
- var testName = nc.clientPropertyNameToServer(cName, parent);
1436
- if (sName !== testName) {
1437
- throw new Error("NamingConvention for this server property name does not roundtrip properly:" + sName + "-->" + testName);
1438
- }
1439
- return cName;
1440
- });
1441
- parent[clientPropName] = Array.isArray(serverName) ? clientNames : clientNames[0];
1442
- }
1443
- }
1444
- function createEmptyCtor(type) {
1445
- if (config.noEval) {
1446
- var Entity = function () { };
1447
- return Entity;
1448
- }
1449
- else {
1450
- var name_1 = type.name.replace(/\W/g, '_');
1451
- return Function('return function ' + name_1 + '(){}')();
1452
- }
1453
- }
1454
- function coEquals(co1, co2) {
1455
- var complexType = co1.complexAspect.parentProperty.dataType;
1456
- var dataProps = complexType.dataProperties;
1457
- var areEqual = dataProps.every(function (dp) {
1458
- if (!dp.isSettable)
1459
- return true;
1460
- var v1 = co1.getProperty(dp.name);
1461
- var v2 = co2.getProperty(dp.name);
1462
- if (dp.isComplexProperty && dp.isScalar) {
1463
- return coEquals(v1, v2);
1464
- }
1465
- else if (dp.isComplexProperty && !dp.isScalar) {
1466
- return core.arrayEquals(v1, v2, coEquals);
1467
- }
1468
- else {
1469
- var dataType = dp.dataType; // this will be a complexType when dp is a complexProperty
1470
- return (v1 === v2 || (dataType && dataType.normalize && v1 && v2 && dataType.normalize(v1) === dataType.normalize(v2)));
1471
- }
1472
- });
1473
- return areEqual;
1474
- }
1475
- function localPropsOnly(props) {
1476
- return props.filter(function (prop) {
1477
- return prop.baseProperty == null;
1478
- });
1479
- }
1480
- function resolveCp(cp, metadataStore) {
1481
- var complexType = metadataStore._getStructuralType(cp.complexTypeName, true);
1482
- if (!complexType)
1483
- return false;
1484
- if (!(complexType instanceof ComplexType)) {
1485
- throw new Error("Unable to resolve ComplexType with the name: " + cp.complexTypeName + " for the property: " + cp.name);
1486
- }
1487
- cp.dataType = complexType;
1488
- cp.defaultValue = null;
1489
- return true;
1490
- }
1491
- function tryResolveNp(np, metadataStore) {
1492
- if (np.entityType)
1493
- return true;
1494
- var entityType = metadataStore._getStructuralType(np.entityTypeName, true);
1495
- if (entityType) {
1496
- np.entityType = entityType;
1497
- np._resolveNp();
1498
- // don't bother removing - _updateNps will do it later.
1499
- // __arrayRemoveItem(incompleteNps, np, false);
1500
- }
1501
- else {
1502
- var incompleteNps = core.getArray(metadataStore._incompleteTypeMap, np.entityTypeName);
1503
- core.arrayAddItemUnique(incompleteNps, np);
1504
- }
1505
- return !!entityType;
1506
- }
1507
- function calcUnmappedProperties(stype, instance) {
1508
- var metadataPropNames = stype.getPropertyNames();
1509
- var modelLib = config.interfaceRegistry.modelLibrary.getDefaultInstance();
1510
- var trackablePropNames = modelLib.getTrackablePropertyNames(instance);
1511
- trackablePropNames.forEach(function (pn) {
1512
- if (metadataPropNames.indexOf(pn) === -1) {
1513
- var val = instance[pn];
1514
- try {
1515
- if (typeof val === "function")
1516
- val = val();
1517
- }
1518
- catch (e) {
1519
- }
1520
- var dt = DataType.fromValue(val);
1521
- var newProp_1 = new DataProperty({
1522
- name: pn,
1523
- dataType: dt,
1524
- isNullable: true,
1525
- isUnmapped: true
1526
- });
1527
- newProp_1.isSettable = core.isSettable(instance, pn);
1528
- if (stype instanceof EntityType && stype.subtypes != null && stype.subtypes.length) {
1529
- stype.getSelfAndSubtypes().forEach(function (st) {
1530
- st._addPropertyCore(new DataProperty(newProp_1));
1531
- });
1532
- }
1533
- else {
1534
- stype._addPropertyCore(newProp_1);
1535
- }
1536
- }
1537
- });
1538
- }
1539
- /** Container for all of the metadata about a specific type of Complex object.
1540
- > let complexType = new ComplexType( {
1541
- > shortName: "address",
1542
- > namespace: "myAppNamespace"
1543
- > });
1544
- @param config - Configuration settings
1545
- **/
1546
- var ComplexType = /** @class */ (function () {
1547
- function ComplexType(config) {
1548
- /** For polymorphic purpose only - always true here */
1549
- this.isComplexType = true;
1550
- // copy entityType methods onto complexType
1551
- /** See [[EntityType.getCtor]] */
1552
- this.getCtor = EntityType.prototype.getCtor;
1553
- // note the name change.
1554
- this.createInstance = EntityType.prototype.createEntity;
1555
- /** See [EntityType.addValidator] */
1556
- this.addValidator = EntityType.prototype.addValidator;
1557
- this.getProperty = EntityType.prototype.getProperty;
1558
- this.getPropertiesOnPath = EntityType.prototype.getPropertiesOnPath;
1559
- this.getPropertyNames = EntityType.prototype.getPropertyNames;
1560
- /** @hidden @internal */
1561
- this._addPropertyCore = EntityType.prototype._addPropertyCore;
1562
- /** @hidden @internal */
1563
- this._addDataProperty = EntityType.prototype._addDataProperty;
1564
- /** @hidden @internal */
1565
- this._updateNames = EntityType.prototype._updateNames;
1566
- /** @hidden @internal */
1567
- this._updateCps = EntityType.prototype._updateCps;
1568
- /** @hidden @internal */
1569
- this._initializeInstance = EntityType.prototype._initializeInstance;
1570
- /** @hidden @internal */
1571
- this._updateTargetFromRaw = EntityType.prototype._updateTargetFromRaw;
1572
- /** @hidden @internal */
1573
- this._setCtor = EntityType.prototype._setCtor;
1574
- if (arguments.length > 1) {
1575
- throw new Error("The ComplexType ctor has a single argument that is a configuration object.");
1576
- }
1577
- assertConfig(config)
1578
- .whereParam("shortName").isNonEmptyString()
1579
- .whereParam("namespace").isString().isOptional().withDefault("")
1580
- .whereParam("dataProperties").isOptional()
1581
- .whereParam("isComplexType").isOptional().isBoolean() // needed because this ctor can get called from the addEntityType method which needs the isComplexType prop
1582
- .whereParam("custom").isOptional()
1583
- .applyAll(this);
1584
- this.name = qualifyTypeName(this.shortName, this.namespace);
1585
- this.isComplexType = true;
1586
- this.dataProperties = [];
1587
- this.complexProperties = [];
1588
- this.validators = [];
1589
- this.concurrencyProperties = [];
1590
- this.unmappedProperties = [];
1591
- this._mappedPropertiesCount = 0;
1592
- // keyProperties and navigationProperties are not used on complexTypes - but here to allow sharing of code between EntityType and ComplexType.
1593
- this.navigationProperties = [];
1594
- this.keyProperties = []; // may be used later to enforce uniqueness on arrays of complextypes.
1595
- if (config.dataProperties) {
1596
- addProperties(this, config.dataProperties, DataProperty);
1597
- }
1598
- }
1599
- /**
1600
- General purpose property set method
1601
- > // assume em1 is an EntityManager
1602
- > let addresstType = em1.metadataStore.getEntityType("Address");
1603
- > addressType.setProperties( {
1604
- > custom: { foo: 7, bar: "test" }
1605
- > });
1606
- @param config - Custom config object
1607
- @param config.custom - {Object}
1608
- **/
1609
- ComplexType.prototype.setProperties = function (config) {
1610
- assertConfig(config)
1611
- .whereParam("custom").isOptional()
1612
- .applyAll(this);
1613
- };
1614
- ComplexType.prototype.getAllValidators = function () {
1615
- // ComplexType inheritance is not YET supported.
1616
- return this.validators;
1617
- };
1618
- /** @hidden @internal */
1619
- ComplexType.prototype._createInstanceCore = function (parent, parentProperty) {
1620
- var aCtor = this.getCtor();
1621
- var instance = new aCtor();
1622
- new ComplexAspect(instance, parent, parentProperty);
1623
- // initialization occurs during either attach or in createInstance call.
1624
- return instance;
1625
- };
1626
- ComplexType.prototype.addProperty = function (dataProperty) {
1627
- assertParam(dataProperty, "dataProperty").isInstanceOf(DataProperty).check();
1628
- return this._addPropertyCore(dataProperty);
1629
- };
1630
- ComplexType.prototype.getProperties = function () {
1631
- return this.dataProperties;
1632
- };
1633
- ComplexType.prototype.toJSON = function () {
1634
- return core.toJson(this, {
1635
- shortName: null,
1636
- namespace: null,
1637
- isComplexType: null,
1638
- dataProperties: null,
1639
- validators: null,
1640
- custom: null
1641
- });
1642
- };
1643
- return ComplexType;
1644
- }());
1645
- export { ComplexType };
1646
- ComplexType.prototype._$typeName = "ComplexType";
1647
- /** Creates an instance of this complexType */
1648
- ComplexType.prototype.createInstance = EntityType.prototype.createEntity;
1649
- /**
1650
- A DataProperty describes the metadata for a single property of an [[EntityType]] that contains simple data.
1651
-
1652
- Instances of the DataProperty class are constructed automatically during Metadata retrieval. However it is also possible to construct them
1653
- directly via the constructor.
1654
- **/
1655
- var DataProperty = /** @class */ (function () {
1656
- /** DataProperty constructor
1657
- > let lastNameProp = new DataProperty( {
1658
- > name: "lastName",
1659
- > dataType: DataType.String,
1660
- > isNullable: true,
1661
- > maxLength: 20
1662
- > });
1663
- > // assuming personEntityType is a newly constructed EntityType
1664
- > personEntityType.addProperty(lastNameProperty);
1665
- @param config - A configuration Object or a DataProperty
1666
- */
1667
- function DataProperty(config) {
1668
- /** Is this a DataProperty? - always true here. Allows polymorphic treatment of DataProperties and NavigationProperties. __Read Only__ */
1669
- this.isDataProperty = true;
1670
- /** Is this a NavigationProperty? - always false here. Allows polymorphic treatment of DataProperties and NavigationProperties. __Read Only__ */
1671
- this.isNavigationProperty = false;
1672
- assertConfig(config)
1673
- .whereParam("name").isString().isOptional()
1674
- .whereParam("nameOnServer").isString().isOptional()
1675
- .whereParam("dataType").isEnumOf(DataType).isOptional().or().isString().or().isInstanceOf(ComplexType)
1676
- .whereParam("complexTypeName").isOptional()
1677
- .whereParam("isNullable").isBoolean().isOptional().withDefault(true)
1678
- .whereParam("isScalar").isOptional().withDefault(true) // will be false for some NoSQL databases.
1679
- .whereParam("defaultValue").isOptional()
1680
- .whereParam("isPartOfKey").isBoolean().isOptional()
1681
- .whereParam("isUnmapped").isBoolean().isOptional()
1682
- .whereParam("isSettable").isBoolean().isOptional().withDefault(true)
1683
- .whereParam("concurrencyMode").isString().isOptional()
1684
- .whereParam("maxLength").isNumber().isOptional()
1685
- .whereParam("validators").isInstanceOf(Validator).isArray().isOptional().withDefault([])
1686
- .whereParam("displayName").isOptional()
1687
- .whereParam("enumType").isOptional()
1688
- .whereParam("rawTypeName").isOptional() // occurs with undefined datatypes
1689
- .whereParam("custom").isOptional()
1690
- .applyAll(this);
1691
- var hasName = !!(this.name || this.nameOnServer);
1692
- if (!hasName) {
1693
- throw new Error("A DataProperty must be instantiated with either a 'name' or a 'nameOnServer' property");
1694
- }
1695
- // name/nameOnServer is resolved later when a metadataStore is available.
1696
- if (this.complexTypeName) {
1697
- this.isComplexProperty = true;
1698
- // this.dataType = null; // TODO: would like to remove this line because dataType will be set later.
1699
- }
1700
- else if (typeof (this.dataType) === "string") {
1701
- var dt = DataType.fromName(this.dataType);
1702
- if (!dt) {
1703
- throw new Error("Unable to find a DataType enumeration by the name of: " + this.dataType);
1704
- }
1705
- this.dataType = dt;
1706
- }
1707
- else if (!this.dataType) {
1708
- this.dataType = DataType.String;
1709
- }
1710
- // == as opposed to === is deliberate here.
1711
- if (this.defaultValue == null) {
1712
- if (this.isNullable) {
1713
- this.defaultValue = null;
1714
- }
1715
- else {
1716
- if (this.isComplexProperty) {
1717
- // what to do? - shouldn't happen from EF - but otherwise ???
1718
- }
1719
- else if (this.dataType === DataType.Binary) {
1720
- this.defaultValue = "AAAAAAAAJ3U="; // hack for all binary fields but value is specifically valid for timestamp fields - arbitrary valid 8 byte base64 value.
1721
- }
1722
- else {
1723
- this.defaultValue = this.dataType.defaultValue;
1724
- var msg = "A nonnullable DataProperty cannot have a null defaultValue. Name: " + (this.name || this.nameOnServer);
1725
- if (this.defaultValue === null) {
1726
- throw new Error(msg); // if defaultValue is explicity set to null, that's an error
1727
- }
1728
- else if (this.defaultValue == null) {
1729
- console.warn(msg); // if defaultValue is not set, that's a warning
1730
- }
1731
- }
1732
- }
1733
- }
1734
- else if (this.dataType.isNumeric) {
1735
- // in case the defaultValue comes in as a string ( which it does in EF6).
1736
- if (typeof (this.defaultValue) === "string") {
1737
- this.defaultValue = parseFloat(this.defaultValue);
1738
- }
1739
- }
1740
- if (this.isComplexProperty) {
1741
- this.isScalar = this.isScalar == null || this.isScalar === true;
1742
- }
1743
- }
1744
- DataProperty.getRawValueFromServer = function (rawEntity, dp) {
1745
- if (dp.isUnmapped) {
1746
- return rawEntity[dp.nameOnServer || dp.name];
1747
- }
1748
- else {
1749
- var val = rawEntity[dp.nameOnServer];
1750
- return val !== undefined ? val : dp.defaultValue;
1751
- }
1752
- };
1753
- DataProperty.getRawValueFromClient = function (rawEntity, dp) {
1754
- var val = rawEntity[dp.name];
1755
- return val !== undefined ? val : dp.defaultValue;
1756
- };
1757
- DataProperty.prototype.resolveProperty = function (propName) {
1758
- var result = this[propName];
1759
- var baseProp = this.baseProperty;
1760
- while (result == undefined && baseProp != null) {
1761
- result = baseProp[propName];
1762
- baseProp = baseProp.baseProperty;
1763
- }
1764
- return result;
1765
- };
1766
- DataProperty.prototype.formatName = function () {
1767
- return this.parentType.name + "--" + this.name;
1768
- };
1769
- /**
1770
- General purpose property set method
1771
- > // assume em1 is an EntityManager
1772
- > let prop = myEntityType.getProperty("myProperty");
1773
- > prop.setProperties( {
1774
- > custom: { foo: 7, bar: "test" }
1775
- > });
1776
- @param config - A configuration object.
1777
- **/
1778
- DataProperty.prototype.setProperties = function (config) {
1779
- assertConfig(config)
1780
- .whereParam("displayName").isOptional()
1781
- .whereParam("custom").isOptional()
1782
- .applyAll(this);
1783
- };
1784
- DataProperty.prototype.getAllValidators = function () {
1785
- var validators = this.validators.slice(0);
1786
- var baseProp = this.baseProperty;
1787
- while (baseProp) {
1788
- validators.push.apply(validators, baseProp.validators);
1789
- baseProp = baseProp.baseProperty;
1790
- }
1791
- return validators;
1792
- };
1793
- DataProperty.prototype.toJSON = function () {
1794
- // do not serialize dataTypes that are complexTypes
1795
- return core.toJson(this, {
1796
- name: null,
1797
- dataType: function (v) {
1798
- return (v && v instanceof DataType) ? v.name : undefined;
1799
- },
1800
- complexTypeName: null,
1801
- isNullable: true,
1802
- defaultValue: null,
1803
- isPartOfKey: false,
1804
- isUnmapped: false,
1805
- isSettable: true,
1806
- concurrencyMode: null,
1807
- maxLength: null,
1808
- validators: null,
1809
- displayName: null,
1810
- enumType: null,
1811
- rawTypeName: null,
1812
- isScalar: true,
1813
- custom: null
1814
- });
1815
- };
1816
- DataProperty.fromJSON = function (json) {
1817
- json.dataType = DataType.fromName(json.dataType);
1818
- // Parse default value into correct data type. (dateTime instances require extra work to deserialize properly.)
1819
- if (json.defaultValue && json.dataType && json.dataType.parse) {
1820
- json.defaultValue = json.dataType.parse(json.defaultValue, typeof json.defaultValue);
1821
- }
1822
- if (json.validators) {
1823
- json.validators = json.validators.map(Validator.fromJSON);
1824
- }
1825
- return new DataProperty(json);
1826
- };
1827
- return DataProperty;
1828
- }());
1829
- export { DataProperty };
1830
- DataProperty.prototype._$typeName = "DataProperty";
1831
- /** A NavigationProperty describes the metadata for a single property of an [[EntityType]] that return instances of other EntityTypes.
1832
-
1833
- Instances of the NavigationProperty class are constructed automatically during Metadata retrieval. However it is also possible to construct them
1834
- directly via the constructor.
1835
- **/
1836
- var NavigationProperty = /** @class */ (function () {
1837
- /** NavigationProperty constructor
1838
- > let homeAddressProp = new NavigationProperty( {
1839
- > name: "homeAddress",
1840
- > entityTypeName: "Address:#myNamespace",
1841
- > isScalar: true,
1842
- > associationName: "address_person",
1843
- > foreignKeyNames: ["homeAddressId"]
1844
- > });
1845
- > let homeAddressIdProp = new DataProperty( {
1846
- > name: "homeAddressId"
1847
- > dataType: DataType.Integer
1848
- > });
1849
- > // assuming personEntityType is a newly constructed EntityType
1850
- > personEntityType.addProperty(homeAddressProp);
1851
- > personEntityType.addProperty(homeAddressIdProp);
1852
- @param config - A configuration object.
1853
- **/
1854
- function NavigationProperty(config) {
1855
- /** Is this a DataProperty? - always false here
1856
- Allows polymorphic treatment of DataProperties and NavigationProperties. __Read Only__ */
1857
- this.isDataProperty = false;
1858
- /** Is this a NavigationProperty? - always true here
1859
- Allows polymorphic treatment of DataProperties and NavigationProperties. __Read Only__ */
1860
- this.isNavigationProperty = true;
1861
- this.formatName = DataProperty.prototype.formatName;
1862
- this.getAllValidators = DataProperty.prototype.getAllValidators;
1863
- this.resolveProperty = DataProperty.prototype.resolveProperty;
1864
- assertConfig(config)
1865
- .whereParam("name").isString().isOptional()
1866
- .whereParam("nameOnServer").isString().isOptional()
1867
- .whereParam("entityTypeName").isString()
1868
- .whereParam("isScalar").isBoolean().isOptional().withDefault(true)
1869
- .whereParam("associationName").isString().isOptional()
1870
- .whereParam("foreignKeyNames").isArray().isString().isOptional().withDefault([])
1871
- .whereParam("foreignKeyNamesOnServer").isArray().isString().isOptional().withDefault([])
1872
- .whereParam("invForeignKeyNames").isArray().isString().isOptional().withDefault([])
1873
- .whereParam("invForeignKeyNamesOnServer").isArray().isString().isOptional().withDefault([])
1874
- .whereParam("validators").isInstanceOf(Validator).isArray().isOptional().withDefault([])
1875
- .whereParam("displayName").isOptional()
1876
- .whereParam("custom").isOptional()
1877
- .applyAll(this);
1878
- var hasName = !!(this.name || this.nameOnServer);
1879
- if (!hasName) {
1880
- throw new Error("A Navigation property must be instantiated with either a 'name' or a 'nameOnServer' property");
1881
- }
1882
- }
1883
- /**
1884
- General purpose property set method
1885
- > // assume myEntityType is an EntityType
1886
- > let prop = myEntityType.getProperty("myProperty");
1887
- > prop.setProperties( {
1888
- > custom: { foo: 7, bar: "test" }
1889
- > });
1890
- @param config - A config object
1891
- **/
1892
- // TODO: create an interface for this.
1893
- NavigationProperty.prototype.setProperties = function (config) {
1894
- if (!this.parentType) {
1895
- throw new Error("Cannot call NavigationProperty.setProperties until the parent EntityType of the NavigationProperty has been set.");
1896
- }
1897
- var inverse = config.inverse;
1898
- if (inverse)
1899
- delete config.inverse;
1900
- assertConfig(config)
1901
- .whereParam("displayName").isOptional()
1902
- .whereParam("foreignKeyNames").isArray().isString().isOptional().withDefault([])
1903
- .whereParam("invForeignKeyNames").isArray().isString().isOptional().withDefault([])
1904
- .whereParam("custom").isOptional()
1905
- .applyAll(this);
1906
- this.parentType._updateNames(this);
1907
- this._resolveNp();
1908
- if (inverse) {
1909
- this.setInverse(inverse);
1910
- }
1911
- };
1912
- Object.defineProperty(NavigationProperty.prototype, "inverse", {
1913
- /** The inverse of this NavigationProperty. The NavigationProperty that represents a navigation in the opposite direction
1914
- to this NavigationProperty. May be undefined for a undirectional NavigationProperty. __Read Only__ */
1915
- get: function () {
1916
- return this.getInverse();
1917
- },
1918
- enumerable: true,
1919
- configurable: true
1920
- });
1921
- /** @hidden @internal */
1922
- NavigationProperty.prototype.getInverse = function () {
1923
- var np = this;
1924
- while (!np._inverse && np.baseProperty) {
1925
- np = np.baseProperty;
1926
- }
1927
- return np._inverse;
1928
- };
1929
- NavigationProperty.prototype.setInverse = function (inverseNp) {
1930
- // let invNp: NavigationProperty;
1931
- var invNp = (inverseNp instanceof NavigationProperty) ? inverseNp : this.entityType.getNavigationProperty(inverseNp);
1932
- if (!invNp) {
1933
- throw throwSetInverseError(this, "Unable to find inverse property: " + inverseNp);
1934
- }
1935
- if (this._inverse || invNp._inverse) {
1936
- throwSetInverseError(this, "It has already been set on one side or the other.");
1937
- }
1938
- if (invNp.entityType !== this.parentType) {
1939
- throwSetInverseError(this, invNp.formatName + " is not a valid inverse property for this.");
1940
- }
1941
- if (this.associationName) {
1942
- invNp.associationName = this.associationName;
1943
- }
1944
- else {
1945
- if (!invNp.associationName) {
1946
- invNp.associationName = this.formatName() + "_" + invNp.formatName();
1947
- }
1948
- this.associationName = invNp.associationName;
1949
- }
1950
- this._resolveNp();
1951
- invNp._resolveNp();
1952
- };
1953
- // // In progress - will be used for manual metadata config
1954
- // createInverse(config: any) {
1955
- // if (!this.entityType) {
1956
- // throwCreateInverseError(this, "has not yet been defined.");
1957
- // }
1958
- // if (this.entityType.isFrozen) {
1959
- // throwCreateInverseError(this, "is frozen.");
1960
- // }
1961
- // let metadataStore = this.entityType.metadataStore;
1962
- // if (metadataStore == null) {
1963
- // throwCreateInverseError(this, "has not yet been added to the metadataStore.");
1964
- // }
1965
- // config.entityTypeName = this.parentEntityType.name;
1966
- // config.associationName = this.associationName;
1967
- // let invNp = new NavigationProperty(config);
1968
- // this.parentEntityType.addNavigationProperty(invNp);
1969
- // return invNp;
1970
- // };
1971
- NavigationProperty.prototype.toJSON = function () {
1972
- return core.toJson(this, {
1973
- name: null,
1974
- entityTypeName: null,
1975
- isScalar: null,
1976
- associationName: null,
1977
- validators: null,
1978
- displayName: null,
1979
- foreignKeyNames: null,
1980
- invForeignKeyNames: null,
1981
- custom: null
1982
- });
1983
- };
1984
- NavigationProperty.fromJSON = function (json) {
1985
- if (json.validators) {
1986
- json.validators = json.validators.map(Validator.fromJSON);
1987
- }
1988
- return new NavigationProperty(json);
1989
- };
1990
- /** @hidden @internal */
1991
- NavigationProperty.prototype._resolveNp = function () {
1992
- var np = this;
1993
- var entityType = np.entityType;
1994
- var invNp = core.arrayFirst(entityType.navigationProperties, function (altNp) {
1995
- // Can't do this because of possibility of comparing a base class np with a subclass altNp.
1996
- // return altNp.associationName === np.associationName
1997
- // && altNp !== np;
1998
- // So use this instead.
1999
- return altNp.associationName === np.associationName &&
2000
- (altNp.name !== np.name || altNp.entityTypeName !== np.entityTypeName);
2001
- });
2002
- np._inverse = invNp || undefined;
2003
- //if (invNp && invNp.inverse == null) {
2004
- // invNp._resolveNp();
2005
- //}
2006
- if (!invNp) {
2007
- // unidirectional 1-n relationship
2008
- np.invForeignKeyNames.forEach(function (invFkName) {
2009
- var fkProp = entityType.getDataProperty(invFkName);
2010
- if (fkProp == null) {
2011
- throw new Error("EntityType '" + np.entityTypeName + "' has no foreign key matching '" + invFkName + "'");
2012
- }
2013
- var invEntityType = np.parentType;
2014
- invNp = core.arrayFirst(invEntityType.navigationProperties, function (np2) {
2015
- return np2.invForeignKeyNames && np2.invForeignKeyNames.indexOf(fkProp.name) >= 0 && np2.entityType === fkProp.parentType;
2016
- });
2017
- fkProp.inverseNavigationProperty = invNp || undefined;
2018
- core.arrayAddItemUnique(entityType.foreignKeyProperties, fkProp);
2019
- });
2020
- }
2021
- resolveRelated(np);
2022
- };
2023
- return NavigationProperty;
2024
- }());
2025
- export { NavigationProperty };
2026
- NavigationProperty.prototype._$typeName = "NavigationProperty";
2027
- function throwSetInverseError(np, message) {
2028
- throw new Error("Cannot set the inverse property for: " + np.formatName() + ". " + message);
2029
- }
2030
- // Not current used.
2031
- // function throwCreateInverseError(np: NavigationProperty, message: string) {
2032
- // throw new Error("Cannot create inverse for: " + np.formatName() + ". The entityType for this navigation property " + message);
2033
- // }
2034
- // sets navigation property: relatedDataProperties and dataProperty: relatedNavigationProperty
2035
- function resolveRelated(np) {
2036
- var fkNames = np.foreignKeyNames;
2037
- if (fkNames.length === 0)
2038
- return;
2039
- var parentEntityType = np.parentType;
2040
- var fkProps = fkNames.map(function (fkName) {
2041
- return parentEntityType.getDataProperty(fkName);
2042
- });
2043
- var fkPropCollection = parentEntityType.foreignKeyProperties;
2044
- fkProps.forEach(function (dp) {
2045
- core.arrayAddItemUnique(fkPropCollection, dp);
2046
- dp.relatedNavigationProperty = np;
2047
- // now update the inverse
2048
- core.arrayAddItemUnique(np.entityType.inverseForeignKeyProperties, dp);
2049
- if (np.relatedDataProperties) {
2050
- core.arrayAddItemUnique(np.relatedDataProperties, dp);
2051
- }
2052
- else {
2053
- np.relatedDataProperties = [dp];
2054
- }
2055
- });
2056
- }
2057
- /**
2058
- AutoGeneratedKeyType is an 'Enum' containing all of the valid states for an automatically generated key.
2059
- **/
2060
- var AutoGeneratedKeyType = /** @class */ (function (_super) {
2061
- __extends(AutoGeneratedKeyType, _super);
2062
- function AutoGeneratedKeyType() {
2063
- return _super !== null && _super.apply(this, arguments) || this;
2064
- }
2065
- /**
2066
- This entity does not have an autogenerated key.
2067
- The client must set the key before adding the entity to the EntityManager
2068
- **/
2069
- AutoGeneratedKeyType.None = new AutoGeneratedKeyType();
2070
- /**
2071
- This entity's key is an Identity column and is set by the backend database.
2072
- Keys for new entities will be temporary until the entities are saved at which point the keys will
2073
- be converted to their 'real' versions.
2074
- **/
2075
- AutoGeneratedKeyType.Identity = new AutoGeneratedKeyType();
2076
- /**
2077
- This entity's key is generated by a KeyGenerator and is set by the backend database.
2078
- Keys for new entities will be temporary until the entities are saved at which point the keys will
2079
- be converted to their 'real' versions.
2080
- **/
2081
- AutoGeneratedKeyType.KeyGenerator = new AutoGeneratedKeyType();
2082
- return AutoGeneratedKeyType;
2083
- }(BreezeEnum));
2084
- export { AutoGeneratedKeyType };
2085
- AutoGeneratedKeyType.prototype._$typeName = "AutoGeneratedKeyType";
2086
- Error['x'] = AutoGeneratedKeyType.resolveSymbols();
2087
- var proto = Param.prototype;
2088
- // 'this' below is TS annotation
2089
- proto.isEntity = function () {
2090
- return this._addContext({
2091
- fn: isEntity,
2092
- msg: " must be an entity"
2093
- });
2094
- };
2095
- function isEntity(context, v) {
2096
- if (v == null)
2097
- return false;
2098
- return (v.entityType !== undefined);
2099
- }
2100
- proto.isEntityProperty = function () {
2101
- return this._addContext({
2102
- fn: isEntityProperty,
2103
- msg: " must be either a DataProperty or a NavigationProperty"
2104
- });
2105
- };
2106
- function isEntityProperty(context, v) {
2107
- if (v == null)
2108
- return false;
2109
- return (v.isDataProperty || v.isNavigationProperty);
2110
- }
2111
- // functions shared between classes related to Metadata
2112
- function isQualifiedTypeName(entityTypeName) {
2113
- return entityTypeName.indexOf(":#") >= 0;
2114
- }
2115
- export function qualifyTypeName(shortName, ns) {
2116
- if (ns && ns.length > 0) {
2117
- return shortName + ":#" + ns;
2118
- }
2119
- else {
2120
- return shortName;
2121
- }
2122
- }
2123
- // Used by both ComplexType and EntityType
2124
- function addProperties(entityType, propObj, ctor) {
2125
- if (propObj == null)
2126
- return;
2127
- if (Array.isArray(propObj)) {
2128
- propObj.forEach(entityType._addPropertyCore.bind(entityType));
2129
- }
2130
- else if (typeof (propObj) === 'object') {
2131
- for (var key in propObj) {
2132
- if (core.hasOwnProperty(propObj, key)) {
2133
- var value = propObj[key];
2134
- value.name = key;
2135
- var prop = new ctor(value);
2136
- entityType._addPropertyCore(prop);
2137
- }
2138
- }
2139
- }
2140
- else {
2141
- throw new Error("The 'dataProperties' or 'navigationProperties' values must be either an array of data/nav properties or an object where each property defines a data/nav property");
2142
- }
2143
- }
2144
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LW1ldGFkYXRhLmpzIiwic291cmNlUm9vdCI6Im5nOi8vYnJlZXplLWNsaWVudC8iLCJzb3VyY2VzIjpbInNyYy9lbnRpdHktbWV0YWRhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxJQUFJLEVBQWlCLE1BQU0sUUFBUSxDQUFDO0FBQzdDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDbEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNsRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUEyQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDekMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN2QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQyxDQUFDLDJCQUEyQjtBQUN4RixPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUMvRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQXVDNUU7Ozs7O0dBS0c7QUFDSDtJQXFERTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BcUJHO0lBQ0gsdUJBQVksTUFBNEI7UUFDdEMsTUFBTSxHQUFHLE1BQU0sSUFBSSxFQUFFLENBQUM7UUFDdEIsWUFBWSxDQUFDLE1B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LEdBQUcsQ0FBQyxFQUFFO1FBQ3ZCLE9BQU8sU0FBUyxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7S0FDOUI7U0FBTTtRQUNMLE9BQU8sU0FBUyxDQUFDO0tBQ2xCO0FBQ0gsQ0FBQztBQUVELDBDQUEwQztBQUMxQyxTQUFTLGFBQWEsQ0FBQyxVQUEwQixFQUFFLE9BQTJCLEVBQUUsSUFBUztJQUN2RixJQUFJLE9BQU8sSUFBSSxJQUFJO1FBQUUsT0FBTztJQUM1QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUU7UUFDMUIsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7S0FDL0Q7U0FBTSxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxRQUFRLEVBQUU7UUFDeEMsS0FBSyxJQUFJLEdBQUcsSUFBSSxPQUFPLEVBQUU7WUFDdkIsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsRUFBRTtnQkFDckMsSUFBSSxLQUFLLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUN6QixLQUFLLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQztnQkFDakIsSUFBSSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzNCLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUNuQztTQUNGO0tBQ0Y7U0FBTTtRQUNMLE1BQU0sSUFBSSxLQUFLLENBQUMsbUtBQW1LLENBQUMsQ0FBQztLQUN0TDtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb3JlLCBFcnJvckNhbGxiYWNrIH0gZnJvbSAnLi9jb3JlJztcclxuaW1wb3J0IHsgY29uZmlnIH0gZnJvbSAnLi9jb25maWcnO1xyXG5pbXBvcnQgeyBCcmVlemVFdmVudCB9IGZyb20gJy4vZXZlbnQnO1xyXG5pbXBvcnQgeyBhc3NlcnRQYXJhbSwgYXNzZXJ0Q29uZmlnLCBQYXJhbSB9IGZyb20gJy4vYXNzZXJ0LXBhcmFtJztcclxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuL2RhdGEtdHlwZSc7XHJcbmltcG9ydCB7IEVudGl0eUFzcGVjdCwgQ29tcGxleEFzcGVjdCwgRW50aXR5LCBDb21wbGV4T2JqZWN0LCBTdHJ1Y3R1cmFsT2JqZWN0IH0gZnJvbSAnLi9lbnRpdHktYXNwZWN0JztcclxuaW1wb3J0IHsgRW50aXR5S2V5IH0gZnJvbSAnLi9lbnRpdHkta2V5JztcclxuaW1wb3J0IHsgVmFsaWRhdG9yIH0gZnJvbSAnLi92YWxpZGF0ZSc7XHJcbmltcG9ydCB7IEJyZWV6ZUVudW0gfSBmcm9tICcuL2VudW0nO1xyXG5pbXBvcnQgeyBEYXRhU2VydmljZSB9IGZyb20gJy4vZGF0YS1zZXJ2aWNlJztcclxuaW1wb3J0IHsgTmFtaW5nQ29udmVudGlvbiB9IGZyb20gJy4vbmFtaW5nLWNvbnZlbnRpb24nO1xyXG5pbXBvcnQgeyBDc2RsTWV0YWRhdGFQYXJzZXIgfSBmcm9tICcuL2NzZGwtbWV0YWRhdGEtcGFyc2VyJzsgLy8gVE9ETyBpc29sYXRlIHRoaXMgbGF0ZXI7XHJcbmltcG9ydCB7IExvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9ucyB9IGZyb20gJy4vbG9jYWwtcXVlcnktY29tcGFyaXNvbi1vcHRpb25zJztcclxuaW1wb3J0IHsgZGVmYXVsdFByb3BlcnR5SW50ZXJjZXB0b3IgfSBmcm9tICcuL2RlZmF1bHQtcHJvcGVydHktaW50ZXJjZXB0b3InO1xyXG5cclxuZXhwb3J0IHR5cGUgRW50aXR5UHJvcGVydHkgPSBEYXRhUHJvcGVydHkgfCBOYXZpZ2F0aW9uUHJvcGVydHk7XHJcbmV4cG9ydCB0eXBlIFN0cnVjdHVyYWxUeXBlID0gRW50aXR5VHlwZSB8IENvbXBsZXhUeXBlO1xyXG5cclxuLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSVN0cnVjdHVyYWxUeXBlTWFwIHtcclxuICBbaW5kZXg6IHN0cmluZ106IFN0cnVjdHVyYWxUeXBlO1xyXG59XHJcblxyXG4vLyBUT0RPOiBjb25zaWRlciBleHBvc2luZyBsYXRlclxyXG4vKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGludGVyZmFjZSBJTWV0YWRhdGFKc29uIHtcclxuICBtZXRhZGF0YVZlcnNpb246IHN0cmluZztcclxuICBuYW1lOiBzdHJpbmc7XHJcbiAgbmFtaW5nQ29udmVudGlvbjogc3RyaW5nO1xyXG4gIGxvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9uczogc3RyaW5nO1xyXG4gIGRhdGFTZXJ2aWNlczogT2JqZWN0W107IC8vIElEYXRhU2VydmljZUpzb25bXVxyXG4gIHN0cnVjdHVyYWxUeXBlczogT2JqZWN0W107IC8vIElTdHJ1Y3R1cmFsVHlwZUpzb25bXTsgXHJcbiAgcmVzb3VyY2VFbnRpdHlUeXBlTWFwOiBPYmplY3RbXTsgLy8gSVJlc291cmNlRW50aXR5VHlwZUpzb25bXVxyXG4gIGluY29tcGxldGVUeXBlTWFwOiBPYmplY3RbXTtcclxufVxyXG5cclxuLyoqIENvbmZpZ3VyYXRpb24gaW5mbyB0byBiZSBwYXNzZWQgdG8gdGhlIFtbTWV0YWRhdGFTdG9yZV1dIGNvbnN0cnVjdG9yICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgTWV0YWRhdGFTdG9yZUNvbmZpZyB7XHJcbiAgLyoqIFRoZSAgW1tOYW1pbmdDb252ZW50aW9uXV0gYXNzb2NpYXRlZCB3aXRoIHRoaXMgTWV0YWRhdGFTdG9yZS4gKi9cclxuICBuYW1pbmdDb252ZW50aW9uPzogTmFtaW5nQ29udmVudGlvbjtcclxuICAvKiogVGhlICBbW0xvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9uc11dIGFzc29jaWF0ZWQgd2l0aCB0aGlzIE1ldGFkYXRhU3RvcmUuICovXHJcbiAgbG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zPzogTG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zO1xyXG4gIHNlcmlhbGl6ZXJGbj86IChwcm9wOiBFbnRpdHlQcm9wZXJ0eSwgdmFsOiBhbnkpID0+IGFueTtcclxuICBuYW1lPzogc3RyaW5nO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIE1ldGFkYXRhRmV0Y2hlZEV2ZW50QXJncyB7XHJcbiAgbWV0YWRhdGFTdG9yZTogTWV0YWRhdGFTdG9yZTtcclxuICBkYXRhU2VydmljZTogRGF0YVNlcnZpY2UgfCBzdHJpbmc7XHJcbiAgcmF3TWV0YWRhdGE6IGFueTtcclxufVxyXG5cclxuLyoqXHJcbkFuIGluc3RhbmNlIG9mIHRoZSBNZXRhZGF0YVN0b3JlIGNvbnRhaW5zIGFsbCBvZiB0aGUgbWV0YWRhdGEgYWJvdXQgYSBjb2xsZWN0aW9uIG9mIFtbRW50aXR5VHlwZV1dJ3MuXHJcbk1ldGFkYXRhU3RvcmVzIG1heSBiZSBzaGFyZWQgYWNyb3NzIFtbRW50aXR5TWFuYWdlcl1dJ3MuICBJZiBhbiBFbnRpdHlNYW5hZ2VyIGlzIGNyZWF0ZWQgd2l0aG91dCBhblxyXG5leHBsaWNpdCBNZXRhZGF0YVN0b3JlLCB0aGUgTWV0YWRhdGFTdG9yZSBmcm9tIHRoZSBNZXRhZGF0YVN0b3JlLmRlZmF1bHRJbnN0YW5jZSBwcm9wZXJ0eSB3aWxsIGJlIHVzZWQuXHJcbkBkeW5hbWljXHJcbioqL1xyXG5leHBvcnQgY2xhc3MgTWV0YWRhdGFTdG9yZSB7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgXyR0eXBlTmFtZTogc3RyaW5nOyAvLyBvbiBwcm90b1xyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBzdGF0aWMgX19pZCA9IDA7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgc3RhdGljIEFOT05UWVBFX1BSRUZJWCA9IFwiX0lCX1wiO1xyXG4gIC8qKiBUaGUgdmVyc2lvbiBvZiBhbnkgTWV0YWRhdGFTdG9yZXMgY3JlYXRlZCBieSB0aGlzIGNsYXNzICovXHJcbiAgc3RhdGljIG1ldGFkYXRhVmVyc2lvbiA9ICcxLjAuNSc7XHJcblxyXG4gIG5hbWU6IHN0cmluZztcclxuICBkYXRhU2VydmljZXM6IERhdGFTZXJ2aWNlW107XHJcblxyXG4gIC8qKiBUaGUgIFtbTmFtaW5nQ29udmVudGlvbl1dIGFzc29jaWF0ZWQgd2l0aCB0aGlzIE1ldGFkYXRhU3RvcmUuIF9fUmVhZCBPbmx5X18gKi9cclxuICBuYW1pbmdDb252ZW50aW9uOiBOYW1pbmdDb252ZW50aW9uO1xyXG4gIC8qKiBUaGUgIFtbTG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zXV0gYXNzb2NpYXRlZCB3aXRoIHRoaXMgTWV0YWRhdGFTdG9yZS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGxvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9uczogTG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zO1xyXG4gIHNlcmlhbGl6ZXJGbj86IChwcm9wOiBFbnRpdHlQcm9wZXJ0eSwgdmFsOiBhbnkpID0+IGFueTtcclxuICAvKipcclxuICBBbiBbW0JyZWV6ZUV2ZW50XV0gdGhhdCBmaXJlcyBhZnRlciBhIE1ldGFkYXRhU3RvcmUgaGFzIGNvbXBsZXRlZCBmZXRjaGluZyBtZXRhZGF0YSBmcm9tIGEgcmVtb3RlIHNlcnZpY2UuXHJcbiAgXHJcbiAgQGV2ZW50QXJncyAtXHJcbiAgICAtIG1ldGFkYXRhU3RvcmUgLSBUaGUgTWV0YWRhdGFTdG9yZSBpbnRvIHdoaWNoIHRoZSBtZXRhZGF0YSB3YXMgZmV0Y2hlZC5cclxuICAgIC0gZGF0YVNlcnZpY2UgLSBUaGUgW1tEYXRhU2VydmljZV1dIHRoYXQgbWV0YWRhdGEgd2FzIGZldGNoZWQgZnJvbS5cclxuICAgIC0gcmF3TWV0YWRhdGEgLSB7T2JqZWN0fSBUaGUgcmF3IG1ldGFkYXRhIHJldHVybmVkIGZyb20gdGhlIHNlcnZpY2UuIChJdCB3aWxsIGhhdmUgYWxyZWFkeSBiZWVuIHByb2Nlc3NlZCBieSB0aGlzIHBvaW50KS5cclxuICA+ICAgICAgbGV0IG1zID0gbXlFbnRpdHlNYW5hZ2VyLm1ldGFkYXRhU3RvcmU7XHJcbiAgPiAgICAgIG1zLm1ldGFkYXRhRmV0Y2hlZC5zdWJzY3JpYmUoZnVuY3Rpb24oYXJncykge1xyXG4gID4gICAgICAgICAgbGV0IG1ldGFkYXRhU3RvcmUgPSBhcmdzLm1ldGFkYXRhU3RvcmU7XHJcbiAgPiAgICAgICAgICBsZXQgZGF0YVNlcnZpY2UgPSBhcmdzLmRhdGFTZXJ2aWNlO1xyXG4gID4gICAgICB9KTtcclxuICBAZXZlbnRcclxuICAqKi9cclxuICBtZXRhZGF0YUZldGNoZWQ6IEJyZWV6ZUV2ZW50PE1ldGFkYXRhRmV0Y2hlZEV2ZW50QXJncz47XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3Jlc291cmNlRW50aXR5VHlwZU1hcDoge307XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2VudGl0eVR5cGVSZXNvdXJjZU1hcDoge307XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3N0cnVjdHVyYWxUeXBlTWFwOiBJU3RydWN0dXJhbFR5cGVNYXA7IC8vIGtleSBpcyBxdWFsaWZpZWQgc3RydWN0dXJhbHR5cGUgbmFtZSAtIHZhbHVlIGlzIHN0cnVjdHVyYWxUeXBlLiAoIHN0cnVjdHVyYWwgPSBlbnRpdHlUeXBlIG9yIGNvbXBsZXhUeXBlKS5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKiovXHJcbiAgX3Nob3J0TmFtZU1hcDoge307IC8vIGtleSBpcyBzaG9ydE5hbWUsIHZhbHVlIGlzIHF1YWxpZmllZCBuYW1lIC0gZG9lcyBub3QgbmVlZCB0byBiZSBzZXJpYWxpemVkLlxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqKi9cclxuICBfY3RvclJlZ2lzdHJ5OiB7fTsgLy8ga2V5IGlzIGVpdGhlciBzaG9ydCBvciBxdWFsIHR5cGUgbmFtZSAtIHZhbHVlIGlzIGN0b3I7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICoqL1xyXG4gIF9pbmNvbXBsZXRlVHlwZU1hcDoge307IC8vIGtleSBpcyBlbnRpdHlUeXBlTmFtZTsgdmFsdWUgaXMgYXJyYXkgb2YgbmF2IHByb3BzXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICoqL1xyXG4gIF9pbmNvbXBsZXRlQ29tcGxleFR5cGVNYXA6IHt9OyAvL1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqKi9cclxuICBfZGVmZXJyZWRUeXBlczoge307XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICoqL1xyXG4gIF9pZDogbnVtYmVyO1xyXG5cclxuICAvKipcclxuICBDb25zdHJ1Y3RzIGEgbmV3IE1ldGFkYXRhU3RvcmUuXHJcbiAgXHJcbiAgPiAgICAgbGV0IG1zID0gbmV3IE1ldGFkYXRhU3RvcmUoKTtcclxuXHJcbiAgVGhlIHN0b3JlIGNhbiB0aGVuIGJlIGFzc29jaWF0ZWQgd2l0aCBhbiBFbnRpdHlNYW5hZ2VyXHJcbiAgPiAgICAgbGV0IGVudGl0eU1hbmFnZXIgPSBuZXcgRW50aXR5TWFuYWdlcigge1xyXG4gID4gICAgICAgICBzZXJ2aWNlTmFtZTogXCJicmVlemUvTm9ydGh3aW5kSUJNb2RlbFwiLCBcclxuICA+ICAgICAgICAgbWV0YWRhdGFTdG9yZTogbXMgXHJcbiAgPiAgICAgfSk7XHJcblxyXG4gIG9yIGZvciBhbiBleGlzdGluZyBFbnRpdHlNYW5hZ2VyXHJcbiAgPiAgICAvLyBBc3N1bWUgZW0xIGlzIGFuIGV4aXN0aW5nIEVudGl0eU1hbmFnZXJcclxuICA+ICAgIGVtMS5zZXRQcm9wZXJ0aWVzKCB7IG1ldGFkYXRhU3RvcmU6IG1zIH0pO1xyXG4gIFxyXG4gIEBwYXJhbSBjb25maWcgLSBDb25maWd1cmF0aW9uIHNldHRpbmdzIC5cclxuICAgIC0gbmFtaW5nQ29udmVudGlvbiAtIChkZWZhdWx0PU5hbWluZ0NvbnZlbnRpb24uZGVmYXVsdEluc3RhbmNlKSBOYW1pbmdDb252ZW50aW9uIHRvIGJlIHVzZWQgaW4gbWFwcGluZyBwcm9wZXJ0eSBuYW1lc1xyXG4gIGJldHdlZW4gY2xpZW50IGFuZCBzZXJ2ZXIuIFVzZXMgdGhlIE5hbWluZ0NvbnZlbnRpb24uZGVmYXVsdEluc3RhbmNlIGlmIG5vdCBzcGVjaWZpZWQuXHJcbiAgICAtIGxvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9ucyAtIChkZWZhdWx0PUxvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9ucy5kZWZhdWx0SW5zdGFuY2UpIFRoZSBMb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnMgdG8gYmVcclxuICB1c2VkIHdoZW4gcGVyZm9ybWluZyBcImxvY2FsIHF1ZXJpZXNcIiBpbiBvcmRlciB0byBtYXRjaCB0aGUgc2VtYW50aWNzIG9mIHF1ZXJpZXMgYWdhaW5zdCBhIHJlbW90ZSBzZXJ2aWNlLlxyXG4gICAgLSBzZXJpYWxpemVyRm4gLSBBIGZ1bmN0aW9uIHRoYXQgaXMgdXNlZCB0byBtZWRpYXRlIHRoZSBzZXJpYWxpemF0aW9uIG9mIGluc3RhbmNlcyBvZiB0aGlzIHR5cGUuXHJcbiAgKiovXHJcbiAgY29uc3RydWN0b3IoY29uZmlnPzogTWV0YWRhdGFTdG9yZUNvbmZpZykge1xyXG4gICAgY29uZmlnID0gY29uZmlnIHx8IHt9O1xyXG4gICAgYXNzZXJ0Q29uZmlnKGNvbmZpZylcclxuICAgICAgLndoZXJlUGFyYW0oXCJuYW1pbmdDb252ZW50aW9uXCIpLmlzT3B0aW9uYWwoKS5pc0luc3RhbmNlT2YoTmFtaW5nQ29udmVudGlvbikud2l0aERlZmF1bHQoTmFtaW5nQ29udmVudGlvbi5kZWZhdWx0SW5zdGFuY2UpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwibG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zXCIpLmlzT3B0aW9uYWwoKS5pc0luc3RhbmNlT2YoTG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zKS53aXRoRGVmYXVsdChMb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnMuZGVmYXVsdEluc3RhbmNlKVxyXG4gICAgICAud2hlcmVQYXJhbShcInNlcmlhbGl6ZXJGblwiKS5pc09wdGlvbmFsKCkuaXNGdW5jdGlvbigpXHJcbiAgICAgIC5hcHBseUFsbCh0aGlzKTtcclxuICAgIHRoaXMuZGF0YVNlcnZpY2VzID0gW107IC8vIGFycmF5IG9mIGRhdGFTZXJ2aWNlcztcclxuICAgIHRoaXMuX3Jlc291cmNlRW50aXR5VHlwZU1hcCA9IHt9OyAvLyBrZXkgaXMgcmVzb3VyY2UgbmFtZSAtIHZhbHVlIGlzIHF1YWxpZmllZCBlbnRpdHlUeXBlIG5hbWVcclxuICAgIHRoaXMuX3N0cnVjdHVyYWxUeXBlTWFwID0ge307IC8vIGtleSBpcyBxdWFsaWZpZWQgc3RydWN0dXJhbHR5cGUgbmFtZSAtIHZhbHVlIGlzIHN0cnVjdHVyYWxUeXBlLiAoIHN0cnVjdHVyYWwgPSBlbnRpdHlUeXBlIG9yIGNvbXBsZXhUeXBlKS5cclxuICAgIHRoaXMuX3Nob3J0TmFtZU1hcCA9IHt9OyAvLyBrZXkgaXMgc2hvcnROYW1lLCB2YWx1ZSBpcyBxdWFsaWZpZWQgbmFtZSAtIGRvZXMgbm90IG5lZWQgdG8gYmUgc2VyaWFsaXplZC5cclxuICAgIHRoaXMuX2N0b3JSZWdpc3RyeSA9IHt9OyAvLyBrZXkgaXMgZWl0aGVyIHNob3J0IG9yIHF1YWwgdHlwZSBuYW1lIC0gdmFsdWUgaXMgY3RvcjtcclxuXHJcbiAgICB0aGlzLl9pbmNvbXBsZXRlVHlwZU1hcCA9IHt9OyAvLyBrZXkgaXMgZW50aXR5VHlwZU5hbWU7IHZhbHVlIGlzIGFycmF5IG9mIG5hdiBwcm9wc1xyXG4gICAgdGhpcy5faW5jb21wbGV0ZUNvbXBsZXhUeXBlTWFwID0ge307IC8vIGtleSBpcyBjb21wbGV4VHlwZU5hbWU7IHZhbHVlIGlzIGFycmF5IG9mIGNvbXBsZXhUeXBlIHByb3BzXHJcbiAgICB0aGlzLl9pZCA9IE1ldGFkYXRhU3RvcmUuX19pZCsrO1xyXG4gICAgdGhpcy5tZXRhZGF0YUZldGNoZWQgPSBuZXcgQnJlZXplRXZlbnQoXCJtZXRhZGF0YUZldGNoZWRcIiwgdGhpcyk7XHJcblxyXG4gIH1cclxuXHJcbiAgLy8gbmVlZHMgdG8gYmUgbWFkZSBhdmFpbCB0byBkYXRhU2VydmljZS54eHggZmlsZXNcclxuICBzdGF0aWMgbm9ybWFsaXplVHlwZU5hbWUgPSBjb3JlLm1lbW9pemUoZnVuY3Rpb24gKHJhd1R5cGVOYW1lOiBzdHJpbmcpIHtcclxuICAgIHJldHVybiByYXdUeXBlTmFtZSAmJiBNZXRhZGF0YVN0b3JlLnBhcnNlVHlwZU5hbWUocmF3VHlwZU5hbWUpLnR5cGVOYW1lO1xyXG4gIH0pO1xyXG4gIC8vIGZvciBkZWJ1Z2dpbmcgdXNlIHRoZSBsaW5lIGJlbG93IGluc3RlYWQuXHJcbiAgLy9jdG9yLm5vcm1hbGl6ZVR5cGVOYW1lID0gZnVuY3Rpb24gKHJhd1R5cGVOYW1lKSB7IHJldHVybiBwYXJzZVR5cGVOYW1lKHJhd1R5cGVOYW1lKS50eXBlTmFtZTsgfTtcclxuXHJcbiAgLyoqXHJcbiAgR2VuZXJhbCBwdXJwb3NlIHByb3BlcnR5IHNldCBtZXRob2RcclxuICBcclxuICA+ICAgICAvLyBhc3N1bWUgZW0xIGlzIGFuIEVudGl0eU1hbmFnZXIgY29udGFpbmluZyBhIG51bWJlciBvZiBleGlzdGluZyBlbnRpdGllcy5cclxuICA+ICAgICBlbTEubWV0YWRhdGFTdG9yZS5zZXRQcm9wZXJ0aWVzKCB7XHJcbiAgPiAgICAgICAgIHZlcnNpb246IFwiNi4xLjNcIixcclxuICA+ICAgICAgICAgc2VyaWFsaXplckZuOiBmdW5jdGlvbihwcm9wLCB2YWx1ZSkge1xyXG4gID4gICAgICAgICByZXR1cm4gKHByb3AuaXNVbm1hcHBlZCkgPyB1bmRlZmluZWQgOiB2YWx1ZTtcclxuICA+ICAgICAgICAgfVxyXG4gID4gICAgICl9O1xyXG4gIEBwYXJhbSBjb25maWcgLSAgQW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHNlbGVjdGVkIHByb3BlcnRpZXMgYW5kIHZhbHVlcyB0byBzZXQuXHJcbiAgKiovXHJcbiAgc2V0UHJvcGVydGllcyhjb25maWc6IE1ldGFkYXRhU3RvcmVDb25maWcpIHtcclxuICAgIGFzc2VydENvbmZpZyhjb25maWcpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwibmFtZVwiKS5pc1N0cmluZygpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAud2hlcmVQYXJhbShcInNlcmlhbGl6ZXJGblwiKS5pc0Z1bmN0aW9uKCkuaXNPcHRpb25hbCgpXHJcbiAgICAgIC5hcHBseUFsbCh0aGlzKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIEFkZHMgYSBEYXRhU2VydmljZSB0byB0aGlzIE1ldGFkYXRhU3RvcmUuIElmIGEgRGF0YVNlcnZpY2Ugd2l0aCB0aGUgc2FtZSBzZXJ2aWNlTmFtZSBpcyBhbHJlYWR5XHJcbiAgaW4gdGhlIE1ldGFkYXRhU3RvcmUgYW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLlxyXG4gIEBwYXJhbSBkYXRhU2VydmljZSAtIFRoZSBbW0RhdGFTZXJ2aWNlXV0gdG8gYWRkXHJcbiAgQHBhcmFtIHNob3VsZE92ZXJ3cml0ZSAtIChkZWZhdWx0PWZhbHNlKSBQZXJtaXQgb3ZlcndyaXRlIG9mIGV4aXN0aW5nIERhdGFTZXJ2aWNlIHJhdGhlciB0aGFuIHRocm93IGV4Y2VwdGlvblxyXG4gICoqL1xyXG4gIGFkZERhdGFTZXJ2aWNlKGRhdGFTZXJ2aWNlOiBEYXRhU2VydmljZSwgc2hvdWxkT3ZlcndyaXRlPzogYm9vbGVhbikge1xyXG4gICAgYXNzZXJ0UGFyYW0oZGF0YVNlcnZpY2UsIFwiZGF0YVNlcnZpY2VcIikuaXNJbnN0YW5jZU9mKERhdGFTZXJ2aWNlKS5jaGVjaygpO1xyXG4gICAgYXNzZXJ0UGFyYW0oc2hvdWxkT3ZlcndyaXRlLCBcInNob3VsZE92ZXJ3cml0ZVwiKS5pc0Jvb2xlYW4oKS5pc09wdGlvbmFsKCkuY2hlY2soKTtcclxuICAgIGxldCBpeCA9IHRoaXMuX2dldERhdGFTZXJ2aWNlSW5kZXgoZGF0YVNlcnZpY2Uuc2VydmljZU5hbWUpO1xyXG4gICAgaWYgKGl4ID49IDApIHtcclxuICAgICAgaWYgKCEhc2hvdWxkT3ZlcndyaXRlKSB7XHJcbiAgICAgICAgdGhpcy5kYXRhU2VydmljZXNbaXhdID0gZGF0YVNlcnZpY2U7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBkYXRhU2VydmljZSB3aXRoIHRoaXMgbmFtZSAnXCIgKyBkYXRhU2VydmljZS5zZXJ2aWNlTmFtZSArIFwiJyBhbHJlYWR5IGV4aXN0cyBpbiB0aGlzIE1ldGFkYXRhU3RvcmVcIik7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZGF0YVNlcnZpY2VzLnB1c2goZGF0YVNlcnZpY2UpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2dldERhdGFTZXJ2aWNlSW5kZXgoc2VydmljZU5hbWU6IHN0cmluZykge1xyXG4gICAgcmV0dXJuIGNvcmUuYXJyYXlJbmRleE9mKHRoaXMuZGF0YVNlcnZpY2VzLCBmdW5jdGlvbiAoZHMpIHtcclxuICAgICAgcmV0dXJuIGRzLnNlcnZpY2VOYW1lID09PSBzZXJ2aWNlTmFtZTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgQWRkcyBhbiBFbnRpdHlUeXBlIHRvIHRoaXMgTWV0YWRhdGFTdG9yZS4gIE5vIGFkZGl0aW9uYWwgcHJvcGVydGllcyBtYXkgYmUgYWRkZWQgdG8gdGhlIEVudGl0eVR5cGUgYWZ0ZXIgaXRzIGhhc1xyXG4gIGJlZW4gYWRkZWQgdG8gdGhlIE1ldGFkYXRhU3RvcmUuXHJcbiAgQHBhcmFtIHN0cnVjdHVyYWxUeXBlIC0gVGhlIEVudGl0eVR5cGUgb3IgQ29tcGxleFR5cGUgdG8gYWRkXHJcbiAgKiovXHJcbiAgYWRkRW50aXR5VHlwZShzdHlwZTogU3RydWN0dXJhbFR5cGUgfCBFbnRpdHlUeXBlQ29uZmlnIHwgQ29tcGxleFR5cGVDb25maWcpIHtcclxuICAgIGxldCBzdHJ1Y3R1cmFsVHlwZTogU3RydWN0dXJhbFR5cGU7XHJcbiAgICBpZiAoc3R5cGUgaW5zdGFuY2VvZiBFbnRpdHlUeXBlIHx8IHN0eXBlIGluc3RhbmNlb2YgQ29tcGxleFR5cGUpIHtcclxuICAgICAgc3RydWN0dXJhbFR5cGUgPSBzdHlwZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHN0cnVjdHVyYWxUeXBlID0gKHN0eXBlIGFzIGFueSkuaXNDb21wbGV4VHlwZSA/IG5ldyBDb21wbGV4VHlwZShzdHlwZSkgOiBuZXcgRW50aXR5VHlwZShzdHlwZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaWYgKCFzdHJ1Y3R1cmFsVHlwZS5pc0NvbXBsZXhUeXBlKSB7IC8vIHNhbWUgYXMgYmVsb3cgYnV0IGlzbid0IGEgJ3R5cGUgZ3VhcmQnXHJcbiAgICBpZiAoc3RydWN0dXJhbFR5cGUgaW5zdGFuY2VvZiBFbnRpdHlUeXBlKSB7XHJcbiAgICAgIGlmIChzdHJ1Y3R1cmFsVHlwZS5iYXNlVHlwZU5hbWUgJiYgIXN0cnVjdHVyYWxUeXBlLmJhc2VFbnRpdHlUeXBlKSB7XHJcbiAgICAgICAgbGV0IGJhc2VFbnRpdHlUeXBlID0gdGhpcy5fZ2V0U3RydWN0dXJhbFR5cGUoc3RydWN0dXJhbFR5cGUuYmFzZVR5cGVOYW1lLCB0cnVlKTtcclxuICAgICAgICAvLyBzYWZlIGNhc3QgYmVjYXVzZSB3ZSBrbm93IHRoYXQgYmFzZUVudGl0eVR5cGUgbXVzdCBiZSBhbiBFbnRpdHlUeXBlIGlmIHRoZSBzdHJ1Y3R1cmFsVHlwZSBpcyBhbiBFbnRpdHlUeXBlXHJcbiAgICAgICAgc3RydWN0dXJhbFR5cGUuX3VwZGF0ZUZyb21CYXNlKGJhc2VFbnRpdHlUeXBlIGFzIEVudGl0eVR5cGUpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChzdHJ1Y3R1cmFsVHlwZS5rZXlQcm9wZXJ0aWVzLmxlbmd0aCA9PT0gMCAmJiAhc3RydWN0dXJhbFR5cGUuaXNBYnN0cmFjdCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVuYWJsZSB0byBhZGQgXCIgKyBzdHJ1Y3R1cmFsVHlwZS5uYW1lICtcclxuICAgICAgICAgIFwiIHRvIHRoaXMgTWV0YWRhdGFTdG9yZS4gIEFuIEVudGl0eVR5cGUgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBwcm9wZXJ0eSBkZXNpZ25hdGVkIGFzIGEga2V5IHByb3BlcnR5IC0gU2VlIHRoZSAnRGF0YVByb3BlcnR5LmlzUGFydE9mS2V5JyBwcm9wZXJ0eS5cIik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzdHJ1Y3R1cmFsVHlwZS5tZXRhZGF0YVN0b3JlID0gdGhpcztcclxuICAgIC8vIGRvbid0IHJlZ2lzdGVyIGFub24gdHlwZXNcclxuICAgIGlmICghKHN0cnVjdHVyYWxUeXBlIGFzIGFueSkuaXNBbm9ueW1vdXMpIHtcclxuICAgICAgaWYgKHRoaXMuX3N0cnVjdHVyYWxUeXBlTWFwW3N0cnVjdHVyYWxUeXBlLm5hbWVdKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVHlwZSBcIiArIHN0cnVjdHVyYWxUeXBlLm5hbWUgKyBcIiBhbHJlYWR5IGV4aXN0cyBpbiB0aGlzIE1ldGFkYXRhU3RvcmUuXCIpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLl9zdHJ1Y3R1cmFsVHlwZU1hcFtzdHJ1Y3R1cmFsVHlwZS5uYW1lXSA9IHN0cnVjdHVyYWxUeXBlO1xyXG4gICAgICB0aGlzLl9zaG9ydE5hbWVNYXBbc3RydWN0dXJhbFR5cGUuc2hvcnROYW1lXSA9IHN0cnVjdHVyYWxUeXBlLm5hbWU7XHJcbiAgICB9XHJcblxyXG4gICAgc3RydWN0dXJhbFR5cGUuZ2V0UHJvcGVydGllcygpLmZvckVhY2gocCA9PiB7XHJcbiAgICAgIHN0cnVjdHVyYWxUeXBlLl91cGRhdGVOYW1lcyhwKTtcclxuICAgICAgaWYgKCFwLmlzVW5tYXBwZWQpIHtcclxuICAgICAgICBzdHJ1Y3R1cmFsVHlwZS5fbWFwcGVkUHJvcGVydGllc0NvdW50Kys7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIHN0cnVjdHVyYWxUeXBlLl91cGRhdGVDcHMoKTtcclxuXHJcbiAgICAvLyAnaXNFbnRpdHlUeXBlJyBpcyBhIHR5cGUgZ3VhcmRcclxuICAgIGlmIChzdHJ1Y3R1cmFsVHlwZSBpbnN0YW5jZW9mIEVudGl0eVR5cGUpIHtcclxuICAgICAgc3RydWN0dXJhbFR5cGUuX3VwZGF0ZU5wcygpO1xyXG4gICAgICAvLyBnaXZlIHRoZSB0eXBlIGl0J3MgYmFzZSdzIHJlc291cmNlIG5hbWUgaWYgaXQgZG9lc24ndCBoYXZlIGl0cyBvd24uXHJcbiAgICAgIGxldCBkZWZSZXNvdXJjZU5hbWUgPSBzdHJ1Y3R1cmFsVHlwZS5kZWZhdWx0UmVzb3VyY2VOYW1lIHx8IChzdHJ1Y3R1cmFsVHlwZS5iYXNlRW50aXR5VHlwZSAmJiBzdHJ1Y3R1cmFsVHlwZS5iYXNlRW50aXR5VHlwZS5kZWZhdWx0UmVzb3VyY2VOYW1lKTtcclxuICAgICAgaWYgKGRlZlJlc291cmNlTmFtZSAmJiAhdGhpcy5nZXRFbnRpdHlUeXBlTmFtZUZvclJlc291cmNlTmFtZShkZWZSZXNvdXJjZU5hbWUpKSB7XHJcbiAgICAgICAgdGhpcy5zZXRFbnRpdHlUeXBlRm9yUmVzb3VyY2VOYW1lKGRlZlJlc291cmNlTmFtZSwgc3RydWN0dXJhbFR5cGUubmFtZSk7XHJcbiAgICAgIH1cclxuICAgICAgc3RydWN0dXJhbFR5cGUuZGVmYXVsdFJlc291cmNlTmFtZSA9IGRlZlJlc291cmNlTmFtZTtcclxuICAgICAgLy8gY2hlY2sgaWYgdGhpcyBzdHJ1Y3R1cmFsIHR5cGUncyBuYW1lLCBzaG9ydCB2ZXJzaW9uIG9yIHF1YWxpZmllZCB2ZXJzaW9uIGhhcyBhIHJlZ2lzdGVyZWQgY3Rvci5cclxuICAgICAgc3RydWN0dXJhbFR5cGUuZ2V0RW50aXR5Q3RvcigpO1xyXG4gICAgfVxyXG5cclxuICB9XHJcblxyXG5cclxuICAvKipcclxuICBFeHBvcnRzIHRoaXMgTWV0YWRhdGFTdG9yZSB0byBhIHNlcmlhbGl6ZWQgc3RyaW5nIGFwcHJvcHJpYXRlIGZvciBsb2NhbCBzdG9yYWdlLiAgIFRoaXMgb3BlcmF0aW9uIGlzIGFsc28gY2FsbGVkXHJcbiAgaW50ZXJuYWxseSB3aGVuIGV4cG9ydGluZyBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICAvLyBhc3N1bWUgbXMgaXMgYSBwcmV2aW91c2x5IGNyZWF0ZWQgTWV0YWRhdGFTdG9yZVxyXG4gID4gICAgICBsZXQgbWV0YWRhdGFBc1N0cmluZyA9IG1zLmV4cG9ydE1ldGFkYXRhKCk7XHJcbiAgPiAgICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbShcIm1ldGFkYXRhXCIsIG1ldGFkYXRhQXNTdHJpbmcpO1xyXG4gID4gICAgICAvLyBhbmQgbGF0ZXIsIHVzdWFsbHkgaW4gYSBkaWZmZXJlbnQgc2Vzc2lvbiBpbXBvcnRlZFxyXG4gID4gICAgICBsZXQgbWV0YWRhdGFGcm9tU3RvcmFnZSA9IHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbShcIm1ldGFkYXRhXCIpO1xyXG4gID4gICAgICBsZXQgbmV3TWV0YWRhdGFTdG9yZSA9IG5ldyBNZXRhZGF0YVN0b3JlKCk7XHJcbiAgPiAgICAgIG5ld01ldGFkYXRhU3RvcmUuaW1wb3J0TWV0YWRhdGEobWV0YWRhdGFGcm9tU3RvcmFnZSk7XHJcbiAgQHJldHVybiBBIHNlcmlhbGl6ZWQgdmVyc2lvbiBvZiB0aGlzIE1ldGFkYXRhU3RvcmUgdGhhdCBtYXkgYmUgc3RvcmVkIGxvY2FsbHkgYW5kIGxhdGVyIHJlc3RvcmVkLlxyXG4gICoqL1xyXG4gIGV4cG9ydE1ldGFkYXRhKCkge1xyXG4gICAgbGV0IHJlc3VsdCA9IEpTT04uc3RyaW5naWZ5KHtcclxuICAgICAgXCJtZXRhZGF0YVZlcnNpb25cIjogTWV0YWRhdGFTdG9yZS5tZXRhZGF0YVZlcnNpb24sXHJcbiAgICAgIFwibmFtZVwiOiB0aGlzLm5hbWUsXHJcbiAgICAgIFwibmFtaW5nQ29udmVudGlvblwiOiB0aGlzLm5hbWluZ0NvbnZlbnRpb24ubmFtZSxcclxuICAgICAgXCJsb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnNcIjogdGhpcy5sb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnMubmFtZSxcclxuICAgICAgXCJkYXRhU2VydmljZXNcIjogdGhpcy5kYXRhU2VydmljZXMsXHJcbiAgICAgIFwic3RydWN0dXJhbFR5cGVzXCI6IGNvcmUub2JqZWN0TWFwKHRoaXMuX3N0cnVjdHVyYWxUeXBlTWFwKSxcclxuICAgICAgXCJyZXNvdXJjZUVudGl0eVR5cGVNYXBcIjogdGhpcy5fcmVzb3VyY2VFbnRpdHlUeXBlTWFwXHJcbiAgICB9LCBudWxsLCBjb25maWcuc3RyaW5naWZ5UGFkKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBJbXBvcnRzIGEgcHJldmlvdXNseSBleHBvcnRlZCBzZXJpYWxpemVkIE1ldGFkYXRhU3RvcmUgaW50byB0aGlzIE1ldGFkYXRhU3RvcmUuXHJcbiAgICBcclxuICA+ICAgICAgLy8gYXNzdW1lIG1zIGlzIGEgcHJldmlvdXNseSBjcmVhdGVkIE1ldGFkYXRhU3RvcmVcclxuICA+ICAgICAgbGV0IG1ldGFkYXRhQXNTdHJpbmcgPSBtcy5leHBvcnRNZXRhZGF0YSgpO1xyXG4gID4gICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnNldEl0ZW0oXCJtZXRhZGF0YVwiLCBtZXRhZGF0YUFzU3RyaW5nKTtcclxuICA+ICAgICAgLy8gYW5kIGxhdGVyLCB1c3VhbGx5IGluIGEgZGlmZmVyZW50IHNlc3Npb25cclxuICA+ICAgICAgbGV0IG1ldGFkYXRhRnJvbVN0b3JhZ2UgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJtZXRhZGF0YVwiKTtcclxuICA+ICAgICAgbGV0IG5ld01ldGFkYXRhU3RvcmUgPSBuZXcgTWV0YWRhdGFTdG9yZSgpO1xyXG4gID4gICAgICBuZXdNZXRhZGF0YVN0b3JlLmltcG9ydE1ldGFkYXRhKG1ldGFkYXRhRnJvbVN0b3JhZ2UpO1xyXG4gIEBwYXJhbSBleHBvcnRlZE1ldGFkYXRhIC0gQSBwcmV2aW91c2x5IGV4cG9ydGVkIE1ldGFkYXRhU3RvcmUuXHJcbiAgQHBhcmFtIGFsbG93TWVyZ2UgLSAgQWxsb3dzIGN1c3RvbSBtZXRhZGF0YSB0byBiZSBtZXJnZWQgaW50byBleGlzdGluZyBtZXRhZGF0YSB0eXBlcy5cclxuICBAcmV0dXJuIFRoaXMgTWV0YWRhdGFTdG9yZS5cclxuICBAY2hhaW5hYmxlXHJcbiAgKiovXHJcbiAgaW1wb3J0TWV0YWRhdGEoZXhwb3J0ZWRNZXRhZGF0YTogc3RyaW5nIHwgT2JqZWN0LCBhbGxvd01lcmdlOiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgIGFzc2VydFBhcmFtKGFsbG93TWVyZ2UsIFwiYWxsb3dNZXJnZVwiKS5pc09wdGlvbmFsKCkuaXNCb29sZWFuKCkuY2hlY2soKTtcclxuICAgIHRoaXMuX2RlZmVycmVkVHlwZXMgPSB7fTtcclxuICAgIC8vIGluc3VyZSB0aGF0IHdlIGRvbid0IG11dGF0ZSBpbmNvbWluZyBleHBvcnRlZE1ldGFkYXRhICggaWYgaXRzIGFuIG9iamVjdClcclxuICAgIGxldCBtZXRhZGF0YUFzU3RyaW5nID0gKHR5cGVvZiAoZXhwb3J0ZWRNZXRhZGF0YSkgPT09IFwic3RyaW5nXCIpID8gZXhwb3J0ZWRNZXRhZGF0YSA6IEpTT04uc3RyaW5naWZ5KGV4cG9ydGVkTWV0YWRhdGEpO1xyXG4gICAgY29uc3QgbWV0YWRhdGFKc29uID0gSlNPTi5wYXJzZShtZXRhZGF0YUFzU3RyaW5nKTtcclxuXHJcbiAgICBpZiAobWV0YWRhdGFKc29uLnNjaGVtYSkge1xyXG4gICAgICByZXR1cm4gQ3NkbE1ldGFkYXRhUGFyc2VyLnBhcnNlKHRoaXMsIG1ldGFkYXRhSnNvbi5zY2hlbWEsIG1ldGFkYXRhSnNvbi5hbHRNZXRhZGF0YSk7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IGpzb24gPSBtZXRhZGF0YUpzb24gYXMgSU1ldGFkYXRhSnNvbjtcclxuICAgIGlmIChqc29uLm1ldGFkYXRhVmVyc2lvbiAmJiBqc29uLm1ldGFkYXRhVmVyc2lvbiAhPT0gTWV0YWRhdGFTdG9yZS5tZXRhZGF0YVZlcnNpb24pIHtcclxuICAgICAgbGV0IG1zZyA9IGNvcmUuZm9ybWF0U3RyaW5nKFwiQ2Fubm90IGltcG9ydCBtZXRhZGF0YSB3aXRoIGEgZGlmZmVyZW50ICdtZXRhZGF0YVZlcnNpb24nICglMSkgdGhhbiB0aGUgY3VycmVudCAnTWV0YWRhdGFTdG9yZS5tZXRhZGF0YVZlcnNpb24nICglMikgXCIsXHJcbiAgICAgICAganNvbi5tZXRhZGF0YVZlcnNpb24sIE1ldGFkYXRhU3RvcmUubWV0YWRhdGFWZXJzaW9uKTtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IG5jTmFtZSA9IGpzb24ubmFtaW5nQ29udmVudGlvbjtcclxuICAgIGxldCBscWNvTmFtZSA9IGpzb24ubG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zO1xyXG4gICAgaWYgKHRoaXMuaXNFbXB0eSgpKSB7XHJcbiAgICAgIHRoaXMubmFtaW5nQ29udmVudGlvbiA9IGNvbmZpZy5fZmV0Y2hPYmplY3QoTmFtaW5nQ29udmVudGlvbiwgbmNOYW1lKSB8fCB0aGlzLm5hbWluZ0NvbnZlbnRpb247XHJcbiAgICAgIHRoaXMubG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zID0gY29uZmlnLl9mZXRjaE9iamVjdChMb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnMsIGxxY29OYW1lKSB8fCB0aGlzLmxvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9ucztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmIChuY05hbWUgJiYgdGhpcy5uYW1pbmdDb252ZW50aW9uLm5hbWUgIT09IG5jTmFtZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBpbXBvcnQgbWV0YWRhdGEgd2l0aCBhIGRpZmZlcmVudCAnbmFtaW5nQ29udmVudGlvbicgZnJvbSB0aGUgY3VycmVudCBNZXRhZGF0YVN0b3JlXCIpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChscWNvTmFtZSAmJiB0aGlzLmxvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9ucy5uYW1lICE9PSBscWNvTmFtZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBpbXBvcnQgbWV0YWRhdGEgd2l0aCBkaWZmZXJlbnQgJ2xvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9ucycgZnJvbSB0aGUgY3VycmVudCBNZXRhZGF0YVN0b3JlXCIpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy9ub2luc3BlY3Rpb24gSlNIaW50XHJcbiAgICBqc29uLmRhdGFTZXJ2aWNlcyAmJiBqc29uLmRhdGFTZXJ2aWNlcy5mb3JFYWNoKChkcykgPT4ge1xyXG4gICAgICBsZXQgcmVhbERzID0gRGF0YVNlcnZpY2UuZnJvbUpTT04oZHMpO1xyXG4gICAgICB0aGlzLmFkZERhdGFTZXJ2aWNlKHJlYWxEcywgdHJ1ZSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBqc29uLnN0cnVjdHVyYWxUeXBlcyAmJiBqc29uLnN0cnVjdHVyYWxUeXBlcy5mb3JFYWNoKChzdHlwZSkgPT4ge1xyXG4gICAgICBzdHJ1Y3R1cmFsVHlwZUZyb21Kc29uKHRoaXMsIHN0eXBlLCBhbGxvd01lcmdlKTtcclxuICAgIH0pO1xyXG4gICAgY29yZS5leHRlbmQodGhpcy5fcmVzb3VyY2VFbnRpdHlUeXBlTWFwLCBqc29uLnJlc291cmNlRW50aXR5VHlwZU1hcCk7XHJcbiAgICBjb3JlLmV4dGVuZCh0aGlzLl9pbmNvbXBsZXRlVHlwZU1hcCwganNvbi5pbmNvbXBsZXRlVHlwZU1hcCk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBDcmVhdGVzIGEgbmV3IE1ldGFkYXRhU3RvcmUgZnJvbSBhIHByZXZpb3VzbHkgZXhwb3J0ZWQgc2VyaWFsaXplZCBNZXRhZGF0YVN0b3JlXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBtcyBpcyBhIHByZXZpb3VzbHkgY3JlYXRlZCBNZXRhZGF0YVN0b3JlXHJcbiAgPiAgICAgIGxldCBtZXRhZGF0YUFzU3RyaW5nID0gbXMuZXhwb3J0TWV0YWRhdGEoKTtcclxuICA+ICAgICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKFwibWV0YWRhdGFcIiwgbWV0YWRhdGFBc1N0cmluZyk7XHJcbiAgPiAgICAgIC8vIGFuZCBsYXRlciwgdXN1YWxseSBpbiBhIGRpZmZlcmVudCBzZXNzaW9uXHJcbiAgPiAgICAgIGxldCBtZXRhZGF0YUZyb21TdG9yYWdlID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKFwibWV0YWRhdGFcIik7XHJcbiAgPiAgICAgIGxldCBuZXdNZXRhZGF0YVN0b3JlID0gTWV0YWRhdGFTdG9yZS5pbXBvcnRNZXRhZGF0YShtZXRhZGF0YUZyb21TdG9yYWdlKTtcclxuICBAcGFyYW0gZXhwb3J0ZWRTdHJpbmcgLSBBIHByZXZpb3VzbHkgZXhwb3J0ZWQgTWV0YWRhdGFTdG9yZS5cclxuICBAcmV0dXJuIEEgbmV3IE1ldGFkYXRhU3RvcmUuXHJcbiAgKiovXHJcbiAgc3RhdGljIGltcG9ydE1ldGFkYXRhKGV4cG9ydGVkU3RyaW5nOiBzdHJpbmcpIHtcclxuICAgIGxldCBtcyA9IG5ldyBNZXRhZGF0YVN0b3JlKCk7XHJcbiAgICBtcy5pbXBvcnRNZXRhZGF0YShleHBvcnRlZFN0cmluZyk7XHJcbiAgICByZXR1cm4gbXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIHdoZXRoZXIgTWV0YWRhdGEgaGFzIGJlZW4gcmV0cmlldmVkIGZvciBhIHNwZWNpZmllZCBzZXJ2aWNlIG5hbWUuXHJcbiAgPiAgICAgIC8vIEFzc3VtZSBlbTEgaXMgYW4gZXhpc3RpbmcgRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgaWYgKCFlbTEubWV0YWRhdGFTdG9yZS5oYXNNZXRhZGF0YUZvcihcImJyZWV6ZS9Ob3J0aHdpbmRJQk1vZGVsXCIpKSkge1xyXG4gID4gICAgICAgICAgLy8gZG8gc29tZXRoaW5nIGludGVyZXN0aW5nXHJcbiAgPiAgICAgIH1cclxuICBAcGFyYW0gc2VydmljZU5hbWUgLSBUaGUgc2VydmljZSBuYW1lLlxyXG4gIEByZXR1cm4gV2hldGhlciBtZXRhZGF0YSBoYXMgYWxyZWFkeSBiZWVuIHJldHJpZXZlZCBmb3IgdGhlIHNwZWNpZmllZCBzZXJ2aWNlIG5hbWUuXHJcbiAgKiovXHJcbiAgaGFzTWV0YWRhdGFGb3Ioc2VydmljZU5hbWU6IHN0cmluZykge1xyXG4gICAgcmV0dXJuICEhdGhpcy5nZXREYXRhU2VydmljZShzZXJ2aWNlTmFtZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIHRoZSBEYXRhU2VydmljZSBmb3IgYSBzcGVjaWZpZWQgc2VydmljZSBuYW1lXHJcbiAgPiAgICAgIC8vIEFzc3VtZSBlbTEgaXMgYW4gZXhpc3RpbmcgRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgbGV0IGRzID0gZW0xLm1ldGFkYXRhU3RvcmUuZ2V0RGF0YVNlcnZpY2UoXCJicmVlemUvTm9ydGh3aW5kSUJNb2RlbFwiKTtcclxuICA+ICAgICAgbGV0IGFkYXB0ZXJOYW1lID0gZHMuYWRhcHRlck5hbWU7IC8vIG1heSBiZSBudWxsXHJcbiAgQHBhcmFtIHNlcnZpY2VOYW1lIC0gVGhlIHNlcnZpY2UgbmFtZS5cclxuICBAcmV0dXJuIFRoZSBEYXRhU2VydmljZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS5cclxuICAqKi9cclxuICBnZXREYXRhU2VydmljZShzZXJ2aWNlTmFtZTogc3RyaW5nKSB7XHJcbiAgICBhc3NlcnRQYXJhbShzZXJ2aWNlTmFtZSwgXCJzZXJ2aWNlTmFtZVwiKS5pc1N0cmluZygpLmNoZWNrKCk7XHJcblxyXG4gICAgc2VydmljZU5hbWUgPSBEYXRhU2VydmljZS5fbm9ybWFsaXplU2VydmljZU5hbWUoc2VydmljZU5hbWUpO1xyXG4gICAgcmV0dXJuIGNvcmUuYXJyYXlGaXJzdCh0aGlzLmRhdGFTZXJ2aWNlcywgZnVuY3Rpb24gKGRzOiBEYXRhU2VydmljZSkge1xyXG4gICAgICByZXR1cm4gZHMuc2VydmljZU5hbWUgPT09IHNlcnZpY2VOYW1lO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBGZXRjaGVzIHRoZSBtZXRhZGF0YSBmb3IgYSBzcGVjaWZpZWQgJ3NlcnZpY2UnLiBUaGlzIG1ldGhvZCBpcyBhdXRvbWF0aWNhbGx5IGNhbGxlZFxyXG4gIGludGVybmFsbHkgYnkgYW4gRW50aXR5TWFuYWdlciBiZWZvcmUgaXRzIGZpcnN0IHF1ZXJ5IGFnYWluc3QgYSBuZXcgc2VydmljZS4gX19Bc3luY19fXHJcblxyXG4gIFVzdWFsbHkgeW91IHdpbGwgbm90IGFjdHVhbGx5IHByb2Nlc3MgdGhlIHJlc3VsdHMgb2YgYSBmZXRjaE1ldGFkYXRhIGNhbGwgZGlyZWN0bHksIGJ1dCB3aWxsIGluc3RlYWRcclxuICBhc2sgZm9yIHRoZSBtZXRhZGF0YSBmcm9tIHRoZSBFbnRpdHlNYW5hZ2VyIGFmdGVyIHRoZSBmZXRjaE1ldGFkYXRhIGNhbGwgcmV0dXJucy5cclxuICA+ICAgICAgbGV0IG1zID0gbmV3IE1ldGFkYXRhU3RvcmUoKTtcclxuICA+ICAgICAgLy8gb3IgbW9yZSBjb21tb25seVxyXG4gID4gICAgICAvLyBsZXQgbXMgPSBhbkVudGl0eU1hbmFnZXIubWV0YWRhdGFTdG9yZTtcclxuICA+ICAgICAgbXMuZmV0Y2hNZXRhZGF0YShcImJyZWV6ZS9Ob3J0aHdpbmRJQk1vZGVsXCIpLnRoZW4oZnVuY3Rpb24ocmF3TWV0YWRhdGEpIHtcclxuICA+ICAgICAgICAgICAgLy8gZG8gc29tZXRoaW5nIHdpdGggdGhlIG1ldGFkYXRhXHJcbiAgPiAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uKGV4Y2VwdGlvbikge1xyXG4gID4gICAgICAgICAgLy8gaGFuZGxlIGV4Y2VwdGlvbiBoZXJlXHJcbiAgPiAgICAgIH0pO1xyXG4gIEBwYXJhbSBkYXRhU2VydmljZSAtICBFaXRoZXIgYSBEYXRhU2VydmljZSBvciBqdXN0IHRoZSBuYW1lIG9mIHRoZSBEYXRhU2VydmljZSB0byBmZXRjaCBtZXRhZGF0YSBmb3IuXHJcbiAgQHBhcmFtIGNhbGxiYWNrIC0gRnVuY3Rpb24gY2FsbGVkIG9uIHN1Y2Nlc3MuXHJcbiAgQHBhcmFtIGVycm9yQ2FsbGJhY2sgLSBGdW5jdGlvbiBjYWxsZWQgb24gZmFpbHVyZS5cclxuICBAcmV0dXJuIFByb21pc2VcclxuICAqKi9cclxuICBmZXRjaE1ldGFkYXRhKGRhdGFTZXJ2aWNlOiBzdHJpbmcgfCBEYXRhU2VydmljZSwgY2FsbGJhY2s/OiAoc2NoZW1hOiBhbnkpID0+IHZvaWQsIGVycm9yQ2FsbGJhY2s/OiBFcnJvckNhbGxiYWNrKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICBhc3NlcnRQYXJhbShkYXRhU2VydmljZSwgXCJkYXRhU2VydmljZVwiKS5pc1N0cmluZygpLm9yKCkuaXNJbnN0YW5jZU9mKERhdGFTZXJ2aWNlKS5jaGVjaygpO1xyXG4gICAgICBhc3NlcnRQYXJhbShjYWxsYmFjaywgXCJjYWxsYmFja1wiKS5pc0Z1bmN0aW9uKCkuaXNPcHRpb25hbCgpLmNoZWNrKCk7XHJcbiAgICAgIGFzc2VydFBhcmFtKGVycm9yQ2FsbGJhY2ssIFwiZXJyb3JDYWxsYmFja1wiKS5pc0Z1bmN0aW9uKCkuaXNPcHRpb25hbCgpLmNoZWNrKCk7XHJcblxyXG4gICAgICBpZiAodHlwZW9mIGRhdGFTZXJ2aWNlID09PSBcInN0cmluZ1wiKSB7XHJcbiAgICAgICAgLy8gdXNlIHRoZSBkYXRhU2VydmljZSB3aXRoIGEgbWF0Y2hpbmcgbmFtZSBvciBjcmVhdGUgYSBuZXcgb25lLlxyXG4gICAgICAgIGRhdGFTZXJ2aWNlID0gdGhpcy5nZXREYXRhU2VydmljZShkYXRhU2VydmljZSkgfHwgbmV3IERhdGFTZXJ2aWNlKHsgc2VydmljZU5hbWU6IGRhdGFTZXJ2aWNlIH0pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBkYXRhU2VydmljZSA9IERhdGFTZXJ2aWNlLnJlc29sdmUoW2RhdGFTZXJ2aWNlXSk7XHJcblxyXG4gICAgICBpZiAodGhpcy5oYXNNZXRhZGF0YUZvcihkYXRhU2VydmljZS5zZXJ2aWNlTmFtZSkpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNZXRhZGF0YSBmb3IgYSBzcGVjaWZpYyBzZXJ2aWNlTmFtZSBtYXkgb25seSBiZSBmZXRjaGVkIG9uY2UgcGVyIE1ldGFkYXRhU3RvcmUuIFNlcnZpY2VOYW1lOiBcIiArIGRhdGFTZXJ2aWNlLnNlcnZpY2VOYW1lKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGRhdGFTZXJ2aWNlLmFkYXB0ZXJJbnN0YW5jZSEuZmV0Y2hNZXRhZGF0YSh0aGlzLCBkYXRhU2VydmljZSkudGhlbigocmF3TWV0YWRhdGE6IGFueSkgPT4ge1xyXG4gICAgICAgIHRoaXMubWV0YWRhdGFGZXRjaGVkLnB1Ymxpc2goeyBtZXRhZGF0YVN0b3JlOiB0aGlzLCBkYXRhU2VydmljZTogZGF0YVNlcnZpY2UsIHJhd01ldGFkYXRhOiByYXdNZXRhZGF0YSB9KTtcclxuICAgICAgICBpZiAoY2FsbGJhY2spIGNhbGxiYWNrKHJhd01ldGFkYXRhKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJhd01ldGFkYXRhKTtcclxuICAgICAgfSwgZnVuY3Rpb24gKGVycm9yOiBhbnkpIHtcclxuICAgICAgICBpZiAoZXJyb3JDYWxsYmFjaykgZXJyb3JDYWxsYmFjayhlcnJvcik7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm9yKTtcclxuICAgICAgfSk7XHJcbiAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICAvLyBUT0RPOiBzdHJvbmdseSB0eXBlIGludGVyY2VwdG9yIGJlbG93LlxyXG4gIC8qKlxyXG4gIFVzZWQgdG8gcmVnaXN0ZXIgYSBjb25zdHJ1Y3RvciBmb3IgYW4gRW50aXR5VHlwZSB0aGF0IGlzIG5vdCBrbm93biB2aWEgc3RhbmRhcmQgTWV0YWRhdGEgZGlzY292ZXJ5O1xyXG4gIGkuZS4gYW4gdW5tYXBwZWQgdHlwZS5cclxuICBAcGFyYW0gZW50aXR5Q3RvciAtIFRoZSBjb25zdHJ1Y3RvciBmdW5jdGlvbiBmb3IgdGhlICd1bm1hcHBlZCcgdHlwZS5cclxuICBAcGFyYW0gaW50ZXJjZXB0b3IgLSBBbiBpbnRlcmNlcHRvciBmdW5jdGlvblxyXG4gICoqL1xyXG4gIHRyYWNrVW5tYXBwZWRUeXBlKGVudGl0eUN0b3I6IGFueSwgaW50ZXJjZXB0b3I6IGFueSkge1xyXG4gICAgYXNzZXJ0UGFyYW0oZW50aXR5Q3RvciwgXCJlbnRpdHlDdG9yXCIpLmlzRnVuY3Rpb24oKS5jaGVjaygpO1xyXG4gICAgYXNzZXJ0UGFyYW0oaW50ZXJjZXB0b3IsIFwiaW50ZXJjZXB0b3JcIikuaXNGdW5jdGlvbigpLmlzT3B0aW9uYWwoKS5jaGVjaygpO1xyXG4gICAgLy8gVE9ETzogdGhpbmsgYWJvdXQgYWRkaW5nIHRoaXMgdG8gdGhlIE1ldGFkYXRhU3RvcmUuXHJcbiAgICBsZXQgZW50aXR5VHlwZSA9IG5ldyBFbnRpdHlUeXBlKHRoaXMpO1xyXG4gICAgZW50aXR5VHlwZS5fc2V0Q3RvcihlbnRpdHlDdG9yLCBpbnRlcmNlcHRvcik7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBQcm92aWRlcyBhIG1lY2hhbmlzbSB0byByZWdpc3RlciBhICdjdXN0b20nIGNvbnN0cnVjdG9yIHRvIGJlIHVzZWQgd2hlbiBjcmVhdGluZyBuZXcgaW5zdGFuY2VzXHJcbiAgb2YgdGhlIHNwZWNpZmllZCBlbnRpdHkgdHlwZS4gIElmIHRoaXMgY2FsbCBpcyBub3QgbWFkZSwgYSBkZWZhdWx0IGNvbnN0cnVjdG9yIGlzIGNyZWF0ZWQgZm9yXHJcbiAgdGhlIGVudGl0eSBhcyBuZWVkZWQuXHJcbiAgVGhpcyBjYWxsIG1heSBiZSBtYWRlIGJlZm9yZSBvciBhZnRlciB0aGUgY29ycmVzcG9uZGluZyBFbnRpdHlUeXBlIGhhcyBiZWVuIGRpc2NvdmVyZWQgdmlhXHJcbiAgTWV0YWRhdGEgZGlzY292ZXJ5LlxyXG4gID4gICAgICBsZXQgQ3VzdG9tZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgPiAgICAgICAgICAgICAgdGhpcy5taXNjRGF0YSA9IFwiYXNkZlwiO1xyXG4gID4gICAgICAgICAgfTtcclxuICA+ICAgICAgQ3VzdG9tZXIucHJvdG90eXBlLmRvRm9vKCkge1xyXG4gID4gICAgICAgICAgICAgIC4uLlxyXG4gID4gICAgICAgICAgfVxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGEgcHJlZXhpc3RpbmcgRW50aXR5TWFuYWdlcjtcclxuICA+ICAgICAgZW0xLm1ldGFkYXRhU3RvcmUucmVnaXN0ZXJFbnRpdHlUeXBlQ3RvcihcIkN1c3RvbWVyXCIsIEN1c3RvbWVyKTtcclxuICA+ICAgICAgLy8gYW55IHF1ZXJpZXMgb3IgRW50aXR5VHlwZS5jcmVhdGUgY2FsbHMgZnJvbSB0aGlzIHBvaW50IG9uIHdpbGwgY2FsbCB0aGUgQ3VzdG9tZXIgY29uc3RydWN0b3JcclxuICA+ICAgICAgLy8gcmVnaXN0ZXJlZCBhYm92ZS5cclxuICBAcGFyYW0gc3RydWN0dXJhbFR5cGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIEVudGl0eVR5cGUgb3IgQ29tcGxleFR5cGUuXHJcbiAgQHBhcmFtIGFDdG9yIC0gVGhlIGNvbnN0cnVjdG9yIGZvciB0aGlzIEVudGl0eVR5cGUgb3IgQ29tcGxleFR5cGU7IG1heSBiZSBudWxsIGlmIGFsbCB5b3Ugd2FudCB0byBkbyBpcyBzZXQgdGhlIG5leHQgcGFyYW1ldGVyLlxyXG4gIEBwYXJhbSBpbml0Rm4gLSBBIGZ1bmN0aW9uIG9yIHRoZSBuYW1lIG9mIGEgZnVuY3Rpb24gb24gdGhlIGVudGl0eSB0aGF0IGlzIHRvIGJlIGV4ZWN1dGVkIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBlbnRpdHkgaGFzIGJlZW4gY3JlYXRlZFxyXG4gIGFuZCBwb3B1bGF0ZWQgd2l0aCBhbnkgaW5pdGlhbCB2YWx1ZXMuIENhbGxlZCB3aXRoICdpbml0Rm4oZW50aXR5KSdcclxuICBAcGFyYW0gbm9UcmFja2luZ0ZuIC0gQSBmdW5jdGlvbiB0aGF0IGlzIGV4ZWN1dGVkIGltbWVkaWF0ZWx5IGFmdGVyIGEgbm9UcmFja2luZyBlbnRpdHkgaGFzIGJlZW4gY3JlYXRlZCBhbmQgd2hvc2UgcmV0dXJuXHJcbiAgdmFsdWUgd2lsbCBiZSB1c2VkIGluIHBsYWNlIG9mIHRoZSBub1RyYWNraW5nIGVudGl0eS5cclxuICAqKi9cclxuICByZWdpc3RlckVudGl0eVR5cGVDdG9yKHN0cnVjdHVyYWxUeXBlTmFtZTogc3RyaW5nLCBhQ3Rvcj86IGFueSwgaW5pdEZuPzogRnVuY3Rpb24gfCBzdHJpbmcsIG5vVHJhY2tpbmdGbj86IEZ1bmN0aW9uKSB7XHJcbiAgICBhc3NlcnRQYXJhbShzdHJ1Y3R1cmFsVHlwZU5hbWUsIFwic3RydWN0dXJhbFR5cGVOYW1lXCIpLmlzU3RyaW5nKCkuY2hlY2soKTtcclxuICAgIGFzc2VydFBhcmFtKGFDdG9yLCBcImFDdG9yXCIpLmlzRnVuY3Rpb24oKS5pc09wdGlvbmFsKCkuY2hlY2soKTtcclxuICAgIGFzc2VydFBhcmFtKGluaXRGbiwgXCJpbml0Rm5cIikuaXNPcHRpb25hbCgpLmlzRnVuY3Rpb24oKS5vcigpLmlzU3RyaW5nKCkuY2hlY2soKTtcclxuICAgIGFzc2VydFBhcmFtKG5vVHJhY2tpbmdGbiwgXCJub1RyYWNraW5nRm5cIikuaXNPcHRpb25hbCgpLmlzRnVuY3Rpb24oKS5jaGVjaygpO1xyXG5cclxuICAgIGxldCBxdWFsaWZpZWRUeXBlTmFtZSA9IGdldFF1YWxpZmllZFR5cGVOYW1lKHRoaXMsIHN0cnVjdHVyYWxUeXBlTmFtZSwgZmFsc2UpO1xyXG4gICAgbGV0IHR5cGVOYW1lID0gcXVhbGlmaWVkVHlwZU5hbWUgfHwgc3RydWN0dXJhbFR5cGVOYW1lO1xyXG5cclxuICAgIGlmIChhQ3Rvcikge1xyXG4gICAgICBpZiAoYUN0b3IuXyR0eXBlTmFtZSAmJiBhQ3Rvci5fJHR5cGVOYW1lICE9PSB0eXBlTmFtZSkge1xyXG4gICAgICAgIC8vIFRPRE86IHdyYXAgdGhpcyAtIGNvbnNvbGUgYW5kIGVzcGVjaWFsbHkgY29uc29sZS53YXJuIGRvZXMgbm90IGV4aXN0IGluIGFsbCBicm93c2Vycy5cclxuICAgICAgICBjb25zb2xlLndhcm4oXCJSZWdpc3RlcmluZyBhIGNvbnN0cnVjdG9yIGZvciBcIiArIHR5cGVOYW1lICsgXCIgdGhhdCBpcyBhbHJlYWR5IHVzZWQgZm9yIFwiICsgYUN0b3IuXyR0eXBlTmFtZSArIFwiLlwiKTtcclxuICAgICAgfVxyXG4gICAgICBhQ3Rvci5fJHR5cGVOYW1lID0gdHlwZU5hbWU7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fY3RvclJlZ2lzdHJ5W3R5cGVOYW1lXSA9IHsgY3RvcjogYUN0b3IsIGluaXRGbjogaW5pdEZuLCBub1RyYWNraW5nRm46IG5vVHJhY2tpbmdGbiB9O1xyXG4gICAgaWYgKHF1YWxpZmllZFR5cGVOYW1lKSB7XHJcbiAgICAgIGxldCBzdHlwZSA9IHRoaXMuX3N0cnVjdHVyYWxUeXBlTWFwW3F1YWxpZmllZFR5cGVOYW1lXTtcclxuICAgICAgc3R5cGUgJiYgc3R5cGUuZ2V0Q3Rvcih0cnVlKTsgLy8gdGhpcyB3aWxsIGNvbXBsZXRlIHRoZSByZWdpc3RyYXRpb24gaWYgYXZhaWwgbm93LlxyXG4gICAgfVxyXG5cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgd2hldGhlciB0aGlzIE1ldGFkYXRhU3RvcmUgY29udGFpbnMgYW55IG1ldGFkYXRhIHlldC5cclxuICA+ICAgICAgLy8gYXNzdW1lIGVtMSBpcyBhIHByZWV4aXN0aW5nIEVudGl0eU1hbmFnZXI7XHJcbiAgPiAgICAgIGlmIChlbTEubWV0YWRhdGFTdG9yZS5pc0VtcHR5KCkpIHtcclxuICA+ICAgICAgICAgIC8vIGRvIHNvbWV0aGluZyBpbnRlcmVzdGluZ1xyXG4gID4gICAgICB9XHJcbiAgKiovXHJcbiAgaXNFbXB0eSgpIHtcclxuICAgIHJldHVybiBjb3JlLmlzRW1wdHkodGhpcy5fc3RydWN0dXJhbFR5cGVNYXApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhbiBbW0VudGl0eVR5cGVdXSBvciBudWxsIGdpdmVuIGl0cyBuYW1lLlxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGEgcHJlZXhpc3RpbmcgRW50aXR5TWFuYWdlclxyXG4gID4gICAgICBsZXQgb2RUeXBlID0gZW0xLm1ldGFkYXRhU3RvcmUuZ2V0QXNFbnRpdHlUeXBlKFwiT3JkZXJEZXRhaWxcIik7XHJcblxyXG4gIG9yIHRvIHRocm93IGFuIGVycm9yIGlmIHRoZSB0eXBlIGlzIG5vdCBmb3VuZFxyXG4gID4gICAgICBsZXQgYmFkVHlwZSA9IGVtMS5tZXRhZGF0YVN0b3JlLmdldEFzRW50aXR5VHlwZShcIkZvb1wiLCBmYWxzZSk7XHJcbiAgPiAgICAgIC8vIGJhZFR5cGUgd2lsbCBub3QgZ2V0IHNldCBhbmQgYW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLlxyXG4gIEBwYXJhbSBzdHJ1Y3R1cmFsVHlwZU5hbWUgLSBFaXRoZXIgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9yIGEgc2hvcnQgbmFtZSBtYXkgYmUgdXNlZC4gSWYgYSBzaG9ydCBuYW1lIGlzIHNwZWNpZmllZCBhbmQgbXVsdGlwbGUgdHlwZXMgc2hhcmVcclxuICB0aGF0IHNhbWUgc2hvcnQgbmFtZSBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uXHJcbiAgQHBhcmFtIG9rSWZOb3RGb3VuZCAtIChkZWZhdWx0PWZhbHNlKSBXaGV0aGVyIHRvIHRocm93IGFuIGVycm9yIGlmIHRoZSBzcGVjaWZpZWQgRW50aXR5VHlwZSBpcyBub3QgZm91bmQuXHJcbiAgQHJldHVybiBUaGUgRW50aXR5VHlwZS4gQ29tcGxleFR5cGUgb3IgJ251bGwnIGlmIG5vdCBub3QgZm91bmQuXHJcbiAgKiovXHJcbiAgZ2V0QXNFbnRpdHlUeXBlKHR5cGVOYW1lOiBzdHJpbmcsIG9rSWZOb3RGb3VuZDogYm9vbGVhbiA9IGZhbHNlKSB7XHJcbiAgICBjb25zdCBzdCA9IHRoaXMuZ2V0U3RydWN0dXJhbFR5cGUodHlwZU5hbWUsIG9rSWZOb3RGb3VuZCk7XHJcbiAgICBpZiAoc3QgaW5zdGFuY2VvZiBFbnRpdHlUeXBlKSB7XHJcbiAgICAgIHJldHVybiBzdCBhcyBFbnRpdHlUeXBlO1xyXG4gICAgfSBlbHNlIGlmIChva0lmTm90Rm91bmQpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBsZXQgbXNnID0gY29yZS5mb3JtYXRTdHJpbmcoXCJVbmFibGUgdG8gbG9jYXRlIGFuICdFbnRpdHlUeXBlJyBieSB0aGUgbmFtZTogJyUxJy4gQmUgc3VyZSB0byBleGVjdXRlIGEgcXVlcnkgb3IgY2FsbCBmZXRjaE1ldGFkYXRhIGZpcnN0LlwiLCB0eXBlTmFtZSk7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhbiBbW0VudGl0eVR5cGVdXSBvciBudWxsIGdpdmVuIGl0cyBuYW1lLlxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGEgcHJlZXhpc3RpbmcgRW50aXR5TWFuYWdlclxyXG4gID4gICAgICBsZXQgbG9jVHlwZSA9IGVtMS5tZXRhZGF0YVN0b3JlLmdldEFzQ29tcGxleFR5cGUoXCJMb2NhdGlvblwiKTtcclxuXHJcbiAgb3IgdG8gdGhyb3cgYW4gZXJyb3IgaWYgdGhlIHR5cGUgaXMgbm90IGZvdW5kXHJcbiAgPiAgICAgIGxldCBiYWRUeXBlID0gZW0xLm1ldGFkYXRhU3RvcmUuZ2V0QXNDb21wbGV4VHlwZShcIkZvb1wiLCBmYWxzZSk7XHJcbiAgPiAgICAgIC8vIGJhZFR5cGUgd2lsbCBub3QgZ2V0IHNldCBhbmQgYW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLlxyXG4gIEBwYXJhbSBzdHJ1Y3R1cmFsVHlwZU5hbWUgLSBFaXRoZXIgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9yIGEgc2hvcnQgbmFtZSBtYXkgYmUgdXNlZC4gSWYgYSBzaG9ydCBuYW1lIGlzIHNwZWNpZmllZCBhbmQgbXVsdGlwbGUgdHlwZXMgc2hhcmVcclxuICB0aGF0IHNhbWUgc2hvcnQgbmFtZSBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uXHJcbiAgQHBhcmFtIG9rSWZOb3RGb3VuZCAtIChkZWZhdWx0PWZhbHNlKSBXaGV0aGVyIHRvIHRocm93IGFuIGVycm9yIGlmIHRoZSBzcGVjaWZpZWQgRW50aXR5VHlwZSBpcyBub3QgZm91bmQuXHJcbiAgQHJldHVybiBUaGUgRW50aXR5VHlwZS4gQ29tcGxleFR5cGUgb3IgJ251bGwnIGlmIG5vdCBub3QgZm91bmQuXHJcbiAgKiovXHJcbiBnZXRBc0NvbXBsZXhUeXBlKHR5cGVOYW1lOiBzdHJpbmcsIG9rSWZOb3RGb3VuZDogYm9vbGVhbiA9IGZhbHNlKSB7XHJcbiAgY29uc3Qgc3QgPSB0aGlzLmdldFN0cnVjdHVyYWxUeXBlKHR5cGVOYW1lLCBva0lmTm90Rm91bmQpO1xyXG4gIGlmIChzdCBpbnN0YW5jZW9mIENvbXBsZXhUeXBlKSB7XHJcbiAgICByZXR1cm4gc3QgYXMgQ29tcGxleFR5cGU7XHJcbiAgfSBlbHNlIGlmIChva0lmTm90Rm91bmQpIHtcclxuICAgIHJldHVybiBudWxsO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBsZXQgbXNnID0gY29yZS5mb3JtYXRTdHJpbmcoXCJVbmFibGUgdG8gbG9jYXRlIGFuICdDb21wbGV4VHlwZScgYnkgdGhlIG5hbWU6ICclMScuIEJlIHN1cmUgdG8gZXhlY3V0ZSBhIHF1ZXJ5IG9yIGNhbGwgZmV0Y2hNZXRhZGF0YSBmaXJzdC5cIiwgdHlwZU5hbWUpO1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XHJcbiAgfVxyXG59XHJcblxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIGFuIFtbRW50aXR5VHlwZV1dIG9yIGEgW1tDb21wbGV4VHlwZV1dIGdpdmVuIGl0cyBuYW1lLlxyXG4gIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IGdldFN0cnVjdHVyYWxUeXBlIGJ1dCAuLi4gaXQgaXMgcHJvYmFibHkgbW9yZSB1c2VmdWxsIHRvIGNhbGwgZWl0aGVyIGdldEFzRW50aXR5VHlwZSBvciBnZXRBc0NvbXBsZXhUeXBlIGluc3RlYWRcclxuICBAcGFyYW0gdHlwZU5hbWUgLSBFaXRoZXIgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9yIGEgc2hvcnQgbmFtZSBtYXkgYmUgdXNlZC4gSWYgYSBzaG9ydCBuYW1lIGlzIHNwZWNpZmllZCBhbmQgbXVsdGlwbGUgdHlwZXMgc2hhcmVcclxuICB0aGF0IHNhbWUgc2hvcnQgbmFtZSBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uXHJcbiAgQHBhcmFtIG9rSWZOb3RGb3VuZCAtIChkZWZhdWx0PWZhbHNlKSBXaGV0aGVyIHRvIHRocm93IGFuIGVycm9yIGlmIHRoZSBzcGVjaWZpZWQgRW50aXR5VHlwZSBpcyBub3QgZm91bmQuXHJcbiAgQHJldHVybiBUaGUgRW50aXR5VHlwZS4gQ29tcGxleFR5cGUgb3IgJ251bGwnIGlmIG5vdCBub3QgZm91bmQuXHJcbiAgKiovXHJcbiAgZ2V0RW50aXR5VHlwZSh0eXBlTmFtZTogc3RyaW5nLCBva0lmTm90Rm91bmQ6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG4gICAgcmV0dXJuIHRoaXMuZ2V0U3RydWN0dXJhbFR5cGUodHlwZU5hbWUsIG9rSWZOb3RGb3VuZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIGFuIFtbRW50aXR5VHlwZV1dIG9yIGEgW1tDb21wbGV4VHlwZV1dIGdpdmVuIGl0cyBuYW1lLlxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGEgcHJlZXhpc3RpbmcgRW50aXR5TWFuYWdlclxyXG4gID4gICAgICBsZXQgb2RUeXBlID0gZW0xLm1ldGFkYXRhU3RvcmUuZ2V0U3RydWN0dXJhbFR5cGUoXCJPcmRlckRldGFpbFwiKTtcclxuXHJcbiAgb3IgdG8gdGhyb3cgYW4gZXJyb3IgaWYgdGhlIHR5cGUgaXMgbm90IGZvdW5kXHJcbiAgPiAgICAgIGxldCBiYWRUeXBlID0gZW0xLm1ldGFkYXRhU3RvcmUuZ2V0U3RydWN0dXJhbFR5cGUoXCJGb29cIiwgZmFsc2UpO1xyXG4gID4gICAgICAvLyBiYWRUeXBlIHdpbGwgbm90IGdldCBzZXQgYW5kIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi5cclxuICBAZGVwcmVjYXRlZCBQcmVmZXJhYmx5IHVzZSBlaXRoZXIgZ2V0QXNFbnRpdHlUeXBlIG9yIGdldEFzQ29tcGxleFR5cGUuICBHZXRcclxuICBAcGFyYW0gdHlwZU5hbWUgLSBFaXRoZXIgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9yIGEgc2hvcnQgbmFtZSBtYXkgYmUgdXNlZC4gSWYgYSBzaG9ydCBuYW1lIGlzIHNwZWNpZmllZCBhbmQgbXVsdGlwbGUgdHlwZXMgc2hhcmVcclxuICB0aGF0IHNhbWUgc2hvcnQgbmFtZSBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uXHJcbiAgQHBhcmFtIG9rSWZOb3RGb3VuZCAtIChkZWZhdWx0PWZhbHNlKSBXaGV0aGVyIHRvIHRocm93IGFuIGVycm9yIGlmIHRoZSBzcGVjaWZpZWQgRW50aXR5VHlwZSBpcyBub3QgZm91bmQuXHJcbiAgQHJldHVybiBUaGUgRW50aXR5VHlwZS4gQ29tcGxleFR5cGUgb3IgJ251bGwnIGlmIG5vdCBub3QgZm91bmQuXHJcbiAgKiovXHJcbiAgZ2V0U3RydWN0dXJhbFR5cGUodHlwZU5hbWU6IHN0cmluZywgb2tJZk5vdEZvdW5kOiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgIGFzc2VydFBhcmFtKHR5cGVOYW1lLCBcInR5cGVOYW1lXCIpLmlzU3RyaW5nKCkuY2hlY2soKTtcclxuICAgIGFzc2VydFBhcmFtKG9rSWZOb3RGb3VuZCwgXCJva0lmTm90Rm91bmRcIikuaXNCb29sZWFuKCkuaXNPcHRpb25hbCgpLmNoZWNrKGZhbHNlKTtcclxuICAgIHJldHVybiB0aGlzLl9nZXRTdHJ1Y3R1cmFsVHlwZSh0eXBlTmFtZSwgb2tJZk5vdEZvdW5kKTtcclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9nZXRTdHJ1Y3R1cmFsVHlwZSh0eXBlTmFtZTogc3RyaW5nLCBva0lmTm90Rm91bmQ6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG4gICAgbGV0IHF1YWxUeXBlTmFtZSA9IGdldFF1YWxpZmllZFR5cGVOYW1lKHRoaXMsIHR5cGVOYW1lLCBmYWxzZSk7XHJcbiAgICBsZXQgdHlwZSA9IHRoaXMuX3N0cnVjdHVyYWxUeXBlTWFwW3F1YWxUeXBlTmFtZV07XHJcbiAgICBpZiAoIXR5cGUpIHtcclxuICAgICAgaWYgKG9rSWZOb3RGb3VuZCkgcmV0dXJuIG51bGw7XHJcbiAgICAgIGxldCBtc2cgPSBjb3JlLmZvcm1hdFN0cmluZyhcIlVuYWJsZSB0byBsb2NhdGUgYSAnVHlwZScgYnkgdGhlIG5hbWU6ICclMScuIEJlIHN1cmUgdG8gZXhlY3V0ZSBhIHF1ZXJ5IG9yIGNhbGwgZmV0Y2hNZXRhZGF0YSBmaXJzdC5cIiwgdHlwZU5hbWUpO1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0eXBlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIGFsbCBvZiB0aGUgW1tFbnRpdHlUeXBlXV1zIG9yIFtbQ29tcGxleFR5cGVdXXMgaW4gdGhpcyBNZXRhZGF0YVN0b3JlLlxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGEgcHJlZXhpc3RpbmcgRW50aXR5TWFuYWdlclxyXG4gID4gICAgICBsZXQgYWxsVHlwZXMgPSBlbTEubWV0YWRhdGFTdG9yZS5nZXRFbnRpdHlUeXBlcygpO1xyXG4gICoqL1xyXG4gIGdldEVudGl0eVR5cGVzKCkge1xyXG4gICAgcmV0dXJuIGdldFR5cGVzRnJvbU1hcCh0aGlzLl9zdHJ1Y3R1cmFsVHlwZU1hcCk7XHJcbiAgfVxyXG5cclxuICBnZXRJbmNvbXBsZXRlTmF2aWdhdGlvblByb3BlcnRpZXMoKSB7XHJcbiAgICByZXR1cm4gY29yZS5vYmplY3RNYXAodGhpcy5faW5jb21wbGV0ZVR5cGVNYXAsIGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XHJcbiAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIGZ1bGx5IHF1YWxpZmllZCBlbnRpdHlUeXBlTmFtZSBmb3IgYSBzcGVjaWZpZWQgcmVzb3VyY2UgbmFtZS4gIFRoZSByZXZlcnNlIG9mIHRoaXMgb3BlcmF0aW9uXHJcbiAgY2FuIGJlIG9idGFpbmVkIHZpYSB0aGUgIFtbRW50aXR5VHlwZS5kZWZhdWx0UmVzb3VyY2VOYW1lXV0gcHJvcGVydHlcclxuICAqKi9cclxuICBnZXRFbnRpdHlUeXBlTmFtZUZvclJlc291cmNlTmFtZShyZXNvdXJjZU5hbWU6IHN0cmluZykge1xyXG4gICAgYXNzZXJ0UGFyYW0ocmVzb3VyY2VOYW1lLCBcInJlc291cmNlTmFtZVwiKS5pc1N0cmluZygpLmNoZWNrKCk7XHJcbiAgICByZXR1cm4gdGhpcy5fcmVzb3VyY2VFbnRpdHlUeXBlTWFwW3Jlc291cmNlTmFtZV07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBBc3NvY2lhdGVzIGEgcmVzb3VyY2VOYW1lIHdpdGggYW4gZW50aXR5VHlwZS5cclxuXHJcbiAgVGhpcyBtZXRob2QgaXMgb25seSBuZWVkZWQgaW4gdGhvc2UgY2FzZXMgd2hlcmUgbXVsdGlwbGUgcmVzb3VyY2VzIHJldHVybiB0aGUgc2FtZVxyXG4gIGVudGl0eVR5cGUuICBJbiB0aGlzIGNhc2UgTWV0YWRhdGEgZGlzY292ZXJ5IHdpbGwgb25seSBkZXRlcm1pbmUgYSBzaW5nbGUgcmVzb3VyY2UgbmFtZSBmb3JcclxuICBlYWNoIGVudGl0eVR5cGUuXHJcbiAgQHBhcmFtIHJlc291cmNlTmFtZSAtIFRoZSByZXNvdXJjZSBuYW1lXHJcbiAgQHBhcmFtIGVudGl0eVR5cGVPck5hbWUgLSBJZiBwYXNzaW5nIGEgc3RyaW5nIGVpdGhlciB0aGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb3IgYSBzaG9ydCBuYW1lIG1heSBiZSB1c2VkLiBJZiBhIHNob3J0IG5hbWUgaXMgc3BlY2lmaWVkIGFuZCBtdWx0aXBsZSB0eXBlcyBzaGFyZVxyXG4gIHRoYXQgc2FtZSBzaG9ydCBuYW1lIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4gSWYgdGhlIGVudGl0eVR5cGUgaGFzIG5vdCB5ZXQgYmVlbiBkaXNjb3ZlcmVkIHRoZW4gYSBmdWxseSBxdWFsaWZpZWQgbmFtZSBtdXN0IGJlIHVzZWQuXHJcbiAgKiovXHJcbiAgc2V0RW50aXR5VHlwZUZvclJlc291cmNlTmFtZShyZXNvdXJjZU5hbWU6IHN0cmluZywgZW50aXR5VHlwZU9yTmFtZTogRW50aXR5VHlwZSB8IHN0cmluZykge1xyXG4gICAgYXNzZXJ0UGFyYW0ocmVzb3VyY2VOYW1lLCBcInJlc291cmNlTmFtZVwiKS5pc1N0cmluZygpLmNoZWNrKCk7XHJcbiAgICBhc3NlcnRQYXJhbShlbnRpdHlUeXBlT3JOYW1lLCBcImVudGl0eVR5cGVPck5hbWVcIikuaXNJbnN0YW5jZU9mKEVudGl0eVR5cGUpLm9yKCkuaXNTdHJpbmcoKS5jaGVjaygpO1xyXG5cclxuICAgIGxldCBlbnRpdHlUeXBlTmFtZTogc3RyaW5nO1xyXG4gICAgaWYgKGVudGl0eVR5cGVPck5hbWUgaW5zdGFuY2VvZiBFbnRpdHlUeXBlKSB7XHJcbiAgICAgIGVudGl0eVR5cGVOYW1lID0gZW50aXR5VHlwZU9yTmFtZS5uYW1lO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgZW50aXR5VHlwZU5hbWUgPSBnZXRRdWFsaWZpZWRUeXBlTmFtZSh0aGlzLCBlbnRpdHlUeXBlT3JOYW1lLCB0cnVlKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9yZXNvdXJjZUVudGl0eVR5cGVNYXBbcmVzb3VyY2VOYW1lXSA9IGVudGl0eVR5cGVOYW1lO1xyXG4gICAgbGV0IGVudGl0eVR5cGUgPSB0aGlzLl9nZXRTdHJ1Y3R1cmFsVHlwZShlbnRpdHlUeXBlTmFtZSwgdHJ1ZSk7XHJcbiAgICBpZiAoZW50aXR5VHlwZSAmJiBlbnRpdHlUeXBlIGluc3RhbmNlb2YgRW50aXR5VHlwZSAmJiAhZW50aXR5VHlwZS5kZWZhdWx0UmVzb3VyY2VOYW1lKSB7XHJcbiAgICAgIGVudGl0eVR5cGUuZGVmYXVsdFJlc291cmNlTmFtZSA9IHJlc291cmNlTmFtZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBfX0RldiBPbmx5X18gLSBmb3IgdXNlIHdoZW4gY3JlYXRpbmcgYSBuZXcgTWV0YWRhdGFQYXJzZXJBZGFwdGVyICAqL1xyXG4gIHN0YXRpYyBwYXJzZVR5cGVOYW1lKGVudGl0eVR5cGVOYW1lOiBzdHJpbmcpIHtcclxuICAgIC8vIFRPRE86IHJlbW92ZWQgXHJcbiAgICAvLyBpZiAoIWVudGl0eVR5cGVOYW1lKSB7XHJcbiAgICAvLyAgIHJldHVybiBudWxsO1xyXG4gICAgLy8gfVxyXG5cclxuICAgIGxldCB0eXBlUGFydHMgPSBlbnRpdHlUeXBlTmFtZS5zcGxpdChcIjojXCIpO1xyXG4gICAgaWYgKHR5cGVQYXJ0cy5sZW5ndGggPiAxKSB7XHJcbiAgICAgIHJldHVybiBNZXRhZGF0YVN0b3JlLm1ha2VUeXBlSGFzaCh0eXBlUGFydHNbMF0sIHR5cGVQYXJ0c1sxXSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGNvcmUuc3RyaW5nU3RhcnRzV2l0aChlbnRpdHlUeXBlTmFtZSwgTWV0YWRhdGFTdG9yZS5BTk9OVFlQRV9QUkVGSVgpKSB7XHJcbiAgICAgIGxldCB0eXBlSGFzaCA9IE1ldGFkYXRhU3RvcmUubWFrZVR5cGVIYXNoKGVudGl0eVR5cGVOYW1lKTtcclxuICAgICAgKHR5cGVIYXNoIGFzIGFueSkuaXNBbm9ueW1vdXMgPSB0cnVlO1xyXG4gICAgICByZXR1cm4gdHlwZUhhc2g7XHJcbiAgICB9XHJcbiAgICBsZXQgZW50aXR5VHlwZU5hbWVOb0Fzc2VtYmx5ID0gZW50aXR5VHlwZU5hbWUuc3BsaXQoXCIsXCIpWzBdO1xyXG4gICAgdHlwZVBhcnRzID0gZW50aXR5VHlwZU5hbWVOb0Fzc2VtYmx5LnNwbGl0KFwiLlwiKTtcclxuICAgIGlmICh0eXBlUGFydHMubGVuZ3RoID4gMSkge1xyXG4gICAgICBsZXQgc2hvcnROYW1lID0gdHlwZVBhcnRzW3R5cGVQYXJ0cy5sZW5ndGggLSAxXTtcclxuICAgICAgbGV0IG5hbWVzcGFjZVBhcnRzID0gdHlwZVBhcnRzLnNsaWNlKDAsIHR5cGVQYXJ0cy5sZW5ndGggLSAxKTtcclxuICAgICAgbGV0IG5zID0gbmFtZXNwYWNlUGFydHMuam9pbihcIi5cIik7XHJcbiAgICAgIHJldHVybiBNZXRhZGF0YVN0b3JlLm1ha2VUeXBlSGFzaChzaG9ydE5hbWUsIG5zKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBNZXRhZGF0YVN0b3JlLm1ha2VUeXBlSGFzaChlbnRpdHlUeXBlTmFtZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogX19EZXYgT25seV9fIC0gZm9yIHVzZSB3aGVuIGNyZWF0aW5nIGEgbmV3IE1ldGFkYXRhUGFyc2VyQWRhcHRlciAgKi9cclxuICBzdGF0aWMgbWFrZVR5cGVIYXNoKHNob3J0TmFtZTogc3RyaW5nLCBucz86IHN0cmluZykge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgc2hvcnRUeXBlTmFtZTogc2hvcnROYW1lLFxyXG4gICAgICBuYW1lc3BhY2U6IG5zLFxyXG4gICAgICB0eXBlTmFtZTogcXVhbGlmeVR5cGVOYW1lKHNob3J0TmFtZSwgbnMpXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLy8gcHJvdGVjdGVkIG1ldGhvZHNcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfY2hlY2tFbnRpdHlUeXBlKGVudGl0eTogRW50aXR5KSB7XHJcbiAgICBpZiAoZW50aXR5LmVudGl0eVR5cGUpIHJldHVybjtcclxuICAgIGxldCB0eXBlTmFtZSA9IGVudGl0eS5wcm90b3R5cGUuXyR0eXBlTmFtZTtcclxuICAgIGlmICghdHlwZU5hbWUpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbnRpdHkgaGFzIG5vdCBiZWVuIHJlZ2lzdGVyZWQuIFNlZSB0aGUgTWV0YWRhdGFTdG9yZS5yZWdpc3RlckVudGl0eVR5cGVDdG9yIG1ldGhvZFwiKTtcclxuICAgIH1cclxuICAgIC8vIHdlIGtub3cgdGhhdCBpdCBpcyBhbiBFbnRpdHlUeXBlICggYXMgb3Bwb3NlZCB0byBhIENvbXBsZXhUeXBlKVxyXG4gICAgbGV0IGVudGl0eVR5cGUgPSB0aGlzLl9nZXRTdHJ1Y3R1cmFsVHlwZSh0eXBlTmFtZSkgYXMgRW50aXR5VHlwZTtcclxuICAgIGlmIChlbnRpdHlUeXBlKSB7XHJcbiAgICAgIGVudGl0eS5lbnRpdHlUeXBlID0gZW50aXR5VHlwZTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxufVxyXG5NZXRhZGF0YVN0b3JlLnByb3RvdHlwZS5fJHR5cGVOYW1lID0gXCJNZXRhZGF0YVN0b3JlXCI7XHJcblxyXG5CcmVlemVFdmVudC5idWJibGVFdmVudChNZXRhZGF0YVN0b3JlLnByb3RvdHlwZSk7XHJcblxyXG5mdW5jdGlvbiBnZXRUeXBlc0Zyb21NYXAodHlwZU1hcDogSVN0cnVjdHVyYWxUeXBlTWFwKSB7XHJcbiAgbGV0IHR5cGVzOiAoU3RydWN0dXJhbFR5cGUpW10gPSBbXTtcclxuICBmb3IgKGxldCBrZXkgaW4gdHlwZU1hcCkge1xyXG4gICAgbGV0IHZhbHVlID0gdHlwZU1hcFtrZXldO1xyXG4gICAgLy8gc2tpcCAnc2hvcnROYW1lJyBlbnRyaWVzXHJcbiAgICBpZiAoa2V5ID09PSB2YWx1ZS5uYW1lKSB7XHJcbiAgICAgIHR5cGVzLnB1c2godHlwZU1hcFtrZXldKTtcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIHR5cGVzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzdHJ1Y3R1cmFsVHlwZUZyb21Kc29uKG1ldGFkYXRhU3RvcmU6IE1ldGFkYXRhU3RvcmUsIGpzb246IGFueSwgYWxsb3dNZXJnZTogYm9vbGVhbikge1xyXG4gIGxldCB0eXBlTmFtZSA9IHF1YWxpZnlUeXBlTmFtZShqc29uLnNob3J0TmFtZSwganNvbi5uYW1lc3BhY2UpO1xyXG4gIGxldCBzdHlwZSA9IG1ldGFkYXRhU3RvcmUuX2dldFN0cnVjdHVyYWxUeXBlKHR5cGVOYW1lLCB0cnVlKTtcclxuICBpZiAoc3R5cGUpIHtcclxuICAgIGlmIChhbGxvd01lcmdlKSB7XHJcbiAgICAgIHJldHVybiBtZXJnZVN0cnVjdHVyYWxUeXBlKHN0eXBlLCBqc29uKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIGFsbG93IGl0IGJ1dCBkb24ndCByZXBsYWNlIGFueXRoaW5nLlxyXG4gICAgICByZXR1cm4gc3R5cGU7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGxldCBjb25maWcgPSB7XHJcbiAgICBzaG9ydE5hbWU6IGpzb24uc2hvcnROYW1lLFxyXG4gICAgbmFtZXNwYWNlOiBqc29uLm5hbWVzcGFjZSxcclxuICAgIGlzQWJzdHJhY3Q6IGpzb24uaXNBYnN0cmFjdCxcclxuICAgIGF1dG9HZW5lcmF0ZWRLZXlUeXBlOiBBdXRvR2VuZXJhdGVkS2V5VHlwZS5mcm9tTmFtZShqc29uLmF1dG9HZW5lcmF0ZWRLZXlUeXBlKSxcclxuICAgIGRlZmF1bHRSZXNvdXJjZU5hbWU6IGpzb24uZGVmYXVsdFJlc291cmNlTmFtZSxcclxuICAgIGN1c3RvbToganNvbi5jdXN0b21cclxuICB9O1xyXG5cclxuICBzdHlwZSA9IGpzb24uaXNDb21wbGV4VHlwZSA/IG5ldyBDb21wbGV4VHlwZShjb25maWcpIDogbmV3IEVudGl0eVR5cGUoY29uZmlnKTtcclxuXHJcbiAgLy8gYmFzZVR5cGUgbWF5IG5vdCBoYXZlIGJlZW4gaW1wb3J0ZWQgeWV0IHNvIHdlIG5lZWQgdG8gZGVmZXIgaGFuZGxpbmcgdGhpcyB0eXBlIHVudGlsIGxhdGVyLlxyXG4gIGlmIChqc29uLmJhc2VUeXBlTmFtZSAmJiBzdHlwZSBpbnN0YW5jZW9mIEVudGl0eVR5cGUpIHtcclxuICAgIHN0eXBlLmJhc2VUeXBlTmFtZSA9IGpzb24uYmFzZVR5cGVOYW1lO1xyXG4gICAgbGV0IGJhc2VFbnRpdHlUeXBlID0gbWV0YWRhdGFTdG9yZS5fZ2V0U3RydWN0dXJhbFR5cGUoanNvbi5iYXNlVHlwZU5hbWUsIHRydWUpO1xyXG4gICAgaWYgKGJhc2VFbnRpdHlUeXBlKSB7XHJcbiAgICAgIGNvbXBsZXRlU3RydWN0dXJhbFR5cGVGcm9tSnNvbihtZXRhZGF0YVN0b3JlLCBqc29uLCBzdHlwZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb3JlLmdldEFycmF5KG1ldGFkYXRhU3RvcmUuX2RlZmVycmVkVHlwZXMsIGpzb24uYmFzZVR5cGVOYW1lKS5wdXNoKHsganNvbjoganNvbiwgc3R5cGU6IHN0eXBlIH0pO1xyXG5cclxuICAgIH1cclxuICB9IGVsc2Uge1xyXG4gICAgY29tcGxldGVTdHJ1Y3R1cmFsVHlwZUZyb21Kc29uKG1ldGFkYXRhU3RvcmUsIGpzb24sIHN0eXBlKTtcclxuICB9XHJcblxyXG4gIC8vIHN0eXBlIG1heSBvciBtYXkgbm90IGhhdmUgYmVlbiBhZGRlZCB0byB0aGUgbWV0YWRhdGFTdG9yZSBhdCB0aGlzIHBvaW50LlxyXG4gIHJldHVybiBzdHlwZTtcclxufVxyXG5cclxuZnVuY3Rpb24gbWVyZ2VTdHJ1Y3R1cmFsVHlwZShzdHlwZTogU3RydWN0dXJhbFR5cGUsIGpzb246IGFueSkge1xyXG4gIGlmIChqc29uLmN1c3RvbSkge1xyXG4gICAgc3R5cGUuY3VzdG9tID0ganNvbi5jdXN0b207XHJcbiAgfVxyXG5cclxuICBtZXJnZVByb3BzKHN0eXBlLCBqc29uLmRhdGFQcm9wZXJ0aWVzKTtcclxuICBtZXJnZVByb3BzKHN0eXBlLCBqc29uLm5hdmlnYXRpb25Qcm9wZXJ0aWVzKTtcclxuICByZXR1cm4gc3R5cGU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG1lcmdlUHJvcHMoc3R5cGU6IFN0cnVjdHVyYWxUeXBlLCBqc29uUHJvcHM6IGFueVtdKSB7XHJcbiAgaWYgKCFqc29uUHJvcHMpIHJldHVybjtcclxuICBqc29uUHJvcHMuZm9yRWFjaCgoanNvblByb3ApID0+IHtcclxuICAgIGxldCBwcm9wTmFtZSA9IGpzb25Qcm9wLm5hbWU7XHJcbiAgICBpZiAoIXByb3BOYW1lKSB7XHJcbiAgICAgIGlmIChqc29uUHJvcC5uYW1lT25TZXJ2ZXIpIHtcclxuICAgICAgICBwcm9wTmFtZSA9IHN0eXBlLm1ldGFkYXRhU3RvcmUubmFtaW5nQ29udmVudGlvbi5zZXJ2ZXJQcm9wZXJ0eU5hbWVUb0NsaWVudChqc29uUHJvcC5uYW1lT25TZXJ2ZXIsIHt9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBiYWNrc2xhc2gtcXVvdGUgd29ya3MgYXJvdW5kIGNvbXBpbGVyIGJ1Z1xyXG4gICAgICAgIGNvbnN0IG1zZyA9IFwiVW5hYmxlIHRvIGNvbXBsZXRlIFxcJ2ltcG9ydE1ldGFkYXRhXFwnIC0gY2Fubm90IGxvY2F0ZSBhIFxcJ25hbWVcXCcgb3IgXFwnbmFtZU9uU2VydmVyXFwnIGZvciBvbmUgb2YgdGhlIGltcG9ydGVkIHByb3BlcnR5IG5vZGVzXCI7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChqc29uUHJvcC5jdXN0b20pIHtcclxuICAgICAgbGV0IHByb3AgPSBzdHlwZS5nZXRQcm9wZXJ0eShwcm9wTmFtZSwgdHJ1ZSk7XHJcbiAgICAgIHByb3AhLmN1c3RvbSA9IGpzb25Qcm9wLmN1c3RvbTtcclxuICAgIH1cclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gY29tcGxldGVTdHJ1Y3R1cmFsVHlwZUZyb21Kc29uKG1ldGFkYXRhU3RvcmU6IE1ldGFkYXRhU3RvcmUsIGpzb246IGFueSwgc3R5cGU6IGFueSkge1xyXG5cclxuICAvLyB2YWxpZGF0b3JzIGZyb20gYmFzZVR5cGUgd29yayBiZWNhdXNlIHZhbGlkYXRpb24gd2Fsa3MgdGhydSBiYXNlIHR5cGVzXHJcbiAgLy8gc28gbm8gbmVlZCB0byBjb3B5IGRvd24uXHJcbiAgaWYgKGpzb24udmFsaWRhdG9ycykge1xyXG4gICAgc3R5cGUudmFsaWRhdG9ycyA9IGpzb24udmFsaWRhdG9ycy5tYXAoVmFsaWRhdG9yLmZyb21KU09OKTtcclxuICB9XHJcblxyXG4gIGpzb24uZGF0YVByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbiAoZHA6IE9iamVjdCkge1xyXG4gICAgc3R5cGUuX2FkZFByb3BlcnR5Q29yZShEYXRhUHJvcGVydHkuZnJvbUpTT04oZHApKTtcclxuICB9KTtcclxuXHJcblxyXG4gIGxldCBpc0VudGl0eVR5cGUgPSAhanNvbi5pc0NvbXBsZXhUeXBlO1xyXG4gIGlmIChpc0VudGl0eVR5cGUpIHtcclxuICAgIC8vbm9pbnNwZWN0aW9uIEpTSGludFxyXG4gICAganNvbi5uYXZpZ2F0aW9uUHJvcGVydGllcyAmJiBqc29uLm5hdmlnYXRpb25Qcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24gKG5wOiBPYmplY3QpIHtcclxuICAgICAgc3R5cGUuX2FkZFByb3BlcnR5Q29yZShOYXZpZ2F0aW9uUHJvcGVydHkuZnJvbUpTT04obnApKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbWV0YWRhdGFTdG9yZS5hZGRFbnRpdHlUeXBlKHN0eXBlKTtcclxuXHJcbiAgbGV0IGRlZmVycmVkVHlwZXMgPSBtZXRhZGF0YVN0b3JlLl9kZWZlcnJlZFR5cGVzO1xyXG4gIGxldCBkZWZlcnJhbHMgPSBkZWZlcnJlZFR5cGVzW3N0eXBlLm5hbWVdO1xyXG4gIGlmIChkZWZlcnJhbHMpIHtcclxuICAgIGRlZmVycmFscy5mb3JFYWNoKGZ1bmN0aW9uIChkOiBhbnkpIHtcclxuICAgICAgY29tcGxldGVTdHJ1Y3R1cmFsVHlwZUZyb21Kc29uKG1ldGFkYXRhU3RvcmUsIGQuanNvbiwgZC5zdHlwZSk7XHJcbiAgICB9KTtcclxuICAgIGRlbGV0ZSBkZWZlcnJlZFR5cGVzW3N0eXBlLm5hbWVdO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0UXVhbGlmaWVkVHlwZU5hbWUobWV0YWRhdGFTdG9yZTogTWV0YWRhdGFTdG9yZSwgc3RydWN0VHlwZU5hbWU6IHN0cmluZywgdGhyb3dJZk5vdEZvdW5kPzogYm9vbGVhbikge1xyXG4gIGlmIChpc1F1YWxpZmllZFR5cGVOYW1lKHN0cnVjdFR5cGVOYW1lKSkgcmV0dXJuIHN0cnVjdFR5cGVOYW1lO1xyXG4gIGxldCByZXN1bHQgPSBtZXRhZGF0YVN0b3JlLl9zaG9ydE5hbWVNYXBbc3RydWN0VHlwZU5hbWVdO1xyXG4gIGlmICghcmVzdWx0ICYmIHRocm93SWZOb3RGb3VuZCkge1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVW5hYmxlIHRvIGxvY2F0ZSAnZW50aXR5VHlwZU5hbWUnIG9mOiBcIiArIHN0cnVjdFR5cGVOYW1lKTtcclxuICB9XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuLyoqIENvbmZpZ3VyYXRpb24gaW5mbyB0byBiZSBwYXNzZWQgdG8gdGhlIFtbRW50aXR5VHlwZV1dIGNvbnN0cnVjdG9yICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRW50aXR5VHlwZUNvbmZpZyB7XHJcbiAgc2hvcnROYW1lPzogc3RyaW5nO1xyXG4gIG5hbWVzcGFjZT86IHN0cmluZztcclxuICBiYXNlVHlwZU5hbWU/OiBzdHJpbmc7XHJcbiAgaXNBYnN0cmFjdD86IGJvb2xlYW47XHJcbiAgYXV0b0dlbmVyYXRlZEtleVR5cGU/OiBBdXRvR2VuZXJhdGVkS2V5VHlwZTtcclxuICBkZWZhdWx0UmVzb3VyY2VOYW1lPzogc3RyaW5nO1xyXG4gIGRhdGFQcm9wZXJ0aWVzPzogRGF0YVByb3BlcnR5W10gfCBPYmplY3RbXSB8IE9iamVjdDsgIC8vIFRPRE86IHNlZSBpZiB3ZSBjYW4ndCBxdWFsaWZ5IE9iamVjdFtdIGEgbGl0dGxlIGJldHRlci5cclxuICBuYXZpZ2F0aW9uUHJvcGVydGllcz86IE5hdmlnYXRpb25Qcm9wZXJ0eVtdIHwgT2JqZWN0W10gfCBPYmplY3Q7XHJcbiAgc2VyaWFsaXplckZuPzogKHByb3A6IEVudGl0eVByb3BlcnR5LCB2YWw6IGFueSkgPT4gYW55O1xyXG4gIGN1c3RvbT86IE9iamVjdDtcclxufVxyXG5cclxuLyoqIENvbmZpZ3VyYXRpb24gaW5mbyB0byBiZSBwYXNzZWQgdG8gdGhlIFtbRW50aXR5VHlwZS5zZXRQcm9wZXJ0aWVzXV0gbWV0aG9kICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRW50aXR5VHlwZVNldENvbmZpZyB7XHJcbiAgYXV0b0dlbmVyYXRlZEtleVR5cGU/OiBBdXRvR2VuZXJhdGVkS2V5VHlwZTtcclxuICBkZWZhdWx0UmVzb3VyY2VOYW1lPzogc3RyaW5nO1xyXG4gIHNlcmlhbGl6ZXJGbj86IChwcm9wOiBFbnRpdHlQcm9wZXJ0eSwgdmFsOiBhbnkpID0+IGFueTtcclxuICBjdXN0b20/OiBPYmplY3Q7XHJcbn1cclxuXHJcbi8qKiBDb250YWluZXIgZm9yIGFsbCBvZiB0aGUgbWV0YWRhdGEgYWJvdXQgYSBzcGVjaWZpYyB0eXBlIG9mIEVudGl0eS5cclxuKiovXHJcbmV4cG9ydCBjbGFzcyBFbnRpdHlUeXBlIHtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfJHR5cGVOYW1lOiBzdHJpbmc7IC8vIG9uIHByb3RvXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgc3RhdGljIF9fbmV4dEFub25JeCA9IDA7XHJcbiAgLyoqIEFsd2F5cyBmYWxzZSBmb3IgYW4gRW50aXR5VHlwZS4gKiovXHJcbiAgaXNDb21wbGV4VHlwZSA9IGZhbHNlO1xyXG4gIC8qKiBUaGUgW1tNZXRhZGF0YVN0b3JlXV0gdGhhdCBjb250YWlucyB0aGlzIEVudGl0eVR5cGUuIF9fUmVhZCBPbmx5X18gKiovXHJcbiAgbWV0YWRhdGFTdG9yZTogTWV0YWRhdGFTdG9yZTtcclxuICAvKiogVGhlIERhdGFQcm9wZXJ0aWVzIChzZWUgW1tEYXRhUHJvcGVydHldXSBhc3NvY2lhdGVkIHdpdGggdGhpcyBFbnRpdHlUeXBlLiBfX1JlYWQgT25seV9fICAqKi9cclxuICBkYXRhUHJvcGVydGllczogRGF0YVByb3BlcnR5W107XHJcbiAgLyoqICBUaGUgTmF2aWdhdGlvblByb3BlcnRpZXMgKHNlZSBbW05hdmlnYXRpb25Qcm9wZXJ0eV1dIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEVudGl0eVR5cGUuIF9fUmVhZCBPbmx5X18gICoqL1xyXG4gIG5hdmlnYXRpb25Qcm9wZXJ0aWVzOiBOYXZpZ2F0aW9uUHJvcGVydHlbXTtcclxuICAvKipcclxuICBUaGUgRGF0YVByb3BlcnRpZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgRW50aXR5VHlwZSB0aGF0IG1ha2UgdXAgaXQncyBbW0VudGl0eUtleV1dLiBfX1JlYWQgT25seV9fICoqL1xyXG4gIGtleVByb3BlcnRpZXM6IERhdGFQcm9wZXJ0eVtdO1xyXG4gIC8qKiBUaGUgRGF0YVByb3BlcnRpZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgRW50aXR5VHlwZSB0aGF0IGFyZSBmb3JlaWduIGtleSBwcm9wZXJ0aWVzLiBfX1JlYWQgT25seV9fICoqL1xyXG4gIGZvcmVpZ25LZXlQcm9wZXJ0aWVzOiBEYXRhUHJvcGVydHlbXTtcclxuICBpbnZlcnNlRm9yZWlnbktleVByb3BlcnRpZXM6IERhdGFQcm9wZXJ0eVtdO1xyXG4gIC8qKiAgVGhlIERhdGFQcm9wZXJ0aWVzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEVudGl0eVR5cGUgdGhhdCBhcmUgY29uY3VycmVuY3kgcHJvcGVydGllcy4gX19SZWFkIE9ubHlfXyAqKi9cclxuICBjb25jdXJyZW5jeVByb3BlcnRpZXM6IERhdGFQcm9wZXJ0eVtdO1xyXG4gIC8qKiBUaGUgRGF0YVByb3BlcnRpZXMgZm9yIHRoaXMgRW50aXR5VHlwZSB0aGF0IGNvbnRhaW4gaW5zdGFuY2VzIG9mIGEgW1tDb21wbGV4VHlwZV1dLiBfX1JlYWQgT25seV9fICAgKiovXHJcbiAgY29tcGxleFByb3BlcnRpZXM6IERhdGFQcm9wZXJ0eVtdO1xyXG4gIC8qKiBUaGUgRGF0YVByb3BlcnRpZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgRW50aXR5VHlwZSB0aGF0IGFyZSBub3QgbWFwcGVkIHRvIGFueSBiYWNrZW5kIGRhdGFzdG9yZS4gVGhlc2UgYXJlIGVmZmVjdGl2ZWx5IGZyZWUgc3RhbmRpbmdcclxuICBwcm9wZXJ0aWVzLiBfX1JlYWQgT25seV9fICoqL1xyXG4gIHVubWFwcGVkUHJvcGVydGllczogRGF0YVByb3BlcnR5W107XHJcblxyXG4gIC8qKiBUaGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb2YgdGhpcyBFbnRpdHlUeXBlLiBfX1JlYWQgT25seV9fICAqKi9cclxuICBuYW1lOiBzdHJpbmc7XHJcbiAgLyoqIFRoZSBzaG9ydCwgdW5xdWFsaWZpZWQsIG5hbWUgZm9yIHRoaXMgRW50aXR5VHlwZS4gX19SZWFkIE9ubHlfXyAgKiovXHJcbiAgc2hvcnROYW1lOiBzdHJpbmc7XHJcbiAgLyoqIFRoZSBuYW1lc3BhY2UgZm9yIHRoaXMgRW50aXR5VHlwZS4gX19SZWFkIE9ubHlfXyAgKiovXHJcbiAgbmFtZXNwYWNlOiBzdHJpbmc7XHJcbiAgLyoqIFRoZSBuYW1lIG9mIHRoaXMgRW50aXR5VHlwZSdzIGJhc2UgRW50aXR5VHlwZSAgKGlmIGFueSkgKi9cclxuICBiYXNlVHlwZU5hbWU/OiBzdHJpbmc7XHJcbiAgLyoqIFRoZSBiYXNlIEVudGl0eVR5cGUgKGlmIGFueSkgZm9yIHRoaXMgRW50aXR5VHlwZS4gX19SZWFkIE9ubHlfXyAgICoqL1xyXG4gIGJhc2VFbnRpdHlUeXBlOiBFbnRpdHlUeXBlO1xyXG4gIHN1YnR5cGVzOiBFbnRpdHlUeXBlW107XHJcblxyXG4gIC8qKiAgV2hldGhlciB0aGlzIEVudGl0eVR5cGUgaXMgYWJzdHJhY3QuIF9fUmVhZCBPbmx5X18gKiovXHJcbiAgaXNBYnN0cmFjdDogYm9vbGVhbjtcclxuICAvKiogIFdoZXRoZXIgdGhpcyBFbnRpdHlUeXBlIGlzIGFub255bW91cy4gQW5vbnltb3VzIHR5cGVzIHdpbGwgbmV2ZXIgYmUgY29tbXVuaWNhdGVkIHRvIG9yIGZyb20gdGhlIHNlcnZlci4gVGhleSBhcmUgcHVyZWx5IGZvclxyXG4gIGNsaWVudCBzaWRlIHVzZSBhbmQgYXJlIGdpdmVuIGFuIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIG5hbWUuICBfX1JlYWQgT25seV9fICoqL1xyXG4gIGlzQW5vbnltb3VzOiBib29sZWFuO1xyXG4gIC8qKiBXaGV0aGVyIHRoaXMgRW50aXR5VHlwZSBoYXMgYmVlbiAnZnJvemVuJy4gIEVudGl0eVR5cGVzIGJlY29tZSBmcm96ZW4gYWZ0ZXIgdGhlIGZpcnN0IGluc3RhbmNlIFxyXG4gIG9mIHRoYXQgdHlwZSBoYXMgYmVlbiBjcmVhdGVkIGFuZCBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLiAqL1xyXG4gIGlzRnJvemVuOiBib29sZWFuO1xyXG5cclxuICAvKiogVGhlIFtbQXV0b0dlbmVyYXRlZEtleVR5cGVdXSBmb3IgdGhpcyBFbnRpdHlUeXBlLiBfX1JlYWQgT25seV9fICoqL1xyXG4gIGF1dG9HZW5lcmF0ZWRLZXlUeXBlOiBBdXRvR2VuZXJhdGVkS2V5VHlwZTtcclxuICAvKiogICBUaGUgZGVmYXVsdCByZXNvdXJjZSBuYW1lIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEVudGl0eVR5cGUuICBBbiBFbnRpdHlUeXBlIG1heSBiZSBxdWVyaWVkIHZpYSBhIHZhcmlldHkgb2YgJ3Jlc291cmNlIG5hbWVzJyBidXQgdGhpcyBvbmVcclxuICBpcyB1c2VkIGFzIHRoZSBkZWZhdWx0IHdoZW4gbm8gcmVzb3VyY2UgbmFtZSBpcyBwcm92aWRlZC4gIFRoaXMgd2lsbCBvY2N1ciB3aGVuIGNhbGxpbmcgW1tFbnRpdHlBc3BlY3QubG9hZE5hdmlnYXRpb25Qcm9wZXJ0eV1dXHJcbiAgb3Igd2hlbiBleGVjdXRpbmcgYW55IFtbRW50aXR5UXVlcnldXSB0aGF0IHdhcyBjcmVhdGVkIHZpYSBhbiBbW0VudGl0eUtleV1dLiBfX1JlYWQgT25seV9fICoqL1xyXG4gIGRlZmF1bHRSZXNvdXJjZU5hbWU6IHN0cmluZztcclxuICAvKiogQSBmdW5jdGlvbiB0aGF0IGlzIHVzZWQgdG8gY3VzdG9taXplIHRoZSBzZXJpYWxpemF0aW9uIG9mIGFueSBFbnRpdHlQcm9wZXJ0aWVzIG9mIHRoaXMgdHlwZS4gKi9cclxuICBzZXJpYWxpemVyRm4/OiAocHJvcDogRW50aXR5UHJvcGVydHksIHZhbDogYW55KSA9PiBhbnk7XHJcbiAgLyoqICBBIGZyZWUgZm9ybSBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byBkZWZpbmUgYW55IGN1c3RvbSBtZXRhZGF0YSBmb3IgdGhpcyBFbnRpdHlUeXBlLiBfX1JlYWQgT25seV9fICAqKi9cclxuICBjdXN0b20/OiBPYmplY3Q7XHJcbiAgLyoqIFRoZSBlbnRpdHkgbGV2ZWwgdmFsaWRhdG9ycyBhc3NvY2lhdGVkIHdpdGggdGhpcyBFbnRpdHlUeXBlLiBWYWxpZGF0b3JzIGNhbiBiZSBhZGRlZCBhbmRcclxuICByZW1vdmVkIGZyb20gdGhpcyBjb2xsZWN0aW9uLiBfX1JlYWQgT25seV9fLiAgICoqL1xyXG4gIHZhbGlkYXRvcnM6IFZhbGlkYXRvcltdO1xyXG5cclxuICB3YXJuaW5nczogYW55W107XHJcbiAgaW5pdEZuOiBGdW5jdGlvbiB8IHN0cmluZztcclxuICBub1RyYWNraW5nRm46IEZ1bmN0aW9uO1xyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfZXh0cmE6IGFueTtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfY3RvcjogeyBuZXcgKCk6IFN0cnVjdHVyYWxPYmplY3QgfTtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfbWFwcGVkUHJvcGVydGllc0NvdW50OiBudW1iZXI7XHJcblxyXG4gIC8qKiBcclxuICBAZGVwcmVjYXRlZCBVc2UgW1tnZXRDdG9yXV0gaW5zdGVhZC4gICBcclxuICAqL1xyXG4gIGdldEVudGl0eUN0b3IgPSB0aGlzLmdldEN0b3I7XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIHN0YXRpYyBxdWFsaWZ5VHlwZU5hbWUgPSBxdWFsaWZ5VHlwZU5hbWU7XHJcblxyXG5cclxuICAvKiogRW50aXR5VHlwZSBjb25zdHJ1Y3RvciAgXHJcbiAgPiAgICAgIGxldCBlbnRpdHlUeXBlID0gbmV3IEVudGl0eVR5cGUoIHtcclxuICA+ICAgICAgICAgIHNob3J0TmFtZTogXCJwZXJzb25cIixcclxuICA+ICAgICAgICAgIG5hbWVzcGFjZTogXCJteUFwcE5hbWVzcGFjZVwiXHJcbiAgPiAgICAgIH0pO1xyXG4gIEBwYXJhbSBjb25maWcgLSBDb25maWd1cmF0aW9uIHNldHRpbmdzIG9yIGEgTWV0YWRhdGFTdG9yZS4gIElmIHRoaXMgcGFyYW1ldGVyIGlzIGp1c3QgYSBNZXRhZGF0YVN0b3JlXHJcbiAgdGhlbiB3aGF0IHdpbGwgYmUgY3JlYXRlZCBpcyBhbiAnYW5vbnltb3VzJyB0eXBlIHRoYXQgd2lsbCBuZXZlciBiZSBjb21tdW5pY2F0ZWQgdG8gb3IgZnJvbSB0aGUgc2VydmVyLiBJdCBpcyBwdXJlbHkgZm9yXHJcbiAgY2xpZW50IHNpZGUgdXNlIGFuZCB3aWxsIGJlIGdpdmVuIGFuIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIG5hbWUuIE5vcm1hbGx5LCBob3dldmVyLCB5b3Ugd2lsbCB1c2UgYSBjb25maWd1cmF0aW9uIG9iamVjdC5cclxuICAqKi9cclxuICBjb25zdHJ1Y3Rvcihjb25maWc6IE1ldGFkYXRhU3RvcmUgfCBFbnRpdHlUeXBlQ29uZmlnKSB7XHJcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIEVudGl0eVR5cGUgY3RvciBoYXMgYSBzaW5nbGUgYXJndW1lbnQgdGhhdCBpcyBlaXRoZXIgYSAnTWV0YWRhdGFTdG9yZScgb3IgYSBjb25maWd1cmF0aW9uIG9iamVjdC5cIik7XHJcbiAgICB9XHJcbiAgICAvLyBsZXQgZXRDb25maWcgPSAgPEVudGl0eVR5cGVDb25maWc+IDxhbnk+IHVuZGVmaW5lZDtcclxuICAgIGxldCBldENvbmZpZzogRW50aXR5VHlwZUNvbmZpZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICBpZiAoKGNvbmZpZyBhcyBhbnkpLl8kdHlwZU5hbWUgPT09IFwiTWV0YWRhdGFTdG9yZVwiKSB7XHJcbiAgICAgIHRoaXMubWV0YWRhdGFTdG9yZSA9IGNvbmZpZyBhcyBNZXRhZGF0YVN0b3JlO1xyXG4gICAgICB0aGlzLnNob3J0TmFtZSA9IFwiQW5vbl9cIiArICgrK0VudGl0eVR5cGUuX19uZXh0QW5vbkl4KTtcclxuICAgICAgdGhpcy5uYW1lc3BhY2UgPSBcIlwiO1xyXG4gICAgICB0aGlzLmlzQW5vbnltb3VzID0gdHJ1ZTtcclxuICAgICAgLy8gZXRDb25maWcgPSB1bmRlZmluZWQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBldENvbmZpZyA9IGNvbmZpZyBhcyBFbnRpdHlUeXBlQ29uZmlnO1xyXG4gICAgICBhc3NlcnRDb25maWcoY29uZmlnKVxyXG4gICAgICAgIC53aGVyZVBhcmFtKFwic2hvcnROYW1lXCIpLmlzTm9uRW1wdHlTdHJpbmcoKVxyXG4gICAgICAgIC53aGVyZVBhcmFtKFwibmFtZXNwYWNlXCIpLmlzU3RyaW5nKCkuaXNPcHRpb25hbCgpLndpdGhEZWZhdWx0KFwiXCIpXHJcbiAgICAgICAgLndoZXJlUGFyYW0oXCJiYXNlVHlwZU5hbWVcIikuaXNTdHJpbmcoKS5pc09wdGlvbmFsKClcclxuICAgICAgICAud2hlcmVQYXJhbShcImlzQWJzdHJhY3RcIikuaXNCb29sZWFuKCkuaXNPcHRpb25hbCgpLndpdGhEZWZhdWx0KGZhbHNlKVxyXG4gICAgICAgIC53aGVyZVBhcmFtKFwiYXV0b0dlbmVyYXRlZEtleVR5cGVcIikuaXNFbnVtT2YoQXV0b0dlbmVyYXRlZEtleVR5cGUpLmlzT3B0aW9uYWwoKS53aXRoRGVmYXVsdChBdXRvR2VuZXJhdGVkS2V5VHlwZS5Ob25lKVxyXG4gICAgICAgIC53aGVyZVBhcmFtKFwiZGVmYXVsdFJlc291cmNlTmFtZVwiKS5pc05vbkVtcHR5U3RyaW5nKCkuaXNPcHRpb25hbCgpLndpdGhEZWZhdWx0KG51bGwpXHJcbiAgICAgICAgLndoZXJlUGFyYW0oXCJkYXRhUHJvcGVydGllc1wiKS5pc09wdGlvbmFsKClcclxuICAgICAgICAud2hlcmVQYXJhbShcIm5hdmlnYXRpb25Qcm9wZXJ0aWVzXCIpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAgIC53aGVyZVBhcmFtKFwic2VyaWFsaXplckZuXCIpLmlzT3B0aW9uYWwoKS5pc0Z1bmN0aW9uKClcclxuICAgICAgICAud2hlcmVQYXJhbShcImN1c3RvbVwiKS5pc09wdGlvbmFsKClcclxuICAgICAgICAuYXBwbHlBbGwodGhpcyk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5uYW1lID0gcXVhbGlmeVR5cGVOYW1lKHRoaXMuc2hvcnROYW1lLCB0aGlzLm5hbWVzcGFjZSk7XHJcblxyXG4gICAgLy8gdGhlIGRlZmF1bHRSZXNvdXJjZU5hbWUgbWF5IGFsc28gYmUgc2V0IHVwIGVpdGhlciB2aWEgbWV0YWRhdGEgbG9va3VwIG9yIGZpcnN0IHF1ZXJ5IG9yIHZpYSB0aGUgJ3NldFByb3BlcnRpZXMnIG1ldGhvZFxyXG4gICAgdGhpcy5kYXRhUHJvcGVydGllcyA9IFtdO1xyXG4gICAgdGhpcy5uYXZpZ2F0aW9uUHJvcGVydGllcyA9IFtdO1xyXG4gICAgdGhpcy5jb21wbGV4UHJvcGVydGllcyA9IFtdO1xyXG4gICAgdGhpcy5rZXlQcm9wZXJ0aWVzID0gW107XHJcbiAgICB0aGlzLmZvcmVpZ25LZXlQcm9wZXJ0aWVzID0gW107XHJcbiAgICB0aGlzLmludmVyc2VGb3JlaWduS2V5UHJvcGVydGllcyA9IFtdO1xyXG4gICAgdGhpcy5jb25jdXJyZW5jeVByb3BlcnRpZXMgPSBbXTtcclxuICAgIHRoaXMudW5tYXBwZWRQcm9wZXJ0aWVzID0gW107IC8vIHdpbGwgYmUgdXBkYXRlZCBsYXRlci5cclxuICAgIHRoaXMudmFsaWRhdG9ycyA9IFtdO1xyXG4gICAgdGhpcy53YXJuaW5ncyA9IFtdO1xyXG4gICAgdGhpcy5fbWFwcGVkUHJvcGVydGllc0NvdW50ID0gMDtcclxuICAgIHRoaXMuc3VidHlwZXMgPSBbXTtcclxuICAgIC8vIG5vdyBwcm9jZXNzIGFueSBkYXRhL25hdiBwcm9wc1xyXG4gICAgaWYgKGV0Q29uZmlnICYmIGV0Q29uZmlnLmRhdGFQcm9wZXJ0aWVzKSB7XHJcbiAgICAgIGFkZFByb3BlcnRpZXModGhpcywgZXRDb25maWcuZGF0YVByb3BlcnRpZXMsIERhdGFQcm9wZXJ0eSk7XHJcbiAgICB9XHJcbiAgICBpZiAoZXRDb25maWcgJiYgZXRDb25maWcubmF2aWdhdGlvblByb3BlcnRpZXMpIHtcclxuICAgICAgYWRkUHJvcGVydGllcyh0aGlzLCBldENvbmZpZy5uYXZpZ2F0aW9uUHJvcGVydGllcywgTmF2aWdhdGlvblByb3BlcnR5KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIEdlbmVyYWwgcHVycG9zZSBwcm9wZXJ0eSBzZXQgbWV0aG9kXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBlbTEgaXMgYW4gRW50aXR5TWFuYWdlciBjb250YWluaW5nIGEgbnVtYmVyIG9mIGV4aXN0aW5nIGVudGl0aWVzLlxyXG4gID4gICAgICBsZXQgY3VzdFR5cGUgPSBlbTEubWV0YWRhdGFTdG9yZS5nZXRFbnRpdHlUeXBlKFwiQ3VzdG9tZXJcIik7XHJcbiAgPiAgICAgIGN1c3RUeXBlLnNldFByb3BlcnRpZXMoIHtcclxuICA+ICAgICAgICAgIGF1dG9HZW5lcmF0ZWRLZXlUeXBlOiBBdXRvR2VuZXJhdGVkS2V5VHlwZS5JZGVudGl0eTtcclxuICA+ICAgICAgICAgIGRlZmF1bHRSZXNvdXJjZU5hbWU6IFwiQ3VzdG9tZXJzQW5kSW5jbHVkZWRPcmRlcnNcIlxyXG4gID4gICAgICApfTtcclxuICBAcGFyYW0gY29uZmlnIC0gYSBjb25maWd1cmF0aW9uIG9iamVjdFxyXG4gICoqL1xyXG4gIHNldFByb3BlcnRpZXMoY29uZmlnOiBFbnRpdHlUeXBlU2V0Q29uZmlnKSB7XHJcbiAgICBhc3NlcnRDb25maWcoY29uZmlnKVxyXG4gICAgICAud2hlcmVQYXJhbShcImF1dG9HZW5lcmF0ZWRLZXlUeXBlXCIpLmlzRW51bU9mKEF1dG9HZW5lcmF0ZWRLZXlUeXBlKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJkZWZhdWx0UmVzb3VyY2VOYW1lXCIpLmlzU3RyaW5nKCkuaXNPcHRpb25hbCgpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwic2VyaWFsaXplckZuXCIpLmlzRnVuY3Rpb24oKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJjdXN0b21cIikuaXNPcHRpb25hbCgpXHJcbiAgICAgIC5hcHBseUFsbCh0aGlzKTtcclxuICAgIGlmIChjb25maWcuZGVmYXVsdFJlc291cmNlTmFtZSkge1xyXG4gICAgICB0aGlzLmRlZmF1bHRSZXNvdXJjZU5hbWUgPSBjb25maWcuZGVmYXVsdFJlc291cmNlTmFtZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgd2hldGhlciB0aGlzIHR5cGUgaXMgYSBzdWJ0eXBlIG9mIGEgc3BlY2lmaWVkIHR5cGUuXHJcbiAgKiovXHJcbiAgaXNTdWJ0eXBlT2YoZW50aXR5VHlwZTogRW50aXR5VHlwZSkge1xyXG4gICAgYXNzZXJ0UGFyYW0oZW50aXR5VHlwZSwgXCJlbnRpdHlUeXBlXCIpLmlzSW5zdGFuY2VPZihFbnRpdHlUeXBlKS5jaGVjaygpO1xyXG4gICAgbGV0IGJhc2VUeXBlOiBFbnRpdHlUeXBlID0gdGhpcztcclxuICAgIGRvIHtcclxuICAgICAgaWYgKGJhc2VUeXBlID09PSBlbnRpdHlUeXBlKSByZXR1cm4gdHJ1ZTtcclxuICAgICAgYmFzZVR5cGUgPSBiYXNlVHlwZS5iYXNlRW50aXR5VHlwZTtcclxuICAgIH0gd2hpbGUgKGJhc2VUeXBlKTtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyB0aGlzIHR5cGUgYW5kIGFueS9hbGwgc3VidHlwZXMgb2YgdGhpcyB0eXBlIGRvd24gdGhydSB0aGUgaGllcmFyY2h5LlxyXG4gICoqL1xyXG4gIGdldFNlbGZBbmRTdWJ0eXBlcygpIHtcclxuICAgIGxldCByZXN1bHQgPSBbdGhpc107XHJcbiAgICB0aGlzLnN1YnR5cGVzLmZvckVhY2goZnVuY3Rpb24gKHN0KSB7XHJcbiAgICAgIGxldCBzdWJ0eXBlcyA9IHN0LmdldFNlbGZBbmRTdWJ0eXBlcygpO1xyXG4gICAgICByZXN1bHQucHVzaC5hcHBseShyZXN1bHQsIHN1YnR5cGVzKTtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9XHJcblxyXG4gIGdldEFsbFZhbGlkYXRvcnMoKSB7XHJcbiAgICBsZXQgcmVzdWx0ID0gdGhpcy52YWxpZGF0b3JzLnNsaWNlKDApO1xyXG4gICAgbGV0IGJ0ID0gdGhpcy5iYXNlRW50aXR5VHlwZTtcclxuICAgIHdoaWxlIChidCkge1xyXG4gICAgICByZXN1bHQucHVzaC5hcHBseShyZXN1bHQsIGJ0LnZhbGlkYXRvcnMpO1xyXG4gICAgICBidCA9IGJ0LmJhc2VFbnRpdHlUeXBlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIEFkZHMgYSAgW1tEYXRhUHJvcGVydHldXSBvciBhIFtbTmF2aWdhdGlvblByb3BlcnR5XV0gdG8gdGhpcyBFbnRpdHlUeXBlLlxyXG4gID4gICAgICAvLyBhc3N1bWUgbXlFbnRpdHlUeXBlIGlzIGEgbmV3bHkgY29uc3RydWN0ZWQgRW50aXR5VHlwZS5cclxuICA+ICAgICAgbXlFbnRpdHlUeXBlLmFkZFByb3BlcnR5KGRhdGFQcm9wZXJ0eTEpO1xyXG4gID4gICAgICBteUVudGl0eVR5cGUuYWRkUHJvcGVydHkoZGF0YVByb3BlcnR5Mik7XHJcbiAgPiAgICAgIG15RW50aXR5VHlwZS5hZGRQcm9wZXJ0eShuYXZpZ2F0aW9uUHJvcGVydHkxKTtcclxuICAqKi9cclxuICBhZGRQcm9wZXJ0eShwcm9wZXJ0eTogRW50aXR5UHJvcGVydHkpIHtcclxuICAgIGFzc2VydFBhcmFtKHByb3BlcnR5LCBcInByb3BlcnR5XCIpLmlzSW5zdGFuY2VPZihEYXRhUHJvcGVydHkpLm9yKCkuaXNJbnN0YW5jZU9mKE5hdmlnYXRpb25Qcm9wZXJ0eSkuY2hlY2soKTtcclxuXHJcbiAgICAvLyB0cnVlIGlzIDJuZCBhcmcgdG8gZm9yY2UgcmVzb2x2ZSBvZiBhbnkgbmF2aWdhdGlvbiBwcm9wZXJ0aWVzLlxyXG4gICAgbGV0IG5ld3Byb3AgPSB0aGlzLl9hZGRQcm9wZXJ0eUNvcmUocHJvcGVydHksIHRydWUpO1xyXG5cclxuICAgIGlmICh0aGlzLnN1YnR5cGVzICYmIHRoaXMuc3VidHlwZXMubGVuZ3RoKSB7XHJcbiAgICAgIGxldCBzdHlwZSA9IHRoaXM7XHJcbiAgICAgIHN0eXBlLmdldFNlbGZBbmRTdWJ0eXBlcygpLmZvckVhY2goZnVuY3Rpb24gKHN0KSB7XHJcbiAgICAgICAgaWYgKHN0ICE9PSBzdHlwZSkge1xyXG4gICAgICAgICAgaWYgKHByb3BlcnR5LmlzTmF2aWdhdGlvblByb3BlcnR5KSB7XHJcbiAgICAgICAgICAgIHN0Ll9hZGRQcm9wZXJ0eUNvcmUobmV3IE5hdmlnYXRpb25Qcm9wZXJ0eShwcm9wZXJ0eSksIHRydWUpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgc3QuX2FkZFByb3BlcnR5Q29yZShuZXcgRGF0YVByb3BlcnR5KHByb3BlcnR5IGFzIERhdGFQcm9wZXJ0eSksIHRydWUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbmV3cHJvcDtcclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF91cGRhdGVGcm9tQmFzZShiYXNlRW50aXR5VHlwZTogRW50aXR5VHlwZSkge1xyXG4gICAgdGhpcy5iYXNlRW50aXR5VHlwZSA9IGJhc2VFbnRpdHlUeXBlO1xyXG4gICAgaWYgKHRoaXMuYXV0b0dlbmVyYXRlZEtleVR5cGUgPT09IEF1dG9HZW5lcmF0ZWRLZXlUeXBlLk5vbmUpIHtcclxuICAgICAgdGhpcy5hdXRvR2VuZXJhdGVkS2V5VHlwZSA9IGJhc2VFbnRpdHlUeXBlLmF1dG9HZW5lcmF0ZWRLZXlUeXBlO1xyXG4gICAgfVxyXG5cclxuICAgIGJhc2VFbnRpdHlUeXBlLmRhdGFQcm9wZXJ0aWVzLmZvckVhY2goKGRwKSA9PiB7XHJcbiAgICAgIGxldCBuZXdEcCA9IG5ldyBEYXRhUHJvcGVydHkoZHApO1xyXG4gICAgICAvLyBkb24ndCBuZWVkIHRvIGNvcHkgdmFsaWRhdG9ycyBiZWNhdWUgd2Ugd2lsbCB3YWxrIHRoZSBoaWVyYXJjaHkgdG8gZmluZCB0aGVtXHJcbiAgICAgIG5ld0RwLnZhbGlkYXRvcnMgPSBbXTtcclxuICAgICAgbmV3RHAuYmFzZVByb3BlcnR5ID0gZHA7XHJcbiAgICAgIHRoaXMuX2FkZFByb3BlcnR5Q29yZShuZXdEcCk7XHJcbiAgICB9LCB0aGlzKTtcclxuICAgIGJhc2VFbnRpdHlUeXBlLm5hdmlnYXRpb25Qcm9wZXJ0aWVzLmZvckVhY2goKG5wKSA9PiB7XHJcbiAgICAgIGxldCBuZXdOcCA9IG5ldyBOYXZpZ2F0aW9uUHJvcGVydHkobnApO1xyXG4gICAgICAvLyBkb24ndCBuZWVkIHRvIGNvcHkgdmFsaWRhdG9ycyBiZWNhdWUgd2Ugd2lsbCB3YWxrIHRoZSBoaWVyYXJjaHkgdG8gZmluZCB0aGVtXHJcbiAgICAgIG5ld05wLnZhbGlkYXRvcnMgPSBbXTtcclxuICAgICAgbmV3TnAuYmFzZVByb3BlcnR5ID0gbnA7XHJcbiAgICAgIHRoaXMuX2FkZFByb3BlcnR5Q29yZShuZXdOcCk7XHJcbiAgICB9LCB0aGlzKTtcclxuICAgIGJhc2VFbnRpdHlUeXBlLnN1YnR5cGVzLnB1c2godGhpcyk7XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfYWRkUHJvcGVydHlDb3JlKHByb3BlcnR5OiBFbnRpdHlQcm9wZXJ0eSwgc2hvdWxkUmVzb2x2ZTogYm9vbGVhbiA9IGZhbHNlKSB7XHJcbiAgICBpZiAodGhpcy5pc0Zyb3plbikge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgJ1wiICsgdGhpcy5uYW1lICsgXCInIEVudGl0eVR5cGUvQ29tcGxleFR5cGUgaGFzIGJlZW4gZnJvemVuLiBZb3UgY2FuIG9ubHkgYWRkIHByb3BlcnRpZXMgdG8gYW4gRW50aXR5VHlwZS9Db21wbGV4VHlwZSBiZWZvcmUgYW55IGluc3RhbmNlcyBvZiB0aGF0IHR5cGUgaGF2ZSBiZWVuIGNyZWF0ZWQgYW5kIGF0dGFjaGVkIHRvIGFuIGVudGl0eU1hbmFnZXIuXCIpO1xyXG4gICAgfVxyXG4gICAgbGV0IHBhcmVudFR5cGUgPSBwcm9wZXJ0eS5wYXJlbnRUeXBlO1xyXG4gICAgaWYgKHBhcmVudFR5cGUpIHtcclxuICAgICAgaWYgKHBhcmVudFR5cGUgIT09IHRoaXMpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIHByb3BlcnR5OiBcIiArIHByb3BlcnR5Lm5hbWUgKyBcIiBoYXMgYWxyZWFkeSBiZWVuIGFkZGVkIHRvIFwiICsgcHJvcGVydHkucGFyZW50VHlwZS5uYW1lKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBhZGRpbmcgdGhlIHNhbWUgcHJvcGVydHkgbW9yZSB0aGFuIG9uY2UgdG8gdGhlIHNhbWUgZW50aXR5VHlwZSBpcyBqdXN0IGlnbm9yZWQuXHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBwcm9wZXJ0eS5wYXJlbnRUeXBlID0gdGhpcztcclxuICAgIGxldCBtcyA9IHRoaXMubWV0YWRhdGFTdG9yZTtcclxuICAgIC8vIGlmIChwcm9wZXJ0eS5pc0RhdGFQcm9wZXJ0eSkgeyAvLyBtb2RpZmllZCBiZWNhdXNlIGRvZXNuJ3QgYWN0IGFzIGEgdHlwZSBndWFyZCBcclxuICAgIGlmIChwcm9wZXJ0eSBpbnN0YW5jZW9mIERhdGFQcm9wZXJ0eSkge1xyXG4gICAgICB0aGlzLl9hZGREYXRhUHJvcGVydHkocHJvcGVydHkpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5fYWRkTmF2aWdhdGlvblByb3BlcnR5KHByb3BlcnR5KTtcclxuICAgICAgLy8gbWV0YWRhdGFTdG9yZSBjYW4gYmUgdW5kZWZpbmVkIGlmIHRoaXMgZW50aXR5VHlwZSBoYXMgbm90IHlldCBiZWVuIGFkZGVkIHRvIGEgTWV0YWRhdGFTdG9yZS5cclxuICAgICAgaWYgKHNob3VsZFJlc29sdmUgJiYgbXMpIHtcclxuICAgICAgICB0cnlSZXNvbHZlTnAocHJvcGVydHksIG1zKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gdW5tYXBwZWQgcHJvcGVydGllcyBjYW4gYmUgYWRkZWQgQUZURVIgZW50aXR5VHlwZSBoYXMgYWxyZWFkeSByZXNvbHZlZCBhbGwgcHJvcGVydHkgbmFtZXMuXHJcbiAgICBpZiAobXMgJiYgIShwcm9wZXJ0eS5uYW1lICYmIHByb3BlcnR5Lm5hbWVPblNlcnZlcikpIHtcclxuICAgICAgdXBkYXRlQ2xpZW50U2VydmVyTmFtZXMobXMubmFtaW5nQ29udmVudGlvbiwgcHJvcGVydHksIFwibmFtZVwiKTtcclxuICAgIH1cclxuICAgIC8vIHByb3BzIGNhbiBiZSBhZGRlZCBhZnRlciBlbnRpdHkgcHJvdG90eXBlIGhhcyBhbHJlYWR5IGJlZW4gd3JhcHBlZC5cclxuICAgIGlmIChtcyAmJiB0aGlzLl9leHRyYSkge1xyXG4gICAgICBpZiAodGhpcy5fZXh0cmEuYWxyZWFkeVdyYXBwZWRQcm9wcykge1xyXG4gICAgICAgIGxldCBwcm90byA9IHRoaXMuX2N0b3IucHJvdG90eXBlO1xyXG4gICAgICAgIGNvbmZpZy5pbnRlcmZhY2VSZWdpc3RyeS5tb2RlbExpYnJhcnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkuaW5pdGlhbGl6ZUVudGl0eVByb3RvdHlwZShwcm90byk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIENyZWF0ZSBhIG5ldyBlbnRpdHkgb2YgdGhpcyB0eXBlLlxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGFuIEVudGl0eU1hbmFnZXIgY29udGFpbmluZyBhIG51bWJlciBvZiBleGlzdGluZyBlbnRpdGllcy5cclxuICA+ICAgICAgbGV0IGN1c3RUeXBlID0gZW0xLm1ldGFkYXRhU3RvcmUuZ2V0QXNFbnRpdHlUeXBlKFwiQ3VzdG9tZXJcIik7XHJcbiAgPiAgICAgIGxldCBjdXN0MSA9IGN1c3RUeXBlLmNyZWF0ZUVudGl0eSgpO1xyXG4gID4gICAgICBlbTEuYWRkRW50aXR5KGN1c3QxKTtcclxuICBAcGFyYW0gaW5pdGlhbFZhbHVlcy0gQ29uZmlndXJhdGlvbiBvYmplY3Qgb2YgdGhlIHByb3BlcnRpZXMgdG8gc2V0IGltbWVkaWF0ZWx5IGFmdGVyIGNyZWF0aW9uLlxyXG4gIEByZXR1cm4gVGhlIG5ldyBlbnRpdHkuXHJcbiAgKiovXHJcbiAgY3JlYXRlRW50aXR5KGluaXRpYWxWYWx1ZXM/OiBhbnkpOiBhbnkge1xyXG4gICAgLy8gaWdub3JlIHRoZSBfJGVyZWYgb25jZSB0aGUgZW50aXR5IGlzIGF0dGFjaGVkIHRvIGFuIGVudGl0eU1hbmFnZXIuXHJcbiAgICBpZiAoaW5pdGlhbFZhbHVlcyAmJiBpbml0aWFsVmFsdWVzLl8kZXJlZiAmJiAhaW5pdGlhbFZhbHVlcy5fJGVyZWYuZW50aXR5QXNwZWN0LmVudGl0eU1hbmFnZXIpIHJldHVybiBpbml0aWFsVmFsdWVzLl8kZXJlZjtcclxuXHJcbiAgICBsZXQgaW5zdGFuY2UgPSB0aGlzLl9jcmVhdGVJbnN0YW5jZUNvcmUoKTtcclxuXHJcbiAgICBpZiAoaW5pdGlhbFZhbHVlcykge1xyXG4gICAgICAvLyBvbmx5IGFzc2lnbiBhbiBfZXJlZiBpZiB0aGUgb2JqZWN0IGlzIGZ1bGx5IFwia2V5ZWRcIlxyXG4gICAgICBpZiAodGhpcy5rZXlQcm9wZXJ0aWVzLmV2ZXJ5KGZ1bmN0aW9uIChrcCkge1xyXG4gICAgICAgIHJldHVybiBpbml0aWFsVmFsdWVzW2twLm5hbWVdICE9IG51bGw7XHJcbiAgICAgIH0pKSB7XHJcbiAgICAgICAgaW5pdGlhbFZhbHVlcy5fJGVyZWYgPSBpbnN0YW5jZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5fdXBkYXRlVGFyZ2V0RnJvbVJhdyhpbnN0YW5jZSwgaW5pdGlhbFZhbHVlcywgZ2V0UmF3VmFsdWVGcm9tQ29uZmlnKTtcclxuXHJcbiAgICAgIHRoaXMubmF2aWdhdGlvblByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbiAobnApIHtcclxuICAgICAgICBsZXQgcmVsYXRlZEVudGl0eTogYW55O1xyXG4gICAgICAgIGxldCB2YWwgPSBpbml0aWFsVmFsdWVzW25wLm5hbWVdO1xyXG4gICAgICAgIGlmICh2YWwgIT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICBsZXQgbmF2RW50aXR5VHlwZSA9IG5wLmVudGl0eVR5cGU7XHJcbiAgICAgICAgICBpZiAobnAuaXNTY2FsYXIpIHtcclxuICAgICAgICAgICAgcmVsYXRlZEVudGl0eSA9IHZhbC5lbnRpdHlBc3BlY3QgPyB2YWwgOiBuYXZFbnRpdHlUeXBlLmNyZWF0ZUVudGl0eSh2YWwpO1xyXG4gICAgICAgICAgICBpbnN0YW5jZS5zZXRQcm9wZXJ0eShucC5uYW1lLCByZWxhdGVkRW50aXR5KTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGxldCByZWxhdGVkRW50aXRpZXMgPSBpbnN0YW5jZS5nZXRQcm9wZXJ0eShucC5uYW1lKTtcclxuICAgICAgICAgICAgdmFsLmZvckVhY2goKHY6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgIHJlbGF0ZWRFbnRpdHkgPSB2LmVudGl0eUFzcGVjdCA/IHYgOiBuYXZFbnRpdHlUeXBlLmNyZWF0ZUVudGl0eSh2KTtcclxuICAgICAgICAgICAgICByZWxhdGVkRW50aXRpZXMucHVzaChyZWxhdGVkRW50aXR5KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9pbml0aWFsaXplSW5zdGFuY2UoaW5zdGFuY2UpO1xyXG4gICAgcmV0dXJuIGluc3RhbmNlO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2NyZWF0ZUluc3RhbmNlQ29yZSgpIHtcclxuICAgIGxldCBhQ3RvciA9IHRoaXMuZ2V0Q3RvcigpO1xyXG4gICAgbGV0IGluc3RhbmNlID0gbmV3IGFDdG9yKCk7XHJcbiAgICBuZXcgRW50aXR5QXNwZWN0KGluc3RhbmNlIGFzIEVudGl0eSk7XHJcbiAgICByZXR1cm4gaW5zdGFuY2U7XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfaW5pdGlhbGl6ZUluc3RhbmNlKGluc3RhbmNlOiBhbnkpIHtcclxuICAgIGlmICh0aGlzLmJhc2VFbnRpdHlUeXBlKSB7XHJcbiAgICAgIHRoaXMuYmFzZUVudGl0eVR5cGUuX2luaXRpYWxpemVJbnN0YW5jZShpbnN0YW5jZSk7XHJcbiAgICB9XHJcbiAgICBsZXQgaW5pdEZuID0gdGhpcy5pbml0Rm47XHJcbiAgICBpZiAoaW5pdEZuKSB7XHJcbiAgICAgIGxldCBmbiA9ICh0eXBlb2YgaW5pdEZuID09PSBcInN0cmluZ1wiKSA/IGluc3RhbmNlW2luaXRGbl0gOiBpbml0Rm47XHJcbiAgICAgIGZuKGluc3RhbmNlKTtcclxuICAgIH1cclxuICAgIHRoaXMuY29tcGxleFByb3BlcnRpZXMgJiYgdGhpcy5jb21wbGV4UHJvcGVydGllcy5mb3JFYWNoKGZ1bmN0aW9uIChjcCkge1xyXG4gICAgICBsZXQgY29tcGxleFR5cGUgPSBjcC5kYXRhVHlwZSBhcyBDb21wbGV4VHlwZTtcclxuICAgICAgbGV0IGN0SW5zdGFuY2UgPSBpbnN0YW5jZS5nZXRQcm9wZXJ0eShjcC5uYW1lKTtcclxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY3RJbnN0YW5jZSkpIHtcclxuICAgICAgICBjdEluc3RhbmNlLmZvckVhY2goKGN0SW5zdCkgPT4ge1xyXG4gICAgICAgICAgY29tcGxleFR5cGUuX2luaXRpYWxpemVJbnN0YW5jZShjdEluc3QpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNvbXBsZXhUeXBlLl9pbml0aWFsaXplSW5zdGFuY2UoY3RJbnN0YW5jZSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgLy8gbm90IG5lZWRlZCBmb3IgY29tcGxleE9iamVjdHNcclxuICAgIGlmIChpbnN0YW5jZS5lbnRpdHlBc3BlY3QpIHtcclxuICAgICAgaW5zdGFuY2UuZW50aXR5QXNwZWN0Ll9pbml0aWFsaXplZCA9IHRydWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIHRoZSBjb25zdHJ1Y3RvciBmb3IgdGhpcyBFbnRpdHlUeXBlLlxyXG4gIEBwYXJhbSBmb3JjZVJlZnJlc2ggLSBXaGV0aGVyIHRvIGlnbm9yZSBhbnkgY2FjaGVkIHZlcnNpb24gb2YgdGhpcyBjb25zdHJ1Y3Rvci4gKGRlZmF1bHQgPT0gZmFsc2UpXHJcbiAgQHJldHVybiBUaGUgY29uc3RydWN0b3IgZm9yIHRoaXMgRW50aXR5VHlwZS5cclxuICAqKi9cclxuICBnZXRDdG9yKGZvcmNlUmVmcmVzaDogYm9vbGVhbiA9IGZhbHNlKTogeyBuZXcgKCk6IFN0cnVjdHVyYWxPYmplY3QgfSB7XHJcbiAgICBpZiAodGhpcy5fY3RvciAmJiAhZm9yY2VSZWZyZXNoKSByZXR1cm4gdGhpcy5fY3RvcjtcclxuXHJcbiAgICBsZXQgY3RvclJlZ2lzdHJ5ID0gdGhpcy5tZXRhZGF0YVN0b3JlLl9jdG9yUmVnaXN0cnk7XHJcbiAgICBsZXQgciA9IGN0b3JSZWdpc3RyeVt0aGlzLm5hbWVdIHx8IGN0b3JSZWdpc3RyeVt0aGlzLnNob3J0TmFtZV0gfHwge307XHJcbiAgICBsZXQgYUN0b3IgPSByLmN0b3IgfHwgdGhpcy5fY3RvcjtcclxuXHJcbiAgICBsZXQgY3RvclR5cGUgPSBhQ3RvciAmJiBhQ3Rvci5wcm90b3R5cGUgJiYgKGFDdG9yLnByb3RvdHlwZS5lbnRpdHlUeXBlIHx8IGFDdG9yLnByb3RvdHlwZS5jb21wbGV4VHlwZSk7XHJcbiAgICBpZiAoY3RvclR5cGUgJiYgY3RvclR5cGUubWV0YWRhdGFTdG9yZSAhPT0gdGhpcy5tZXRhZGF0YVN0b3JlKSB7XHJcbiAgICAgIC8vIFdlIGNhbid0IHJpc2sgYSBtaXNtYXRjaCBiZXR3ZWVuIHRoZSBjdG9yIGFuZCB0aGUgdHlwZSBpbmZvIGluIGEgc3BlY2lmaWMgbWV0YWRhdGFzdG9yZVxyXG4gICAgICAvLyBiZWNhdXNlIG1vZGVsTGlicmFyaWVzIHJlbHkgb24gdHlwZSBpbmZvIHRvIGludGVyY2VwdCBjdG9yIHByb3BlcnRpZXNcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IHJlZ2lzdGVyIHRoZSBzYW1lIGNvbnN0cnVjdG9yIGZvciBcIiArIHRoaXMubmFtZSArIFwiIGluIGRpZmZlcmVudCBtZXRhZGF0YSBzdG9yZXMuICBQbGVhc2UgZGVmaW5lIGEgc2VwYXJhdGUgY29uc3RydWN0b3IgZm9yIGVhY2ggbWV0YWRhdGEgc3RvcmUuXCIpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICBpZiAoci5jdG9yICYmIGZvcmNlUmVmcmVzaCkge1xyXG4gICAgICB0aGlzLl9leHRyYSA9IHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWFDdG9yKSB7XHJcbiAgICAgIGxldCBjcmVhdGVDdG9yID0gY29uZmlnLmludGVyZmFjZVJlZ2lzdHJ5Lm1vZGVsTGlicmFyeS5nZXREZWZhdWx0SW5zdGFuY2UoKS5jcmVhdGVDdG9yO1xyXG4gICAgICBhQ3RvciA9IGNyZWF0ZUN0b3IgPyBjcmVhdGVDdG9yKHRoaXMpIDogY3JlYXRlRW1wdHlDdG9yKHRoaXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuaW5pdEZuID0gci5pbml0Rm47XHJcbiAgICB0aGlzLm5vVHJhY2tpbmdGbiA9IHIubm9UcmFja2luZ0ZuO1xyXG5cclxuICAgIGFDdG9yLnByb3RvdHlwZS5fJHR5cGVOYW1lID0gdGhpcy5uYW1lO1xyXG4gICAgdGhpcy5fc2V0Q3RvcihhQ3Rvcik7XHJcbiAgICByZXR1cm4gYUN0b3I7XHJcbiAgfVxyXG5cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgLy8gTWF5IG1ha2UgcHVibGljIGxhdGVyLlxyXG4gIF9zZXRDdG9yKGFDdG9yOiB7IG5ldyAoKTogU3RydWN0dXJhbE9iamVjdCB9LCBpbnRlcmNlcHRvcj86IGFueSkge1xyXG5cclxuICAgIGxldCBpbnN0YW5jZVByb3RvID0gYUN0b3IucHJvdG90eXBlO1xyXG5cclxuICAgIC8vIHBsYWNlIGZvciBleHRyYSBicmVlemUgcmVsYXRlZCBkYXRhXHJcbiAgICB0aGlzLl9leHRyYSA9IHRoaXMuX2V4dHJhIHx8IHt9O1xyXG5cclxuICAgIGxldCBpbnN0YW5jZSA9IG5ldyBhQ3RvcigpO1xyXG4gICAgY2FsY1VubWFwcGVkUHJvcGVydGllcyh0aGlzLCBpbnN0YW5jZSk7XHJcblxyXG4gICAgaWYgKHRoaXMuXyR0eXBlTmFtZSA9PT0gXCJFbnRpdHlUeXBlXCIpIHtcclxuICAgICAgLy8gaW5zdXJlIHRoYXQgYWxsIG9mIHRoZSBwcm9wZXJ0aWVzIGFyZSBvbiB0aGUgJ3RlbXBsYXRlJyBpbnN0YW5jZSBiZWZvcmUgd2F0Y2hpbmcgdGhlIGNsYXNzLlxyXG4gICAgICBpbnN0YW5jZVByb3RvLmVudGl0eVR5cGUgPSB0aGlzO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaW5zdGFuY2VQcm90by5jb21wbGV4VHlwZSA9IHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZGVmYXVsdFByb3BlcnR5SW50ZXJjZXB0b3IgaXMgYSAnZ2xvYmFsJyAoYnV0IGludGVybmFsIHRvIGJyZWV6ZSkgZnVuY3Rpb247XHJcbiAgICAoaW5zdGFuY2VQcm90byBhcyBhbnkpLl8kaW50ZXJjZXB0b3IgPSBpbnRlcmNlcHRvciB8fCBkZWZhdWx0UHJvcGVydHlJbnRlcmNlcHRvcjtcclxuICAgIGNvbmZpZy5pbnRlcmZhY2VSZWdpc3RyeS5tb2RlbExpYnJhcnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkuaW5pdGlhbGl6ZUVudGl0eVByb3RvdHlwZShpbnN0YW5jZVByb3RvKTtcclxuICAgIHRoaXMuX2N0b3IgPSBhQ3RvcjtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIEFkZHMgZWl0aGVyIGFuIGVudGl0eSBvciBwcm9wZXJ0eSBsZXZlbCB2YWxpZGF0b3IgdG8gdGhpcyBFbnRpdHlUeXBlLlxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGFuIEVudGl0eU1hbmFnZXIgY29udGFpbmluZyBhIG51bWJlciBvZiBleGlzdGluZyBlbnRpdGllcy5cclxuICA+ICAgICAgbGV0IGN1c3RUeXBlID0gZW0xLm1ldGFkYXRhU3RvcmUuZ2V0RW50aXR5VHlwZShcIkN1c3RvbWVyXCIpO1xyXG4gID4gICAgICBsZXQgY291bnRyeVByb3AgPSBjdXN0VHlwZS5nZXRQcm9wZXJ0eShcIkNvdW50cnlcIik7XHJcbiAgPiAgICAgIGxldCB2YWxGbiA9IGZ1bmN0aW9uICh2KSB7XHJcbiAgPiAgICAgICAgICAgICAgaWYgKHYgPT0gbnVsbCkgcmV0dXJuIHRydWU7XHJcbiAgPiAgICAgICAgICAgICAgcmV0dXJuIChjb3JlLnN0cmluZ1N0YXJ0c1dpdGgodiwgXCJVU1wiKSk7XHJcbiAgPiAgICAgICAgICB9O1xyXG4gID4gICAgICBsZXQgY291bnRyeVZhbGlkYXRvciA9IG5ldyBWYWxpZGF0b3IoXCJjb3VudHJ5SXNVU1wiLCB2YWxGbixcclxuICA+ICAgICAgeyBkaXNwbGF5TmFtZTogXCJDb3VudHJ5XCIsIG1lc3NhZ2VUZW1wbGF0ZTogXCInJWRpc3BsYXlOYW1lJScgbXVzdCBzdGFydCB3aXRoICdVUydcIiB9KTtcclxuICA+ICAgICAgY3VzdFR5cGUuYWRkVmFsaWRhdG9yKGNvdW50cnlWYWxpZGF0b3IsIGNvdW50cnlQcm9wKTtcclxuXHJcbiAgVGhpcyBpcyB0aGUgc2FtZSBhcyBhZGRpbmcgYW4gZW50aXR5IGxldmVsIHZhbGlkYXRvciB2aWEgdGhlICd2YWxpZGF0b3JzJyBwcm9wZXJ0eSBvZiBEYXRhUHJvcGVydHkgb3IgTmF2aWdhdGlvblByb3BlcnR5XHJcbiAgPiAgICAgIGNvdW50cnlQcm9wLnZhbGlkYXRvcnMucHVzaChjb3VudHJ5VmFsaWRhdG9yKTtcclxuXHJcbiAgRW50aXR5IGxldmVsIHZhbGlkYXRvcnMgY2FuIGFsc28gYmUgYWRkZWQgYnkgb21pdHRpbmcgdGhlICdwcm9wZXJ0eScgcGFyYW1ldGVyLlxyXG4gID4gICAgICBjdXN0VHlwZS5hZGRWYWxpZGF0b3Ioc29tZUVudGl0eUxldmVsVmFsaWRhdG9yKTtcclxuXHJcbiAgb3JcclxuICA+ICAgICAgY3VzdFR5cGUudmFsaWRhdG9ycy5wdXNoKHNvbWVFbnRpdHlMZXZlbFZhbGlkYXRvcik7XHJcbiAgQHBhcmFtIHZhbGlkYXRvciAtIFZhbGlkYXRvciB0byBhZGQuXHJcbiAgQHBhcmFtIHByb3BlcnR5IC0gUHJvcGVydHkgdG8gYWRkIHRoaXMgdmFsaWRhdG9yIHRvLiAgSWYgb21pdHRlZCwgdGhlIHZhbGlkYXRvciBpcyBhc3N1bWVkIHRvIGJlIGFuXHJcbiAgZW50aXR5IGxldmVsIHZhbGlkYXRvciBhbmQgaXMgYWRkZWQgdG8gdGhlIEVudGl0eVR5cGUncyAndmFsaWRhdG9ycycuXHJcbiAgKiovXHJcbiAgYWRkVmFsaWRhdG9yKHZhbGlkYXRvcjogVmFsaWRhdG9yLCBwcm9wZXJ0eT86IEVudGl0eVByb3BlcnR5IHwgc3RyaW5nKSB7XHJcbiAgICBhc3NlcnRQYXJhbSh2YWxpZGF0b3IsIFwidmFsaWRhdG9yXCIpLmlzSW5zdGFuY2VPZihWYWxpZGF0b3IpLmNoZWNrKCk7XHJcbiAgICBhc3NlcnRQYXJhbShwcm9wZXJ0eSwgXCJwcm9wZXJ0eVwiKS5pc09wdGlvbmFsKCkuaXNTdHJpbmcoKS5vcigpLmlzRW50aXR5UHJvcGVydHkoKS5jaGVjaygpO1xyXG4gICAgaWYgKHByb3BlcnR5ICE9IG51bGwpIHtcclxuICAgICAgbGV0IHByb3AgPSAodHlwZW9mIHByb3BlcnR5ID09PSAnc3RyaW5nJykgPyB0aGlzLmdldFByb3BlcnR5KHByb3BlcnR5LCB0cnVlKSA6IHByb3BlcnR5O1xyXG4gICAgICBwcm9wIS52YWxpZGF0b3JzLnB1c2godmFsaWRhdG9yKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMudmFsaWRhdG9ycy5wdXNoKHZhbGlkYXRvcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIGFsbCBvZiB0aGUgcHJvcGVydGllcyAoIGRhdGFQcm9wZXJ0aWVzIGFuZCBuYXZpZ2F0aW9uUHJvcGVydGllcykgZm9yIHRoaXMgRW50aXR5VHlwZS5cclxuICA+ICAgICAgLy8gYXNzdW1lIGVtMSBpcyBhbiBFbnRpdHlNYW5hZ2VyIGNvbnRhaW5pbmcgYSBudW1iZXIgb2YgZXhpc3RpbmcgZW50aXRpZXMuXHJcbiAgPiAgICAgIGxldCBjdXN0VHlwZSA9IGVtMS5tZXRhZGF0YVN0b3JlLmdldEVudGl0eVR5cGUoXCJDdXN0b21lclwiKTtcclxuICA+ICAgICAgbGV0IGFycmF5T2ZQcm9wcyA9IGN1c3RUeXBlLmdldFByb3BlcnRpZXMoKTtcclxuICBAcmV0dXJuIEFuIGFycmF5IG9mIERhdGEgYW5kIE5hdmlnYXRpb24gcHJvcGVydGllcy5cclxuICAqKi9cclxuICBnZXRQcm9wZXJ0aWVzKCk6IEVudGl0eVByb3BlcnR5W10ge1xyXG4gICAgcmV0dXJuICh0aGlzLmRhdGFQcm9wZXJ0aWVzIGFzIEVudGl0eVByb3BlcnR5W10pLmNvbmNhdCh0aGlzLm5hdmlnYXRpb25Qcm9wZXJ0aWVzKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgYWxsIG9mIHRoZSBwcm9wZXJ0eSBuYW1lcyAoIGZvciBib3RoIGRhdGFQcm9wZXJ0aWVzIGFuZCBuYXZpZ2F0aW9uUHJvcGVydGllcykgZm9yIHRoaXMgRW50aXR5VHlwZS5cclxuICA+ICAgICAgLy8gYXNzdW1lIGVtMSBpcyBhbiBFbnRpdHlNYW5hZ2VyIGNvbnRhaW5pbmcgYSBudW1iZXIgb2YgZXhpc3RpbmcgZW50aXRpZXMuXHJcbiAgPiAgICAgIGxldCBjdXN0VHlwZSA9IGVtMS5tZXRhZGF0YVN0b3JlLmdldEVudGl0eVR5cGUoXCJDdXN0b21lclwiKTtcclxuICA+ICAgICAgbGV0IGFycmF5T2ZQcm9wTmFtZXMgPSBjdXN0VHlwZS5nZXRQcm9wZXJ0eU5hbWVzKCk7XHJcbiAgKiovXHJcbiAgZ2V0UHJvcGVydHlOYW1lcygpIHtcclxuICAgIHJldHVybiB0aGlzLmdldFByb3BlcnRpZXMoKS5tYXAoY29yZS5wbHVjaygnbmFtZScpKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgYSBkYXRhIHByb3BlcnR5IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIG9yIG51bGwuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBlbTEgaXMgYW4gRW50aXR5TWFuYWdlciBjb250YWluaW5nIGEgbnVtYmVyIG9mIGV4aXN0aW5nIGVudGl0aWVzLlxyXG4gID4gICAgICBsZXQgY3VzdFR5cGUgPSBlbTEubWV0YWRhdGFTdG9yZS5nZXRFbnRpdHlUeXBlKFwiQ3VzdG9tZXJcIik7XHJcbiAgPiAgICAgIGxldCBjdXN0b21lck5hbWVEYXRhUHJvcCA9IGN1c3RUeXBlLmdldERhdGFQcm9wZXJ0eShcIkN1c3RvbWVyTmFtZVwiKTtcclxuICBAcmV0dXJuIEEgRGF0YVByb3BlcnR5IG9yIG51bGwgaWYgbm90IGZvdW5kLlxyXG4gICoqL1xyXG4gIGdldERhdGFQcm9wZXJ0eShwcm9wZXJ0eU5hbWU6IHN0cmluZykge1xyXG4gICAgcmV0dXJuIGNvcmUuYXJyYXlGaXJzdCh0aGlzLmRhdGFQcm9wZXJ0aWVzLCBjb3JlLnByb3BFcSgnbmFtZScsIHByb3BlcnR5TmFtZSkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIG5hdmlnYXRpb24gcHJvcGVydHkgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgb3IgbnVsbC5cclxuICA+ICAgICAgLy8gYXNzdW1lIGVtMSBpcyBhbiBFbnRpdHlNYW5hZ2VyIGNvbnRhaW5pbmcgYSBudW1iZXIgb2YgZXhpc3RpbmcgZW50aXRpZXMuXHJcbiAgPiAgICAgIGxldCBjdXN0VHlwZSA9IGVtMS5tZXRhZGF0YVN0b3JlLmdldEVudGl0eVR5cGUoXCJDdXN0b21lclwiKTtcclxuICA+ICAgICAgbGV0IGN1c3RvbWVyT3JkZXJzTmF2UHJvcCA9IGN1c3RUeXBlLmdldERhdGFQcm9wZXJ0eShcIk9yZGVyc1wiKTtcclxuICBAcmV0dXJuIEEgTmF2aWdhdGlvblByb3BlcnR5IG9yIG51bGwgaWYgbm90IGZvdW5kLlxyXG4gICoqL1xyXG4gIGdldE5hdmlnYXRpb25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWU6IHN0cmluZykge1xyXG4gICAgcmV0dXJuIGNvcmUuYXJyYXlGaXJzdCh0aGlzLm5hdmlnYXRpb25Qcm9wZXJ0aWVzLCBjb3JlLnByb3BFcSgnbmFtZScsIHByb3BlcnR5TmFtZSkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBlaXRoZXIgYSBEYXRhUHJvcGVydHkgb3IgYSBOYXZpZ2F0aW9uUHJvcGVydHkgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgb3IgbnVsbC5cclxuICBcclxuICBUaGlzIG1ldGhvZCBhbHNvIGFjY2VwdHMgYSAnLicgZGVsaW1pdGVkIHByb3BlcnR5IHBhdGggYW5kIHdpbGwgcmV0dXJuIHRoZSAncHJvcGVydHknIGF0IHRoZVxyXG4gIGVuZCBvZiB0aGUgcGF0aC5cclxuICA+ICAgICAgbGV0IGN1c3RUeXBlID0gZW0xLm1ldGFkYXRhU3RvcmUuZ2V0RW50aXR5VHlwZShcIkN1c3RvbWVyXCIpO1xyXG4gID4gICAgICBsZXQgY29tcGFueU5hbWVQcm9wID0gY3VzdFR5cGUuZ2V0UHJvcGVydHkoXCJDb21wYW55TmFtZVwiKTtcclxuXHJcbiAgVGhpcyBtZXRob2QgY2FuIGFsc28gd2FsayBhIHByb3BlcnR5IHBhdGggdG8gcmV0dXJuIGEgcHJvcGVydHlcclxuICA+ICAgICAgbGV0IG9yZGVyRGV0YWlsVHlwZSA9IGVtMS5tZXRhZGF0YVN0b3JlLmdldEVudGl0eVR5cGUoXCJPcmRlckRldGFpbFwiKTtcclxuICA+ICAgICAgbGV0IGNvbXBhbnlOYW1lUHJvcDIgPSBvcmRlckRldGFpbFR5cGUuZ2V0UHJvcGVydHkoXCJPcmRlci5DdXN0b21lci5Db21wYW55TmFtZVwiKTtcclxuICA+ICAgICAgLy8gY29tcGFueU5hbWVQcm9wID09PSBjb21wYW55TmFtZVByb3AyXHJcbiAgQHBhcmFtIFt0aHJvd0lmTm90Rm91bmQ9ZmFsc2VdIHtCb29sZWFufSBXaGV0aGVyIHRvIHRocm93IGFuIGV4Y2VwdGlvbiBpZiBub3QgZm91bmQuXHJcbiAgQHJldHVybiBBIERhdGFQcm9wZXJ0eSBvciBOYXZpZ2F0aW9uUHJvcGVydHkgb3IgbnVsbCBpZiBub3QgZm91bmQuXHJcbiAgKiovXHJcbiAgZ2V0UHJvcGVydHkocHJvcGVydHlQYXRoOiBzdHJpbmcsIHRocm93SWZOb3RGb3VuZDogYm9vbGVhbiA9IGZhbHNlKSB7XHJcbiAgICBsZXQgcHJvcHMgPSB0aGlzLmdldFByb3BlcnRpZXNPblBhdGgocHJvcGVydHlQYXRoLCBmYWxzZSwgdGhyb3dJZk5vdEZvdW5kKTtcclxuICAgIHJldHVybiAocHJvcHMgJiYgcHJvcHMubGVuZ3RoID4gMCkgPyBwcm9wc1twcm9wcy5sZW5ndGggLSAxXSA6IG51bGw7XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICAvLyBUT0RPOiBoYXZlIHRoaXMgcmV0dXJuIGVtcHR5IGFycmF5IGluc3RlYWQgb2YgbnVsbCBhbmQgZml4IGNvbnN1bWVycy5cclxuICAvLyBUT0RPOiB0aGluayBhYm91dCByZW5hbWluZyB3aXRoICdfJyBwcmVmaXguXHJcbiAgZ2V0UHJvcGVydGllc09uUGF0aChwcm9wZXJ0eVBhdGg6IHN0cmluZywgdXNlU2VydmVyTmFtZTogYm9vbGVhbiB8IG51bGwsIHRocm93SWZOb3RGb3VuZDogYm9vbGVhbiA9IGZhbHNlKSB7XHJcbiAgICBsZXQgcHJvcGVydHlOYW1lczogc3RyaW5nW10gPSAoQXJyYXkuaXNBcnJheShwcm9wZXJ0eVBhdGgpKSA/IHByb3BlcnR5UGF0aCA6IHByb3BlcnR5UGF0aC50cmltKCkuc3BsaXQoJy4nKTtcclxuXHJcbiAgICBsZXQgb2sgPSB0cnVlO1xyXG4gICAgbGV0IGtleSA9IHVzZVNlcnZlck5hbWUgPT09IHRydWUgPyBcIm5hbWVPblNlcnZlclwiIDogdXNlU2VydmVyTmFtZSA9PT0gZmFsc2UgPyBcIm5hbWVcIiA6IG51bGw7XHJcbiAgICBsZXQgcGFyZW50VHlwZSA9IHRoaXMgYXMgU3RydWN0dXJhbFR5cGU7XHJcbiAgICBcclxuICAgIGNvbnN0IGdldFByb3BzID0gKHByb3BOYW1lOiBzdHJpbmcpID0+IHsgXHJcbiAgICAgIGNvbnN0IGZuID0ga2V5ID09PSBudWxsID8gY29yZS5wcm9wc0VxKFwibmFtZVwiLCBcIm5hbWVPblNlcnZlclwiLCBwcm9wTmFtZSkgOiBjb3JlLnByb3BFcShrZXksIHByb3BOYW1lKTtcclxuICAgICAgbGV0IHByb3AgPSBjb3JlLmFycmF5Rmlyc3QocGFyZW50VHlwZS5nZXRQcm9wZXJ0aWVzKCksIGZuKTtcclxuICAgICAgaWYgKHByb3ApIHtcclxuICAgICAgICBwYXJlbnRUeXBlID0gKHByb3AgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uUHJvcGVydHkpID8gcHJvcC5lbnRpdHlUeXBlIDogcHJvcC5kYXRhVHlwZSBhcyBDb21wbGV4VHlwZTtcclxuICAgICAgICAvLyBwYXJlbnRUeXBlID0gcHJvcC5pc05hdmlnYXRpb25Qcm9wZXJ0eSA/IHByb3AuZW50aXR5VHlwZSA6IHByb3AuZGF0YVR5cGU7XHJcbiAgICAgIH0gZWxzZSBpZiAodGhyb3dJZk5vdEZvdW5kKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidW5hYmxlIHRvIGxvY2F0ZSBwcm9wZXJ0eTogXCIgKyBwcm9wTmFtZSArIFwiIG9uIGVudGl0eVR5cGU6IFwiICsgcGFyZW50VHlwZS5uYW1lKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBvayA9IGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBwcm9wO1xyXG4gICAgfTtcclxuXHJcbiAgICBsZXQgcHJvcHMgPSBwcm9wZXJ0eU5hbWVzLm1hcChnZXRQcm9wcykgYXMgRW50aXR5UHJvcGVydHlbXTtcclxuICAgIHJldHVybiBvayA/IHByb3BzIDogbnVsbDtcclxuICB9XHJcblxyXG4gIC8qKiBGb3IgdXNlIGluIHBsdWdnYWJsZSBhZGFwdGVycy4gKi9cclxuICAvLyBUT0RPOiBkb2N1bWVudCB1c2VcclxuICBjbGllbnRQcm9wZXJ0eVBhdGhUb1NlcnZlcihwcm9wZXJ0eVBhdGg6IHN0cmluZywgZGVsaW1pdGVyOiBzdHJpbmcgPSAnLicpIHtcclxuICAgIGxldCBwcm9wTmFtZXM6IHN0cmluZ1tdO1xyXG4gICAgaWYgKHRoaXMuaXNBbm9ueW1vdXMpIHtcclxuICAgICAgbGV0IGZuID0gdGhpcy5tZXRhZGF0YVN0b3JlLm5hbWluZ0NvbnZlbnRpb24uY2xpZW50UHJvcGVydHlOYW1lVG9TZXJ2ZXI7XHJcbiAgICAgIHByb3BOYW1lcyA9IHByb3BlcnR5UGF0aC5zcGxpdChcIi5cIikubWFwKGZ1bmN0aW9uIChwcm9wTmFtZSkge1xyXG4gICAgICAgIHJldHVybiBmbihwcm9wTmFtZSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbGV0IHByb3BzID0gdGhpcy5nZXRQcm9wZXJ0aWVzT25QYXRoKHByb3BlcnR5UGF0aCwgZmFsc2UsIHRydWUpO1xyXG4gICAgICBwcm9wTmFtZXMgPSBwcm9wcyEubWFwKChwcm9wOiBFbnRpdHlQcm9wZXJ0eSkgPT4gcHJvcC5uYW1lT25TZXJ2ZXIpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHByb3BOYW1lcy5qb2luKGRlbGltaXRlcik7XHJcbiAgfVxyXG5cclxuICAvKiogRm9yIHVzZSBpbiBwbHVnZ2FibGUgYWRhcHRlcnMuICovXHJcbiAgLy8gVE9ETzogZG9jdW1lbnQgdXNlXHJcbiAgZ2V0RW50aXR5S2V5RnJvbVJhd0VudGl0eShyYXdFbnRpdHk6IGFueSwgcmF3VmFsdWVGbjogRnVuY3Rpb24pIHtcclxuICAgIGxldCBrZXlWYWx1ZXMgPSB0aGlzLmtleVByb3BlcnRpZXMubWFwKChkcCkgPT4ge1xyXG4gICAgICBsZXQgdmFsID0gcmF3VmFsdWVGbihyYXdFbnRpdHksIGRwKTtcclxuICAgICAgcmV0dXJuIERhdGFUeXBlLnBhcnNlUmF3VmFsdWUodmFsLCBkcC5kYXRhVHlwZSBhcyBEYXRhVHlwZSk7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBuZXcgRW50aXR5S2V5KHRoaXMsIGtleVZhbHVlcyk7XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfdXBkYXRlVGFyZ2V0RnJvbVJhdyh0YXJnZXQ6IFN0cnVjdHVyYWxPYmplY3QsIHJhdzogYW55LCByYXdWYWx1ZUZuOiBGdW5jdGlvbikge1xyXG4gICAgLy8gY2FsbGVkIHJlY3Vyc2l2ZWx5IGZvciBjb21wbGV4IHByb3BlcnRpZXNcclxuICAgIHRoaXMuZGF0YVByb3BlcnRpZXMuZm9yRWFjaCgoZHApID0+IHtcclxuICAgICAgaWYgKCFkcC5pc1NldHRhYmxlKSByZXR1cm47XHJcbiAgICAgIGxldCByYXdWYWwgPSByYXdWYWx1ZUZuKHJhdywgZHApO1xyXG4gICAgICBpZiAocmF3VmFsID09PSB1bmRlZmluZWQpIHJldHVybjtcclxuICAgICAgbGV0IGRhdGFUeXBlID0gZHAuZGF0YVR5cGU7IC8vIHRoaXMgd2lsbCBiZSBhIGNvbXBsZXhUeXBlIHdoZW4gZHAgaXMgYSBjb21wbGV4UHJvcGVydHlcclxuICAgICAgbGV0IG9sZFZhbDogYW55O1xyXG4gICAgICBpZiAoZHAuaXNDb21wbGV4UHJvcGVydHkpIHtcclxuICAgICAgICBsZXQgY29tcGxleFR5cGUgPSBkcC5kYXRhVHlwZSBhcyBDb21wbGV4VHlwZTtcclxuICAgICAgICBpZiAocmF3VmFsID09PSBudWxsKSByZXR1cm47IC8vIHJhd1ZhbCBtYXkgYmUgbnVsbCBpbiBub3NxbCBkYnMgd2hlcmUgaXQgd2FzIG5ldmVyIGRlZmluZWQgZm9yIHRoZSBnaXZlbiByb3cuXHJcbiAgICAgICAgb2xkVmFsID0gdGFyZ2V0LmdldFByb3BlcnR5KGRwLm5hbWUpO1xyXG4gICAgICAgIGlmIChkcC5pc1NjYWxhcikge1xyXG4gICAgICAgICAgY29tcGxleFR5cGUuX3VwZGF0ZVRhcmdldEZyb21SYXcob2xkVmFsLCByYXdWYWwsIHJhd1ZhbHVlRm4pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShyYXdWYWwpKSB7XHJcbiAgICAgICAgICAgIGxldCBuZXdWYWwgPSByYXdWYWwubWFwKGZ1bmN0aW9uIChyYXdDbykge1xyXG4gICAgICAgICAgICAgIGxldCBuZXdDbyA9IGNvbXBsZXhUeXBlLl9jcmVhdGVJbnN0YW5jZUNvcmUodGFyZ2V0LCBkcCk7XHJcbiAgICAgICAgICAgICAgY29tcGxleFR5cGUuX3VwZGF0ZVRhcmdldEZyb21SYXcobmV3Q28sIHJhd0NvLCByYXdWYWx1ZUZuKTtcclxuICAgICAgICAgICAgICBjb21wbGV4VHlwZS5faW5pdGlhbGl6ZUluc3RhbmNlKG5ld0NvKTtcclxuICAgICAgICAgICAgICByZXR1cm4gbmV3Q287XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBpZiAoIWNvcmUuYXJyYXlFcXVhbHMob2xkVmFsLCBuZXdWYWwsIGNvRXF1YWxzKSkge1xyXG4gICAgICAgICAgICAgIC8vIGNsZWFyIHRoZSBvbGQgYXJyYXkgYW5kIHB1c2ggbmV3IG9iamVjdHMgaW50byBpdC5cclxuICAgICAgICAgICAgICBvbGRWYWwubGVuZ3RoID0gMDtcclxuICAgICAgICAgICAgICBuZXdWYWwuZm9yRWFjaChmdW5jdGlvbiAobnYpIHtcclxuICAgICAgICAgICAgICAgIG9sZFZhbC5wdXNoKG52KTtcclxuICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgb2xkVmFsLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmIChkcC5pc1NjYWxhcikge1xyXG4gICAgICAgICAgbGV0IG5ld1ZhbCA9IERhdGFUeXBlLnBhcnNlUmF3VmFsdWUocmF3VmFsLCBkYXRhVHlwZSBhcyBEYXRhVHlwZSk7XHJcbiAgICAgICAgICB0YXJnZXQuc2V0UHJvcGVydHkoZHAubmFtZSwgbmV3VmFsKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgb2xkVmFsID0gdGFyZ2V0LmdldFByb3BlcnR5KGRwLm5hbWUpO1xyXG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmF3VmFsKSkge1xyXG4gICAgICAgICAgICAvLyBuZWVkIHRvIGNvbXBhcmUgdmFsdWVzXHJcbiAgICAgICAgICAgIGxldCBuZXdWYWwgPSByYXdWYWwubWFwKChydikgPT4ge1xyXG4gICAgICAgICAgICAgIHJldHVybiBEYXRhVHlwZS5wYXJzZVJhd1ZhbHVlKHJ2LCBkYXRhVHlwZSBhcyBEYXRhVHlwZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBpZiAoIWNvcmUuYXJyYXlFcXVhbHMob2xkVmFsLCBuZXdWYWwpKSB7XHJcbiAgICAgICAgICAgICAgLy8gY2xlYXIgdGhlIG9sZCBhcnJheSBhbmQgcHVzaCBuZXcgb2JqZWN0cyBpbnRvIGl0LlxyXG4gICAgICAgICAgICAgIG9sZFZhbC5sZW5ndGggPSAwO1xyXG4gICAgICAgICAgICAgIG5ld1ZhbC5mb3JFYWNoKGZ1bmN0aW9uIChudikge1xyXG4gICAgICAgICAgICAgICAgb2xkVmFsLnB1c2gobnYpO1xyXG4gICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBvbGRWYWwubGVuZ3RoID0gMDtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBpZiBtZXJnaW5nIGZyb20gYW4gaW1wb3J0IHRoZW4gcmF3IHdpbGwgaGF2ZSBhbiBlbnRpdHlBc3BlY3Qgb3IgYSBjb21wbGV4QXNwZWN0XHJcbiAgICBsZXQgcmF3QXNwZWN0ID0gcmF3LmVudGl0eUFzcGVjdCB8fCByYXcuY29tcGxleEFzcGVjdDtcclxuICAgIGlmIChyYXdBc3BlY3QpIHtcclxuXHJcbiAgICAgIGxldCB0YXJnZXRBc3BlY3QgPSBFbnRpdHlBc3BlY3QuaXNFbnRpdHkodGFyZ2V0KSA/IHRhcmdldC5lbnRpdHlBc3BlY3QgOiB0YXJnZXQuY29tcGxleEFzcGVjdDtcclxuICAgICAgaWYgKHJhd0FzcGVjdC5vcmlnaW5hbFZhbHVlc01hcCkge1xyXG4gICAgICAgIHRhcmdldEFzcGVjdC5vcmlnaW5hbFZhbHVlcyA9IHJhd0FzcGVjdC5vcmlnaW5hbFZhbHVlc01hcDtcclxuICAgICAgfVxyXG4gICAgICBpZiAocmF3QXNwZWN0LmV4dHJhTWV0YWRhdGEpIHtcclxuICAgICAgICB0YXJnZXRBc3BlY3QuZXh0cmFNZXRhZGF0YSA9IHJhd0FzcGVjdC5leHRyYU1ldGFkYXRhO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuXHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBFbnRpdHlUeXBlLlxyXG4gICoqL1xyXG4gIHRvU3RyaW5nKCkge1xyXG4gICAgcmV0dXJuIHRoaXMubmFtZTtcclxuICB9XHJcblxyXG4gIHRvSlNPTigpIHtcclxuICAgIHJldHVybiBjb3JlLnRvSnNvbih0aGlzLCB7XHJcbiAgICAgIHNob3J0TmFtZTogbnVsbCxcclxuICAgICAgbmFtZXNwYWNlOiBudWxsLFxyXG4gICAgICBiYXNlVHlwZU5hbWU6IG51bGwsXHJcbiAgICAgIGlzQWJzdHJhY3Q6IGZhbHNlLFxyXG4gICAgICBhdXRvR2VuZXJhdGVkS2V5VHlwZTogbnVsbCwgLy8gZG8gbm90IHN1cHByZXNzIGRlZmF1bHQgdmFsdWVcclxuICAgICAgZGVmYXVsdFJlc291cmNlTmFtZTogbnVsbCxcclxuICAgICAgZGF0YVByb3BlcnRpZXM6IGxvY2FsUHJvcHNPbmx5LFxyXG4gICAgICBuYXZpZ2F0aW9uUHJvcGVydGllczogbG9jYWxQcm9wc09ubHksXHJcbiAgICAgIHZhbGlkYXRvcnM6IG51bGwsXHJcbiAgICAgIGN1c3RvbTogbnVsbFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfdXBkYXRlTmFtZXMocHJvcGVydHk6IEVudGl0eVByb3BlcnR5KSB7XHJcbiAgICBsZXQgbmMgPSB0aGlzLm1ldGFkYXRhU3RvcmUubmFtaW5nQ29udmVudGlvbjtcclxuICAgIHVwZGF0ZUNsaWVudFNlcnZlck5hbWVzKG5jLCBwcm9wZXJ0eSwgXCJuYW1lXCIpO1xyXG5cclxuICAgIGlmIChwcm9wZXJ0eS5pc05hdmlnYXRpb25Qcm9wZXJ0eSkge1xyXG4gICAgICB1cGRhdGVDbGllbnRTZXJ2ZXJOYW1lcyhuYywgcHJvcGVydHksIFwiZm9yZWlnbktleU5hbWVzXCIpO1xyXG4gICAgICB1cGRhdGVDbGllbnRTZXJ2ZXJOYW1lcyhuYywgcHJvcGVydHksIFwiaW52Rm9yZWlnbktleU5hbWVzXCIpO1xyXG5cclxuICAgICAgLy8gdGhlc2Ugd2lsbCBnZXQgc2V0IGxhdGVyIHZpYSBfdXBkYXRlTnBzXHJcbiAgICAgIC8vIHRoaXMuaW52ZXJzZVxyXG4gICAgICAvLyB0aGlzLmVudGl0eVR5cGVcclxuICAgICAgLy8gdGhpcy5yZWxhdGVkRGF0YVByb3BlcnRpZXNcclxuICAgICAgLy8gICAgZGF0YVByb3BlcnR5LnJlbGF0ZWROYXZpZ2F0aW9uUHJvcGVydHlcclxuICAgICAgLy8gICAgZGF0YVByb3BlcnR5LmludmVyc2VOYXZpZ2F0aW9uUHJvcGVydHlcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9jaGVja05hdlByb3BlcnR5KG5hdmlnYXRpb25Qcm9wZXJ0eTogTmF2aWdhdGlvblByb3BlcnR5IHwgc3RyaW5nKSB7XHJcbiAgICAvLyBpZiAobmF2aWdhdGlvblByb3BlcnR5LmlzTmF2aWdhdGlvblByb3BlcnR5KSB7XHJcbiAgICBpZiAobmF2aWdhdGlvblByb3BlcnR5IGluc3RhbmNlb2YgTmF2aWdhdGlvblByb3BlcnR5KSB7XHJcbiAgICAgIGlmIChuYXZpZ2F0aW9uUHJvcGVydHkucGFyZW50VHlwZSAhPT0gdGhpcykge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihjb3JlLmZvcm1hdFN0cmluZyhcIlRoZSBuYXZpZ2F0aW9uUHJvcGVydHkgJyUxJyBpcyBub3QgYSBwcm9wZXJ0eSBvZiBlbnRpdHkgdHlwZSAnJTInXCIsXHJcbiAgICAgICAgICBuYXZpZ2F0aW9uUHJvcGVydHkubmFtZSwgdGhpcy5uYW1lKSk7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIG5hdmlnYXRpb25Qcm9wZXJ0eTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHlwZW9mIChuYXZpZ2F0aW9uUHJvcGVydHkpID09PSAnc3RyaW5nJykge1xyXG4gICAgICBsZXQgbnAgPSB0aGlzLmdldFByb3BlcnR5KG5hdmlnYXRpb25Qcm9wZXJ0eSk7XHJcbiAgICAgIC8vIGlmIChucCAmJiBucC5pc05hdmlnYXRpb25Qcm9wZXJ0eSkgcmV0dXJuIG5wO1xyXG4gICAgICBpZiAobnAgJiYgbnAgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uUHJvcGVydHkpIHJldHVybiBucDtcclxuICAgIH1cclxuICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSAnbmF2aWdhdGlvblByb3BlcnR5JyBwYXJhbWV0ZXIgbXVzdCBlaXRoZXIgYmUgYSBOYXZpZ2F0aW9uUHJvcGVydHkgb3IgdGhlIG5hbWUgb2YgYSBOYXZpZ2F0aW9uUHJvcGVydHlcIik7XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfYWRkRGF0YVByb3BlcnR5KGRwOiBEYXRhUHJvcGVydHkpIHtcclxuXHJcbiAgICB0aGlzLmRhdGFQcm9wZXJ0aWVzLnB1c2goZHApO1xyXG5cclxuICAgIGlmIChkcC5pc1BhcnRPZktleSkge1xyXG4gICAgICB0aGlzLmtleVByb3BlcnRpZXMucHVzaChkcCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGRwLmlzQ29tcGxleFByb3BlcnR5KSB7XHJcbiAgICAgIHRoaXMuY29tcGxleFByb3BlcnRpZXMucHVzaChkcCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGRwLmNvbmN1cnJlbmN5TW9kZSAmJiBkcC5jb25jdXJyZW5jeU1vZGUgIT09IFwiTm9uZVwiKSB7XHJcbiAgICAgIHRoaXMuY29uY3VycmVuY3lQcm9wZXJ0aWVzLnB1c2goZHApO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChkcC5pc1VubWFwcGVkKSB7XHJcbiAgICAgIHRoaXMudW5tYXBwZWRQcm9wZXJ0aWVzLnB1c2goZHApO1xyXG4gICAgfVxyXG5cclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9hZGROYXZpZ2F0aW9uUHJvcGVydHkobnA6IE5hdmlnYXRpb25Qcm9wZXJ0eSkge1xyXG5cclxuICAgIHRoaXMubmF2aWdhdGlvblByb3BlcnRpZXMucHVzaChucCk7XHJcblxyXG4gICAgaWYgKCFpc1F1YWxpZmllZFR5cGVOYW1lKG5wLmVudGl0eVR5cGVOYW1lKSkge1xyXG4gICAgICBucC5lbnRpdHlUeXBlTmFtZSA9IHF1YWxpZnlUeXBlTmFtZShucC5lbnRpdHlUeXBlTmFtZSwgdGhpcy5uYW1lc3BhY2UpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3VwZGF0ZUNwcygpIHtcclxuICAgIGxldCBtZXRhZGF0YVN0b3JlID0gdGhpcy5tZXRhZGF0YVN0b3JlO1xyXG4gICAgbGV0IGluY29tcGxldGVUeXBlTWFwID0gbWV0YWRhdGFTdG9yZS5faW5jb21wbGV0ZUNvbXBsZXhUeXBlTWFwO1xyXG4gICAgdGhpcy5jb21wbGV4UHJvcGVydGllcy5mb3JFYWNoKGZ1bmN0aW9uIChjcCkge1xyXG4gICAgICBpZiAoY3AuY29tcGxleFR5cGUpIHJldHVybjtcclxuICAgICAgaWYgKCFyZXNvbHZlQ3AoY3AsIG1ldGFkYXRhU3RvcmUpKSB7XHJcbiAgICAgICAgY29yZS5nZXRBcnJheShpbmNvbXBsZXRlVHlwZU1hcCwgY3AuY29tcGxleFR5cGVOYW1lKS5wdXNoKGNwKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgaWYgKHRoaXMuaXNDb21wbGV4VHlwZSkge1xyXG4gICAgICAoaW5jb21wbGV0ZVR5cGVNYXBbdGhpcy5uYW1lXSB8fCBbXSkuZm9yRWFjaChmdW5jdGlvbiAoY3A6IERhdGFQcm9wZXJ0eSkge1xyXG4gICAgICAgIHJlc29sdmVDcChjcCwgbWV0YWRhdGFTdG9yZSk7XHJcbiAgICAgIH0pO1xyXG4gICAgICBkZWxldGUgaW5jb21wbGV0ZVR5cGVNYXBbdGhpcy5uYW1lXTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF91cGRhdGVOcHMoKSB7XHJcbiAgICBsZXQgbWV0YWRhdGFTdG9yZSA9IHRoaXMubWV0YWRhdGFTdG9yZTtcclxuXHJcbiAgICAvLyByZXNvbHZlIGFsbCBuYXZQcm9wcyBmb3IgdGhpcyBlbnRpdHlUeXBlXHJcbiAgICB0aGlzLm5hdmlnYXRpb25Qcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24gKG5wKSB7XHJcbiAgICAgIHRyeVJlc29sdmVOcChucCwgbWV0YWRhdGFTdG9yZSk7XHJcbiAgICB9KTtcclxuICAgIGxldCBpbmNvbXBsZXRlVHlwZU1hcCA9IG1ldGFkYXRhU3RvcmUuX2luY29tcGxldGVUeXBlTWFwO1xyXG4gICAgLy8gbmV4dCByZXNvbHZlIGFsbCBuYXZQcm9wIHRoYXQgcG9pbnQgdG8gdGhpcyBlbnRpdHlUeXBlLlxyXG4gICAgKGluY29tcGxldGVUeXBlTWFwW3RoaXMubmFtZV0gfHwgW10pLmZvckVhY2goZnVuY3Rpb24gKG5wOiBOYXZpZ2F0aW9uUHJvcGVydHkpIHtcclxuICAgICAgdHJ5UmVzb2x2ZU5wKG5wLCBtZXRhZGF0YVN0b3JlKTtcclxuICAgIH0pO1xyXG4gICAgLy8gZXZlcnkgbmF2UHJvcCB0aGF0IHBvaW50ZWQgdG8gdGhpcyB0eXBlIHNob3VsZCBub3cgYmUgcmVzb2x2ZWRcclxuICAgIGRlbGV0ZSBpbmNvbXBsZXRlVHlwZU1hcFt0aGlzLm5hbWVdO1xyXG4gIH1cclxufVxyXG5cclxuRW50aXR5VHlwZS5wcm90b3R5cGUuXyR0eXBlTmFtZSA9IFwiRW50aXR5VHlwZVwiO1xyXG5cclxuZnVuY3Rpb24gZ2V0UmF3VmFsdWVGcm9tQ29uZmlnKHJhd0VudGl0eTogYW55LCBkcDogRGF0YVByb3BlcnR5KSB7XHJcbiAgLy8gJ3RydWUnIGZvcmsgY2FuIGhhcHBlbiBpZiBhbiBpbml0aWFsaXplciBjb250YWlucyBhbiBhY3RhdWwgaW5zdGFuY2Ugb2YgYW4gYWxyZWFkeSBjcmVhdGVkIGNvbXBsZXggb2JqZWN0LlxyXG4gIHJldHVybiAocmF3RW50aXR5LmVudGl0eUFzcGVjdCB8fCByYXdFbnRpdHkuY29tcGxleEFzcGVjdCkgPyByYXdFbnRpdHkuZ2V0UHJvcGVydHkoZHAubmFtZSkgOiByYXdFbnRpdHlbZHAubmFtZV07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHVwZGF0ZUNsaWVudFNlcnZlck5hbWVzKG5jOiBOYW1pbmdDb252ZW50aW9uLCBwYXJlbnQ6IGFueSwgY2xpZW50UHJvcE5hbWU6IHN0cmluZykge1xyXG4gIGxldCBzZXJ2ZXJQcm9wTmFtZSA9IGNsaWVudFByb3BOYW1lICsgXCJPblNlcnZlclwiO1xyXG4gIGxldCBjbGllbnROYW1lID0gcGFyZW50W2NsaWVudFByb3BOYW1lXTtcclxuICBpZiAoY2xpZW50TmFtZSAmJiBjbGllbnROYW1lLmxlbmd0aCkge1xyXG4gICAgLy8gaWYgKHBhcmVudC5pc1VubWFwcGVkKSByZXR1cm47XHJcbiAgICBsZXQgc2VydmVyTmFtZXMgPSBjb3JlLnRvQXJyYXkoY2xpZW50TmFtZSkubWFwKGZ1bmN0aW9uIChjTmFtZSkge1xyXG4gICAgICBsZXQgc05hbWUgPSBuYy5jbGllbnRQcm9wZXJ0eU5hbWVUb1NlcnZlcihjTmFtZSwgcGFyZW50KTtcclxuICAgICAgbGV0IHRlc3ROYW1lID0gbmMuc2VydmVyUHJvcGVydHlOYW1lVG9DbGllbnQoc05hbWUsIHBhcmVudCk7XHJcbiAgICAgIGlmIChjTmFtZSAhPT0gdGVzdE5hbWUpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJOYW1pbmdDb252ZW50aW9uIGZvciB0aGlzIGNsaWVudCBwcm9wZXJ0eSBuYW1lIGRvZXMgbm90IHJvdW5kdHJpcCBwcm9wZXJseTpcIiArIGNOYW1lICsgXCItLT5cIiArIHRlc3ROYW1lKTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gc05hbWU7XHJcbiAgICB9KTtcclxuICAgIHBhcmVudFtzZXJ2ZXJQcm9wTmFtZV0gPSBBcnJheS5pc0FycmF5KGNsaWVudE5hbWUpID8gc2VydmVyTmFtZXMgOiBzZXJ2ZXJOYW1lc1swXTtcclxuICB9IGVsc2Uge1xyXG4gICAgbGV0IHNlcnZlck5hbWUgPSBwYXJlbnRbc2VydmVyUHJvcE5hbWVdO1xyXG4gICAgaWYgKCghc2VydmVyTmFtZSkgfHwgc2VydmVyTmFtZS5sZW5ndGggPT09IDApIHJldHVybjtcclxuICAgIGxldCBjbGllbnROYW1lcyA9IGNvcmUudG9BcnJheShzZXJ2ZXJOYW1lKS5tYXAoZnVuY3Rpb24gKHNOYW1lKSB7XHJcbiAgICAgIGxldCBjTmFtZSA9IG5jLnNlcnZlclByb3BlcnR5TmFtZVRvQ2xpZW50KHNOYW1lLCBwYXJlbnQpO1xyXG4gICAgICBsZXQgdGVzdE5hbWUgPSBuYy5jbGllbnRQcm9wZXJ0eU5hbWVUb1NlcnZlcihjTmFtZSwgcGFyZW50KTtcclxuICAgICAgaWYgKHNOYW1lICE9PSB0ZXN0TmFtZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5hbWluZ0NvbnZlbnRpb24gZm9yIHRoaXMgc2VydmVyIHByb3BlcnR5IG5hbWUgZG9lcyBub3Qgcm91bmR0cmlwIHByb3Blcmx5OlwiICsgc05hbWUgKyBcIi0tPlwiICsgdGVzdE5hbWUpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBjTmFtZTtcclxuICAgIH0pO1xyXG4gICAgcGFyZW50W2NsaWVudFByb3BOYW1lXSA9IEFycmF5LmlzQXJyYXkoc2VydmVyTmFtZSkgPyBjbGllbnROYW1lcyA6IGNsaWVudE5hbWVzWzBdO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlRW1wdHlDdG9yKHR5cGU6IGFueSkge1xyXG4gIGlmIChjb25maWcubm9FdmFsKSB7XHJcbiAgICBsZXQgRW50aXR5ID0gZnVuY3Rpb24oKSB7fTtcclxuICAgIHJldHVybiBFbnRpdHk7XHJcbiAgfSBlbHNlIHtcclxuICAgIGxldCBuYW1lID0gdHlwZS5uYW1lLnJlcGxhY2UoL1xcVy9nLCAnXycpO1xyXG4gICAgcmV0dXJuIEZ1bmN0aW9uKCdyZXR1cm4gZnVuY3Rpb24gJyArIG5hbWUgKyAnKCl7fScpKCk7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBjb0VxdWFscyhjbzE6IENvbXBsZXhPYmplY3QsIGNvMjogQ29tcGxleE9iamVjdCk6IGJvb2xlYW4ge1xyXG4gIGxldCBjb21wbGV4VHlwZSA9IGNvMS5jb21wbGV4QXNwZWN0IS5wYXJlbnRQcm9wZXJ0eSEuZGF0YVR5cGUgYXMgQ29tcGxleFR5cGU7XHJcbiAgbGV0IGRhdGFQcm9wcyA9IGNvbXBsZXhUeXBlLmRhdGFQcm9wZXJ0aWVzO1xyXG4gIGxldCBhcmVFcXVhbCA9IGRhdGFQcm9wcy5ldmVyeShmdW5jdGlvbiAoZHApIHtcclxuICAgIGlmICghZHAuaXNTZXR0YWJsZSkgcmV0dXJuIHRydWU7XHJcbiAgICBsZXQgdjEgPSBjbzEuZ2V0UHJvcGVydHkoZHAubmFtZSk7XHJcbiAgICBsZXQgdjIgPSBjbzIuZ2V0UHJvcGVydHkoZHAubmFtZSk7XHJcbiAgICBpZiAoZHAuaXNDb21wbGV4UHJvcGVydHkgJiYgZHAuaXNTY2FsYXIpIHtcclxuICAgICAgcmV0dXJuIGNvRXF1YWxzKHYxLCB2Mik7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChkcC5pc0NvbXBsZXhQcm9wZXJ0eSAmJiAhZHAuaXNTY2FsYXIpIHtcclxuICAgICAgcmV0dXJuIGNvcmUuYXJyYXlFcXVhbHModjEsIHYyLCBjb0VxdWFscyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBsZXQgZGF0YVR5cGUgPSA8YW55PmRwLmRhdGFUeXBlOyAvLyB0aGlzIHdpbGwgYmUgYSBjb21wbGV4VHlwZSB3aGVuIGRwIGlzIGEgY29tcGxleFByb3BlcnR5XHJcbiAgICAgIHJldHVybiAodjEgPT09IHYyIHx8IChkYXRhVHlwZSAmJiBkYXRhVHlwZS5ub3JtYWxpemUgJiYgdjEgJiYgdjIgJiYgZGF0YVR5cGUubm9ybWFsaXplKHYxKSA9PT0gZGF0YVR5cGUubm9ybWFsaXplKHYyKSkpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIHJldHVybiBhcmVFcXVhbDtcclxufVxyXG5cclxuZnVuY3Rpb24gbG9jYWxQcm9wc09ubHkocHJvcHM6IEVudGl0eVByb3BlcnR5W10pIHtcclxuICByZXR1cm4gcHJvcHMuZmlsdGVyKGZ1bmN0aW9uIChwcm9wKSB7XHJcbiAgICByZXR1cm4gcHJvcC5iYXNlUHJvcGVydHkgPT0gbnVsbDtcclxuICB9KTtcclxufVxyXG5cclxuXHJcbmZ1bmN0aW9uIHJlc29sdmVDcChjcDogRGF0YVByb3BlcnR5LCBtZXRhZGF0YVN0b3JlOiBNZXRhZGF0YVN0b3JlKSB7XHJcbiAgbGV0IGNvbXBsZXhUeXBlID0gbWV0YWRhdGFTdG9yZS5fZ2V0U3RydWN0dXJhbFR5cGUoY3AuY29tcGxleFR5cGVOYW1lLCB0cnVlKTtcclxuICBpZiAoIWNvbXBsZXhUeXBlKSByZXR1cm4gZmFsc2U7XHJcbiAgaWYgKCEoY29tcGxleFR5cGUgaW5zdGFuY2VvZiBDb21wbGV4VHlwZSkpIHtcclxuICAgIHRocm93IG5ldyBFcnJvcihcIlVuYWJsZSB0byByZXNvbHZlIENvbXBsZXhUeXBlIHdpdGggdGhlIG5hbWU6IFwiICsgY3AuY29tcGxleFR5cGVOYW1lICsgXCIgZm9yIHRoZSBwcm9wZXJ0eTogXCIgKyBjcC5uYW1lKTtcclxuICB9XHJcbiAgY3AuZGF0YVR5cGUgPSBjb21wbGV4VHlwZTtcclxuICBjcC5kZWZhdWx0VmFsdWUgPSBudWxsO1xyXG4gIHJldHVybiB0cnVlO1xyXG59XHJcblxyXG5mdW5jdGlvbiB0cnlSZXNvbHZlTnAobnA6IE5hdmlnYXRpb25Qcm9wZXJ0eSwgbWV0YWRhdGFTdG9yZTogTWV0YWRhdGFTdG9yZSkge1xyXG4gIGlmIChucC5lbnRpdHlUeXBlKSByZXR1cm4gdHJ1ZTtcclxuXHJcbiAgbGV0IGVudGl0eVR5cGUgPSBtZXRhZGF0YVN0b3JlLl9nZXRTdHJ1Y3R1cmFsVHlwZShucC5lbnRpdHlUeXBlTmFtZSwgdHJ1ZSkgYXMgRW50aXR5VHlwZTtcclxuICBpZiAoZW50aXR5VHlwZSkge1xyXG4gICAgbnAuZW50aXR5VHlwZSA9IGVudGl0eVR5cGU7XHJcbiAgICBucC5fcmVzb2x2ZU5wKCk7XHJcbiAgICAvLyBkb24ndCBib3RoZXIgcmVtb3ZpbmcgLSBfdXBkYXRlTnBzIHdpbGwgZG8gaXQgbGF0ZXIuXHJcbiAgICAvLyBfX2FycmF5UmVtb3ZlSXRlbShpbmNvbXBsZXRlTnBzLCBucCwgZmFsc2UpO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBsZXQgaW5jb21wbGV0ZU5wcyA9IGNvcmUuZ2V0QXJyYXkobWV0YWRhdGFTdG9yZS5faW5jb21wbGV0ZVR5cGVNYXAsIG5wLmVudGl0eVR5cGVOYW1lKTtcclxuICAgIGNvcmUuYXJyYXlBZGRJdGVtVW5pcXVlKGluY29tcGxldGVOcHMsIG5wKTtcclxuICB9XHJcbiAgcmV0dXJuICEhZW50aXR5VHlwZTtcclxufVxyXG5cclxuZnVuY3Rpb24gY2FsY1VubWFwcGVkUHJvcGVydGllcyhzdHlwZTogU3RydWN0dXJhbFR5cGUsIGluc3RhbmNlOiBhbnkpIHtcclxuICBsZXQgbWV0YWRhdGFQcm9wTmFtZXMgPSBzdHlwZS5nZXRQcm9wZXJ0eU5hbWVzKCk7XHJcbiAgbGV0IG1vZGVsTGliID0gY29uZmlnLmludGVyZmFjZVJlZ2lzdHJ5Lm1vZGVsTGlicmFyeS5nZXREZWZhdWx0SW5zdGFuY2UoKTtcclxuICBsZXQgdHJhY2thYmxlUHJvcE5hbWVzID0gbW9kZWxMaWIuZ2V0VHJhY2thYmxlUHJvcGVydHlOYW1lcyhpbnN0YW5jZSk7XHJcbiAgdHJhY2thYmxlUHJvcE5hbWVzLmZvckVhY2goZnVuY3Rpb24gKHBuOiBzdHJpbmcpIHtcclxuICAgIGlmIChtZXRhZGF0YVByb3BOYW1lcy5pbmRleE9mKHBuKSA9PT0gLTEpIHtcclxuICAgICAgbGV0IHZhbCA9IGluc3RhbmNlW3BuXTtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbCA9PT0gXCJmdW5jdGlvblwiKSB2YWwgPSB2YWwoKTtcclxuICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICB9XHJcbiAgICAgIGxldCBkdCA9IERhdGFUeXBlLmZyb21WYWx1ZSh2YWwpO1xyXG4gICAgICBsZXQgbmV3UHJvcCA9IG5ldyBEYXRhUHJvcGVydHkoe1xyXG4gICAgICAgIG5hbWU6IHBuLFxyXG4gICAgICAgIGRhdGFUeXBlOiBkdCxcclxuICAgICAgICBpc051bGxhYmxlOiB0cnVlLFxyXG4gICAgICAgIGlzVW5tYXBwZWQ6IHRydWVcclxuICAgICAgfSk7XHJcbiAgICAgIG5ld1Byb3AuaXNTZXR0YWJsZSA9IGNvcmUuaXNTZXR0YWJsZShpbnN0YW5jZSwgcG4pO1xyXG4gICAgICBpZiAoc3R5cGUgaW5zdGFuY2VvZiBFbnRpdHlUeXBlICYmIHN0eXBlLnN1YnR5cGVzICE9IG51bGwgJiYgc3R5cGUuc3VidHlwZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgc3R5cGUuZ2V0U2VsZkFuZFN1YnR5cGVzKCkuZm9yRWFjaCgoc3QpID0+IHtcclxuICAgICAgICAgIHN0Ll9hZGRQcm9wZXJ0eUNvcmUobmV3IERhdGFQcm9wZXJ0eShuZXdQcm9wKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgc3R5cGUuX2FkZFByb3BlcnR5Q29yZShuZXdQcm9wKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIENvbXBsZXhUeXBlQ29uZmlnIHtcclxuICBzaG9ydE5hbWU/OiBzdHJpbmc7XHJcbiAgbmFtZXNwYWNlPzogc3RyaW5nO1xyXG4gIGRhdGFQcm9wZXJ0aWVzPzogRGF0YVByb3BlcnR5W10gfCBPYmplY3RbXSB8IE9iamVjdDtcclxuICBpc0NvbXBsZXhUeXBlPzogYm9vbGVhbjsgIC8vIG5lZWRlZCBiZWNhdXNlIHRoaXMgY3RvciBjYW4gZ2V0IGNhbGxlZCBmcm9tIHRoZSBhZGRFbnRpdHlUeXBlIG1ldGhvZCB3aGljaCBuZWVkcyB0aGUgaXNDb21wbGV4VHlwZSBwcm9wXHJcbiAgY3VzdG9tPzogT2JqZWN0O1xyXG59XHJcblxyXG4vKiogIENvbnRhaW5lciBmb3IgYWxsIG9mIHRoZSBtZXRhZGF0YSBhYm91dCBhIHNwZWNpZmljIHR5cGUgb2YgQ29tcGxleCBvYmplY3QuXHJcbj4gICAgIGxldCBjb21wbGV4VHlwZSA9IG5ldyBDb21wbGV4VHlwZSgge1xyXG4+ICAgICAgICAgc2hvcnROYW1lOiBcImFkZHJlc3NcIixcclxuPiAgICAgICAgIG5hbWVzcGFjZTogXCJteUFwcE5hbWVzcGFjZVwiXHJcbj4gICAgIH0pO1xyXG5AcGFyYW0gY29uZmlnIC0gQ29uZmlndXJhdGlvbiBzZXR0aW5nc1xyXG4qKi9cclxuZXhwb3J0IGNsYXNzIENvbXBsZXhUeXBlIHtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfJHR5cGVOYW1lOiBzdHJpbmc7IC8vIG9uIHByb3RvXHJcbiAgLyoqIEZvciBwb2x5bW9ycGhpYyBwdXJwb3NlIG9ubHkgLSBhbHdheXMgdHJ1ZSBoZXJlICovXHJcbiAgaXNDb21wbGV4VHlwZSA9IHRydWU7XHJcblxyXG4gIC8qKiBUaGUgW1tNZXRhZGF0YVN0b3JlXV0gY29udGFpbmluZyB0aGlzIENvbXBsZXhUeXBlLiAqL1xyXG4gIG1ldGFkYXRhU3RvcmU6IE1ldGFkYXRhU3RvcmU7XHJcblxyXG4gIC8qKiAgVGhlIGZ1bGx5IHF1YWxpZmVkIG5hbWUgb2YgdGhpcyBDb21wbGV4VHlwZS4gX19SZWFkIE9ubHlfXyAgKiovXHJcbiAgbmFtZTogc3RyaW5nO1xyXG4gIC8qKiAgVGhlIHNob3J0LCB1bnF1YWxpZmllZCwgbmFtZSBmb3IgdGhpcyBDb21wbGV4VHlwZS4gX19SZWFkIE9ubHlfXyAqKi9cclxuICBzaG9ydE5hbWU6IHN0cmluZztcclxuXHJcbiAgLyoqIFRoZSBuYW1lc3BhY2UgZm9yIHRoaXMgQ29tcGxleFR5cGUuIF9fUmVhZCBPbmx5X18gKiovXHJcbiAgbmFtZXNwYWNlOiBzdHJpbmc7XHJcbiAgLyoqIFRoZSBEYXRhUHJvcGVydGllcyAoc2VlIFtbRGF0YVByb3BlcnR5XV0gYXNzb2NpYXRlZCB3aXRoIHRoaXMgQ29tcGxleFR5cGUuIF9fUmVhZCBPbmx5X18gKi9cclxuICBkYXRhUHJvcGVydGllczogRGF0YVByb3BlcnR5W107XHJcbiAgLyoqIFRoZSBEYXRhUHJvcGVydGllcyBmb3IgdGhpcyBDb21wbGV4VHlwZSB0aGF0IGNvbnRhaW4gaW5zdGFuY2VzIG9mIGEgW1tDb21wbGV4VHlwZV1dLiBfX1JlYWQgT25seV9fICovXHJcbiAgY29tcGxleFByb3BlcnRpZXM6IERhdGFQcm9wZXJ0eVtdO1xyXG5cclxuICAvKipcclxuICBUaGUgZW50aXR5IGxldmVsIHZhbGlkYXRvcnMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgQ29tcGxleFR5cGUuIFZhbGlkYXRvcnMgY2FuIGJlIGFkZGVkIGFuZFxyXG4gIHJlbW92ZWQgZnJvbSB0aGlzIGNvbGxlY3Rpb24uIF9fUmVhZCBPbmx5X18gICoqL1xyXG4gIHZhbGlkYXRvcnM6IFZhbGlkYXRvcltdO1xyXG4gIC8qKiBGb3IgcG9seW1vcnBoaWMgcHVycG9zZSBvbmx5IC0gYWx3YXlzIGVtcHR5IGhlcmUgKi9cclxuICBjb25jdXJyZW5jeVByb3BlcnRpZXM6IERhdGFQcm9wZXJ0eVtdO1xyXG4gIC8qKiBUaGUgRGF0YVByb3BlcnRpZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgQ29tcGxleFR5cGUgdGhhdCBhcmUgbm90IG1hcHBlZCB0byBhbnkgYmFja2VuZCBkYXRhc3RvcmUuIFRoZXNlIGFyZSBlZmZlY3RpdmVseSBmcmVlIHN0YW5kaW5nXHJcbiAgcHJvcGVydGllcy4gX19SZWFkIE9ubHlfXyAgICoqL1xyXG4gIHVubWFwcGVkUHJvcGVydGllczogRGF0YVByb3BlcnR5W107XHJcblxyXG4gIC8vIGtleVByb3BlcnRpZXMgYW5kIG5hdmlnYXRpb25Qcm9wZXJ0aWVzIGFyZSBub3QgdXNlZCBvbiBjb21wbGV4VHlwZXMgLSBidXQgaGVyZSB0byBhbGxvdyBzaGFyaW5nIG9mIGNvZGUgYmV0d2VlbiBFbnRpdHlUeXBlIGFuZCBDb21wbGV4VHlwZS5cclxuICBuYXZpZ2F0aW9uUHJvcGVydGllczogRGF0YVByb3BlcnR5W107XHJcbiAgLy8gYW5kIG1heSBiZSB1c2VkIGxhdGVyIHRvIGVuZm9yY2UgdW5pcXVlbmVzcyBvbiBhcnJheXMgb2YgY29tcGxleHR5cGVzLlxyXG4gIGtleVByb3BlcnRpZXM6IERhdGFQcm9wZXJ0eVtdO1xyXG4gIHdhcm5pbmdzOiBhbnlbXTtcclxuICBzZXJpYWxpemVyRm4/OiAocHJvcDogRW50aXR5UHJvcGVydHksIHZhbDogYW55KSA9PiBhbnk7XHJcblxyXG4gIC8qKiBBIGZyZWUgZm9ybSBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byBkZWZpbmUgYW55IGN1c3RvbSBtZXRhZGF0YSBmb3IgdGhpcyBDb21wbGV4VHlwZS4gKioqL1xyXG4gIGN1c3RvbT86IGFueTtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfbWFwcGVkUHJvcGVydGllc0NvdW50OiBudW1iZXI7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2V4dHJhPzogYW55O1xyXG5cclxuICAvLyBjb3B5IGVudGl0eVR5cGUgbWV0aG9kcyBvbnRvIGNvbXBsZXhUeXBlXHJcbiAgLyoqIFNlZSBbW0VudGl0eVR5cGUuZ2V0Q3Rvcl1dICovXHJcbiAgZ2V0Q3RvciA9IEVudGl0eVR5cGUucHJvdG90eXBlLmdldEN0b3I7XHJcbiAgLy8gbm90ZSB0aGUgbmFtZSBjaGFuZ2UuXHJcbiAgY3JlYXRlSW5zdGFuY2UgPSBFbnRpdHlUeXBlLnByb3RvdHlwZS5jcmVhdGVFbnRpdHk7XHJcbiAgLyoqIFNlZSBbRW50aXR5VHlwZS5hZGRWYWxpZGF0b3JdICovXHJcbiAgYWRkVmFsaWRhdG9yID0gRW50aXR5VHlwZS5wcm90b3R5cGUuYWRkVmFsaWRhdG9yO1xyXG4gIGdldFByb3BlcnR5ID0gRW50aXR5VHlwZS5wcm90b3R5cGUuZ2V0UHJvcGVydHk7XHJcbiAgZ2V0UHJvcGVydGllc09uUGF0aCA9IEVudGl0eVR5cGUucHJvdG90eXBlLmdldFByb3BlcnRpZXNPblBhdGg7XHJcbiAgZ2V0UHJvcGVydHlOYW1lcyA9IEVudGl0eVR5cGUucHJvdG90eXBlLmdldFByb3BlcnR5TmFtZXM7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2FkZFByb3BlcnR5Q29yZSA9IEVudGl0eVR5cGUucHJvdG90eXBlLl9hZGRQcm9wZXJ0eUNvcmU7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2FkZERhdGFQcm9wZXJ0eSA9IEVudGl0eVR5cGUucHJvdG90eXBlLl9hZGREYXRhUHJvcGVydHk7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3VwZGF0ZU5hbWVzID0gRW50aXR5VHlwZS5wcm90b3R5cGUuX3VwZGF0ZU5hbWVzO1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF91cGRhdGVDcHMgPSBFbnRpdHlUeXBlLnByb3RvdHlwZS5fdXBkYXRlQ3BzO1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9pbml0aWFsaXplSW5zdGFuY2UgPSBFbnRpdHlUeXBlLnByb3RvdHlwZS5faW5pdGlhbGl6ZUluc3RhbmNlO1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF91cGRhdGVUYXJnZXRGcm9tUmF3ID0gRW50aXR5VHlwZS5wcm90b3R5cGUuX3VwZGF0ZVRhcmdldEZyb21SYXc7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3NldEN0b3IgPSBFbnRpdHlUeXBlLnByb3RvdHlwZS5fc2V0Q3RvcjtcclxuXHJcbiAgY29uc3RydWN0b3IoY29uZmlnOiBDb21wbGV4VHlwZUNvbmZpZykge1xyXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBDb21wbGV4VHlwZSBjdG9yIGhhcyBhIHNpbmdsZSBhcmd1bWVudCB0aGF0IGlzIGEgY29uZmlndXJhdGlvbiBvYmplY3QuXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzc2VydENvbmZpZyhjb25maWcpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwic2hvcnROYW1lXCIpLmlzTm9uRW1wdHlTdHJpbmcoKVxyXG4gICAgICAud2hlcmVQYXJhbShcIm5hbWVzcGFjZVwiKS5pc1N0cmluZygpLmlzT3B0aW9uYWwoKS53aXRoRGVmYXVsdChcIlwiKVxyXG4gICAgICAud2hlcmVQYXJhbShcImRhdGFQcm9wZXJ0aWVzXCIpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAud2hlcmVQYXJhbShcImlzQ29tcGxleFR5cGVcIikuaXNPcHRpb25hbCgpLmlzQm9vbGVhbigpICAgLy8gbmVlZGVkIGJlY2F1c2UgdGhpcyBjdG9yIGNhbiBnZXQgY2FsbGVkIGZyb20gdGhlIGFkZEVudGl0eVR5cGUgbWV0aG9kIHdoaWNoIG5lZWRzIHRoZSBpc0NvbXBsZXhUeXBlIHByb3BcclxuICAgICAgLndoZXJlUGFyYW0oXCJjdXN0b21cIikuaXNPcHRpb25hbCgpXHJcbiAgICAgIC5hcHBseUFsbCh0aGlzKTtcclxuXHJcbiAgICB0aGlzLm5hbWUgPSBxdWFsaWZ5VHlwZU5hbWUodGhpcy5zaG9ydE5hbWUsIHRoaXMubmFtZXNwYWNlKTtcclxuICAgIHRoaXMuaXNDb21wbGV4VHlwZSA9IHRydWU7XHJcbiAgICB0aGlzLmRhdGFQcm9wZXJ0aWVzID0gW107XHJcbiAgICB0aGlzLmNvbXBsZXhQcm9wZXJ0aWVzID0gW107XHJcbiAgICB0aGlzLnZhbGlkYXRvcnMgPSBbXTtcclxuICAgIHRoaXMuY29uY3VycmVuY3lQcm9wZXJ0aWVzID0gW107XHJcbiAgICB0aGlzLnVubWFwcGVkUHJvcGVydGllcyA9IFtdO1xyXG4gICAgdGhpcy5fbWFwcGVkUHJvcGVydGllc0NvdW50ID0gMDtcclxuICAgIC8vIGtleVByb3BlcnRpZXMgYW5kIG5hdmlnYXRpb25Qcm9wZXJ0aWVzIGFyZSBub3QgdXNlZCBvbiBjb21wbGV4VHlwZXMgLSBidXQgaGVyZSB0byBhbGxvdyBzaGFyaW5nIG9mIGNvZGUgYmV0d2VlbiBFbnRpdHlUeXBlIGFuZCBDb21wbGV4VHlwZS5cclxuICAgIHRoaXMubmF2aWdhdGlvblByb3BlcnRpZXMgPSBbXTtcclxuICAgIHRoaXMua2V5UHJvcGVydGllcyA9IFtdOyAvLyBtYXkgYmUgdXNlZCBsYXRlciB0byBlbmZvcmNlIHVuaXF1ZW5lc3Mgb24gYXJyYXlzIG9mIGNvbXBsZXh0eXBlcy5cclxuICAgIGlmIChjb25maWcuZGF0YVByb3BlcnRpZXMpIHtcclxuICAgICAgYWRkUHJvcGVydGllcyh0aGlzLCBjb25maWcuZGF0YVByb3BlcnRpZXMsIERhdGFQcm9wZXJ0eSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBHZW5lcmFsIHB1cnBvc2UgcHJvcGVydHkgc2V0IG1ldGhvZFxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGFuIEVudGl0eU1hbmFnZXJcclxuICA+ICAgICAgbGV0IGFkZHJlc3N0VHlwZSA9IGVtMS5tZXRhZGF0YVN0b3JlLmdldEVudGl0eVR5cGUoXCJBZGRyZXNzXCIpO1xyXG4gID4gICAgICBhZGRyZXNzVHlwZS5zZXRQcm9wZXJ0aWVzKCB7XHJcbiAgPiAgICAgICAgICBjdXN0b206IHsgZm9vOiA3LCBiYXI6IFwidGVzdFwiIH1cclxuICA+ICAgICAgfSk7XHJcbiAgQHBhcmFtIGNvbmZpZyAtIEN1c3RvbSBjb25maWcgb2JqZWN0XHJcbiAgQHBhcmFtIGNvbmZpZy5jdXN0b20gLSB7T2JqZWN0fVxyXG4gICoqL1xyXG4gIHNldFByb3BlcnRpZXMoY29uZmlnOiB7IGN1c3RvbT86IE9iamVjdCB9KSB7XHJcbiAgICBhc3NlcnRDb25maWcoY29uZmlnKVxyXG4gICAgICAud2hlcmVQYXJhbShcImN1c3RvbVwiKS5pc09wdGlvbmFsKClcclxuICAgICAgLmFwcGx5QWxsKHRoaXMpO1xyXG4gIH1cclxuXHJcblxyXG4gIGdldEFsbFZhbGlkYXRvcnMoKSB7XHJcbiAgICAvLyBDb21wbGV4VHlwZSBpbmhlcml0YW5jZSBpcyBub3QgWUVUIHN1cHBvcnRlZC5cclxuICAgIHJldHVybiB0aGlzLnZhbGlkYXRvcnM7XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfY3JlYXRlSW5zdGFuY2VDb3JlKHBhcmVudDogU3RydWN0dXJhbE9iamVjdCwgcGFyZW50UHJvcGVydHk6IERhdGFQcm9wZXJ0eSkge1xyXG4gICAgbGV0IGFDdG9yID0gdGhpcy5nZXRDdG9yKCk7XHJcbiAgICBsZXQgaW5zdGFuY2UgPSBuZXcgYUN0b3IoKSBhcyBDb21wbGV4T2JqZWN0O1xyXG4gICAgbmV3IENvbXBsZXhBc3BlY3QoaW5zdGFuY2UsIHBhcmVudCwgcGFyZW50UHJvcGVydHkpO1xyXG4gICAgLy8gaW5pdGlhbGl6YXRpb24gb2NjdXJzIGR1cmluZyBlaXRoZXIgYXR0YWNoIG9yIGluIGNyZWF0ZUluc3RhbmNlIGNhbGwuXHJcbiAgICByZXR1cm4gaW5zdGFuY2U7XHJcbiAgfVxyXG5cclxuXHJcbiAgYWRkUHJvcGVydHkoZGF0YVByb3BlcnR5OiBEYXRhUHJvcGVydHkpIHtcclxuICAgIGFzc2VydFBhcmFtKGRhdGFQcm9wZXJ0eSwgXCJkYXRhUHJvcGVydHlcIikuaXNJbnN0YW5jZU9mKERhdGFQcm9wZXJ0eSkuY2hlY2soKTtcclxuICAgIHJldHVybiB0aGlzLl9hZGRQcm9wZXJ0eUNvcmUoZGF0YVByb3BlcnR5KTtcclxuICB9XHJcblxyXG4gIGdldFByb3BlcnRpZXMoKTogRW50aXR5UHJvcGVydHlbXSB7XHJcbiAgICByZXR1cm4gdGhpcy5kYXRhUHJvcGVydGllcztcclxuICB9XHJcblxyXG4gIHRvSlNPTigpIHtcclxuICAgIHJldHVybiBjb3JlLnRvSnNvbih0aGlzLCB7XHJcbiAgICAgIHNob3J0TmFtZTogbnVsbCxcclxuICAgICAgbmFtZXNwYWNlOiBudWxsLFxyXG4gICAgICBpc0NvbXBsZXhUeXBlOiBudWxsLFxyXG4gICAgICBkYXRhUHJvcGVydGllczogbnVsbCxcclxuICAgICAgdmFsaWRhdG9yczogbnVsbCxcclxuICAgICAgY3VzdG9tOiBudWxsXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG59XHJcbkNvbXBsZXhUeXBlLnByb3RvdHlwZS5fJHR5cGVOYW1lID0gXCJDb21wbGV4VHlwZVwiO1xyXG4vKiogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiB0aGlzIGNvbXBsZXhUeXBlICovXHJcbkNvbXBsZXhUeXBlLnByb3RvdHlwZS5jcmVhdGVJbnN0YW5jZSA9IEVudGl0eVR5cGUucHJvdG90eXBlLmNyZWF0ZUVudGl0eTtcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRGF0YVByb3BlcnR5Q29uZmlnIHtcclxuICBuYW1lPzogc3RyaW5nO1xyXG4gIG5hbWVPblNlcnZlcj86IHN0cmluZztcclxuICBkYXRhVHlwZT86IERhdGFUeXBlIHwgc3RyaW5nIHwgQ29tcGxleFR5cGU7XHJcbiAgY29tcGxleFR5cGVOYW1lPzogc3RyaW5nO1xyXG4gIGlzTnVsbGFibGU/OiBib29sZWFuO1xyXG4gIGlzU2NhbGFyPzogYm9vbGVhbjsgLy8gd2lsbCBiZSBmYWxzZSBmb3Igc29tZSBOb1NRTCBkYXRhYmFzZXMuXHJcbiAgZGVmYXVsdFZhbHVlPzogYW55O1xyXG4gIGlzUGFydE9mS2V5PzogYm9vbGVhbjtcclxuICBpc1VubWFwcGVkPzogYm9vbGVhbjtcclxuICBpc1NldHRhYmxlPzogYm9vbGVhbjtcclxuICBjb25jdXJyZW5jeU1vZGU/OiBzdHJpbmc7XHJcbiAgbWF4TGVuZ3RoPzogbnVtYmVyO1xyXG4gIHZhbGlkYXRvcnM/OiBWYWxpZGF0b3JbXTtcclxuICBkaXNwbGF5TmFtZT86IHN0cmluZztcclxuICBlbnVtVHlwZT86IGFueTtcclxuICByYXdUeXBlTmFtZT86IHN0cmluZzsgIC8vIG9jY3VycyB3aXRoIHVuZGVmaW5lZCBkYXRhdHlwZXNcclxuICBjdXN0b20/OiBPYmplY3Q7XHJcbn1cclxuXHJcbi8qKlxyXG5BIERhdGFQcm9wZXJ0eSBkZXNjcmliZXMgdGhlIG1ldGFkYXRhIGZvciBhIHNpbmdsZSBwcm9wZXJ0eSBvZiBhbiAgW1tFbnRpdHlUeXBlXV0gdGhhdCBjb250YWlucyBzaW1wbGUgZGF0YS5cclxuXHJcbkluc3RhbmNlcyBvZiB0aGUgRGF0YVByb3BlcnR5IGNsYXNzIGFyZSBjb25zdHJ1Y3RlZCBhdXRvbWF0aWNhbGx5IGR1cmluZyBNZXRhZGF0YSByZXRyaWV2YWwuIEhvd2V2ZXIgaXQgaXMgYWxzbyBwb3NzaWJsZSB0byBjb25zdHJ1Y3QgdGhlbVxyXG5kaXJlY3RseSB2aWEgdGhlIGNvbnN0cnVjdG9yLlxyXG4qKi9cclxuZXhwb3J0IGNsYXNzIERhdGFQcm9wZXJ0eSB7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgXyR0eXBlTmFtZTogc3RyaW5nOyAvLyBvbiBwcm90b1xyXG4gIC8qKiBJcyB0aGlzIGEgRGF0YVByb3BlcnR5PyAtIGFsd2F5cyB0cnVlIGhlcmUuIEFsbG93cyBwb2x5bW9ycGhpYyB0cmVhdG1lbnQgb2YgRGF0YVByb3BlcnRpZXMgYW5kIE5hdmlnYXRpb25Qcm9wZXJ0aWVzLiBfX1JlYWQgT25seV9fICovXHJcbiAgaXNEYXRhUHJvcGVydHkgPSB0cnVlO1xyXG4gIC8qKiBJcyB0aGlzIGEgTmF2aWdhdGlvblByb3BlcnR5PyAtIGFsd2F5cyBmYWxzZSBoZXJlLiAgQWxsb3dzIHBvbHltb3JwaGljIHRyZWF0bWVudCBvZiBEYXRhUHJvcGVydGllcyBhbmQgTmF2aWdhdGlvblByb3BlcnRpZXMuIF9fUmVhZCBPbmx5X18gKi9cclxuICBpc05hdmlnYXRpb25Qcm9wZXJ0eSA9IGZhbHNlO1xyXG4gIC8qKiBUaGUgbmFtZSBvZiB0aGlzIHByb3BlcnR5LiBfX1JlYWQgT25seV9fICAqKi9cclxuICBuYW1lOiBzdHJpbmc7XHJcbiAgLyoqIFRoZSBuYW1lIG9mIHRoaXMgcHJvcGVydHkgb24gdGhlIHNlcnZlci4gX19SZWFkIE9ubHlfXyAqKi9cclxuICBuYW1lT25TZXJ2ZXI6IHN0cmluZztcclxuICAvKiogVGhlIFtbRGF0YVR5cGVdXSBvZiB0aGlzIHByb3BlcnR5LiBfX1JlYWQgT25seV9fICovXHJcbiAgZGF0YVR5cGU6IERhdGFUeXBlIHwgQ29tcGxleFR5cGU7IC8vIHRoaXMgd2lsbCBiZSBhIGNvbXBsZXhUeXBlIHdoZW4gZHAgaXMgYSBjb21wbGV4UHJvcGVydHlcclxuICAvKiogVGhlIG5hbWUgb2YgdGhlIFtbQ29tcGxleFR5cGVdXSBhc3NvY2lhdGVkIHdpdGggdGhpcyBwcm9wZXJ0eTsgbWF5IGJlIG51bGwuIF9fUmVhZCBPbmx5X18gKi9cclxuICBjb21wbGV4VHlwZU5hbWU6IHN0cmluZztcclxuICAvKiogVGhlIFtbQ29tcGxleFR5cGVdXSBhc3NvY2lhdGVkIHdpdGggdGhpcyBwcm9wZXJ0eTsgbWF5IGJlIHVuZGVmaW5lZC4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGNvbXBsZXhUeXBlPzogQ29tcGxleFR5cGU7XHJcbiAgLyoqICBXaGV0aGVyIHRoZSBjb250ZW50cyBvZiB0aGlzIHByb3BlcnR5IGlzIGFuIGluc3RhbmNlIG9mIGEgW1tDb21wbGV4VHlwZV1dLiBfX1JlYWQgT25seV9fICovXHJcbiAgaXNDb21wbGV4UHJvcGVydHk6IGJvb2xlYW47XHJcbiAgLyoqIFdoZXRoZXIgdGhpcyBwcm9wZXJ0eSBpcyBudWxsYWJsZS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGlzTnVsbGFibGU6IGJvb2xlYW47XHJcbiAgLyoqICBXaGV0aGVyIHRoaXMgcHJvcGVydHkgaXMgc2NhbGFyIChpLmUuLCByZXR1cm5zIGEgc2luZ2xlIHZhbHVlIGFzIG9wcG9zZWQgdG8gYW4gYXJyYXkpLiBfX1JlYWQgT25seV9fICovXHJcbiAgaXNTY2FsYXI6IGJvb2xlYW47IC8vIHdpbGwgYmUgZmFsc2UgZm9yIHNvbWUgTm9TUUwgZGF0YWJhc2VzLlxyXG4gIC8qKiBUaGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcyBwcm9wZXJ0eS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlZmF1bHRWYWx1ZTogYW55O1xyXG4gIC8qKiAgV2hldGhlciB0aGlzIHByb3BlcnR5IGlzIGEgJ2tleScgcHJvcGVydHkuIF9fUmVhZCBPbmx5X18gKi9cclxuICBpc1BhcnRPZktleTogYm9vbGVhbjtcclxuICAvKiogV2hldGhlciB0aGlzIHByb3BlcnR5IGlzIGFuICd1bm1hcHBlZCcgcHJvcGVydHkuIF9fUmVhZCBPbmx5X18gKi9cclxuICBpc1VubWFwcGVkOiBib29sZWFuO1xyXG4gIC8qKiBXaGV0aGVyIHRoaXMgcHJvcGVydHkgaXMgJ3NldHRhYmxlJy4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGlzU2V0dGFibGU6IGJvb2xlYW47XHJcbiAgLy8gVE9ETzogZG9jIHRoaXNcclxuICBjb25jdXJyZW5jeU1vZGU6IHN0cmluZztcclxuICAvKiogIFRoZSBtYXhpbXVtIGxlbmd0aCBmb3IgdGhlIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkuIE9ubHkgbWVhbmluZ2Z1bCBmb3Igc3RyaW5ncy4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIG1heExlbmd0aD86IG51bWJlcjtcclxuICAvKiogVGhlIFtbVmFsaWRhdG9yXV0gaW5zdGFuY2VzIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHByb3BlcnR5LiBWYWxpZGF0b3JzIGNhbiBiZSBhZGRlZCBhbmRcclxuICByZW1vdmVkIGZyb20gdGhpcyBjb2xsZWN0aW9uLiBfX1JlYWQgT25seV9fICovXHJcbiAgdmFsaWRhdG9yczogVmFsaWRhdG9yW107XHJcbiAgLyoqIFRoZSBkaXNwbGF5IG5hbWUgb2YgdGhpcyBwcm9wZXJ0eS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRpc3BsYXlOYW1lOiBzdHJpbmc7XHJcbiAgLy8gVE9ETzogZG9jIHRoaXNcclxuICBlbnVtVHlwZT86IGFueTtcclxuICAvKiogVGhlIHJhdyB0eXBlIG5hbWUgb2YgdGhpcyBwcm9wZXJ0eS4gd2lsbCBvbmx5IGJlIGRlZmluZWQgZm9yIHByb3BlcnRpZXMgd2l0aCBhIERhdGFUeXBlIG9mICdVbmRlZmluZWQnICovXHJcbiAgcmF3VHlwZU5hbWU/OiBzdHJpbmc7ICAvLyBvY2N1cnMgd2l0aCB1bmRlZmluZWQgZGF0YXR5cGVzXHJcbiAgLyoqICBBIGZyZWUgZm9ybSBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byBkZWZpbmUgYW55IGN1c3RvbSBtZXRhZGF0YSBmb3IgdGhpcyBEYXRhUHJvcGVydHkuIF9fUmVhZCBPbmx5X18gKi9cclxuICBjdXN0b20/OiBPYmplY3Q7XHJcbiAgLy8gVE9ETzogZG9jIHRoaXNcclxuICBpbnZlcnNlTmF2aWdhdGlvblByb3BlcnR5PzogTmF2aWdhdGlvblByb3BlcnR5O1xyXG4gIC8qKlxyXG4gIFRoZSBuYXZpZ2F0aW9uIHByb3BlcnR5IHJlbGF0ZWQgdG8gdGhpcyBwcm9wZXJ0eS4gIFdpbGwgb25seSBiZSBzZXQgaWYgdGhpcyBpcyBhIGZvcmVpZ24ga2V5IHByb3BlcnR5LiBfX1JlYWQgT25seV9fICovXHJcbiAgcmVsYXRlZE5hdmlnYXRpb25Qcm9wZXJ0eT86IE5hdmlnYXRpb25Qcm9wZXJ0eTtcclxuICAvKiogVGhlIHBhcmVudCB0eXBlIHRoYXQgdGhpcyBwcm9wZXJ0eSBiZWxvbmdzIHRvIC0gd2lsbCBiZSBlaXRoZXIgYSBbW0VudGl0eVR5cGVdXSBvciBhIFtbQ29tcGxleFR5cGVdXS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIHBhcmVudFR5cGU6IFN0cnVjdHVyYWxUeXBlO1xyXG4gIC8qKiBQcm9wZXJ0eSBvbiB0aGUgYmFzZSB0eXBlIHRoYXQgdGhpcyBwcm9wZXJ0eSBpcyBpbmhlcml0ZWQgZnJvbS4gV2lsbCBiZSBudWxsIGlmIHRoZSBwcm9wZXJ0eSBpcyBub3Qgb24gdGhlIGJhc2UgdHlwZS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGJhc2VQcm9wZXJ0eT86IERhdGFQcm9wZXJ0eTtcclxuXHJcbiAgLyoqIERhdGFQcm9wZXJ0eSBjb25zdHJ1Y3RvclxyXG4gID4gICAgICBsZXQgbGFzdE5hbWVQcm9wID0gbmV3IERhdGFQcm9wZXJ0eSgge1xyXG4gID4gICAgICAgICAgbmFtZTogXCJsYXN0TmFtZVwiLFxyXG4gID4gICAgICAgICAgZGF0YVR5cGU6IERhdGFUeXBlLlN0cmluZyxcclxuICA+ICAgICAgICAgIGlzTnVsbGFibGU6IHRydWUsXHJcbiAgPiAgICAgICAgICBtYXhMZW5ndGg6IDIwXHJcbiAgPiAgICAgIH0pO1xyXG4gID4gICAgICAvLyBhc3N1bWluZyBwZXJzb25FbnRpdHlUeXBlIGlzIGEgbmV3bHkgY29uc3RydWN0ZWQgRW50aXR5VHlwZVxyXG4gID4gICAgICBwZXJzb25FbnRpdHlUeXBlLmFkZFByb3BlcnR5KGxhc3ROYW1lUHJvcGVydHkpO1xyXG4gIEBwYXJhbSBjb25maWcgLSBBIGNvbmZpZ3VyYXRpb24gT2JqZWN0IG9yIGEgRGF0YVByb3BlcnR5XHJcbiAgKi9cclxuICBjb25zdHJ1Y3Rvcihjb25maWc6IERhdGFQcm9wZXJ0eUNvbmZpZyB8IERhdGFQcm9wZXJ0eSkge1xyXG4gICAgYXNzZXJ0Q29uZmlnKGNvbmZpZylcclxuICAgICAgLndoZXJlUGFyYW0oXCJuYW1lXCIpLmlzU3RyaW5nKCkuaXNPcHRpb25hbCgpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwibmFtZU9uU2VydmVyXCIpLmlzU3RyaW5nKCkuaXNPcHRpb25hbCgpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiZGF0YVR5cGVcIikuaXNFbnVtT2YoRGF0YVR5cGUpLmlzT3B0aW9uYWwoKS5vcigpLmlzU3RyaW5nKCkub3IoKS5pc0luc3RhbmNlT2YoQ29tcGxleFR5cGUpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiY29tcGxleFR5cGVOYW1lXCIpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAud2hlcmVQYXJhbShcImlzTnVsbGFibGVcIikuaXNCb29sZWFuKCkuaXNPcHRpb25hbCgpLndpdGhEZWZhdWx0KHRydWUpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiaXNTY2FsYXJcIikuaXNPcHRpb25hbCgpLndpdGhEZWZhdWx0KHRydWUpLy8gd2lsbCBiZSBmYWxzZSBmb3Igc29tZSBOb1NRTCBkYXRhYmFzZXMuXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiZGVmYXVsdFZhbHVlXCIpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAud2hlcmVQYXJhbShcImlzUGFydE9mS2V5XCIpLmlzQm9vbGVhbigpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAud2hlcmVQYXJhbShcImlzVW5tYXBwZWRcIikuaXNCb29sZWFuKCkuaXNPcHRpb25hbCgpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiaXNTZXR0YWJsZVwiKS5pc0Jvb2xlYW4oKS5pc09wdGlvbmFsKCkud2l0aERlZmF1bHQodHJ1ZSlcclxuICAgICAgLndoZXJlUGFyYW0oXCJjb25jdXJyZW5jeU1vZGVcIikuaXNTdHJpbmcoKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJtYXhMZW5ndGhcIikuaXNOdW1iZXIoKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJ2YWxpZGF0b3JzXCIpLmlzSW5zdGFuY2VPZihWYWxpZGF0b3IpLmlzQXJyYXkoKS5pc09wdGlvbmFsKCkud2l0aERlZmF1bHQoW10pXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiZGlzcGxheU5hbWVcIikuaXNPcHRpb25hbCgpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiZW51bVR5cGVcIikuaXNPcHRpb25hbCgpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwicmF3VHlwZU5hbWVcIikuaXNPcHRpb25hbCgpIC8vIG9jY3VycyB3aXRoIHVuZGVmaW5lZCBkYXRhdHlwZXNcclxuICAgICAgLndoZXJlUGFyYW0oXCJjdXN0b21cIikuaXNPcHRpb25hbCgpXHJcbiAgICAgIC5hcHBseUFsbCh0aGlzKTtcclxuICAgIGxldCBoYXNOYW1lID0gISEodGhpcy5uYW1lIHx8IHRoaXMubmFtZU9uU2VydmVyKTtcclxuICAgIGlmICghaGFzTmFtZSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIERhdGFQcm9wZXJ0eSBtdXN0IGJlIGluc3RhbnRpYXRlZCB3aXRoIGVpdGhlciBhICduYW1lJyBvciBhICduYW1lT25TZXJ2ZXInIHByb3BlcnR5XCIpO1xyXG4gICAgfVxyXG4gICAgLy8gbmFtZS9uYW1lT25TZXJ2ZXIgaXMgcmVzb2x2ZWQgbGF0ZXIgd2hlbiBhIG1ldGFkYXRhU3RvcmUgaXMgYXZhaWxhYmxlLlxyXG5cclxuICAgIGlmICh0aGlzLmNvbXBsZXhUeXBlTmFtZSkge1xyXG4gICAgICB0aGlzLmlzQ29tcGxleFByb3BlcnR5ID0gdHJ1ZTtcclxuICAgICAgLy8gdGhpcy5kYXRhVHlwZSA9IG51bGw7IC8vIFRPRE86IHdvdWxkIGxpa2UgdG8gcmVtb3ZlIHRoaXMgbGluZSBiZWNhdXNlIGRhdGFUeXBlIHdpbGwgYmUgc2V0IGxhdGVyLlxyXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgKHRoaXMuZGF0YVR5cGUpID09PSBcInN0cmluZ1wiKSB7XHJcbiAgICAgIGxldCBkdCA9IERhdGFUeXBlLmZyb21OYW1lKHRoaXMuZGF0YVR5cGUpO1xyXG4gICAgICBpZiAoIWR0KSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5hYmxlIHRvIGZpbmQgYSBEYXRhVHlwZSBlbnVtZXJhdGlvbiBieSB0aGUgbmFtZSBvZjogXCIgKyB0aGlzLmRhdGFUeXBlKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmRhdGFUeXBlID0gZHQ7XHJcbiAgICB9IGVsc2UgaWYgKCF0aGlzLmRhdGFUeXBlKSB7XHJcbiAgICAgIHRoaXMuZGF0YVR5cGUgPSBEYXRhVHlwZS5TdHJpbmc7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gPT0gYXMgb3Bwb3NlZCB0byA9PT0gaXMgZGVsaWJlcmF0ZSBoZXJlLlxyXG4gICAgaWYgKHRoaXMuZGVmYXVsdFZhbHVlID09IG51bGwpIHtcclxuICAgICAgaWYgKHRoaXMuaXNOdWxsYWJsZSkge1xyXG4gICAgICAgIHRoaXMuZGVmYXVsdFZhbHVlID0gbnVsbDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAodGhpcy5pc0NvbXBsZXhQcm9wZXJ0eSkge1xyXG4gICAgICAgICAgLy8gd2hhdCB0byBkbz8gLSBzaG91bGRuJ3QgaGFwcGVuIGZyb20gRUYgLSBidXQgb3RoZXJ3aXNlID8/P1xyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5kYXRhVHlwZSA9PT0gRGF0YVR5cGUuQmluYXJ5KSB7XHJcbiAgICAgICAgICB0aGlzLmRlZmF1bHRWYWx1ZSA9IFwiQUFBQUFBQUFKM1U9XCI7IC8vIGhhY2sgZm9yIGFsbCBiaW5hcnkgZmllbGRzIGJ1dCB2YWx1ZSBpcyBzcGVjaWZpY2FsbHkgdmFsaWQgZm9yIHRpbWVzdGFtcCBmaWVsZHMgLSBhcmJpdHJhcnkgdmFsaWQgOCBieXRlIGJhc2U2NCB2YWx1ZS5cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5kZWZhdWx0VmFsdWUgPSAodGhpcy5kYXRhVHlwZSBhcyBhbnkpLmRlZmF1bHRWYWx1ZTtcclxuICAgICAgICAgIGNvbnN0IG1zZyA9IFwiQSBub25udWxsYWJsZSBEYXRhUHJvcGVydHkgY2Fubm90IGhhdmUgYSBudWxsIGRlZmF1bHRWYWx1ZS4gTmFtZTogXCIgKyAodGhpcy5uYW1lIHx8IHRoaXMubmFtZU9uU2VydmVyKTtcclxuICAgICAgICAgIGlmICh0aGlzLmRlZmF1bHRWYWx1ZSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTsgIC8vIGlmIGRlZmF1bHRWYWx1ZSBpcyBleHBsaWNpdHkgc2V0IHRvIG51bGwsIHRoYXQncyBhbiBlcnJvclxyXG4gICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmRlZmF1bHRWYWx1ZSA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUud2Fybihtc2cpOyAgLy8gaWYgZGVmYXVsdFZhbHVlIGlzIG5vdCBzZXQsIHRoYXQncyBhIHdhcm5pbmdcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSBpZiAoKHRoaXMuZGF0YVR5cGUgYXMgYW55KS5pc051bWVyaWMpIHtcclxuICAgICAgLy8gaW4gY2FzZSB0aGUgZGVmYXVsdFZhbHVlIGNvbWVzIGluIGFzIGEgc3RyaW5nICggd2hpY2ggaXQgZG9lcyBpbiBFRjYpLlxyXG4gICAgICBpZiAodHlwZW9mICh0aGlzLmRlZmF1bHRWYWx1ZSkgPT09IFwic3RyaW5nXCIpIHtcclxuICAgICAgICB0aGlzLmRlZmF1bHRWYWx1ZSA9IHBhcnNlRmxvYXQodGhpcy5kZWZhdWx0VmFsdWUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuaXNDb21wbGV4UHJvcGVydHkpIHtcclxuICAgICAgdGhpcy5pc1NjYWxhciA9IHRoaXMuaXNTY2FsYXIgPT0gbnVsbCB8fCB0aGlzLmlzU2NhbGFyID09PSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICB9XHJcblxyXG4gIHN0YXRpYyBnZXRSYXdWYWx1ZUZyb21TZXJ2ZXIocmF3RW50aXR5OiBPYmplY3QsIGRwOiBEYXRhUHJvcGVydHkpIHtcclxuICAgIGlmIChkcC5pc1VubWFwcGVkKSB7XHJcbiAgICAgIHJldHVybiByYXdFbnRpdHlbZHAubmFtZU9uU2VydmVyIHx8IGRwLm5hbWVdO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbGV0IHZhbCA9IHJhd0VudGl0eVtkcC5uYW1lT25TZXJ2ZXJdO1xyXG4gICAgICByZXR1cm4gdmFsICE9PSB1bmRlZmluZWQgPyB2YWwgOiBkcC5kZWZhdWx0VmFsdWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzdGF0aWMgZ2V0UmF3VmFsdWVGcm9tQ2xpZW50KHJhd0VudGl0eTogT2JqZWN0LCBkcDogRGF0YVByb3BlcnR5KSB7XHJcbiAgICBsZXQgdmFsID0gcmF3RW50aXR5W2RwLm5hbWVdO1xyXG4gICAgcmV0dXJuIHZhbCAhPT0gdW5kZWZpbmVkID8gdmFsIDogZHAuZGVmYXVsdFZhbHVlO1xyXG4gIH1cclxuXHJcbiAgcmVzb2x2ZVByb3BlcnR5KHByb3BOYW1lOiBzdHJpbmcpIHtcclxuICAgIGxldCByZXN1bHQgPSB0aGlzW3Byb3BOYW1lXTtcclxuICAgIGxldCBiYXNlUHJvcCA9IHRoaXMuYmFzZVByb3BlcnR5O1xyXG4gICAgd2hpbGUgKHJlc3VsdCA9PSB1bmRlZmluZWQgJiYgYmFzZVByb3AgIT0gbnVsbCkge1xyXG4gICAgICByZXN1bHQgPSBiYXNlUHJvcFtwcm9wTmFtZV07XHJcbiAgICAgIGJhc2VQcm9wID0gYmFzZVByb3AuYmFzZVByb3BlcnR5O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9XHJcblxyXG4gIGZvcm1hdE5hbWUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5wYXJlbnRUeXBlLm5hbWUgKyBcIi0tXCIgKyB0aGlzLm5hbWU7XHJcbiAgfVxyXG5cclxuXHJcbiAgLyoqXHJcbiAgR2VuZXJhbCBwdXJwb3NlIHByb3BlcnR5IHNldCBtZXRob2RcclxuICA+ICAgICAgLy8gYXNzdW1lIGVtMSBpcyBhbiBFbnRpdHlNYW5hZ2VyXHJcbiAgPiAgICAgIGxldCBwcm9wID0gbXlFbnRpdHlUeXBlLmdldFByb3BlcnR5KFwibXlQcm9wZXJ0eVwiKTtcclxuICA+ICAgICAgcHJvcC5zZXRQcm9wZXJ0aWVzKCB7XHJcbiAgPiAgICAgICAgICBjdXN0b206IHsgZm9vOiA3LCBiYXI6IFwidGVzdFwiIH1cclxuICA+ICAgICAgfSk7XHJcbiAgQHBhcmFtIGNvbmZpZyAtIEEgY29uZmlndXJhdGlvbiBvYmplY3QuXHJcbiAgKiovXHJcbiAgc2V0UHJvcGVydGllcyhjb25maWc6IHsgZGlzcGxheU5hbWU/OiBzdHJpbmcsIGN1c3RvbT86IE9iamVjdCB9KSB7XHJcbiAgICBhc3NlcnRDb25maWcoY29uZmlnKVxyXG4gICAgICAud2hlcmVQYXJhbShcImRpc3BsYXlOYW1lXCIpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAud2hlcmVQYXJhbShcImN1c3RvbVwiKS5pc09wdGlvbmFsKClcclxuICAgICAgLmFwcGx5QWxsKHRoaXMpO1xyXG4gIH1cclxuXHJcbiAgZ2V0QWxsVmFsaWRhdG9ycygpIHtcclxuICAgIGxldCB2YWxpZGF0b3JzID0gdGhpcy52YWxpZGF0b3JzLnNsaWNlKDApO1xyXG4gICAgbGV0IGJhc2VQcm9wID0gdGhpcy5iYXNlUHJvcGVydHk7XHJcbiAgICB3aGlsZSAoYmFzZVByb3ApIHtcclxuICAgICAgdmFsaWRhdG9ycy5wdXNoLmFwcGx5KHZhbGlkYXRvcnMsIGJhc2VQcm9wLnZhbGlkYXRvcnMpO1xyXG4gICAgICBiYXNlUHJvcCA9IGJhc2VQcm9wLmJhc2VQcm9wZXJ0eTtcclxuICAgIH1cclxuICAgIHJldHVybiB2YWxpZGF0b3JzO1xyXG4gIH1cclxuXHJcbiAgdG9KU09OKCkge1xyXG4gICAgLy8gZG8gbm90IHNlcmlhbGl6ZSBkYXRhVHlwZXMgdGhhdCBhcmUgY29tcGxleFR5cGVzXHJcbiAgICByZXR1cm4gY29yZS50b0pzb24odGhpcywge1xyXG4gICAgICBuYW1lOiBudWxsLFxyXG4gICAgICBkYXRhVHlwZTogZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICAgIHJldHVybiAodiAmJiB2IGluc3RhbmNlb2YgRGF0YVR5cGUpID8gdi5uYW1lIDogdW5kZWZpbmVkO1xyXG4gICAgICB9LCAvLyBkbyBub3Qgc2VyaWFsaXplIGRhdGFUeXBlcyB0aGF0IGFyZSBjb21wbGV4VHlwZXNcclxuICAgICAgY29tcGxleFR5cGVOYW1lOiBudWxsLFxyXG4gICAgICBpc051bGxhYmxlOiB0cnVlLFxyXG4gICAgICBkZWZhdWx0VmFsdWU6IG51bGwsXHJcbiAgICAgIGlzUGFydE9mS2V5OiBmYWxzZSxcclxuICAgICAgaXNVbm1hcHBlZDogZmFsc2UsXHJcbiAgICAgIGlzU2V0dGFibGU6IHRydWUsXHJcbiAgICAgIGNvbmN1cnJlbmN5TW9kZTogbnVsbCxcclxuICAgICAgbWF4TGVuZ3RoOiBudWxsLFxyXG4gICAgICB2YWxpZGF0b3JzOiBudWxsLFxyXG4gICAgICBkaXNwbGF5TmFtZTogbnVsbCxcclxuICAgICAgZW51bVR5cGU6IG51bGwsXHJcbiAgICAgIHJhd1R5cGVOYW1lOiBudWxsLFxyXG4gICAgICBpc1NjYWxhcjogdHJ1ZSxcclxuICAgICAgY3VzdG9tOiBudWxsXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHN0YXRpYyBmcm9tSlNPTihqc29uOiBhbnkpIHtcclxuICAgIGpzb24uZGF0YVR5cGUgPSBEYXRhVHlwZS5mcm9tTmFtZShqc29uLmRhdGFUeXBlKTtcclxuICAgIC8vIFBhcnNlIGRlZmF1bHQgdmFsdWUgaW50byBjb3JyZWN0IGRhdGEgdHlwZS4gKGRhdGVUaW1lIGluc3RhbmNlcyByZXF1aXJlIGV4dHJhIHdvcmsgdG8gZGVzZXJpYWxpemUgcHJvcGVybHkuKVxyXG4gICAgaWYgKGpzb24uZGVmYXVsdFZhbHVlICYmIGpzb24uZGF0YVR5cGUgJiYganNvbi5kYXRhVHlwZS5wYXJzZSkge1xyXG4gICAgICBqc29uLmRlZmF1bHRWYWx1ZSA9IGpzb24uZGF0YVR5cGUucGFyc2UoanNvbi5kZWZhdWx0VmFsdWUsIHR5cGVvZiBqc29uLmRlZmF1bHRWYWx1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGpzb24udmFsaWRhdG9ycykge1xyXG4gICAgICBqc29uLnZhbGlkYXRvcnMgPSBqc29uLnZhbGlkYXRvcnMubWFwKFZhbGlkYXRvci5mcm9tSlNPTik7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG5ldyBEYXRhUHJvcGVydHkoanNvbik7XHJcbiAgfVxyXG5cclxufVxyXG5EYXRhUHJvcGVydHkucHJvdG90eXBlLl8kdHlwZU5hbWUgPSBcIkRhdGFQcm9wZXJ0eVwiO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBOYXZpZ2F0aW9uUHJvcGVydHlDb25maWcge1xyXG4gIG5hbWU/OiBzdHJpbmc7XHJcbiAgbmFtZU9uU2VydmVyPzogc3RyaW5nO1xyXG4gIGVudGl0eVR5cGVOYW1lPzogc3RyaW5nO1xyXG4gIGlzU2NhbGFyPzogYm9vbGVhbjtcclxuICBhc3NvY2lhdGlvbk5hbWU/OiBzdHJpbmc7XHJcbiAgZm9yZWlnbktleU5hbWVzPzogc3RyaW5nW107XHJcbiAgZm9yZWlnbktleU5hbWVzT25TZXJ2ZXI/OiBzdHJpbmdbXTtcclxuICBpbnZGb3JlaWduS2V5TmFtZXM/OiBzdHJpbmdbXTtcclxuICBpbnZGb3JlaWduS2V5TmFtZXNPblNlcnZlcj86IHN0cmluZ1tdO1xyXG4gIHZhbGlkYXRvcnM/OiBWYWxpZGF0b3JbXTtcclxuICBkaXNwbGF5TmFtZT86IHN0cmluZztcclxuICBjdXN0b20/OiBPYmplY3Q7XHJcbn1cclxuXHJcbi8qKiAgIEEgTmF2aWdhdGlvblByb3BlcnR5IGRlc2NyaWJlcyB0aGUgbWV0YWRhdGEgZm9yIGEgc2luZ2xlIHByb3BlcnR5IG9mIGFuIFtbRW50aXR5VHlwZV1dIHRoYXQgcmV0dXJuIGluc3RhbmNlcyBvZiBvdGhlciBFbnRpdHlUeXBlcy5cclxuXHJcbkluc3RhbmNlcyBvZiB0aGUgTmF2aWdhdGlvblByb3BlcnR5IGNsYXNzIGFyZSBjb25zdHJ1Y3RlZCBhdXRvbWF0aWNhbGx5IGR1cmluZyBNZXRhZGF0YSByZXRyaWV2YWwuICAgSG93ZXZlciBpdCBpcyBhbHNvIHBvc3NpYmxlIHRvIGNvbnN0cnVjdCB0aGVtXHJcbmRpcmVjdGx5IHZpYSB0aGUgY29uc3RydWN0b3IuXHJcbioqL1xyXG5leHBvcnQgY2xhc3MgTmF2aWdhdGlvblByb3BlcnR5IHtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfJHR5cGVOYW1lOiBzdHJpbmc7XHJcbiAgLyoqIElzIHRoaXMgYSBEYXRhUHJvcGVydHk/IC0gYWx3YXlzIGZhbHNlIGhlcmUgXHJcbiAgQWxsb3dzIHBvbHltb3JwaGljIHRyZWF0bWVudCBvZiBEYXRhUHJvcGVydGllcyBhbmQgTmF2aWdhdGlvblByb3BlcnRpZXMuIF9fUmVhZCBPbmx5X18gKi9cclxuICBpc0RhdGFQcm9wZXJ0eSA9IGZhbHNlO1xyXG4gIC8qKiBJcyB0aGlzIGEgTmF2aWdhdGlvblByb3BlcnR5PyAtIGFsd2F5cyB0cnVlIGhlcmVcclxuICBBbGxvd3MgcG9seW1vcnBoaWMgdHJlYXRtZW50IG9mIERhdGFQcm9wZXJ0aWVzIGFuZCBOYXZpZ2F0aW9uUHJvcGVydGllcy4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGlzTmF2aWdhdGlvblByb3BlcnR5ID0gdHJ1ZTtcclxuXHJcbiAgZm9ybWF0TmFtZSA9IERhdGFQcm9wZXJ0eS5wcm90b3R5cGUuZm9ybWF0TmFtZTtcclxuICBnZXRBbGxWYWxpZGF0b3JzID0gRGF0YVByb3BlcnR5LnByb3RvdHlwZS5nZXRBbGxWYWxpZGF0b3JzO1xyXG4gIHJlc29sdmVQcm9wZXJ0eSA9IERhdGFQcm9wZXJ0eS5wcm90b3R5cGUucmVzb2x2ZVByb3BlcnR5O1xyXG5cclxuICAvKiogVGhlIFtbRW50aXR5VHlwZV1dIHJldHVybmVkIGJ5IHRoaXMgcHJvcGVydHkuIF9fUmVhZCBPbmx5X18gKi9cclxuICBlbnRpdHlUeXBlOiBFbnRpdHlUeXBlO1xyXG4gIC8qKiBUaGUgbmFtZSBvZiB0aGUgW1tFbnRpdHlUeXBlXV0gcmV0dXJuZWQgYnkgdGhpcyBwcm9wZXJ0eS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGVudGl0eVR5cGVOYW1lOiBzdHJpbmc7XHJcbiAgLyoqIFRoZSBbW0VudGl0eVR5cGVdXSB0aGF0IHRoaXMgcHJvcGVydHkgYmVsb25ncyB0by4gKCBzYW1lIGFzIGVudGl0eVR5cGUpLiBfX1JlYWQgT25seV9fICovXHJcbiAgcGFyZW50VHlwZTogRW50aXR5VHlwZTsgLy8gPz8gc2FtZSBhcyBlbnRpdHlUeXBlXHJcbiAgLyoqIFRoZSBbW0VudGl0eVR5cGVdXSB0aGF0IHRoaXMgcHJvcGVydHkgYmVsb25ncyB0by4gKCBzYW1lIGFzIGVudGl0eVR5cGUpLiBfX1JlYWQgT25seV9fICovXHJcbiAgcGFyZW50RW50aXR5VHlwZTogRW50aXR5VHlwZTsgLy8gPz8gc2FtZSBhcyBhYm92ZVxyXG4gIC8qKiBQcm9wZXJ0eSBvbiB0aGUgYmFzZSB0eXBlIHRoYXQgdGhpcyBwcm9wZXJ0eSBpcyBpbmhlcml0ZWQgZnJvbS4gV2lsbCBiZSBudWxsIGlmIHRoZSBwcm9wZXJ0eSBpcyBub3Qgb24gdGhlIGJhc2UgdHlwZS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGJhc2VQcm9wZXJ0eT86IE5hdmlnYXRpb25Qcm9wZXJ0eTtcclxuICAvKiogVGhlIGludmVyc2Ugb2YgdGhpcyBOYXZpZ2F0aW9uUHJvcGVydHkuICBUaGUgTmF2aWdhdGlvblByb3BlcnR5IHRoYXQgcmVwcmVzZW50cyBhIG5hdmlnYXRpb24gaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvblxyXG4gIHRvIHRoaXMgTmF2aWdhdGlvblByb3BlcnR5LiBNYXkgYmUgdW5kZWZpbmVkIGZvciBhIHVuZGlyZWN0aW9uYWwgTmF2aWdhdGlvblByb3BlcnR5LiBfX1JlYWQgT25seV9fICovXHJcbiAgcHJpdmF0ZSBfaW52ZXJzZT86IE5hdmlnYXRpb25Qcm9wZXJ0eTtcclxuICAvKiogVGhlIG5hbWUgb2YgdGhpcyBwcm9wZXJ0eS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIG5hbWU6IHN0cmluZztcclxuICAvKiogVGhlIG5hbWUgb2YgdGhpcyBwcm9wZXJ0eSBvbiB0aGUgc2VydmVyLiBfX1JlYWQgT25seV9fICovXHJcbiAgbmFtZU9uU2VydmVyOiBzdHJpbmc7XHJcbiAgLyoqXHJcbiAgV2hldGhlciB0aGlzIHByb3BlcnR5IHJldHVybnMgYSBzaW5nbGUgZW50aXR5IGFzIG9wcG9zZWQgdG8gIGFuIGFycmF5IG9mIGVudGl0aWVzLiBfX1JlYWQgT25seV9fICovXHJcbiAgaXNTY2FsYXI6IGJvb2xlYW47XHJcbiAgLyoqIFRoZSBuYW1lIG9mIHRoZSBhc3NvY2lhdGlvbiB0byB3aGljaCB0aGF0IHRoaXMgcHJvcGVydHkgYmVsb25ncy4gIFRoaXMgYXNzb2NpYXRpb25OYW1lIHdpbGwgYmUgc2hhcmVkIHdpdGggdGhpc1xyXG4gIHByb3BlcnRpZXMgJ2ludmVyc2UnLiBfX1JlYWQgT25seV9fICovXHJcbiAgYXNzb2NpYXRpb25OYW1lOiBzdHJpbmc7XHJcbiAgLyoqIFRoZSBuYW1lcyBvZiB0aGUgZm9yZWlnbiBrZXkgRGF0YVByb3BlcnRpZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgTmF2aWdhdGlvblByb3BlcnR5LiBUaGVyZSB3aWxsIHVzdWFsbHkgb25seSBiZSBhIHNpbmdsZSBEYXRhUHJvcGVydHkgYXNzb2NpYXRlZFxyXG4gIHdpdGggYSBOYXZpZ2F0aW9uIHByb3BlcnR5IGV4Y2VwdCBpbiB0aGUgY2FzZSBvZiBlbnRpdGllcyB3aXRoIG11bHRpcGFydCBrZXlzLiBfX1JlYWQgT25seV9fICovXHJcbiAgZm9yZWlnbktleU5hbWVzOiBzdHJpbmdbXTtcclxuICAvKiogVGhlIHNlcnZlciBzaWRlIG5hbWVzIG9mIHRoZSBmb3JlaWduIGtleSBEYXRhUHJvcGVydGllcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBOYXZpZ2F0aW9uUHJvcGVydHkuIFRoZXJlIHdpbGwgdXN1YWxseSBvbmx5IGJlIGEgc2luZ2xlIERhdGFQcm9wZXJ0eSBhc3NvY2lhdGVkXHJcbiAgd2l0aCBhIE5hdmlnYXRpb24gcHJvcGVydHkgZXhjZXB0IGluIHRoZSBjYXNlIG9mIGVudGl0aWVzIHdpdGggbXVsdGlwYXJ0IGtleXMuIF9fUmVhZCBPbmx5X18gKi9cclxuICBmb3JlaWduS2V5TmFtZXNPblNlcnZlcjogc3RyaW5nW107XHJcbiAgLyoqIFRoZSBuYW1lcyBvZiB0aGUgZm9yZWlnbiBrZXkgRGF0YVByb3BlcnRpZXMgYXQgdGhlIG90aGVyIGVuZCBvZiB0aGUgcmVsYXRpb25zaGlwLiBfX1JlYWQgT25seV9fICovXHJcbiAgaW52Rm9yZWlnbktleU5hbWVzOiBzdHJpbmdbXTtcclxuICAvKiogVGhlIHNlcnZlciBzaWRlIG5hbWVzIG9mIHRoZSBmb3JlaWduIGtleSBEYXRhUHJvcGVydGllcyBhdCB0aGUgb3RoZXIgZW5kIG9mIHRoZSByZWxhdGlvbnNoaXAuIF9fUmVhZCBPbmx5X18gKi9cclxuICBpbnZGb3JlaWduS2V5TmFtZXNPblNlcnZlcjogc3RyaW5nW107XHJcbiAgLyoqIFRoZSAnZm9yZWlnbiBrZXknIERhdGFQcm9wZXJ0aWVzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIE5hdmlnYXRpb25Qcm9wZXJ0eS4gVGhlcmUgd2lsbCB1c3VhbGx5IG9ubHkgYmUgYSBzaW5nbGUgRGF0YVByb3BlcnR5IGFzc29jaWF0ZWRcclxuICB3aXRoIGEgTmF2aWdhdGlvbiBwcm9wZXJ0eSBleGNlcHQgaW4gdGhlIGNhc2Ugb2YgZW50aXRpZXMgd2l0aCBtdWx0aXBhcnQga2V5cy4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIHJlbGF0ZWREYXRhUHJvcGVydGllczogRGF0YVByb3BlcnR5W107XHJcbiAgLyoqIFRoZSBbW1ZhbGlkYXRvcl1dIGluc3RhbmNlcyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBwcm9wZXJ0eS4gVmFsaWRhdG9ycyBjYW4gYmUgYWRkZWQgYW5kXHJcbiAgcmVtb3ZlZCBmcm9tIHRoaXMgY29sbGVjdGlvbi4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIHZhbGlkYXRvcnM6IFZhbGlkYXRvcltdO1xyXG4gIC8qKiBUaGUgZGlzcGxheSBuYW1lIG9mIHRoaXMgcHJvcGVydHkuIF9fUmVhZCBPbmx5X18gKi9cclxuICBkaXNwbGF5TmFtZTogc3RyaW5nO1xyXG4gIGlzVW5tYXBwZWQ6IGJvb2xlYW47XHJcbiAgLyoqIEEgZnJlZSBmb3JtIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIGRlZmluZSBhbnkgY3VzdG9tIG1ldGFkYXRhIGZvciB0aGlzIE5hdmlnYXRpb25Qcm9wZXJ0eS4gICAqKi9cclxuICBjdXN0b206IE9iamVjdDtcclxuXHJcbiAgLyoqIE5hdmlnYXRpb25Qcm9wZXJ0eSBjb25zdHJ1Y3RvclxyXG4gID4gICAgICBsZXQgaG9tZUFkZHJlc3NQcm9wID0gbmV3IE5hdmlnYXRpb25Qcm9wZXJ0eSgge1xyXG4gID4gICAgICAgICAgbmFtZTogXCJob21lQWRkcmVzc1wiLFxyXG4gID4gICAgICAgICAgZW50aXR5VHlwZU5hbWU6IFwiQWRkcmVzczojbXlOYW1lc3BhY2VcIixcclxuICA+ICAgICAgICAgIGlzU2NhbGFyOiB0cnVlLFxyXG4gID4gICAgICAgICAgYXNzb2NpYXRpb25OYW1lOiBcImFkZHJlc3NfcGVyc29uXCIsXHJcbiAgPiAgICAgICAgICBmb3JlaWduS2V5TmFtZXM6IFtcImhvbWVBZGRyZXNzSWRcIl1cclxuICA+ICAgICAgfSk7XHJcbiAgPiAgICAgIGxldCBob21lQWRkcmVzc0lkUHJvcCA9IG5ldyBEYXRhUHJvcGVydHkoIHtcclxuICA+ICAgICAgICAgIG5hbWU6IFwiaG9tZUFkZHJlc3NJZFwiXHJcbiAgPiAgICAgICAgICBkYXRhVHlwZTogRGF0YVR5cGUuSW50ZWdlclxyXG4gID4gICAgICB9KTtcclxuICA+ICAgICAgLy8gYXNzdW1pbmcgcGVyc29uRW50aXR5VHlwZSBpcyBhIG5ld2x5IGNvbnN0cnVjdGVkIEVudGl0eVR5cGVcclxuICA+ICAgICAgcGVyc29uRW50aXR5VHlwZS5hZGRQcm9wZXJ0eShob21lQWRkcmVzc1Byb3ApO1xyXG4gID4gICAgICBwZXJzb25FbnRpdHlUeXBlLmFkZFByb3BlcnR5KGhvbWVBZGRyZXNzSWRQcm9wKTtcclxuICBAcGFyYW0gY29uZmlnIC0gQSBjb25maWd1cmF0aW9uIG9iamVjdC5cclxuICAqKi9cclxuICBjb25zdHJ1Y3Rvcihjb25maWc6IE5hdmlnYXRpb25Qcm9wZXJ0eUNvbmZpZykge1xyXG4gICAgYXNzZXJ0Q29uZmlnKGNvbmZpZylcclxuICAgICAgLndoZXJlUGFyYW0oXCJuYW1lXCIpLmlzU3RyaW5nKCkuaXNPcHRpb25hbCgpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwibmFtZU9uU2VydmVyXCIpLmlzU3RyaW5nKCkuaXNPcHRpb25hbCgpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiZW50aXR5VHlwZU5hbWVcIikuaXNTdHJpbmcoKVxyXG4gICAgICAud2hlcmVQYXJhbShcImlzU2NhbGFyXCIpLmlzQm9vbGVhbigpLmlzT3B0aW9uYWwoKS53aXRoRGVmYXVsdCh0cnVlKVxyXG4gICAgICAud2hlcmVQYXJhbShcImFzc29jaWF0aW9uTmFtZVwiKS5pc1N0cmluZygpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAud2hlcmVQYXJhbShcImZvcmVpZ25LZXlOYW1lc1wiKS5pc0FycmF5KCkuaXNTdHJpbmcoKS5pc09wdGlvbmFsKCkud2l0aERlZmF1bHQoW10pXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiZm9yZWlnbktleU5hbWVzT25TZXJ2ZXJcIikuaXNBcnJheSgpLmlzU3RyaW5nKCkuaXNPcHRpb25hbCgpLndpdGhEZWZhdWx0KFtdKVxyXG4gICAgICAud2hlcmVQYXJhbShcImludkZvcmVpZ25LZXlOYW1lc1wiKS5pc0FycmF5KCkuaXNTdHJpbmcoKS5pc09wdGlvbmFsKCkud2l0aERlZmF1bHQoW10pXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiaW52Rm9yZWlnbktleU5hbWVzT25TZXJ2ZXJcIikuaXNBcnJheSgpLmlzU3RyaW5nKCkuaXNPcHRpb25hbCgpLndpdGhEZWZhdWx0KFtdKVxyXG4gICAgICAud2hlcmVQYXJhbShcInZhbGlkYXRvcnNcIikuaXNJbnN0YW5jZU9mKFZhbGlkYXRvcikuaXNBcnJheSgpLmlzT3B0aW9uYWwoKS53aXRoRGVmYXVsdChbXSlcclxuICAgICAgLndoZXJlUGFyYW0oXCJkaXNwbGF5TmFtZVwiKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJjdXN0b21cIikuaXNPcHRpb25hbCgpXHJcbiAgICAgIC5hcHBseUFsbCh0aGlzKTtcclxuICAgIGxldCBoYXNOYW1lID0gISEodGhpcy5uYW1lIHx8IHRoaXMubmFtZU9uU2VydmVyKTtcclxuXHJcbiAgICBpZiAoIWhhc05hbWUpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBOYXZpZ2F0aW9uIHByb3BlcnR5IG11c3QgYmUgaW5zdGFudGlhdGVkIHdpdGggZWl0aGVyIGEgJ25hbWUnIG9yIGEgJ25hbWVPblNlcnZlcicgcHJvcGVydHlcIik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBHZW5lcmFsIHB1cnBvc2UgcHJvcGVydHkgc2V0IG1ldGhvZFxyXG4gID4gICAgICAvLyBhc3N1bWUgbXlFbnRpdHlUeXBlIGlzIGFuIEVudGl0eVR5cGVcclxuICA+ICAgICAgbGV0IHByb3AgPSBteUVudGl0eVR5cGUuZ2V0UHJvcGVydHkoXCJteVByb3BlcnR5XCIpO1xyXG4gID4gICAgICBwcm9wLnNldFByb3BlcnRpZXMoIHtcclxuICA+ICAgICAgICAgIGN1c3RvbTogeyBmb286IDcsIGJhcjogXCJ0ZXN0XCIgfVxyXG4gID4gICAgICB9KTtcclxuICBAcGFyYW0gY29uZmlnIC0gQSBjb25maWcgb2JqZWN0XHJcbiAgKiovXHJcbiAgLy8gVE9ETzogY3JlYXRlIGFuIGludGVyZmFjZSBmb3IgdGhpcy5cclxuICBzZXRQcm9wZXJ0aWVzKGNvbmZpZzoge1xyXG4gICAgZGlzcGxheU5hbWU/OiBzdHJpbmcsXHJcbiAgICBmb3JlaWduS2V5TmFtZXM/OiBzdHJpbmdbXSxcclxuICAgIGludkZvcmVpZ25LZXlOYW1lcz86IHN0cmluZ1tdLFxyXG4gICAgaW52ZXJzZT86IE5hdmlnYXRpb25Qcm9wZXJ0eSB8IHN0cmluZyxcclxuICAgIGN1c3RvbT86IE9iamVjdFxyXG4gIH0pIHtcclxuICAgIGlmICghdGhpcy5wYXJlbnRUeXBlKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBjYWxsIE5hdmlnYXRpb25Qcm9wZXJ0eS5zZXRQcm9wZXJ0aWVzIHVudGlsIHRoZSBwYXJlbnQgRW50aXR5VHlwZSBvZiB0aGUgTmF2aWdhdGlvblByb3BlcnR5IGhhcyBiZWVuIHNldC5cIik7XHJcbiAgICB9XHJcbiAgICBsZXQgaW52ZXJzZSA9IGNvbmZpZy5pbnZlcnNlO1xyXG4gICAgaWYgKGludmVyc2UpIGRlbGV0ZSBjb25maWcuaW52ZXJzZTtcclxuICAgIGFzc2VydENvbmZpZyhjb25maWcpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiZGlzcGxheU5hbWVcIikuaXNPcHRpb25hbCgpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiZm9yZWlnbktleU5hbWVzXCIpLmlzQXJyYXkoKS5pc1N0cmluZygpLmlzT3B0aW9uYWwoKS53aXRoRGVmYXVsdChbXSlcclxuICAgICAgLndoZXJlUGFyYW0oXCJpbnZGb3JlaWduS2V5TmFtZXNcIikuaXNBcnJheSgpLmlzU3RyaW5nKCkuaXNPcHRpb25hbCgpLndpdGhEZWZhdWx0KFtdKVxyXG4gICAgICAud2hlcmVQYXJhbShcImN1c3RvbVwiKS5pc09wdGlvbmFsKClcclxuICAgICAgLmFwcGx5QWxsKHRoaXMpO1xyXG4gICAgdGhpcy5wYXJlbnRUeXBlLl91cGRhdGVOYW1lcyh0aGlzKTtcclxuXHJcbiAgICB0aGlzLl9yZXNvbHZlTnAoKTtcclxuICAgIGlmIChpbnZlcnNlKSB7XHJcbiAgICAgIHRoaXMuc2V0SW52ZXJzZShpbnZlcnNlKTtcclxuICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICAvKiogVGhlIGludmVyc2Ugb2YgdGhpcyBOYXZpZ2F0aW9uUHJvcGVydHkuICBUaGUgTmF2aWdhdGlvblByb3BlcnR5IHRoYXQgcmVwcmVzZW50cyBhIG5hdmlnYXRpb24gaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvblxyXG4gIHRvIHRoaXMgTmF2aWdhdGlvblByb3BlcnR5LiBNYXkgYmUgdW5kZWZpbmVkIGZvciBhIHVuZGlyZWN0aW9uYWwgTmF2aWdhdGlvblByb3BlcnR5LiBfX1JlYWQgT25seV9fICovXHJcbiAgZ2V0IGludmVyc2UoKTogTmF2aWdhdGlvblByb3BlcnR5IHwgdW5kZWZpbmVkIHtcclxuICAgIHJldHVybiB0aGlzLmdldEludmVyc2UoKTtcclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIGdldEludmVyc2UoKTogTmF2aWdhdGlvblByb3BlcnR5IHwgdW5kZWZpbmVkIHtcclxuICAgIGxldCBucDogTmF2aWdhdGlvblByb3BlcnR5ID0gdGhpcztcclxuICAgIHdoaWxlICghbnAuX2ludmVyc2UgJiYgbnAuYmFzZVByb3BlcnR5KSB7XHJcbiAgICAgIG5wID0gbnAuYmFzZVByb3BlcnR5O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5wLl9pbnZlcnNlO1xyXG4gIH1cclxuXHJcbiAgc2V0SW52ZXJzZShpbnZlcnNlTnA6IE5hdmlnYXRpb25Qcm9wZXJ0eSB8IHN0cmluZykge1xyXG4gICAgLy8gbGV0IGludk5wOiBOYXZpZ2F0aW9uUHJvcGVydHk7XHJcbiAgICBsZXQgaW52TnAgPSAoaW52ZXJzZU5wIGluc3RhbmNlb2YgTmF2aWdhdGlvblByb3BlcnR5KSA/IGludmVyc2VOcCA6IHRoaXMuZW50aXR5VHlwZS5nZXROYXZpZ2F0aW9uUHJvcGVydHkoaW52ZXJzZU5wKTtcclxuXHJcbiAgICBpZiAoIWludk5wKSB7XHJcbiAgICAgIHRocm93IHRocm93U2V0SW52ZXJzZUVycm9yKHRoaXMsIFwiVW5hYmxlIHRvIGZpbmQgaW52ZXJzZSBwcm9wZXJ0eTogXCIgKyBpbnZlcnNlTnApO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9pbnZlcnNlIHx8IGludk5wLl9pbnZlcnNlKSB7XHJcbiAgICAgIHRocm93U2V0SW52ZXJzZUVycm9yKHRoaXMsIFwiSXQgaGFzIGFscmVhZHkgYmVlbiBzZXQgb24gb25lIHNpZGUgb3IgdGhlIG90aGVyLlwiKTtcclxuICAgIH1cclxuICAgIGlmIChpbnZOcC5lbnRpdHlUeXBlICE9PSB0aGlzLnBhcmVudFR5cGUpIHtcclxuICAgICAgdGhyb3dTZXRJbnZlcnNlRXJyb3IodGhpcywgaW52TnAuZm9ybWF0TmFtZSArIFwiIGlzIG5vdCBhIHZhbGlkIGludmVyc2UgcHJvcGVydHkgZm9yIHRoaXMuXCIpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuYXNzb2NpYXRpb25OYW1lKSB7XHJcbiAgICAgIGludk5wLmFzc29jaWF0aW9uTmFtZSA9IHRoaXMuYXNzb2NpYXRpb25OYW1lO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKCFpbnZOcC5hc3NvY2lhdGlvbk5hbWUpIHtcclxuICAgICAgICBpbnZOcC5hc3NvY2lhdGlvbk5hbWUgPSB0aGlzLmZvcm1hdE5hbWUoKSArIFwiX1wiICsgaW52TnAuZm9ybWF0TmFtZSgpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuYXNzb2NpYXRpb25OYW1lID0gaW52TnAuYXNzb2NpYXRpb25OYW1lO1xyXG4gICAgfVxyXG4gICAgdGhpcy5fcmVzb2x2ZU5wKCk7XHJcbiAgICBpbnZOcC5fcmVzb2x2ZU5wKCk7XHJcbiAgfVxyXG5cclxuICAvLyAvLyBJbiBwcm9ncmVzcyAtIHdpbGwgYmUgdXNlZCBmb3IgbWFudWFsIG1ldGFkYXRhIGNvbmZpZ1xyXG4gIC8vIGNyZWF0ZUludmVyc2UoY29uZmlnOiBhbnkpIHtcclxuXHJcbiAgLy8gICBpZiAoIXRoaXMuZW50aXR5VHlwZSkge1xyXG4gIC8vICAgICB0aHJvd0NyZWF0ZUludmVyc2VFcnJvcih0aGlzLCBcImhhcyBub3QgeWV0IGJlZW4gZGVmaW5lZC5cIik7XHJcbiAgLy8gICB9XHJcbiAgLy8gICBpZiAodGhpcy5lbnRpdHlUeXBlLmlzRnJvemVuKSB7XHJcbiAgLy8gICAgIHRocm93Q3JlYXRlSW52ZXJzZUVycm9yKHRoaXMsIFwiaXMgZnJvemVuLlwiKTtcclxuICAvLyAgIH1cclxuICAvLyAgIGxldCBtZXRhZGF0YVN0b3JlID0gdGhpcy5lbnRpdHlUeXBlLm1ldGFkYXRhU3RvcmU7XHJcbiAgLy8gICBpZiAobWV0YWRhdGFTdG9yZSA9PSBudWxsKSB7XHJcbiAgLy8gICAgIHRocm93Q3JlYXRlSW52ZXJzZUVycm9yKHRoaXMsIFwiaGFzIG5vdCB5ZXQgYmVlbiBhZGRlZCB0byB0aGUgbWV0YWRhdGFTdG9yZS5cIik7XHJcbiAgLy8gICB9XHJcblxyXG4gIC8vICAgY29uZmlnLmVudGl0eVR5cGVOYW1lID0gdGhpcy5wYXJlbnRFbnRpdHlUeXBlLm5hbWU7XHJcbiAgLy8gICBjb25maWcuYXNzb2NpYXRpb25OYW1lID0gdGhpcy5hc3NvY2lhdGlvbk5hbWU7XHJcbiAgLy8gICBsZXQgaW52TnAgPSBuZXcgTmF2aWdhdGlvblByb3BlcnR5KGNvbmZpZyk7XHJcbiAgLy8gICB0aGlzLnBhcmVudEVudGl0eVR5cGUuYWRkTmF2aWdhdGlvblByb3BlcnR5KGludk5wKTtcclxuICAvLyAgIHJldHVybiBpbnZOcDtcclxuICAvLyB9O1xyXG5cclxuXHJcblxyXG4gIHRvSlNPTigpIHtcclxuICAgIHJldHVybiBjb3JlLnRvSnNvbih0aGlzLCB7XHJcbiAgICAgIG5hbWU6IG51bGwsXHJcbiAgICAgIGVudGl0eVR5cGVOYW1lOiBudWxsLFxyXG4gICAgICBpc1NjYWxhcjogbnVsbCxcclxuICAgICAgYXNzb2NpYXRpb25OYW1lOiBudWxsLFxyXG4gICAgICB2YWxpZGF0b3JzOiBudWxsLFxyXG4gICAgICBkaXNwbGF5TmFtZTogbnVsbCxcclxuICAgICAgZm9yZWlnbktleU5hbWVzOiBudWxsLFxyXG4gICAgICBpbnZGb3JlaWduS2V5TmFtZXM6IG51bGwsXHJcbiAgICAgIGN1c3RvbTogbnVsbFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBzdGF0aWMgZnJvbUpTT04oanNvbjogYW55KSB7XHJcbiAgICBpZiAoanNvbi52YWxpZGF0b3JzKSB7XHJcbiAgICAgIGpzb24udmFsaWRhdG9ycyA9IGpzb24udmFsaWRhdG9ycy5tYXAoVmFsaWRhdG9yLmZyb21KU09OKTtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXcgTmF2aWdhdGlvblByb3BlcnR5KGpzb24pO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3Jlc29sdmVOcCgpIHtcclxuICAgIGxldCBucCA9IHRoaXM7XHJcbiAgICBsZXQgZW50aXR5VHlwZSA9IG5wLmVudGl0eVR5cGU7XHJcbiAgICBsZXQgaW52TnAgPSBjb3JlLmFycmF5Rmlyc3QoZW50aXR5VHlwZS5uYXZpZ2F0aW9uUHJvcGVydGllcywgKGFsdE5wKSA9PiB7XHJcbiAgICAgIC8vIENhbid0IGRvIHRoaXMgYmVjYXVzZSBvZiBwb3NzaWJpbGl0eSBvZiBjb21wYXJpbmcgYSBiYXNlIGNsYXNzIG5wIHdpdGggYSBzdWJjbGFzcyBhbHROcC5cclxuICAgICAgLy8gcmV0dXJuIGFsdE5wLmFzc29jaWF0aW9uTmFtZSA9PT0gbnAuYXNzb2NpYXRpb25OYW1lXHJcbiAgICAgIC8vICAgICYmIGFsdE5wICE9PSBucDtcclxuICAgICAgLy8gU28gdXNlIHRoaXMgaW5zdGVhZC5cclxuICAgICAgcmV0dXJuIGFsdE5wLmFzc29jaWF0aW9uTmFtZSA9PT0gbnAuYXNzb2NpYXRpb25OYW1lICYmXHJcbiAgICAgICAgKGFsdE5wLm5hbWUgIT09IG5wLm5hbWUgfHwgYWx0TnAuZW50aXR5VHlwZU5hbWUgIT09IG5wLmVudGl0eVR5cGVOYW1lKTtcclxuICAgIH0pO1xyXG4gICAgbnAuX2ludmVyc2UgPSBpbnZOcCB8fCB1bmRlZmluZWQ7XHJcbiAgICAvL2lmIChpbnZOcCAmJiBpbnZOcC5pbnZlcnNlID09IG51bGwpIHtcclxuICAgIC8vICAgIGludk5wLl9yZXNvbHZlTnAoKTtcclxuICAgIC8vfVxyXG4gICAgaWYgKCFpbnZOcCkge1xyXG4gICAgICAvLyB1bmlkaXJlY3Rpb25hbCAxLW4gcmVsYXRpb25zaGlwXHJcbiAgICAgIG5wLmludkZvcmVpZ25LZXlOYW1lcy5mb3JFYWNoKGZ1bmN0aW9uIChpbnZGa05hbWUpIHtcclxuICAgICAgICBsZXQgZmtQcm9wID0gZW50aXR5VHlwZS5nZXREYXRhUHJvcGVydHkoaW52RmtOYW1lKTtcclxuICAgICAgICBpZiAoZmtQcm9wID09IG51bGwpIHtcclxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkVudGl0eVR5cGUgJ1wiICsgbnAuZW50aXR5VHlwZU5hbWUgKyBcIicgaGFzIG5vIGZvcmVpZ24ga2V5IG1hdGNoaW5nICdcIiArIGludkZrTmFtZSArIFwiJ1wiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IGludkVudGl0eVR5cGUgPSBucC5wYXJlbnRUeXBlO1xyXG4gICAgICAgIGludk5wID0gY29yZS5hcnJheUZpcnN0KGludkVudGl0eVR5cGUubmF2aWdhdGlvblByb3BlcnRpZXMsIChucDIpID0+IHtcclxuICAgICAgICAgIHJldHVybiBucDIuaW52Rm9yZWlnbktleU5hbWVzICYmIG5wMi5pbnZGb3JlaWduS2V5TmFtZXMuaW5kZXhPZihma1Byb3AhLm5hbWUpID49IDAgJiYgbnAyLmVudGl0eVR5cGUgPT09IGZrUHJvcCEucGFyZW50VHlwZTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBma1Byb3AuaW52ZXJzZU5hdmlnYXRpb25Qcm9wZXJ0eSA9IGludk5wIHx8IHVuZGVmaW5lZDtcclxuICAgICAgICBjb3JlLmFycmF5QWRkSXRlbVVuaXF1ZShlbnRpdHlUeXBlLmZvcmVpZ25LZXlQcm9wZXJ0aWVzLCBma1Byb3ApO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZXNvbHZlUmVsYXRlZChucCk7XHJcbiAgfVxyXG5cclxufVxyXG5OYXZpZ2F0aW9uUHJvcGVydHkucHJvdG90eXBlLl8kdHlwZU5hbWUgPSBcIk5hdmlnYXRpb25Qcm9wZXJ0eVwiO1xyXG5cclxuZnVuY3Rpb24gdGhyb3dTZXRJbnZlcnNlRXJyb3IobnA6IE5hdmlnYXRpb25Qcm9wZXJ0eSwgbWVzc2FnZTogc3RyaW5nKSB7XHJcbiAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IHNldCB0aGUgaW52ZXJzZSBwcm9wZXJ0eSBmb3I6IFwiICsgbnAuZm9ybWF0TmFtZSgpICsgXCIuIFwiICsgbWVzc2FnZSk7XHJcbn1cclxuXHJcbi8vIE5vdCBjdXJyZW50IHVzZWQuXHJcbi8vIGZ1bmN0aW9uIHRocm93Q3JlYXRlSW52ZXJzZUVycm9yKG5wOiBOYXZpZ2F0aW9uUHJvcGVydHksIG1lc3NhZ2U6IHN0cmluZykge1xyXG4vLyAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBjcmVhdGUgaW52ZXJzZSBmb3I6IFwiICsgbnAuZm9ybWF0TmFtZSgpICsgXCIuIFRoZSBlbnRpdHlUeXBlIGZvciB0aGlzIG5hdmlnYXRpb24gcHJvcGVydHkgXCIgKyBtZXNzYWdlKTtcclxuLy8gfVxyXG5cclxuLy8gc2V0cyBuYXZpZ2F0aW9uIHByb3BlcnR5OiByZWxhdGVkRGF0YVByb3BlcnRpZXMgYW5kIGRhdGFQcm9wZXJ0eTogcmVsYXRlZE5hdmlnYXRpb25Qcm9wZXJ0eVxyXG5mdW5jdGlvbiByZXNvbHZlUmVsYXRlZChucDogTmF2aWdhdGlvblByb3BlcnR5KSB7XHJcblxyXG4gIGxldCBma05hbWVzID0gbnAuZm9yZWlnbktleU5hbWVzO1xyXG4gIGlmIChma05hbWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xyXG5cclxuICBsZXQgcGFyZW50RW50aXR5VHlwZSA9IG5wLnBhcmVudFR5cGU7XHJcbiAgbGV0IGZrUHJvcHMgPSBma05hbWVzLm1hcChmdW5jdGlvbiAoZmtOYW1lKSB7XHJcbiAgICByZXR1cm4gcGFyZW50RW50aXR5VHlwZS5nZXREYXRhUHJvcGVydHkoZmtOYW1lKTtcclxuICB9KTtcclxuICBsZXQgZmtQcm9wQ29sbGVjdGlvbiA9IHBhcmVudEVudGl0eVR5cGUuZm9yZWlnbktleVByb3BlcnRpZXM7XHJcblxyXG4gIGZrUHJvcHMuZm9yRWFjaCgoZHA6IERhdGFQcm9wZXJ0eSkgPT4ge1xyXG4gICAgY29yZS5hcnJheUFkZEl0ZW1VbmlxdWUoZmtQcm9wQ29sbGVjdGlvbiwgZHApO1xyXG4gICAgZHAucmVsYXRlZE5hdmlnYXRpb25Qcm9wZXJ0eSA9IG5wO1xyXG4gICAgLy8gbm93IHVwZGF0ZSB0aGUgaW52ZXJzZVxyXG4gICAgY29yZS5hcnJheUFkZEl0ZW1VbmlxdWUobnAuZW50aXR5VHlwZS5pbnZlcnNlRm9yZWlnbktleVByb3BlcnRpZXMsIGRwKTtcclxuICAgIGlmIChucC5yZWxhdGVkRGF0YVByb3BlcnRpZXMpIHtcclxuICAgICAgY29yZS5hcnJheUFkZEl0ZW1VbmlxdWUobnAucmVsYXRlZERhdGFQcm9wZXJ0aWVzLCBkcCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBucC5yZWxhdGVkRGF0YVByb3BlcnRpZXMgPSBbZHBdO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG5cclxuLyoqXHJcbkF1dG9HZW5lcmF0ZWRLZXlUeXBlIGlzIGFuICdFbnVtJyBjb250YWluaW5nIGFsbCBvZiB0aGUgdmFsaWQgc3RhdGVzIGZvciBhbiBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBrZXkuXHJcbioqL1xyXG5leHBvcnQgY2xhc3MgQXV0b0dlbmVyYXRlZEtleVR5cGUgZXh0ZW5kcyBCcmVlemVFbnVtIHtcclxuXHJcbiAgLyoqXHJcbiAgVGhpcyBlbnRpdHkgZG9lcyBub3QgaGF2ZSBhbiBhdXRvZ2VuZXJhdGVkIGtleS5cclxuICBUaGUgY2xpZW50IG11c3Qgc2V0IHRoZSBrZXkgYmVmb3JlIGFkZGluZyB0aGUgZW50aXR5IHRvIHRoZSBFbnRpdHlNYW5hZ2VyXHJcbiAgKiovXHJcbiAgc3RhdGljIE5vbmUgPSBuZXcgQXV0b0dlbmVyYXRlZEtleVR5cGUoKTtcclxuICAvKiogXHJcbiAgVGhpcyBlbnRpdHkncyBrZXkgaXMgYW4gSWRlbnRpdHkgY29sdW1uIGFuZCBpcyBzZXQgYnkgdGhlIGJhY2tlbmQgZGF0YWJhc2UuXHJcbiAgS2V5cyBmb3IgbmV3IGVudGl0aWVzIHdpbGwgYmUgdGVtcG9yYXJ5IHVudGlsIHRoZSBlbnRpdGllcyBhcmUgc2F2ZWQgYXQgd2hpY2ggcG9pbnQgdGhlIGtleXMgd2lsbFxyXG4gIGJlIGNvbnZlcnRlZCB0byB0aGVpciAncmVhbCcgdmVyc2lvbnMuXHJcbiAgKiovXHJcbiAgc3RhdGljIElkZW50aXR5ID0gbmV3IEF1dG9HZW5lcmF0ZWRLZXlUeXBlKCk7XHJcbiAgLyoqXHJcbiAgVGhpcyBlbnRpdHkncyBrZXkgaXMgZ2VuZXJhdGVkIGJ5IGEgS2V5R2VuZXJhdG9yIGFuZCBpcyBzZXQgYnkgdGhlIGJhY2tlbmQgZGF0YWJhc2UuXHJcbiAgS2V5cyBmb3IgbmV3IGVudGl0aWVzIHdpbGwgYmUgdGVtcG9yYXJ5IHVudGlsIHRoZSBlbnRpdGllcyBhcmUgc2F2ZWQgYXQgd2hpY2ggcG9pbnQgdGhlIGtleXMgd2lsbFxyXG4gIGJlIGNvbnZlcnRlZCB0byB0aGVpciAncmVhbCcgdmVyc2lvbnMuXHJcbiAgKiovXHJcbiAgc3RhdGljIEtleUdlbmVyYXRvciA9IG5ldyBBdXRvR2VuZXJhdGVkS2V5VHlwZSgpO1xyXG5cclxufVxyXG5BdXRvR2VuZXJhdGVkS2V5VHlwZS5wcm90b3R5cGUuXyR0eXBlTmFtZSA9IFwiQXV0b0dlbmVyYXRlZEtleVR5cGVcIjtcclxuRXJyb3JbJ3gnXSA9IEF1dG9HZW5lcmF0ZWRLZXlUeXBlLnJlc29sdmVTeW1ib2xzKCk7XHJcblxyXG5cclxuLy8gbWl4aW4gbWV0aG9kc1xyXG4vKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuZGVjbGFyZSBtb2R1bGUgXCIuL2Fzc2VydC1wYXJhbVwiIHtcclxuICBpbnRlcmZhY2UgUGFyYW0ge1xyXG4gICAgaXNFbnRpdHkoKTogUGFyYW07XHJcbiAgICBpc0VudGl0eVByb3BlcnR5KCk6IFBhcmFtO1xyXG4gIH1cclxufVxyXG5cclxubGV0IHByb3RvID0gUGFyYW0ucHJvdG90eXBlO1xyXG5cclxuLy8gJ3RoaXMnIGJlbG93IGlzIFRTIGFubm90YXRpb24gXHJcbnByb3RvLmlzRW50aXR5ID0gZnVuY3Rpb24gKHRoaXM6IFBhcmFtKSB7XHJcbiAgcmV0dXJuIHRoaXMuX2FkZENvbnRleHQoe1xyXG4gICAgZm46IGlzRW50aXR5LFxyXG4gICAgbXNnOiBcIiBtdXN0IGJlIGFuIGVudGl0eVwiXHJcbiAgfSk7XHJcbn07XHJcblxyXG5mdW5jdGlvbiBpc0VudGl0eShjb250ZXh0OiBhbnksIHY6IGFueSkge1xyXG4gIGlmICh2ID09IG51bGwpIHJldHVybiBmYWxzZTtcclxuICByZXR1cm4gKHYuZW50aXR5VHlwZSAhPT0gdW5kZWZpbmVkKTtcclxufVxyXG5cclxucHJvdG8uaXNFbnRpdHlQcm9wZXJ0eSA9IGZ1bmN0aW9uICh0aGlzOiBQYXJhbSkge1xyXG4gIHJldHVybiB0aGlzLl9hZGRDb250ZXh0KHtcclxuICAgIGZuOiBpc0VudGl0eVByb3BlcnR5LFxyXG4gICAgbXNnOiBcIiBtdXN0IGJlIGVpdGhlciBhIERhdGFQcm9wZXJ0eSBvciBhIE5hdmlnYXRpb25Qcm9wZXJ0eVwiXHJcbiAgfSk7XHJcbn07XHJcblxyXG5mdW5jdGlvbiBpc0VudGl0eVByb3BlcnR5KGNvbnRleHQ6IGFueSwgdjogYW55KSB7XHJcbiAgaWYgKHYgPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xyXG4gIHJldHVybiAodi5pc0RhdGFQcm9wZXJ0eSB8fCB2LmlzTmF2aWdhdGlvblByb3BlcnR5KTtcclxufVxyXG5cclxuLy8gZnVuY3Rpb25zIHNoYXJlZCBiZXR3ZWVuIGNsYXNzZXMgcmVsYXRlZCB0byBNZXRhZGF0YVxyXG5cclxuZnVuY3Rpb24gaXNRdWFsaWZpZWRUeXBlTmFtZShlbnRpdHlUeXBlTmFtZTogc3RyaW5nKSB7XHJcbiAgcmV0dXJuIGVudGl0eVR5cGVOYW1lLmluZGV4T2YoXCI6I1wiKSA+PSAwO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gcXVhbGlmeVR5cGVOYW1lKHNob3J0TmFtZTogc3RyaW5nLCBucz86IHN0cmluZykge1xyXG4gIGlmIChucyAmJiBucy5sZW5ndGggPiAwKSB7XHJcbiAgICByZXR1cm4gc2hvcnROYW1lICsgXCI6I1wiICsgbnM7XHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiBzaG9ydE5hbWU7XHJcbiAgfVxyXG59XHJcblxyXG4vLyBVc2VkIGJ5IGJvdGggQ29tcGxleFR5cGUgYW5kIEVudGl0eVR5cGVcclxuZnVuY3Rpb24gYWRkUHJvcGVydGllcyhlbnRpdHlUeXBlOiBTdHJ1Y3R1cmFsVHlwZSwgcHJvcE9iajogT2JqZWN0IHwgdW5kZWZpbmVkLCBjdG9yOiBhbnkpIHtcclxuICBpZiAocHJvcE9iaiA9PSBudWxsKSByZXR1cm47XHJcbiAgaWYgKEFycmF5LmlzQXJyYXkocHJvcE9iaikpIHtcclxuICAgIHByb3BPYmouZm9yRWFjaChlbnRpdHlUeXBlLl9hZGRQcm9wZXJ0eUNvcmUuYmluZChlbnRpdHlUeXBlKSk7XHJcbiAgfSBlbHNlIGlmICh0eXBlb2YgKHByb3BPYmopID09PSAnb2JqZWN0Jykge1xyXG4gICAgZm9yIChsZXQga2V5IGluIHByb3BPYmopIHtcclxuICAgICAgaWYgKGNvcmUuaGFzT3duUHJvcGVydHkocHJvcE9iaiwga2V5KSkge1xyXG4gICAgICAgIGxldCB2YWx1ZSA9IHByb3BPYmpba2V5XTtcclxuICAgICAgICB2YWx1ZS5uYW1lID0ga2V5O1xyXG4gICAgICAgIGxldCBwcm9wID0gbmV3IGN0b3IodmFsdWUpO1xyXG4gICAgICAgIGVudGl0eVR5cGUuX2FkZFByb3BlcnR5Q29yZShwcm9wKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0gZWxzZSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgJ2RhdGFQcm9wZXJ0aWVzJyBvciAnbmF2aWdhdGlvblByb3BlcnRpZXMnIHZhbHVlcyBtdXN0IGJlIGVpdGhlciBhbiBhcnJheSBvZiBkYXRhL25hdiBwcm9wZXJ0aWVzIG9yIGFuIG9iamVjdCB3aGVyZSBlYWNoIHByb3BlcnR5IGRlZmluZXMgYSBkYXRhL25hdiBwcm9wZXJ0eVwiKTtcclxuICB9XHJcbn1cclxuXHJcblxyXG5cclxuXHJcblxyXG4iXX0=