breeze-client 2.1.4 → 2.1.5-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 (395) hide show
  1. package/adapter-ajax-angularjs/{breeze-client-adapter-ajax-angularjs.d.ts → index.d.ts} +1 -0
  2. package/adapter-ajax-fetch/{breeze-client-adapter-ajax-fetch.d.ts → index.d.ts} +1 -0
  3. package/adapter-ajax-httpclient/{breeze-client-adapter-ajax-httpclient.d.ts → index.d.ts} +1 -0
  4. package/adapter-ajax-jquery/{breeze-client-adapter-ajax-jquery.d.ts → index.d.ts} +1 -0
  5. package/adapter-ajax-post/{breeze-client-adapter-ajax-post.d.ts → index.d.ts} +1 -0
  6. package/adapter-data-service-odata/{breeze-client-adapter-data-service-odata.d.ts → index.d.ts} +1 -0
  7. package/adapter-data-service-webapi/{breeze-client-adapter-data-service-webapi.d.ts → index.d.ts} +1 -0
  8. package/adapter-model-library-backing-store/{breeze-client-adapter-model-library-backing-store.d.ts → index.d.ts} +1 -0
  9. package/adapter-model-library-ko/{breeze-client-adapter-model-library-ko.d.ts → index.d.ts} +1 -0
  10. package/adapter-uri-builder-json/{breeze-client-adapter-uri-builder-json.d.ts → index.d.ts} +1 -0
  11. package/adapter-uri-builder-odata/{breeze-client-adapter-uri-builder-odata.d.ts → index.d.ts} +1 -0
  12. package/esm2020/adapter-ajax-angularjs/adapter-ajax-angularjs.mjs +130 -0
  13. package/esm2020/adapter-ajax-angularjs/adapter-core.mjs +49 -0
  14. package/esm2020/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.mjs +5 -0
  15. package/esm2020/adapter-ajax-fetch/adapter-ajax-fetch.mjs +132 -0
  16. package/esm2020/adapter-ajax-fetch/adapter-core.mjs +49 -0
  17. package/esm2020/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.mjs +5 -0
  18. package/esm2020/adapter-ajax-httpclient/adapter-ajax-httpclient.mjs +137 -0
  19. package/esm2020/adapter-ajax-httpclient/adapter-core.mjs +49 -0
  20. package/esm2020/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.mjs +5 -0
  21. package/esm2020/adapter-ajax-jquery/adapter-ajax-jquery.mjs +103 -0
  22. package/esm2020/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.mjs +5 -0
  23. package/esm2020/adapter-ajax-post/adapter-ajax-post.mjs +77 -0
  24. package/esm2020/adapter-ajax-post/breeze-client-adapter-ajax-post.mjs +5 -0
  25. package/esm2020/adapter-data-service-odata/adapter-core.mjs +49 -0
  26. package/esm2020/adapter-data-service-odata/adapter-data-service-odata.mjs +456 -0
  27. package/esm2020/adapter-data-service-odata/breeze-client-adapter-data-service-odata.mjs +5 -0
  28. package/esm2020/adapter-data-service-webapi/adapter-data-service-webapi.mjs +93 -0
  29. package/esm2020/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.mjs +5 -0
  30. package/esm2020/adapter-model-library-backing-store/adapter-model-library-backing-store.mjs +268 -0
  31. package/esm2020/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.mjs +5 -0
  32. package/esm2020/adapter-model-library-ko/adapter-model-library-ko.mjs +240 -0
  33. package/esm2020/adapter-model-library-ko/breeze-client-adapter-model-library-ko.mjs +5 -0
  34. package/esm2020/adapter-uri-builder-json/adapter-core.mjs +49 -0
  35. package/esm2020/adapter-uri-builder-json/adapter-uri-builder-json.mjs +36 -0
  36. package/esm2020/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.mjs +5 -0
  37. package/esm2020/adapter-uri-builder-odata/adapter-core.mjs +49 -0
  38. package/esm2020/adapter-uri-builder-odata/adapter-uri-builder-odata.mjs +190 -0
  39. package/esm2020/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.mjs +5 -0
  40. package/esm2020/breeze-client.mjs +5 -0
  41. package/esm2020/index.mjs +2 -0
  42. package/esm2020/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.mjs +5 -0
  43. package/esm2020/mixin-get-entity-graph/mixin-get-entity-graph.mjs +269 -0
  44. package/esm2020/mixin-save-queuing/breeze-client-mixin-save-queuing.mjs +5 -0
  45. package/esm2020/mixin-save-queuing/mixin-save-queuing.mjs +400 -0
  46. package/esm2020/src/abstract-data-service-adapter.mjs +296 -0
  47. package/esm2020/src/array.mjs +4 -0
  48. package/esm2020/src/assert-param.mjs +312 -0
  49. package/esm2020/src/breeze.mjs +85 -0
  50. package/esm2020/src/complex-array.mjs +117 -0
  51. package/esm2020/src/config.mjs +223 -0
  52. package/esm2020/src/core.mjs +707 -0
  53. package/esm2020/src/csdl-metadata-parser.mjs +385 -0
  54. package/esm2020/src/data-service.mjs +203 -0
  55. package/esm2020/src/data-type.mjs +444 -0
  56. package/esm2020/src/default-property-interceptor.mjs +460 -0
  57. package/esm2020/src/entity-action.mjs +45 -0
  58. package/esm2020/src/entity-aspect.mjs +806 -0
  59. package/esm2020/src/entity-group.mjs +187 -0
  60. package/esm2020/src/entity-key.mjs +116 -0
  61. package/esm2020/src/entity-manager.mjs +2094 -0
  62. package/esm2020/src/entity-metadata.mjs +2109 -0
  63. package/esm2020/src/entity-query.mjs +996 -0
  64. package/esm2020/src/entity-state.mjs +99 -0
  65. package/esm2020/src/enum.mjs +141 -0
  66. package/esm2020/src/event.mjs +256 -0
  67. package/esm2020/src/interface-registry.mjs +41 -0
  68. package/esm2020/src/key-generator.mjs +108 -0
  69. package/esm2020/src/local-query-comparison-options.mjs +65 -0
  70. package/esm2020/src/mapping-context.mjs +405 -0
  71. package/esm2020/src/naming-convention.mjs +88 -0
  72. package/esm2020/src/observable-array.mjs +183 -0
  73. package/esm2020/src/predicate.mjs +1232 -0
  74. package/esm2020/src/primitive-array.mjs +85 -0
  75. package/esm2020/src/query-options.mjs +152 -0
  76. package/esm2020/src/relation-array.mjs +173 -0
  77. package/esm2020/src/save-options.mjs +41 -0
  78. package/esm2020/src/unattached-children-map.mjs +58 -0
  79. package/esm2020/src/validate.mjs +988 -0
  80. package/esm2020/src/validation-options.mjs +64 -0
  81. package/fesm2015/{breeze-client-adapter-ajax-angularjs.js → breeze-client-adapter-ajax-angularjs.mjs} +2 -1
  82. package/fesm2015/breeze-client-adapter-ajax-angularjs.mjs.map +1 -0
  83. package/fesm2015/{breeze-client-adapter-ajax-fetch.js → breeze-client-adapter-ajax-fetch.mjs} +6 -3
  84. package/fesm2015/breeze-client-adapter-ajax-fetch.mjs.map +1 -0
  85. package/fesm2015/{breeze-client-adapter-ajax-httpclient.js → breeze-client-adapter-ajax-httpclient.mjs} +2 -1
  86. package/fesm2015/breeze-client-adapter-ajax-httpclient.mjs.map +1 -0
  87. package/fesm2015/{breeze-client-adapter-ajax-jquery.js → breeze-client-adapter-ajax-jquery.mjs} +3 -2
  88. package/fesm2015/breeze-client-adapter-ajax-jquery.mjs.map +1 -0
  89. package/fesm2015/{breeze-client-adapter-ajax-post.js → breeze-client-adapter-ajax-post.mjs} +2 -1
  90. package/fesm2015/breeze-client-adapter-ajax-post.mjs.map +1 -0
  91. package/fesm2015/{breeze-client-adapter-data-service-odata.js → breeze-client-adapter-data-service-odata.mjs} +21 -22
  92. package/fesm2015/breeze-client-adapter-data-service-odata.mjs.map +1 -0
  93. package/fesm2015/{breeze-client-adapter-data-service-webapi.js → breeze-client-adapter-data-service-webapi.mjs} +14 -13
  94. package/fesm2015/breeze-client-adapter-data-service-webapi.mjs.map +1 -0
  95. package/fesm2015/{breeze-client-adapter-model-library-backing-store.js → breeze-client-adapter-model-library-backing-store.mjs} +14 -13
  96. package/fesm2015/breeze-client-adapter-model-library-backing-store.mjs.map +1 -0
  97. package/fesm2015/{breeze-client-adapter-model-library-ko.js → breeze-client-adapter-model-library-ko.mjs} +14 -13
  98. package/fesm2015/breeze-client-adapter-model-library-ko.mjs.map +1 -0
  99. package/fesm2015/{breeze-client-adapter-uri-builder-json.js → breeze-client-adapter-uri-builder-json.mjs} +9 -8
  100. package/fesm2015/breeze-client-adapter-uri-builder-json.mjs.map +1 -0
  101. package/fesm2015/{breeze-client-adapter-uri-builder-odata.js → breeze-client-adapter-uri-builder-odata.mjs} +86 -86
  102. package/fesm2015/breeze-client-adapter-uri-builder-odata.mjs.map +1 -0
  103. package/fesm2015/{breeze-client-mixin-get-entity-graph.js → breeze-client-mixin-get-entity-graph.mjs} +2 -1
  104. package/fesm2015/breeze-client-mixin-get-entity-graph.mjs.map +1 -0
  105. package/fesm2015/{breeze-client-mixin-save-queuing.js → breeze-client-mixin-save-queuing.mjs} +2 -1
  106. package/fesm2015/breeze-client-mixin-save-queuing.mjs.map +1 -0
  107. package/fesm2015/{breeze-client.js → breeze-client.mjs} +410 -419
  108. package/fesm2015/breeze-client.mjs.map +1 -0
  109. package/{fesm5/breeze-client-adapter-ajax-angularjs.js → fesm2020/breeze-client-adapter-ajax-angularjs.mjs} +42 -42
  110. package/fesm2020/breeze-client-adapter-ajax-angularjs.mjs.map +1 -0
  111. package/{fesm5/breeze-client-adapter-ajax-fetch.js → fesm2020/breeze-client-adapter-ajax-fetch.mjs} +45 -43
  112. package/fesm2020/breeze-client-adapter-ajax-fetch.mjs.map +1 -0
  113. package/{fesm5/breeze-client-adapter-ajax-httpclient.js → fesm2020/breeze-client-adapter-ajax-httpclient.mjs} +44 -44
  114. package/fesm2020/breeze-client-adapter-ajax-httpclient.mjs.map +1 -0
  115. package/{fesm5/breeze-client-adapter-ajax-jquery.js → fesm2020/breeze-client-adapter-ajax-jquery.mjs} +19 -19
  116. package/fesm2020/breeze-client-adapter-ajax-jquery.mjs.map +1 -0
  117. package/{fesm5/breeze-client-adapter-ajax-post.js → fesm2020/breeze-client-adapter-ajax-post.mjs} +9 -11
  118. package/fesm2020/breeze-client-adapter-ajax-post.mjs.map +1 -0
  119. package/{fesm5/breeze-client-adapter-data-service-odata.js → fesm2020/breeze-client-adapter-data-service-odata.mjs} +127 -134
  120. package/fesm2020/breeze-client-adapter-data-service-odata.mjs.map +1 -0
  121. package/{fesm5/breeze-client-adapter-data-service-webapi.js → fesm2020/breeze-client-adapter-data-service-webapi.mjs} +39 -42
  122. package/fesm2020/breeze-client-adapter-data-service-webapi.mjs.map +1 -0
  123. package/{fesm5/breeze-client-adapter-model-library-backing-store.js → fesm2020/breeze-client-adapter-model-library-backing-store.mjs} +64 -64
  124. package/fesm2020/breeze-client-adapter-model-library-backing-store.mjs.map +1 -0
  125. package/{fesm5/breeze-client-adapter-model-library-ko.js → fesm2020/breeze-client-adapter-model-library-ko.mjs} +58 -58
  126. package/fesm2020/breeze-client-adapter-model-library-ko.mjs.map +1 -0
  127. package/fesm2020/breeze-client-adapter-uri-builder-json.mjs +92 -0
  128. package/fesm2020/breeze-client-adapter-uri-builder-json.mjs.map +1 -0
  129. package/fesm2020/breeze-client-adapter-uri-builder-odata.mjs +246 -0
  130. package/fesm2020/breeze-client-adapter-uri-builder-odata.mjs.map +1 -0
  131. package/{fesm5/breeze-client-mixin-get-entity-graph.js → fesm2020/breeze-client-mixin-get-entity-graph.mjs} +46 -45
  132. package/fesm2020/breeze-client-mixin-get-entity-graph.mjs.map +1 -0
  133. package/{fesm5/breeze-client-mixin-save-queuing.js → fesm2020/breeze-client-mixin-save-queuing.mjs} +117 -126
  134. package/fesm2020/breeze-client-mixin-save-queuing.mjs.map +1 -0
  135. package/{fesm5/breeze-client.js → fesm2020/breeze-client.mjs} +3397 -3613
  136. package/fesm2020/breeze-client.mjs.map +1 -0
  137. package/mixin-get-entity-graph/{breeze-client-mixin-get-entity-graph.d.ts → index.d.ts} +1 -0
  138. package/mixin-save-queuing/{breeze-client-mixin-save-queuing.d.ts → index.d.ts} +1 -0
  139. package/mjs/README.md +17 -0
  140. package/package.json +125 -11
  141. package/src/entity-aspect.d.ts +2 -2
  142. package/src/entity-metadata.d.ts +6 -4
  143. package/src/entity-query.d.ts +1 -1
  144. package/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.metadata.json +0 -1
  145. package/adapter-ajax-angularjs/package.json +0 -13
  146. package/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.metadata.json +0 -1
  147. package/adapter-ajax-fetch/package.json +0 -13
  148. package/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.metadata.json +0 -1
  149. package/adapter-ajax-httpclient/package.json +0 -13
  150. package/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.metadata.json +0 -1
  151. package/adapter-ajax-jquery/package.json +0 -13
  152. package/adapter-ajax-post/breeze-client-adapter-ajax-post.metadata.json +0 -1
  153. package/adapter-ajax-post/package.json +0 -13
  154. package/adapter-data-service-odata/breeze-client-adapter-data-service-odata.metadata.json +0 -1
  155. package/adapter-data-service-odata/package.json +0 -13
  156. package/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.metadata.json +0 -1
  157. package/adapter-data-service-webapi/package.json +0 -13
  158. package/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.metadata.json +0 -1
  159. package/adapter-model-library-backing-store/package.json +0 -13
  160. package/adapter-model-library-ko/breeze-client-adapter-model-library-ko.metadata.json +0 -1
  161. package/adapter-model-library-ko/package.json +0 -13
  162. package/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.metadata.json +0 -1
  163. package/adapter-uri-builder-json/package.json +0 -13
  164. package/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.metadata.json +0 -1
  165. package/adapter-uri-builder-odata/package.json +0 -13
  166. package/breeze-client.d.ts +0 -8
  167. package/breeze-client.metadata.json +0 -1
  168. package/bundles/breeze-client-adapter-ajax-angularjs.umd.js +0 -190
  169. package/bundles/breeze-client-adapter-ajax-angularjs.umd.js.map +0 -1
  170. package/bundles/breeze-client-adapter-ajax-angularjs.umd.min.js +0 -2
  171. package/bundles/breeze-client-adapter-ajax-angularjs.umd.min.js.map +0 -1
  172. package/bundles/breeze-client-adapter-ajax-fetch.umd.js +0 -190
  173. package/bundles/breeze-client-adapter-ajax-fetch.umd.js.map +0 -1
  174. package/bundles/breeze-client-adapter-ajax-fetch.umd.min.js +0 -2
  175. package/bundles/breeze-client-adapter-ajax-fetch.umd.min.js.map +0 -1
  176. package/bundles/breeze-client-adapter-ajax-httpclient.umd.js +0 -195
  177. package/bundles/breeze-client-adapter-ajax-httpclient.umd.js.map +0 -1
  178. package/bundles/breeze-client-adapter-ajax-httpclient.umd.min.js +0 -2
  179. package/bundles/breeze-client-adapter-ajax-httpclient.umd.min.js.map +0 -1
  180. package/bundles/breeze-client-adapter-ajax-jquery.umd.js +0 -115
  181. package/bundles/breeze-client-adapter-ajax-jquery.umd.js.map +0 -1
  182. package/bundles/breeze-client-adapter-ajax-jquery.umd.min.js +0 -2
  183. package/bundles/breeze-client-adapter-ajax-jquery.umd.min.js.map +0 -1
  184. package/bundles/breeze-client-adapter-ajax-post.umd.js +0 -92
  185. package/bundles/breeze-client-adapter-ajax-post.umd.js.map +0 -1
  186. package/bundles/breeze-client-adapter-ajax-post.umd.min.js +0 -2
  187. package/bundles/breeze-client-adapter-ajax-post.umd.min.js.map +0 -1
  188. package/bundles/breeze-client-adapter-data-service-odata.umd.js +0 -743
  189. package/bundles/breeze-client-adapter-data-service-odata.umd.js.map +0 -1
  190. package/bundles/breeze-client-adapter-data-service-odata.umd.min.js +0 -16
  191. package/bundles/breeze-client-adapter-data-service-odata.umd.min.js.map +0 -1
  192. package/bundles/breeze-client-adapter-data-service-webapi.umd.js +0 -326
  193. package/bundles/breeze-client-adapter-data-service-webapi.umd.js.map +0 -1
  194. package/bundles/breeze-client-adapter-data-service-webapi.umd.min.js +0 -16
  195. package/bundles/breeze-client-adapter-data-service-webapi.umd.min.js.map +0 -1
  196. package/bundles/breeze-client-adapter-model-library-backing-store.umd.js +0 -280
  197. package/bundles/breeze-client-adapter-model-library-backing-store.umd.js.map +0 -1
  198. package/bundles/breeze-client-adapter-model-library-backing-store.umd.min.js +0 -2
  199. package/bundles/breeze-client-adapter-model-library-backing-store.umd.min.js.map +0 -1
  200. package/bundles/breeze-client-adapter-model-library-ko.umd.js +0 -252
  201. package/bundles/breeze-client-adapter-model-library-ko.umd.js.map +0 -1
  202. package/bundles/breeze-client-adapter-model-library-ko.umd.min.js +0 -2
  203. package/bundles/breeze-client-adapter-model-library-ko.umd.min.js.map +0 -1
  204. package/bundles/breeze-client-adapter-uri-builder-json.umd.js +0 -96
  205. package/bundles/breeze-client-adapter-uri-builder-json.umd.js.map +0 -1
  206. package/bundles/breeze-client-adapter-uri-builder-json.umd.min.js +0 -2
  207. package/bundles/breeze-client-adapter-uri-builder-json.umd.min.js.map +0 -1
  208. package/bundles/breeze-client-adapter-uri-builder-odata.umd.js +0 -262
  209. package/bundles/breeze-client-adapter-uri-builder-odata.umd.js.map +0 -1
  210. package/bundles/breeze-client-adapter-uri-builder-odata.umd.min.js +0 -2
  211. package/bundles/breeze-client-adapter-uri-builder-odata.umd.min.js.map +0 -1
  212. package/bundles/breeze-client-mixin-get-entity-graph.umd.js +0 -258
  213. package/bundles/breeze-client-mixin-get-entity-graph.umd.js.map +0 -1
  214. package/bundles/breeze-client-mixin-get-entity-graph.umd.min.js +0 -2
  215. package/bundles/breeze-client-mixin-get-entity-graph.umd.min.js.map +0 -1
  216. package/bundles/breeze-client-mixin-save-queuing.umd.js +0 -579
  217. package/bundles/breeze-client-mixin-save-queuing.umd.js.map +0 -1
  218. package/bundles/breeze-client-mixin-save-queuing.umd.min.js +0 -16
  219. package/bundles/breeze-client-mixin-save-queuing.umd.min.js.map +0 -1
  220. package/bundles/breeze-client.umd.js +0 -14098
  221. package/bundles/breeze-client.umd.js.map +0 -1
  222. package/bundles/breeze-client.umd.min.js +0 -16
  223. package/bundles/breeze-client.umd.min.js.map +0 -1
  224. package/esm2015/adapter-ajax-angularjs/adapter-ajax-angularjs.js +0 -130
  225. package/esm2015/adapter-ajax-angularjs/adapter-core.js +0 -49
  226. package/esm2015/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.js +0 -5
  227. package/esm2015/adapter-ajax-fetch/adapter-ajax-fetch.js +0 -130
  228. package/esm2015/adapter-ajax-fetch/adapter-core.js +0 -49
  229. package/esm2015/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.js +0 -5
  230. package/esm2015/adapter-ajax-httpclient/adapter-ajax-httpclient.js +0 -137
  231. package/esm2015/adapter-ajax-httpclient/adapter-core.js +0 -49
  232. package/esm2015/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.js +0 -5
  233. package/esm2015/adapter-ajax-jquery/adapter-ajax-jquery.js +0 -103
  234. package/esm2015/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.js +0 -5
  235. package/esm2015/adapter-ajax-post/adapter-ajax-post.js +0 -77
  236. package/esm2015/adapter-ajax-post/breeze-client-adapter-ajax-post.js +0 -5
  237. package/esm2015/adapter-data-service-odata/adapter-core.js +0 -49
  238. package/esm2015/adapter-data-service-odata/adapter-data-service-odata.js +0 -459
  239. package/esm2015/adapter-data-service-odata/breeze-client-adapter-data-service-odata.js +0 -5
  240. package/esm2015/adapter-data-service-webapi/adapter-data-service-webapi.js +0 -93
  241. package/esm2015/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.js +0 -5
  242. package/esm2015/adapter-model-library-backing-store/adapter-model-library-backing-store.js +0 -268
  243. package/esm2015/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.js +0 -5
  244. package/esm2015/adapter-model-library-ko/adapter-model-library-ko.js +0 -240
  245. package/esm2015/adapter-model-library-ko/breeze-client-adapter-model-library-ko.js +0 -5
  246. package/esm2015/adapter-uri-builder-json/adapter-core.js +0 -49
  247. package/esm2015/adapter-uri-builder-json/adapter-uri-builder-json.js +0 -36
  248. package/esm2015/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.js +0 -5
  249. package/esm2015/adapter-uri-builder-odata/adapter-core.js +0 -49
  250. package/esm2015/adapter-uri-builder-odata/adapter-uri-builder-odata.js +0 -192
  251. package/esm2015/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.js +0 -5
  252. package/esm2015/breeze-client.js +0 -9
  253. package/esm2015/index.js +0 -2
  254. package/esm2015/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.js +0 -5
  255. package/esm2015/mixin-get-entity-graph/mixin-get-entity-graph.js +0 -269
  256. package/esm2015/mixin-save-queuing/breeze-client-mixin-save-queuing.js +0 -5
  257. package/esm2015/mixin-save-queuing/mixin-save-queuing.js +0 -400
  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 -709
  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 -460
  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/src/abstract-data-service-adapter.js +0 -302
  328. package/esm5/src/array.js +0 -4
  329. package/esm5/src/assert-param.js +0 -317
  330. package/esm5/src/breeze.js +0 -85
  331. package/esm5/src/complex-array.js +0 -119
  332. package/esm5/src/config.js +0 -228
  333. package/esm5/src/core.js +0 -717
  334. package/esm5/src/csdl-metadata-parser.js +0 -385
  335. package/esm5/src/data-service.js +0 -207
  336. package/esm5/src/data-type.js +0 -451
  337. package/esm5/src/default-property-interceptor.js +0 -460
  338. package/esm5/src/entity-action.js +0 -52
  339. package/esm5/src/entity-aspect.js +0 -812
  340. package/esm5/src/entity-group.js +0 -189
  341. package/esm5/src/entity-key.js +0 -118
  342. package/esm5/src/entity-manager.js +0 -2112
  343. package/esm5/src/entity-metadata.js +0 -2144
  344. package/esm5/src/entity-query.js +0 -1023
  345. package/esm5/src/entity-state.js +0 -106
  346. package/esm5/src/enum.js +0 -144
  347. package/esm5/src/event.js +0 -259
  348. package/esm5/src/interface-registry.js +0 -43
  349. package/esm5/src/key-generator.js +0 -111
  350. package/esm5/src/local-query-comparison-options.js +0 -67
  351. package/esm5/src/mapping-context.js +0 -407
  352. package/esm5/src/naming-convention.js +0 -90
  353. package/esm5/src/observable-array.js +0 -201
  354. package/esm5/src/predicate.js +0 -1300
  355. package/esm5/src/primitive-array.js +0 -87
  356. package/esm5/src/query-options.js +0 -167
  357. package/esm5/src/relation-array.js +0 -175
  358. package/esm5/src/save-options.js +0 -43
  359. package/esm5/src/unattached-children-map.js +0 -60
  360. package/esm5/src/validate.js +0 -996
  361. package/esm5/src/validation-options.js +0 -66
  362. package/fesm2015/breeze-client-adapter-ajax-angularjs.js.map +0 -1
  363. package/fesm2015/breeze-client-adapter-ajax-fetch.js.map +0 -1
  364. package/fesm2015/breeze-client-adapter-ajax-httpclient.js.map +0 -1
  365. package/fesm2015/breeze-client-adapter-ajax-jquery.js.map +0 -1
  366. package/fesm2015/breeze-client-adapter-ajax-post.js.map +0 -1
  367. package/fesm2015/breeze-client-adapter-data-service-odata.js.map +0 -1
  368. package/fesm2015/breeze-client-adapter-data-service-webapi.js.map +0 -1
  369. package/fesm2015/breeze-client-adapter-model-library-backing-store.js.map +0 -1
  370. package/fesm2015/breeze-client-adapter-model-library-ko.js.map +0 -1
  371. package/fesm2015/breeze-client-adapter-uri-builder-json.js.map +0 -1
  372. package/fesm2015/breeze-client-adapter-uri-builder-odata.js.map +0 -1
  373. package/fesm2015/breeze-client-mixin-get-entity-graph.js.map +0 -1
  374. package/fesm2015/breeze-client-mixin-save-queuing.js.map +0 -1
  375. package/fesm2015/breeze-client.js.map +0 -1
  376. package/fesm5/breeze-client-adapter-ajax-angularjs.js.map +0 -1
  377. package/fesm5/breeze-client-adapter-ajax-fetch.js.map +0 -1
  378. package/fesm5/breeze-client-adapter-ajax-httpclient.js.map +0 -1
  379. package/fesm5/breeze-client-adapter-ajax-jquery.js.map +0 -1
  380. package/fesm5/breeze-client-adapter-ajax-post.js.map +0 -1
  381. package/fesm5/breeze-client-adapter-data-service-odata.js.map +0 -1
  382. package/fesm5/breeze-client-adapter-data-service-webapi.js.map +0 -1
  383. package/fesm5/breeze-client-adapter-model-library-backing-store.js.map +0 -1
  384. package/fesm5/breeze-client-adapter-model-library-ko.js.map +0 -1
  385. package/fesm5/breeze-client-adapter-uri-builder-json.js +0 -92
  386. package/fesm5/breeze-client-adapter-uri-builder-json.js.map +0 -1
  387. package/fesm5/breeze-client-adapter-uri-builder-odata.js +0 -250
  388. package/fesm5/breeze-client-adapter-uri-builder-odata.js.map +0 -1
  389. package/fesm5/breeze-client-mixin-get-entity-graph.js.map +0 -1
  390. package/fesm5/breeze-client-mixin-save-queuing.js.map +0 -1
  391. package/fesm5/breeze-client.js.map +0 -1
  392. package/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.metadata.json +0 -1
  393. package/mixin-get-entity-graph/package.json +0 -13
  394. package/mixin-save-queuing/breeze-client-mixin-save-queuing.metadata.json +0 -1
  395. package/mixin-save-queuing/package.json +0 -13
@@ -0,0 +1,806 @@
1
+ import { core } from './core';
2
+ import { config } from './config';
3
+ import { BreezeEvent } from './event';
4
+ import { assertParam } from './assert-param';
5
+ import { EntityState } from './entity-state';
6
+ import { EntityAction } from './entity-action';
7
+ import { EntityType } from './entity-metadata';
8
+ import { EntityKey } from './entity-key';
9
+ import { Validator, ValidationError } from './validate';
10
+ import { EntityQuery } from './entity-query';
11
+ /**
12
+ An EntityAspect instance is associated with every attached entity and is accessed via the entity's 'entityAspect' property.
13
+
14
+ The EntityAspect itself provides properties to determine and modify the EntityState of the entity and has methods
15
+ that provide a variety of services including validation and change tracking.
16
+
17
+ An EntityAspect will almost never need to be constructed directly. You will usually get an EntityAspect by accessing
18
+ an entities 'entityAspect' property. This property will be automatically attached when an entity is created via either
19
+ a query, import or [[EntityManager.createEntity]] call.
20
+ > // assume order is an order entity attached to an EntityManager.
21
+ > var aspect = order.entityAspect;
22
+ > var currentState = aspect.entityState;
23
+
24
+ **/
25
+ export class EntityAspect {
26
+ /** @hidden @internal */
27
+ constructor(entity) {
28
+ // if called without new
29
+ // if (!(this instanceof EntityAspect)) {
30
+ // return new EntityAspect(entity);
31
+ // }
32
+ /**
33
+ Sets the entity to an EntityState of 'Unchanged'. This is also the equivalent of calling [[EntityAspect.acceptChanges]].
34
+ The same operation can be performed by calling [[EntityAspect.setEntityState]].
35
+ > // assume order is an order entity attached to an EntityManager.
36
+ > order.entityAspect.setUnchanged();
37
+ > // The 'order' entity will now be in an 'Unchanged' state with any changes committed.
38
+ **/
39
+ this.setUnchanged = function () {
40
+ return this.setEntityState(EntityState.Unchanged);
41
+ };
42
+ /**
43
+ Sets the entity to an EntityState of 'Modified'. This can also be achieved by changing the value of any property on an 'Unchanged' entity.
44
+ The same operation can be performed by calling [[EntityAspect.setEntityState]].
45
+ > // assume order is an order entity attached to an EntityManager.
46
+ > order.entityAspect.setModified();
47
+ > // The 'order' entity will now be in a 'Modified' state.
48
+ **/
49
+ this.setModified = function () {
50
+ return this.setEntityState(EntityState.Modified);
51
+ };
52
+ /**
53
+ Sets the entity to an EntityState of 'Deleted'. This both marks the entity as being scheduled for deletion during the next 'Save' call
54
+ but also removes the entity from all of its related entities.
55
+ The same operation can be performed by calling [[EntityAspect.setEntityState]].
56
+ > // assume order is an order entity attached to an EntityManager.
57
+ > order.entityAspect.setDeleted();
58
+ > // The 'order' entity will now be in a 'Deleted' state and it will no longer have any 'related' entities.
59
+ **/
60
+ this.setDeleted = function () {
61
+ return this.setEntityState(EntityState.Deleted);
62
+ };
63
+ /**
64
+ Sets the entity to an EntityState of 'Detached'. This removes the entity from all of its related entities, but does NOT change the EntityState of any existing entities.
65
+ The same operation can be performed by calling [[EntityAspect.setEntityState]].
66
+ > // assume order is an order entity attached to an EntityManager.
67
+ > order.entityAspect.setDetached();
68
+ > // The 'order' entity will now be in a 'Detached' state and it will no longer have any 'related' entities.
69
+ **/
70
+ this.setDetached = function () {
71
+ return this.setEntityState(EntityState.Detached);
72
+ };
73
+ this.entity = entity;
74
+ // TODO: keep public or not?
75
+ this.entityGroup = undefined;
76
+ this.entityManager = undefined;
77
+ this.entityState = EntityState.Detached;
78
+ this.isBeingSaved = false;
79
+ this.originalValues = {};
80
+ this.hasValidationErrors = false;
81
+ this._validationErrors = {};
82
+ // Uncomment when we implement entityAspect.isNavigationPropertyLoaded method
83
+ // this._loadedNavPropMap = {};
84
+ this.validationErrorsChanged = new BreezeEvent("validationErrorsChanged", this);
85
+ this.propertyChanged = new BreezeEvent("propertyChanged", this);
86
+ // in case this is the NULL entityAspect. - used with ComplexAspects that have no parent.
87
+ if (entity != null) {
88
+ // remove properties that should be on prototype but placed on class by Babel
89
+ if (!entity.entityType) {
90
+ delete (entity.entityType);
91
+ }
92
+ if (!entity.entityAspect) {
93
+ delete (entity.entityAspect);
94
+ }
95
+ entity.entityAspect = this;
96
+ // entityType should already be on the entity from 'watch'
97
+ let entityType = entity.entityType || entity._$entityType;
98
+ if (!entityType) {
99
+ let typeName = entity.prototype._$typeName;
100
+ if (!typeName) {
101
+ throw new Error("This entity is not registered as a valid EntityType");
102
+ }
103
+ else {
104
+ throw new Error("Metadata for this entityType has not yet been resolved: " + typeName);
105
+ }
106
+ }
107
+ let entityCtor = entityType.getEntityCtor();
108
+ config.interfaceRegistry.modelLibrary.getDefaultInstance().startTracking(entity, entityCtor.prototype);
109
+ }
110
+ }
111
+ /** @hidden */
112
+ // type-guard
113
+ static isEntity(obj) {
114
+ return obj.entityAspect != null;
115
+ }
116
+ // No longer used
117
+ // static createFrom(entity: Entity): EntityAspect {
118
+ // if (entity == null) {
119
+ // return EntityAspect._nullInstance;
120
+ // } else if (entity.entityAspect) {
121
+ // return entity.entityAspect;
122
+ // }
123
+ // return new EntityAspect(entity);
124
+ // }
125
+ // TODO: refactor this and the instance getPropertyValue method.
126
+ /**
127
+ Returns the value of a specified 'property path' for a specified entity.
128
+
129
+ The propertyPath can be either a string delimited with '.' or a string array.
130
+ **/
131
+ // used by EntityQuery and Predicate
132
+ static getPropertyPathValue(obj, propertyPath) {
133
+ let properties = Array.isArray(propertyPath) ? propertyPath : propertyPath.split(".");
134
+ if (properties.length === 1) {
135
+ return obj.getProperty(propertyPath);
136
+ }
137
+ else {
138
+ let nextValue = obj;
139
+ // hack use of some to perform mapFirst operation.
140
+ properties.some((prop) => {
141
+ nextValue = nextValue.getProperty(prop);
142
+ return nextValue == null;
143
+ });
144
+ return nextValue;
145
+ }
146
+ }
147
+ /**
148
+ Returns the [[EntityKey]] for this Entity.
149
+ > // assume order is an order entity attached to an EntityManager.
150
+ > var entityKey = order.entityAspect.getKey();
151
+ @param forceRefresh - (boolean=false) Forces the recalculation of the key. This should normally be unnecessary.
152
+ @return The [[EntityKey]] associated with this Entity.
153
+ **/
154
+ getKey(forceRefresh = false) {
155
+ forceRefresh = assertParam(forceRefresh, "forceRefresh").isBoolean().isOptional().check(false);
156
+ if (forceRefresh || !this._entityKey) {
157
+ let entityType = this.entity.entityType;
158
+ let keyProps = entityType.keyProperties;
159
+ let values = keyProps.map(function (p) {
160
+ return this.entity.getProperty(p.name);
161
+ }, this);
162
+ this._entityKey = new EntityKey(entityType, values);
163
+ }
164
+ return this._entityKey;
165
+ }
166
+ /**
167
+ Returns the entity to an [[EntityState]] of 'Unchanged' by committing all changes made since the entity was last queried
168
+ had 'acceptChanges' called on it.
169
+ > // assume order is an order entity attached to an EntityManager.
170
+ > order.entityAspect.acceptChanges();
171
+ > // The 'order' entity will now be in an 'Unchanged' state with any changes committed.
172
+ **/
173
+ acceptChanges() {
174
+ if (!this.entity)
175
+ return;
176
+ this._checkOperation("acceptChanges");
177
+ let em = this.entityManager;
178
+ if (this.entityState.isDeleted()) {
179
+ em.detachEntity(this.entity);
180
+ }
181
+ else {
182
+ this.setUnchanged();
183
+ }
184
+ em.entityChanged.publish({ entityAction: EntityAction.AcceptChanges, entity: this.entity });
185
+ }
186
+ /**
187
+ Returns the entity to an [[EntityState]] of 'Unchanged' by rejecting all changes made to it since the entity was last queried
188
+ had 'rejectChanges' called on it.
189
+ > // assume order is an order entity attached to an EntityManager.
190
+ > order.entityAspect.rejectChanges();
191
+ > // The 'order' entity will now be in an 'Unchanged' state with any changes rejected.
192
+ **/
193
+ rejectChanges() {
194
+ this._checkOperation("rejectChanges");
195
+ let entity = this.entity;
196
+ let entityManager = this.entityManager;
197
+ // we do not want PropertyChange or EntityChange events to occur here
198
+ core.using(entityManager, "isRejectingChanges", true, function () {
199
+ rejectChangesCore(entity);
200
+ });
201
+ if (this.entityState.isAdded()) {
202
+ // next line is needed because the following line will cause this.entityManager -> null;
203
+ entityManager.detachEntity(entity);
204
+ // need to tell em that an entity that needed to be saved no longer does.
205
+ entityManager._notifyStateChange(entity, false);
206
+ }
207
+ else {
208
+ if (this.entityState.isDeleted()) {
209
+ entityManager._linkRelatedEntities(entity);
210
+ }
211
+ this.setUnchanged();
212
+ // propertyChanged propertyName is not specified because more than one property may have changed.
213
+ this.propertyChanged.publish({ entity: entity, propertyName: null });
214
+ entityManager.entityChanged.publish({ entityAction: EntityAction.RejectChanges, entity: entity });
215
+ }
216
+ }
217
+ /** @hidden @internal */
218
+ // TODO: rename - and use '_'; used on both EntityAspect and ComplexAspect for polymorphic reasons.
219
+ getPropertyPath(propName) {
220
+ return propName;
221
+ }
222
+ /**
223
+ Sets the entity to an EntityState of 'Added'. This is NOT the equivalent of calling [[EntityManager.addEntity]]
224
+ because no key generation will occur for autogenerated keys as a result of this operation. As a result this operation can be problematic
225
+ unless you are certain that the entity being marked 'Added' does not already exist in the database and does not have an autogenerated key.
226
+ The same operation can be performed by calling [[EntityAspect.setEntityState]].
227
+ > // assume order is an order entity attached to an EntityManager.
228
+ > order.entityAspect.setAdded();
229
+ > // The 'order' entity will now be in an 'Added' state.
230
+ **/
231
+ setAdded() {
232
+ return this.setEntityState(EntityState.Added);
233
+ }
234
+ /**
235
+ Sets the entity to the specified EntityState. See also 'setUnchanged', 'setModified', 'setDetached', etc.
236
+ > // assume order is an order entity attached to an EntityManager.
237
+ > order.entityAspect.setEntityState(EntityState.Unchanged);
238
+ > // The 'order' entity will now be in a 'Unchanged' state.
239
+ **/
240
+ setEntityState(entityState) {
241
+ if (this.entityState === entityState)
242
+ return false;
243
+ this._checkOperation("setEntityState");
244
+ if (this.entityState.isDetached()) {
245
+ throw new Error("You cannot set the 'entityState' of an entity when it is detached - except by first attaching it to an EntityManager");
246
+ }
247
+ let entity = this.entity;
248
+ let em = this.entityManager;
249
+ let needsSave = true;
250
+ if (entityState === EntityState.Unchanged) {
251
+ clearOriginalValues(entity);
252
+ delete this.hasTempKey;
253
+ needsSave = false;
254
+ }
255
+ else if (entityState === EntityState.Added) {
256
+ clearOriginalValues(entity);
257
+ // TODO: more to do here... like regenerating key ???
258
+ }
259
+ else if (entityState === EntityState.Deleted) {
260
+ if (this.entityState.isAdded()) {
261
+ // turn it into a detach and exit early
262
+ this.setEntityState(EntityState.Detached);
263
+ return true;
264
+ }
265
+ else {
266
+ // TODO: think about cascade deletes
267
+ // entityState needs to be set it early in this one case to insure that fk's are not cleared.
268
+ this.entityState = EntityState.Deleted;
269
+ removeFromRelations(entity, EntityState.Deleted);
270
+ }
271
+ }
272
+ else if (entityState === EntityState.Modified) {
273
+ // nothing extra needed
274
+ }
275
+ else if (entityState === EntityState.Detached) {
276
+ let group = this.entityGroup;
277
+ // no group === already detached.
278
+ if (!group)
279
+ return false;
280
+ group.detachEntity(entity);
281
+ // needs to occur early here - so this IS deliberately redundent with the same code later in this method.
282
+ this.entityState = entityState;
283
+ removeFromRelations(entity, EntityState.Detached);
284
+ this._detach();
285
+ em.entityChanged.publish({ entityAction: EntityAction.Detach, entity: entity });
286
+ needsSave = false;
287
+ }
288
+ this.entityState = entityState;
289
+ em._notifyStateChange(entity, needsSave);
290
+ return true;
291
+ }
292
+ /**
293
+ Performs a query for the value of a specified [[NavigationProperty]]. __Async__
294
+ > emp.entityAspect.loadNavigationProperty("Orders").then(function (data) {
295
+ > var orders = data.results;
296
+ > }).catch(function (exception) {
297
+ > // handle exception here;
298
+ > });
299
+ @param navigationProperty - The NavigationProperty or the name of the NavigationProperty to 'load'.
300
+ @param callback - Function to call on success.
301
+ @param errorCallback - Function to call on failure.
302
+ @return Promise with shape
303
+ - results {Array of Entity}
304
+ - query {EntityQuery} The original query
305
+ - httpResponse {httpResponse} The HttpResponse returned from the server.
306
+ **/
307
+ loadNavigationProperty(navigationProperty, callback, errorCallback) {
308
+ let entity = this.entity;
309
+ let navProperty = entity.entityType._checkNavProperty(navigationProperty);
310
+ let query = EntityQuery.fromEntityNavigation(entity, navProperty);
311
+ // return entity.entityAspect.entityManager.executeQuery(query, callback, errorCallback);
312
+ let promise = entity.entityAspect.entityManager.executeQuery(query);
313
+ return promise.then((data) => {
314
+ this._markAsLoaded(navProperty.name);
315
+ if (callback)
316
+ callback(data);
317
+ return Promise.resolve(data);
318
+ }, (error) => {
319
+ if (errorCallback)
320
+ errorCallback(error);
321
+ return Promise.reject(error);
322
+ });
323
+ }
324
+ /**
325
+ Marks this navigationProperty on this entity as already having been loaded.
326
+ > emp.entityAspect.markNavigationPropertyAsLoaded("Orders");
327
+ @param navigationProperty - The NavigationProperty or name of NavigationProperty to 'load'.
328
+ **/
329
+ markNavigationPropertyAsLoaded(navigationProperty) {
330
+ if (!this.entity)
331
+ return;
332
+ let navProperty = this.entity.entityType._checkNavProperty(navigationProperty);
333
+ this._markAsLoaded(navProperty.name);
334
+ }
335
+ /**
336
+ Determines whether a navigationProperty on this entity has already been loaded.
337
+
338
+ A navigation property is considered loaded when any of the following three conditions applies:
339
+
340
+ 1. It was fetched from the backend server.
341
+ <br/> This can be the result of an expand query or a call to the [[EntityAspect.loadNavigationProperty]] method.
342
+ <br/> Note that even if the fetch returns nothing the property is still marked as loaded in this case.
343
+ 1. The property is scalar and has been set to a nonnull value.
344
+ 1. The [[EntityAspect.markNavigationPropertyAsLoaded]] was called.
345
+
346
+ > var wasLoaded = emp.entityAspect.isNavigationPropertyLoaded("Orders");
347
+ @param navigationProperty - The NavigationProperty or name of NavigationProperty to 'load'.
348
+ **/
349
+ isNavigationPropertyLoaded(navigationProperty) {
350
+ if (!this.entity)
351
+ return;
352
+ let navProperty = this.entity.entityType._checkNavProperty(navigationProperty);
353
+ if (navProperty.isScalar && this.entity.getProperty(navProperty.name) != null) {
354
+ return true;
355
+ }
356
+ return this._loadedNps && this._loadedNps.indexOf(navProperty.name) >= 0;
357
+ }
358
+ /** @hidden @internal */
359
+ _markAsLoaded(navPropName) {
360
+ this._loadedNps = this._loadedNps || [];
361
+ core.arrayAddItemUnique(this._loadedNps, navPropName);
362
+ }
363
+ /**
364
+ Performs validation on the entity, any errors encountered during the validation are available via the
365
+ [[EntityAspect.getValidationErrors]] method. Validating an entity means executing
366
+ all of the validators on both the entity itself as well as those on each of its properties.
367
+ > // assume order is an order entity attached to an EntityManager.
368
+ > var isOk = order.entityAspect.validateEntity();
369
+ > // isOk will be 'true' if there are no errors on the entity.
370
+ > if (!isOk) {
371
+ > var errors = order.entityAspect.getValidationErrors();
372
+ > }
373
+ @return Whether the entity passed validation.
374
+ **/
375
+ validateEntity() {
376
+ let ok = true;
377
+ this._processValidationOpAndPublish(function (that) {
378
+ ok = validateTarget(that.entity);
379
+ });
380
+ return ok;
381
+ }
382
+ /**
383
+ Performs validation on a specific property of this entity, any errors encountered during the validation are available via the
384
+ [[EntityAspect.getValidationErrors]] method. Validating a property means executing
385
+ all of the validators on the specified property. This call is also made automatically anytime a property
386
+ of an entity is changed.
387
+ > // assume order is an order entity attached to an EntityManager.
388
+ > var isOk = order.entityAspect.validateProperty("Order");
389
+
390
+ or
391
+ > var orderDateProperty = order.entityType.getProperty("OrderDate");
392
+ > var isOk = order.entityAspect.validateProperty(OrderDateProperty);
393
+ @param property - The [[DataProperty]] or [[NavigationProperty]] to validate or a string
394
+ with the name of the property or a property path with the path to a property of a complex object.
395
+ @param context - A context object used to pass additional information to each [[Validator]].
396
+ @return Whether the entity passed validation.
397
+ **/
398
+ validateProperty(property, context) {
399
+ let value = this.getPropertyValue(property); // performs validations
400
+ if (value && value.complexAspect) {
401
+ return validateTarget(value);
402
+ }
403
+ context = context || {};
404
+ context.entity = this.entity;
405
+ if (typeof property === "string") {
406
+ context.property = this.entity.entityType.getProperty(property, true);
407
+ context.propertyName = property;
408
+ }
409
+ else {
410
+ context.property = property;
411
+ context.propertyName = property.name;
412
+ }
413
+ return this._validateProperty(value, context);
414
+ }
415
+ /**
416
+ Returns the validation errors associated with either the entire entity or any specified property.
417
+
418
+ This method can return all of the errors for an Entity
419
+ > // assume order is an order entity attached to an EntityManager.
420
+ > var valErrors = order.entityAspect.getValidationErrors();
421
+
422
+ as well as those for just a specific property.
423
+ > // assume order is an order entity attached to an EntityManager.
424
+ > var orderDateErrors = order.entityAspect.getValidationErrors("OrderDate");
425
+
426
+ which can also be expressed as
427
+ > // assume order is an order entity attached to an EntityManager.
428
+ > var orderDateProperty = order.entityType.getProperty("OrderDate");
429
+ > var orderDateErrors = order.entityAspect.getValidationErrors(orderDateProperty);
430
+ @param property - The property for which validation errors should be retrieved.
431
+ If omitted, all of the validation errors for this entity will be returned.
432
+ @return A array of validation errors.
433
+ **/
434
+ getValidationErrors(property) {
435
+ assertParam(property, "property").isOptional().isEntityProperty().or().isString().check();
436
+ let result = core.getOwnPropertyValues(this._validationErrors);
437
+ if (property) {
438
+ let propertyName = typeof (property) === 'string' ? property : property.name;
439
+ result = result.filter(function (ve) {
440
+ return ve.property && (ve.property.name === propertyName || (propertyName.indexOf(".") !== -1 && ve.propertyName === propertyName));
441
+ });
442
+ }
443
+ return result;
444
+ }
445
+ /**
446
+ Adds a validation error.
447
+ **/
448
+ addValidationError(validationError) {
449
+ assertParam(validationError, "validationError").isInstanceOf(ValidationError).check();
450
+ this._processValidationOpAndPublish(function (that) {
451
+ that._addValidationError(validationError);
452
+ });
453
+ }
454
+ /**
455
+ Removes a validation error.
456
+ @param validationErrorOrKey - Either a ValidationError or a ValidationError 'key' value
457
+ **/
458
+ removeValidationError(validationErrorOrKey) {
459
+ assertParam(validationErrorOrKey, "validationErrorOrKey").isString().or().isInstanceOf(ValidationError).or().isInstanceOf(Validator).check();
460
+ let key = (typeof (validationErrorOrKey) === "string") ? validationErrorOrKey : validationErrorOrKey.key;
461
+ this._processValidationOpAndPublish(function (that) {
462
+ that._removeValidationError(key);
463
+ });
464
+ }
465
+ /**
466
+ Removes all of the validation errors for a specified entity
467
+ **/
468
+ clearValidationErrors() {
469
+ this._processValidationOpAndPublish(function (that) {
470
+ core.objectForEach(that._validationErrors, function (key, valError) {
471
+ if (valError) {
472
+ delete that._validationErrors[key];
473
+ that._pendingValidationResult.removed.push(valError);
474
+ }
475
+ });
476
+ that.hasValidationErrors = !core.isEmpty(that._validationErrors);
477
+ });
478
+ }
479
+ /**
480
+ Returns an [[EntityKey]] for the entity pointed to by the specified scalar NavigationProperty.
481
+ This only returns an EntityKey if the current entity is a 'child' entity along the specified NavigationProperty.
482
+ i.e. has a single parent.
483
+
484
+ @param navigationProperty - The [[NavigationProperty]] ( pointing to a parent).
485
+ @returns Either a parent EntityKey if this is a 'child' entity or null;
486
+ */
487
+ getParentKey(navigationProperty) {
488
+ if (!this.entity)
489
+ return null;
490
+ // TODO: review this - not sure about the comment.
491
+ // NavigationProperty doesn't yet exist
492
+ // assertParam(navigationProperty, "navigationProperty").isInstanceOf(NavigationProperty).check();
493
+ let fkNames = navigationProperty.foreignKeyNames;
494
+ if (fkNames.length === 0)
495
+ return null;
496
+ let that = this;
497
+ let fkValues = fkNames.map(function (fkn) {
498
+ return that.entity.getProperty(fkn);
499
+ });
500
+ return new EntityKey(navigationProperty.entityType, fkValues);
501
+ }
502
+ // TODO: refactor this and the static getPropertyPathValue.
503
+ /**
504
+ Returns the value of a specified DataProperty or NavigationProperty or 'property path'.
505
+ **/
506
+ getPropertyValue(property) {
507
+ assertParam(property, "property").isString().or().isEntityProperty().check();
508
+ let value;
509
+ if (typeof (property) === 'string') {
510
+ let propNames = property.trim().split(".");
511
+ let propName = propNames.shift();
512
+ value = this.entity;
513
+ value = value.getProperty(propName);
514
+ while (propNames.length > 0) {
515
+ propName = propNames.shift();
516
+ value = value.getProperty(propName);
517
+ }
518
+ }
519
+ else {
520
+ if (!(property.parentType instanceof EntityType)) {
521
+ throw new Error("The validateProperty method does not accept a 'property' parameter whose parentType is a ComplexType; " +
522
+ "Pass a 'property path' string as the 'property' parameter instead ");
523
+ }
524
+ value = this.entity.getProperty(property.name);
525
+ }
526
+ return value;
527
+ }
528
+ // internal methods
529
+ /** @hidden @internal */
530
+ _checkOperation(operationName) {
531
+ if (this.isBeingSaved) {
532
+ throw new Error("Cannot perform a '" + operationName + "' on an entity that is in the process of being saved");
533
+ }
534
+ // allows chaining
535
+ return this;
536
+ }
537
+ /** @hidden @internal */
538
+ _detach() {
539
+ this.entityGroup = undefined;
540
+ this.entityManager = undefined;
541
+ this.entityState = EntityState.Detached;
542
+ this.originalValues = {};
543
+ this._validationErrors = {};
544
+ this.hasValidationErrors = false;
545
+ this.validationErrorsChanged.clear();
546
+ this.propertyChanged.clear();
547
+ }
548
+ // called from defaultInterceptor.
549
+ /** @hidden @internal */
550
+ _validateProperty(value, context) {
551
+ let ok = true;
552
+ this._processValidationOpAndPublish(function (that) {
553
+ context.property.getAllValidators().forEach(function (validator) {
554
+ ok = validate(that, validator, value, context) && ok;
555
+ });
556
+ });
557
+ return ok;
558
+ }
559
+ /** @hidden @internal */
560
+ _processValidationOpAndPublish(validationFn) {
561
+ if (this._pendingValidationResult) {
562
+ // only top level processValidations call publishes
563
+ validationFn(this);
564
+ }
565
+ else {
566
+ try {
567
+ this._pendingValidationResult = { entity: this.entity, added: [], removed: [] };
568
+ validationFn(this);
569
+ if (this._pendingValidationResult.added.length > 0 || this._pendingValidationResult.removed.length > 0) {
570
+ this.validationErrorsChanged.publish(this._pendingValidationResult);
571
+ // this might be a detached entity hence the guard below.
572
+ this.entityManager && this.entityManager.validationErrorsChanged.publish(this._pendingValidationResult);
573
+ }
574
+ }
575
+ finally {
576
+ this._pendingValidationResult = undefined;
577
+ }
578
+ }
579
+ }
580
+ /** @hidden @internal */
581
+ // TODO: add/use a ValidationError type
582
+ _addValidationError(validationError) {
583
+ this._validationErrors[validationError.key] = validationError;
584
+ this.hasValidationErrors = true;
585
+ this._pendingValidationResult.added.push(validationError);
586
+ }
587
+ /** @hidden @internal */
588
+ _removeValidationError(key) {
589
+ let valError = this._validationErrors[key];
590
+ if (valError) {
591
+ delete this._validationErrors[key];
592
+ this.hasValidationErrors = !core.isEmpty(this._validationErrors);
593
+ this._pendingValidationResult.removed.push(valError);
594
+ }
595
+ }
596
+ }
597
+ /** @hidden @internal */
598
+ EntityAspect._nullInstance = new EntityAspect(); // TODO: determine if this works
599
+ BreezeEvent.bubbleEvent(EntityAspect.prototype, function () {
600
+ return this.entityManager;
601
+ });
602
+ function rejectChangesCore(target) {
603
+ let aspect = target.entityAspect || target.complexAspect;
604
+ let stype = target.entityType || target.complexType;
605
+ let originalValues = aspect.originalValues;
606
+ for (let propName in originalValues) {
607
+ target.setProperty(propName, originalValues[propName]);
608
+ }
609
+ stype.complexProperties.forEach(function (cp) {
610
+ let cos = target.getProperty(cp.name);
611
+ if (cp.isScalar) {
612
+ rejectChangesCore(cos);
613
+ }
614
+ else {
615
+ cos._rejectChanges();
616
+ cos.forEach(rejectChangesCore);
617
+ }
618
+ });
619
+ }
620
+ function removeFromRelations(entity, entityState) {
621
+ // remove this entity from any collections.
622
+ // mark the entity deleted or detached
623
+ let isDeleted = entityState.isDeleted();
624
+ if (isDeleted) {
625
+ removeFromRelationsCore(entity);
626
+ }
627
+ else {
628
+ core.using(entity.entityAspect.entityManager, "isLoading", true, function () {
629
+ removeFromRelationsCore(entity);
630
+ });
631
+ }
632
+ }
633
+ function removeFromRelationsCore(entity) {
634
+ entity.entityType.navigationProperties.forEach(function (np) {
635
+ let inverseNp = np.inverse;
636
+ let npValue = entity.getProperty(np.name);
637
+ if (np.isScalar) {
638
+ if (npValue) {
639
+ if (inverseNp) {
640
+ if (inverseNp.isScalar) {
641
+ npValue.setProperty(inverseNp.name, null);
642
+ }
643
+ else {
644
+ let collection = npValue.getProperty(inverseNp.name);
645
+ if (collection.length) {
646
+ core.arrayRemoveItem(collection, entity);
647
+ }
648
+ }
649
+ }
650
+ entity.setProperty(np.name, null);
651
+ }
652
+ }
653
+ else {
654
+ if (inverseNp != null) {
655
+ // npValue is a live list so we need to copy it first.
656
+ npValue.slice(0).forEach((v) => {
657
+ if (inverseNp.isScalar) {
658
+ v.setProperty(inverseNp.name, null);
659
+ }
660
+ else {
661
+ // TODO: many to many - not yet handled.
662
+ }
663
+ });
664
+ }
665
+ // now clear it.
666
+ npValue.length = 0;
667
+ }
668
+ });
669
+ }
670
+ // note entityAspect only - ( no complex aspect allowed on the call).
671
+ function validate(entityAspect, validator, value, context) {
672
+ let ve = validator.validate(value, context);
673
+ if (ve) {
674
+ entityAspect._addValidationError(ve);
675
+ return false;
676
+ }
677
+ else {
678
+ let key = ValidationError.getKey(validator, context ? context.propertyName : null);
679
+ entityAspect._removeValidationError(key);
680
+ return true;
681
+ }
682
+ }
683
+ // coIndex is only used where target is a complex object that is part of an array of complex objects
684
+ // in which case ctIndex is the index of the target within the array.
685
+ function validateTarget(target, coIndex) {
686
+ let ok = true;
687
+ let stype = target.entityType || target.complexType;
688
+ let aspect = target.entityAspect || target.complexAspect;
689
+ let entityAspect = target.entityAspect || target.complexAspect.getEntityAspect();
690
+ let context = { entity: entityAspect.entity };
691
+ if (coIndex !== undefined) {
692
+ context.index = coIndex;
693
+ }
694
+ stype.getProperties().forEach(function (p) {
695
+ let value = target.getProperty(p.name);
696
+ let validators = p.getAllValidators();
697
+ if (validators.length > 0) {
698
+ context.property = p;
699
+ context.propertyName = aspect.getPropertyPath(p.name);
700
+ ok = entityAspect._validateProperty(value, context) && ok;
701
+ }
702
+ if (p.isComplexProperty) {
703
+ if (p.isScalar) {
704
+ ok = validateTarget(value) && ok;
705
+ }
706
+ else {
707
+ ok = value.reduce(function (pv, cv, ix) {
708
+ return validateTarget(cv, ix) && pv;
709
+ }, ok);
710
+ }
711
+ }
712
+ });
713
+ // then target level
714
+ stype.getAllValidators().forEach(function (validator) {
715
+ ok = validate(entityAspect, validator, target) && ok;
716
+ });
717
+ return ok;
718
+ }
719
+ /**
720
+ An ComplexAspect instance is associated with every complex object instance and is accessed via the complex object's 'complexAspect' property.
721
+
722
+ The ComplexAspect itself provides properties to determine the parent object, parent property and original values for the complex object.
723
+
724
+ A ComplexAspect will almost never need to be constructed directly. You will usually get an ComplexAspect by accessing
725
+ an entities 'complexAspect' property. This property will be automatically attached when an complex object is created as part of an
726
+ entity via either a query, import or EntityManager.createEntity call.
727
+ > // assume address is a complex property on the 'Customer' type
728
+ > var aspect = aCustomer.address.complexAspect;
729
+ > // aCustomer === aspect.parent;
730
+ **/
731
+ export class ComplexAspect {
732
+ /** You will rarely, if ever, create a ComplexAspect directly. */
733
+ constructor(complexObject, parent, parentProperty) {
734
+ if (!complexObject) {
735
+ throw new Error("The ComplexAspect ctor requires an entity as its only argument.");
736
+ }
737
+ if (complexObject.complexAspect) {
738
+ return complexObject.complexAspect;
739
+ }
740
+ // if called without new
741
+ if (!(this instanceof ComplexAspect)) {
742
+ return new ComplexAspect(complexObject, parent, parentProperty);
743
+ }
744
+ // entityType should already be on the entity from 'watch'
745
+ this.complexObject = complexObject;
746
+ complexObject.complexAspect = this;
747
+ // TODO: keep public or not?
748
+ this.originalValues = {};
749
+ // if a standalone complexObject
750
+ if (parent != null) {
751
+ this.parent = parent;
752
+ this.parentProperty = parentProperty;
753
+ }
754
+ let complexType = complexObject.complexType;
755
+ if (!complexType) {
756
+ let typeName = complexObject.prototype._$typeName;
757
+ if (!typeName) {
758
+ throw new Error("This entity is not registered as a valid ComplexType");
759
+ }
760
+ else {
761
+ throw new Error("Metadata for this complexType has not yet been resolved: " + typeName);
762
+ }
763
+ }
764
+ let complexCtor = complexType.getCtor();
765
+ config.interfaceRegistry.modelLibrary.getDefaultInstance().startTracking(complexObject, complexCtor.prototype);
766
+ }
767
+ /**
768
+ Returns the EntityAspect for the top level entity that contains this complex object.
769
+ **/
770
+ getEntityAspect() {
771
+ let parent = this.parent;
772
+ if (!parent)
773
+ return new EntityAspect();
774
+ let entityAspect = parent.entityAspect;
775
+ while (parent && !entityAspect) {
776
+ parent = parent.complexAspect && parent.complexAspect.parent;
777
+ entityAspect = parent && parent.entityAspect;
778
+ }
779
+ return entityAspect || new EntityAspect();
780
+ }
781
+ /** @hidden @internal */
782
+ // TODO: rename - and use '_'; used on both EntityAspect and ComplexAspect for polymorphic reasons.
783
+ getPropertyPath(propName) {
784
+ let parent = this.parent;
785
+ if (!parent)
786
+ return null;
787
+ let aspect = parent.complexAspect || parent.entityAspect;
788
+ return aspect.getPropertyPath(this.parentProperty.name + "." + propName);
789
+ }
790
+ }
791
+ function clearOriginalValues(target) {
792
+ let aspect = target.entityAspect || target.complexAspect;
793
+ aspect.originalValues = {};
794
+ let stype = target.entityType || target.complexType;
795
+ stype.complexProperties.forEach(function (cp) {
796
+ let cos = target.getProperty(cp.name);
797
+ if (cp.isScalar) {
798
+ clearOriginalValues(cos);
799
+ }
800
+ else {
801
+ cos._acceptChanges();
802
+ cos.forEach(clearOriginalValues);
803
+ }
804
+ });
805
+ }
806
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LWFzcGVjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9lbnRpdHktYXNwZWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDOUIsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNsQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsV0FBVyxFQUFHLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxVQUFVLEVBQWlFLE1BQU0sbUJBQW1CLENBQUM7QUFDOUcsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUd6QyxPQUFPLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN4RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUF5QzdDOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxNQUFNLE9BQU8sWUFBWTtJQXNGdkIsd0JBQXdCO0lBQ3hCLFlBQVksTUFBZTtRQUV6Qix3QkFBd0I7UUFDeEIseUNBQXlDO1FBQ3pDLHFDQUFxQztRQUNyQyxJQUFJO1FBdUtOOzs7Ozs7V0FNRztRQUNILGlCQUFZLEdBQUc7WUFDYixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3BELENBQUMsQ0FBQztRQUdGOzs7Ozs7V0FNRztRQUNILGdCQUFXLEdBQUc7WUFDWixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ25ELENBQUMsQ0FBQztRQUVGOzs7Ozs7O1dBT0c7UUFD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RCxPQUFPLFlBQVksSUFBSSxJQUFJLFlBQVksRUFBRSxDQUFDO0lBQzVDLENBQUM7SUFFRCx5QkFBeUI7SUFDekIsbUdBQW1HO0lBQ25HLGVBQWUsQ0FBQyxRQUFnQjtRQUM5QixJQUFJLE1BQU0sR0FBUSxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzlCLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDekIsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLGFBQWEsSUFBSSxNQUFNLENBQUMsWUFBWSxDQUFDO1FBQ3pELE9BQU8sTUFBTSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsY0FBZSxDQUFDLElBQUksR0FBRyxHQUFHLEdBQUcsUUFBUSxDQUFDLENBQUM7SUFDNUUsQ0FBQztDQUVGO0FBRUQsU0FBUyxtQkFBbUIsQ0FBQyxNQUFXO0lBQ3RDLElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxZQUFZLElBQUksTUFBTSxDQUFDLGFBQWEsQ0FBQztJQUN6RCxNQUFNLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQztJQUMzQixJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsVUFBVSxJQUFJLE1BQU0sQ0FBQyxXQUFXLENBQUM7SUFDcEQsS0FBSyxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQU87UUFDL0MsSUFBSSxHQUFHLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFO1lBQ2YsbUJBQW1CLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDMUI7YUFBTTtZQUNMLEdBQUcsQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNyQixHQUFHLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQUM7U0FDbEM7SUFDSCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb3JlIH0gZnJvbSAnLi9jb3JlJztcclxuaW1wb3J0IHsgY29uZmlnIH0gZnJvbSAnLi9jb25maWcnO1xyXG5pbXBvcnQgeyBCcmVlemVFdmVudCB9IGZyb20gJy4vZXZlbnQnO1xyXG5pbXBvcnQgeyBhc3NlcnRQYXJhbSB9IGZyb20gJy4vYXNzZXJ0LXBhcmFtJztcclxuaW1wb3J0IHsgRW50aXR5U3RhdGUgIH0gZnJvbSAnLi9lbnRpdHktc3RhdGUnO1xyXG5pbXBvcnQgeyBFbnRpdHlBY3Rpb24gfSBmcm9tICcuL2VudGl0eS1hY3Rpb24nO1xyXG5pbXBvcnQgeyBFbnRpdHlUeXBlLCBDb21wbGV4VHlwZSwgRGF0YVByb3BlcnR5LCBOYXZpZ2F0aW9uUHJvcGVydHksIEVudGl0eVByb3BlcnR5IH0gZnJvbSAnLi9lbnRpdHktbWV0YWRhdGEnO1xyXG5pbXBvcnQgeyBFbnRpdHlLZXkgfSBmcm9tICcuL2VudGl0eS1rZXknO1xyXG5pbXBvcnQgeyBFbnRpdHlHcm91cCB9IGZyb20gJy4vZW50aXR5LWdyb3VwJztcclxuaW1wb3J0IHsgRW50aXR5TWFuYWdlciwgUXVlcnlSZXN1bHQsIFF1ZXJ5RXJyb3JDYWxsYmFjaywgUXVlcnlTdWNjZXNzQ2FsbGJhY2sgfSBmcm9tICcuL2VudGl0eS1tYW5hZ2VyJztcclxuaW1wb3J0IHsgVmFsaWRhdG9yLCBWYWxpZGF0aW9uRXJyb3IgfSBmcm9tICcuL3ZhbGlkYXRlJztcclxuaW1wb3J0IHsgRW50aXR5UXVlcnkgfSBmcm9tICcuL2VudGl0eS1xdWVyeSc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEVudGl0eSB7XHJcbiAgZW50aXR5QXNwZWN0OiBFbnRpdHlBc3BlY3Q7XHJcbiAgZW50aXR5VHlwZTogRW50aXR5VHlwZTtcclxuICAvKiogQGludGVybmFsICovXHJcbiAgZ2V0UHJvcGVydHk/KHByb3A6IHN0cmluZyk6IGFueTtcclxuICAvKiogQGludGVybmFsICovXHJcbiAgc2V0UHJvcGVydHk/KHByb3A6IGFueSwgdmFsdWU6IGFueSk6IHZvaWQ7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgcHJvdG90eXBlPzogeyBfJHR5cGVOYW1lOiBzdHJpbmcgfTtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfJGVudGl0eVR5cGU/OiBFbnRpdHlUeXBlO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIENvbXBsZXhPYmplY3Qge1xyXG4gIGNvbXBsZXhBc3BlY3Q6IENvbXBsZXhBc3BlY3Q7XHJcbiAgY29tcGxleFR5cGU6IENvbXBsZXhUeXBlO1xyXG4gIGdldFByb3BlcnR5Pyhwcm9wOiBzdHJpbmcpOiBhbnk7XHJcbiAgc2V0UHJvcGVydHk/KHByb3A6IGFueSwgdmFsdWU6IGFueSk6IHZvaWQ7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgcHJvdG90eXBlPzogeyBfJHR5cGVOYW1lOiBzdHJpbmcgfTtcclxufVxyXG5cclxuZXhwb3J0IHR5cGUgU3RydWN0dXJhbE9iamVjdCA9IEVudGl0eSB8IENvbXBsZXhPYmplY3Q7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFByb3BlcnR5Q2hhbmdlZEV2ZW50QXJncyB7XHJcbiAgZW50aXR5OiBFbnRpdHk7XHJcbiAgcHJvcGVydHlOYW1lOiBzdHJpbmcgfCBudWxsO1xyXG4gIHBhcmVudD86IFN0cnVjdHVyYWxPYmplY3Q7XHJcbiAgcHJvcGVydHk/OiBFbnRpdHlQcm9wZXJ0eTtcclxuICBvbGRWYWx1ZT86IGFueTtcclxuICBuZXdWYWx1ZT86IGFueTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0aW9uRXJyb3JzQ2hhbmdlZEV2ZW50QXJncyB7XHJcbiAgZW50aXR5OiBFbnRpdHk7XHJcbiAgYWRkZWQ6IFZhbGlkYXRpb25FcnJvcltdO1xyXG4gIHJlbW92ZWQ6IFZhbGlkYXRpb25FcnJvcltdO1xyXG59XHJcblxyXG4vKipcclxuQW4gRW50aXR5QXNwZWN0IGluc3RhbmNlIGlzIGFzc29jaWF0ZWQgd2l0aCBldmVyeSBhdHRhY2hlZCBlbnRpdHkgYW5kIGlzIGFjY2Vzc2VkIHZpYSB0aGUgZW50aXR5J3MgJ2VudGl0eUFzcGVjdCcgcHJvcGVydHkuXHJcblxyXG5UaGUgRW50aXR5QXNwZWN0IGl0c2VsZiBwcm92aWRlcyBwcm9wZXJ0aWVzIHRvIGRldGVybWluZSBhbmQgbW9kaWZ5IHRoZSBFbnRpdHlTdGF0ZSBvZiB0aGUgZW50aXR5IGFuZCBoYXMgbWV0aG9kc1xyXG50aGF0IHByb3ZpZGUgYSB2YXJpZXR5IG9mIHNlcnZpY2VzIGluY2x1ZGluZyB2YWxpZGF0aW9uIGFuZCBjaGFuZ2UgdHJhY2tpbmcuXHJcblxyXG5BbiBFbnRpdHlBc3BlY3Qgd2lsbCBhbG1vc3QgbmV2ZXIgbmVlZCB0byBiZSBjb25zdHJ1Y3RlZCBkaXJlY3RseS4gWW91IHdpbGwgdXN1YWxseSBnZXQgYW4gRW50aXR5QXNwZWN0IGJ5IGFjY2Vzc2luZ1xyXG5hbiBlbnRpdGllcyAnZW50aXR5QXNwZWN0JyBwcm9wZXJ0eS4gIFRoaXMgcHJvcGVydHkgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGF0dGFjaGVkIHdoZW4gYW4gZW50aXR5IGlzIGNyZWF0ZWQgdmlhIGVpdGhlclxyXG5hIHF1ZXJ5LCBpbXBvcnQgb3IgW1tFbnRpdHlNYW5hZ2VyLmNyZWF0ZUVudGl0eV1dIGNhbGwuXHJcbj4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbj4gICAgICB2YXIgYXNwZWN0ID0gb3JkZXIuZW50aXR5QXNwZWN0O1xyXG4+ICAgICAgdmFyIGN1cnJlbnRTdGF0ZSA9IGFzcGVjdC5lbnRpdHlTdGF0ZTtcclxuXHJcbioqL1xyXG5leHBvcnQgY2xhc3MgRW50aXR5QXNwZWN0IHtcclxuICAvKiogVGhlIEVudGl0eSB0aGF0IHRoaXMgYXNwZWN0IGlzIGFzc29jaWF0ZWQgd2l0aC4gX19SZWFkIE9ubHlfXyAgKiovXHJcbiAgZW50aXR5PzogRW50aXR5O1xyXG4gIC8qKiBUaGUgW1tFbnRpdHlNYW5hZ2VyXV0gdGhhdCBjb250YWlucyB0aGlzIGVudGl0eS4gX19SZWFkIE9ubHlfXyAqKi9cclxuICBlbnRpdHlNYW5hZ2VyPzogRW50aXR5TWFuYWdlcjtcclxuICAvKiogIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgZW50aXR5R3JvdXA/OiBFbnRpdHlHcm91cDtcclxuICAvKiogVGhlIFtbRW50aXR5U3RhdGVdXSBvZiB0aGlzIGVudGl0eS4gX19SZWFkIE9ubHlfXyAqKi9cclxuICBlbnRpdHlTdGF0ZTogRW50aXR5U3RhdGU7XHJcbiAgLyoqICAgV2hldGhlciB0aGlzIGVudGl0eSBpcyBpbiB0aGUgcHJvY2VzcyBvZiBiZWluZyBzYXZlZC4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGlzQmVpbmdTYXZlZDogYm9vbGVhbjtcclxuICAvKiogVGhlICdvcmlnaW5hbCB2YWx1ZXMnIG9mIHRoaXMgZW50aXR5IHdoZXJlIHRoZXkgYXJlIGRpZmZlcmVudCBmcm9tIHRoZSAnY3VycmVudCB2YWx1ZXMnLlxyXG4gIFRoaXMgaXMgYSBtYXAgd2hlcmUgdGhlIGtleSBpcyBhIHByb3BlcnR5IG5hbWUgYW5kIHRoZSB2YWx1ZSBpcyB0aGUgJ29yaWdpbmFsIHZhbHVlJyBvZiB0aGUgcHJvcGVydHkuICovXHJcbiAgb3JpZ2luYWxWYWx1ZXM6IHt9O1xyXG4gIC8qKiAgV2hldGhlciB0aGlzIGVudGl0eSBoYXMgYW55IHZhbGlkYXRpb24gZXJyb3JzLiBfX1JlYWQgT25seV9fICovXHJcbiAgaGFzVmFsaWRhdGlvbkVycm9yczogYm9vbGVhbjtcclxuICAvKiogV2hldGhlciB0aGlzIGVudGl0eSBoYXMgYSB0ZW1wb3JhcnkgW1tFbnRpdHlLZXldXS4gKi9cclxuICBoYXNUZW1wS2V5OiBib29sZWFuO1xyXG4gIC8qKiBXaGV0aGVyIHRoaXMgZW50aXR5IHdhcyBjcmVhdGVkIGJ5IGJlaW5nIGxvYWRlZCBmcm9tIHRoZSBkYXRhYmFzZSAqL1xyXG4gIHdhc0xvYWRlZD86IGJvb2xlYW47XHJcbiAgLyoqIEV4dHJhIG1ldGFkYXRhIGFib3V0IHRoaXMgZW50aXR5IHN1Y2ggYXMgdGhlIGVudGl0eSdzIGV0YWcuXHJcbiAgWW91IG1heSBleHRlbmQgdGhpcyBvYmplY3Qgd2l0aCB5b3VyIG93biBtZXRhZGF0YSBpbmZvcm1hdGlvbi5cclxuICBCcmVlemUgKGRlKXNlcmlhbGl6ZXMgdGhpcyBvYmplY3Qgd2hlbiBpbXBvcnRpbmcvZXhwb3J0aW5nIHRoZSBlbnRpdHkuICoqL1xyXG4gIGV4dHJhTWV0YWRhdGE/OiBhbnk7XHJcbiAgLyoqXHJcbiAgQSBbW0JyZWV6ZUV2ZW50XV0gdGhhdCBmaXJlcyB3aGVuZXZlciBhbnkgb2YgdGhlIHZhbGlkYXRpb24gZXJyb3JzIG9uIHRoaXMgZW50aXR5IGNoYW5nZS5cclxuICBOb3RlIHRoYXQgdGhpcyBtaWdodCBiZSB0aGUgcmVtb3ZhbCBvZiBhbiBlcnJvciB3aGVuIHNvbWUgZGF0YSBvbiB0aGUgZW50aXR5IGlzIGZpeGVkLlxyXG4gIEBldmVudEFyZ3MgLSBcclxuICAgIC0gZW50aXR5IC0gVGhlIGVudGl0eSBvbiB3aGljaCB0aGUgdmFsaWRhdGlvbiBlcnJvcnMgYXJlIGJlaW5nIGFkZGVkIG9yIHJlbW92ZWQuXHJcbiAgICAtIGFkZGVkIC0gQW4gYXJyYXkgY29udGFpbmluZyBhbnkgbmV3bHkgYWRkZWQgW1tWYWxpZGF0aW9uRXJyb3JdXXNcclxuICAgIC0gcmVtb3ZlZCAtIEFuIGFycmF5IGNvbnRhaW5pbmcgYW55IG5ld2x5IHJlbW92ZWQgW1tWYWxpZGF0aW9uRXJyb3JdXXMuIFRoaXMgaXMgdGhvc2VcclxuICAgICAgZXJyb3JzIHRoYXQgaGF2ZSBiZWVuICdmaXhlZCcuXHJcblxyXG4+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4+ICAgICAgb3JkZXIuZW50aXR5QXNwZWN0LnZhbGlkYXRpb25FcnJvcnNDaGFuZ2VkLnN1YnNjcmliZShcclxuPiAgICAgIGZ1bmN0aW9uICh2YWxpZGF0aW9uQ2hhbmdlQXJncykge1xyXG4+ICAgICAgICAgIC8vIHRoaXMgY29kZSB3aWxsIGJlIGV4ZWN1dGVkIGFueXRpbWUgYSBwcm9wZXJ0eSB2YWx1ZSBjaGFuZ2VzIG9uIHRoZSAnb3JkZXInIGVudGl0eS5cclxuPiAgICAgICAgICB2YXIgZW50aXR5ID09IHZhbGlkYXRpb25DaGFuZ2VBcmdzLmVudGl0eTsgLy8gTm90ZTogZW50aXR5ID09PSBvcmRlclxyXG4+ICAgICAgICAgIHZhciBlcnJvcnNBZGRlZCA9IHZhbGlkYXRpb25DaGFuZ2VBcmdzLmFkZGVkO1xyXG4+ICAgICAgICAgIHZhciBlcnJvcnNDbGVhcmVkID0gdmFsaWRhdGlvbkNoYW5nZUFyZ3MucmVtb3ZlZDtcclxuPiAgICAgIH0pO1xyXG4gIEBldmVudFxyXG4gICoqL1xyXG4gIHZhbGlkYXRpb25FcnJvcnNDaGFuZ2VkOiBCcmVlemVFdmVudDxWYWxpZGF0aW9uRXJyb3JzQ2hhbmdlZEV2ZW50QXJncz47XHJcbiAgLyoqXHJcbiAgQSBbW0JyZWV6ZUV2ZW50XV0gdGhhdCBmaXJlcyB3aGVuZXZlciBhIHZhbHVlIG9mIG9uZSBvZiB0aGlzIGVudGl0eSdzIHByb3BlcnRpZXMgY2hhbmdlLlxyXG4gIEBldmVudEFyZ3MgLVxyXG4gICAgLSBlbnRpdHkgLSBUaGUgZW50aXR5IHdob3NlIHByb3BlcnR5IGhhcyBjaGFuZ2VkLlxyXG4gICAgLSBwcm9wZXJ0eSAtIFRoZSBbW0RhdGFQcm9wZXJ0eV1dIHRoYXQgY2hhbmdlZC5cclxuICAgIC0gcHJvcGVydHlOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRoYXQgY2hhbmdlZC4gVGhpcyB2YWx1ZSB3aWxsIGJlICdudWxsJyBmb3Igb3BlcmF0aW9ucyB0aGF0IHJlcGxhY2UgdGhlIGVudGlyZSBlbnRpdHkuICBUaGlzIGluY2x1ZGVzXHJcbiAgICAgIHF1ZXJpZXMsIGltcG9ydHMgYW5kIHNhdmVzIHRoYXQgcmVxdWlyZSBhIG1lcmdlLiBUaGUgcmVtYWluaW5nIHBhcmFtZXRlcnMgd2lsbCBub3QgZXhpc3QgaW4gdGhpcyBjYXNlIGVpdGhlci4gVGhpcyB3aWxsIGFjdHVhbGx5IGJlIGEgXCJwcm9wZXJ0eSBwYXRoXCJcclxuICAgICAgZm9yIGFueSBwcm9wZXJ0aWVzIG9mIGEgY29tcGxleCB0eXBlLlxyXG4gICAgLSBvbGRWYWx1ZSAtIFRoZSBvbGQgdmFsdWUgb2YgdGhpcyBwcm9wZXJ0eSBiZWZvcmUgdGhlIGNoYW5nZS5cclxuICAgIC0gbmV3VmFsdWUgLSBUaGUgbmV3IHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgYWZ0ZXIgdGhlIGNoYW5nZS5cclxuICAgIC0gcGFyZW50IC0gVGhlIGltbWVkaWF0ZSBwYXJlbnQgb2JqZWN0IGZvciB0aGUgY2hhbmdlZCBwcm9wZXJ0eS4gIFRoaXMgd2lsbCBiZSBhIENvbXBsZXhUeXBlIGluc3RhbmNlIGFzIG9wcG9zZWQgdG8gYW4gRW50aXR5IFxyXG4gICAgICBmb3IgYW55IGNvbXBsZXggdHlwZSBvciBuZXN0ZWQgY29tcGxleCB0eXBlIHByb3BlcnRpZXMuXHJcblxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIG9yZGVyLmVudGl0eUFzcGVjdC5wcm9wZXJ0eUNoYW5nZWQuc3Vic2NyaWJlKFxyXG4gID4gICAgICBmdW5jdGlvbiAocHJvcGVydHlDaGFuZ2VkQXJncykge1xyXG4gID4gICAgICAgICAgLy8gdGhpcyBjb2RlIHdpbGwgYmUgZXhlY3V0ZWQgYW55dGltZSBhIHByb3BlcnR5IHZhbHVlIGNoYW5nZXMgb24gdGhlICdvcmRlcicgZW50aXR5LlxyXG4gID4gICAgICAgICAgdmFyIGVudGl0eSA9IHByb3BlcnR5Q2hhbmdlZEFyZ3MuZW50aXR5OyAvLyBOb3RlOiBlbnRpdHkgPT09IG9yZGVyXHJcbiAgPiAgICAgICAgICB2YXIgcHJvcGVydHlOYW1lQ2hhbmdlZCA9IHByb3BlcnR5Q2hhbmdlZEFyZ3MucHJvcGVydHlOYW1lO1xyXG4gID4gICAgICAgICAgdmFyIG9sZFZhbHVlID0gcHJvcGVydHlDaGFuZ2VkQXJncy5vbGRWYWx1ZTtcclxuICA+ICAgICAgICAgIHZhciBuZXdWYWx1ZSA9IHByb3BlcnR5Q2hhbmdlZEFyZ3MubmV3VmFsdWU7XHJcbiAgPiAgICAgIH0pO1xyXG4gIEBldmVudFxyXG4gICoqL1xyXG4gIHByb3BlcnR5Q2hhbmdlZDogQnJlZXplRXZlbnQ8UHJvcGVydHlDaGFuZ2VkRXZlbnRBcmdzPjtcclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3ZhbGlkYXRpb25FcnJvcnM6IHsgW2luZGV4OiBzdHJpbmddOiBWYWxpZGF0aW9uRXJyb3IgfTtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfcGVuZGluZ1ZhbGlkYXRpb25SZXN1bHQ6IGFueTtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfZW50aXR5S2V5OiBFbnRpdHlLZXk7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2xvYWRlZE5wczogYW55W107XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2luaXRpYWxpemVkPzogYm9vbGVhbjtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfaW5Qcm9jZXNzOiBhbnlbXTsgLy8gdXNlZCBpbiBkZWZhdWx0UHJvcGVydHlJbnRlcmNlcHRvciBmb3IgdGVtcCBzdG9yYWdlLlxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9pblByb2Nlc3NFbnRpdHk/OiBFbnRpdHk7IC8vIHVzZWQgaW4gRW50aXR5TWFuYWdlclxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIHN0YXRpYyBfbnVsbEluc3RhbmNlID0gbmV3IEVudGl0eUFzcGVjdCgpOyAvLyBUT0RPOiBkZXRlcm1pbmUgaWYgdGhpcyB3b3Jrc1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIGNvbnN0cnVjdG9yKGVudGl0eT86IEVudGl0eSkge1xyXG5cclxuICAgIC8vIGlmIGNhbGxlZCB3aXRob3V0IG5ld1xyXG4gICAgLy8gaWYgKCEodGhpcyBpbnN0YW5jZW9mIEVudGl0eUFzcGVjdCkpIHtcclxuICAgIC8vICAgcmV0dXJuIG5ldyBFbnRpdHlBc3BlY3QoZW50aXR5KTtcclxuICAgIC8vIH1cclxuXHJcbiAgICB0aGlzLmVudGl0eSA9IGVudGl0eTtcclxuICAgIC8vIFRPRE86IGtlZXAgcHVibGljIG9yIG5vdD9cclxuICAgIHRoaXMuZW50aXR5R3JvdXAgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLmVudGl0eU1hbmFnZXIgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLmVudGl0eVN0YXRlID0gRW50aXR5U3RhdGUuRGV0YWNoZWQ7XHJcbiAgICB0aGlzLmlzQmVpbmdTYXZlZCA9IGZhbHNlO1xyXG4gICAgdGhpcy5vcmlnaW5hbFZhbHVlcyA9IHt9O1xyXG4gICAgdGhpcy5oYXNWYWxpZGF0aW9uRXJyb3JzID0gZmFsc2U7XHJcbiAgICB0aGlzLl92YWxpZGF0aW9uRXJyb3JzID0ge307XHJcblxyXG4gICAgLy8gVW5jb21tZW50IHdoZW4gd2UgaW1wbGVtZW50IGVudGl0eUFzcGVjdC5pc05hdmlnYXRpb25Qcm9wZXJ0eUxvYWRlZCBtZXRob2RcclxuICAgIC8vIHRoaXMuX2xvYWRlZE5hdlByb3BNYXAgPSB7fTtcclxuXHJcbiAgICB0aGlzLnZhbGlkYXRpb25FcnJvcnNDaGFuZ2VkID0gbmV3IEJyZWV6ZUV2ZW50KFwidmFsaWRhdGlvbkVycm9yc0NoYW5nZWRcIiwgdGhpcyk7XHJcbiAgICB0aGlzLnByb3BlcnR5Q2hhbmdlZCA9IG5ldyBCcmVlemVFdmVudChcInByb3BlcnR5Q2hhbmdlZFwiLCB0aGlzKTtcclxuICAgIC8vIGluIGNhc2UgdGhpcyBpcyB0aGUgTlVMTCBlbnRpdHlBc3BlY3QuIC0gdXNlZCB3aXRoIENvbXBsZXhBc3BlY3RzIHRoYXQgaGF2ZSBubyBwYXJlbnQuXHJcblxyXG4gICAgaWYgKGVudGl0eSAhPSBudWxsKSB7XHJcbiAgICAgIC8vIHJlbW92ZSBwcm9wZXJ0aWVzIHRoYXQgc2hvdWxkIGJlIG9uIHByb3RvdHlwZSBidXQgcGxhY2VkIG9uIGNsYXNzIGJ5IEJhYmVsXHJcbiAgICAgIGlmICghZW50aXR5LmVudGl0eVR5cGUpIHsgZGVsZXRlKGVudGl0eS5lbnRpdHlUeXBlKTsgfVxyXG4gICAgICBpZiAoIWVudGl0eS5lbnRpdHlBc3BlY3QpIHsgZGVsZXRlKGVudGl0eS5lbnRpdHlBc3BlY3QpOyB9XHJcbiAgICAgIGVudGl0eS5lbnRpdHlBc3BlY3QgPSB0aGlzO1xyXG5cclxuICAgICAgLy8gZW50aXR5VHlwZSBzaG91bGQgYWxyZWFkeSBiZSBvbiB0aGUgZW50aXR5IGZyb20gJ3dhdGNoJ1xyXG4gICAgICBsZXQgZW50aXR5VHlwZSA9IGVudGl0eS5lbnRpdHlUeXBlIHx8IGVudGl0eS5fJGVudGl0eVR5cGU7XHJcbiAgICAgIGlmICghZW50aXR5VHlwZSkge1xyXG4gICAgICAgIGxldCB0eXBlTmFtZSA9IGVudGl0eS5wcm90b3R5cGUuXyR0eXBlTmFtZTtcclxuICAgICAgICBpZiAoIXR5cGVOYW1lKSB7XHJcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIGVudGl0eSBpcyBub3QgcmVnaXN0ZXJlZCBhcyBhIHZhbGlkIEVudGl0eVR5cGVcIik7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1ldGFkYXRhIGZvciB0aGlzIGVudGl0eVR5cGUgaGFzIG5vdCB5ZXQgYmVlbiByZXNvbHZlZDogXCIgKyB0eXBlTmFtZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGxldCBlbnRpdHlDdG9yID0gZW50aXR5VHlwZS5nZXRFbnRpdHlDdG9yKCk7XHJcbiAgICAgIGNvbmZpZy5pbnRlcmZhY2VSZWdpc3RyeS5tb2RlbExpYnJhcnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkuc3RhcnRUcmFja2luZyhlbnRpdHksIGVudGl0eUN0b3IucHJvdG90eXBlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuICovXHJcbiAgLy8gdHlwZS1ndWFyZFxyXG4gIHN0YXRpYyBpc0VudGl0eShvYmo6IFN0cnVjdHVyYWxPYmplY3QpOiBvYmogaXMgRW50aXR5IHtcclxuICAgIHJldHVybiAob2JqIGFzIGFueSkuZW50aXR5QXNwZWN0ICE9IG51bGw7XHJcbiAgfVxyXG5cclxuICAvLyBObyBsb25nZXIgdXNlZFxyXG4gIC8vIHN0YXRpYyBjcmVhdGVGcm9tKGVudGl0eTogRW50aXR5KTogRW50aXR5QXNwZWN0IHtcclxuICAvLyAgIGlmIChlbnRpdHkgPT0gbnVsbCkge1xyXG4gIC8vICAgICByZXR1cm4gRW50aXR5QXNwZWN0Ll9udWxsSW5zdGFuY2U7XHJcbiAgLy8gICB9IGVsc2UgaWYgKGVudGl0eS5lbnRpdHlBc3BlY3QpIHtcclxuICAvLyAgICAgcmV0dXJuIGVudGl0eS5lbnRpdHlBc3BlY3Q7XHJcbiAgLy8gICB9XHJcbiAgLy8gICByZXR1cm4gbmV3IEVudGl0eUFzcGVjdChlbnRpdHkpO1xyXG4gIC8vIH1cclxuXHJcbiAgLy8gVE9ETzogcmVmYWN0b3IgdGhpcyBhbmQgdGhlIGluc3RhbmNlIGdldFByb3BlcnR5VmFsdWUgbWV0aG9kLlxyXG4gIC8qKlxyXG4gIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkICdwcm9wZXJ0eSBwYXRoJyBmb3IgYSBzcGVjaWZpZWQgZW50aXR5LlxyXG5cclxuICBUaGUgcHJvcGVydHlQYXRoIGNhbiBiZSBlaXRoZXIgYSBzdHJpbmcgZGVsaW1pdGVkIHdpdGggJy4nIG9yIGEgc3RyaW5nIGFycmF5LiAgXHJcbiAgKiovXHJcbiAgLy8gdXNlZCBieSBFbnRpdHlRdWVyeSBhbmQgUHJlZGljYXRlXHJcbiAgc3RhdGljIGdldFByb3BlcnR5UGF0aFZhbHVlKG9iajogRW50aXR5LCBwcm9wZXJ0eVBhdGg6IHN0cmluZyB8IHN0cmluZ1tdKSB7XHJcbiAgICBsZXQgcHJvcGVydGllcyA9IEFycmF5LmlzQXJyYXkocHJvcGVydHlQYXRoKSA/IHByb3BlcnR5UGF0aCA6IHByb3BlcnR5UGF0aC5zcGxpdChcIi5cIik7XHJcbiAgICBpZiAocHJvcGVydGllcy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgcmV0dXJuIG9iai5nZXRQcm9wZXJ0eShwcm9wZXJ0eVBhdGggYXMgc3RyaW5nKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGxldCBuZXh0VmFsdWUgPSBvYmo7XHJcbiAgICAgIC8vIGhhY2sgdXNlIG9mIHNvbWUgdG8gcGVyZm9ybSBtYXBGaXJzdCBvcGVyYXRpb24uXHJcbiAgICAgIHByb3BlcnRpZXMuc29tZSgocHJvcCkgPT4ge1xyXG4gICAgICAgIG5leHRWYWx1ZSA9IG5leHRWYWx1ZS5nZXRQcm9wZXJ0eShwcm9wKTtcclxuICAgICAgICByZXR1cm4gbmV4dFZhbHVlID09IG51bGw7XHJcbiAgICAgIH0pO1xyXG4gICAgICByZXR1cm4gbmV4dFZhbHVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyB0aGUgW1tFbnRpdHlLZXldXSBmb3IgdGhpcyBFbnRpdHkuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgdmFyIGVudGl0eUtleSA9IG9yZGVyLmVudGl0eUFzcGVjdC5nZXRLZXkoKTtcclxuICBAcGFyYW0gZm9yY2VSZWZyZXNoIC0gKGJvb2xlYW49ZmFsc2UpIEZvcmNlcyB0aGUgcmVjYWxjdWxhdGlvbiBvZiB0aGUga2V5LiAgVGhpcyBzaG91bGQgbm9ybWFsbHkgYmUgdW5uZWNlc3NhcnkuXHJcbiAgQHJldHVybiBUaGUgW1tFbnRpdHlLZXldXSBhc3NvY2lhdGVkIHdpdGggdGhpcyBFbnRpdHkuXHJcbiAgKiovXHJcbiAgZ2V0S2V5KGZvcmNlUmVmcmVzaDogYm9vbGVhbiA9IGZhbHNlKSB7XHJcbiAgICBmb3JjZVJlZnJlc2ggPSBhc3NlcnRQYXJhbShmb3JjZVJlZnJlc2gsIFwiZm9yY2VSZWZyZXNoXCIpLmlzQm9vbGVhbigpLmlzT3B0aW9uYWwoKS5jaGVjayhmYWxzZSk7XHJcbiAgICBpZiAoZm9yY2VSZWZyZXNoIHx8ICF0aGlzLl9lbnRpdHlLZXkpIHtcclxuICAgICAgbGV0IGVudGl0eVR5cGUgPSB0aGlzLmVudGl0eSEuZW50aXR5VHlwZTtcclxuICAgICAgbGV0IGtleVByb3BzID0gZW50aXR5VHlwZS5rZXlQcm9wZXJ0aWVzO1xyXG4gICAgICBsZXQgdmFsdWVzID0ga2V5UHJvcHMubWFwKGZ1bmN0aW9uIChwKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZW50aXR5LmdldFByb3BlcnR5KHAubmFtZSk7XHJcbiAgICAgIH0sIHRoaXMpO1xyXG4gICAgICB0aGlzLl9lbnRpdHlLZXkgPSBuZXcgRW50aXR5S2V5KGVudGl0eVR5cGUsIHZhbHVlcyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5fZW50aXR5S2V5O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyB0aGUgZW50aXR5IHRvIGFuIFtbRW50aXR5U3RhdGVdXSBvZiAnVW5jaGFuZ2VkJyBieSBjb21taXR0aW5nIGFsbCBjaGFuZ2VzIG1hZGUgc2luY2UgdGhlIGVudGl0eSB3YXMgbGFzdCBxdWVyaWVkXHJcbiAgaGFkICdhY2NlcHRDaGFuZ2VzJyBjYWxsZWQgb24gaXQuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgb3JkZXIuZW50aXR5QXNwZWN0LmFjY2VwdENoYW5nZXMoKTtcclxuICA+ICAgICAgLy8gVGhlICdvcmRlcicgZW50aXR5IHdpbGwgbm93IGJlIGluIGFuICdVbmNoYW5nZWQnIHN0YXRlIHdpdGggYW55IGNoYW5nZXMgY29tbWl0dGVkLlxyXG4gICoqL1xyXG4gIGFjY2VwdENoYW5nZXMoKSB7XHJcbiAgICBpZiAoIXRoaXMuZW50aXR5KSByZXR1cm47XHJcbiAgICB0aGlzLl9jaGVja09wZXJhdGlvbihcImFjY2VwdENoYW5nZXNcIik7XHJcbiAgICBsZXQgZW0gPSB0aGlzLmVudGl0eU1hbmFnZXIhO1xyXG4gICAgaWYgKHRoaXMuZW50aXR5U3RhdGUuaXNEZWxldGVkKCkpIHtcclxuICAgICAgZW0uZGV0YWNoRW50aXR5KHRoaXMuZW50aXR5KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc2V0VW5jaGFuZ2VkKCk7XHJcbiAgICB9XHJcbiAgICBlbS5lbnRpdHlDaGFuZ2VkLnB1Ymxpc2goeyBlbnRpdHlBY3Rpb246IEVudGl0eUFjdGlvbi5BY2NlcHRDaGFuZ2VzLCBlbnRpdHk6IHRoaXMuZW50aXR5IH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyB0aGUgZW50aXR5IHRvIGFuIFtbRW50aXR5U3RhdGVdXSBvZiAnVW5jaGFuZ2VkJyBieSByZWplY3RpbmcgYWxsIGNoYW5nZXMgbWFkZSB0byBpdCBzaW5jZSB0aGUgZW50aXR5IHdhcyBsYXN0IHF1ZXJpZWRcclxuICBoYWQgJ3JlamVjdENoYW5nZXMnIGNhbGxlZCBvbiBpdC5cclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICBvcmRlci5lbnRpdHlBc3BlY3QucmVqZWN0Q2hhbmdlcygpO1xyXG4gID4gICAgICAvLyBUaGUgJ29yZGVyJyBlbnRpdHkgd2lsbCBub3cgYmUgaW4gYW4gJ1VuY2hhbmdlZCcgc3RhdGUgd2l0aCBhbnkgY2hhbmdlcyByZWplY3RlZC5cclxuICAqKi9cclxuICByZWplY3RDaGFuZ2VzKCkge1xyXG4gICAgdGhpcy5fY2hlY2tPcGVyYXRpb24oXCJyZWplY3RDaGFuZ2VzXCIpO1xyXG4gICAgbGV0IGVudGl0eSA9IHRoaXMuZW50aXR5ITtcclxuICAgIGxldCBlbnRpdHlNYW5hZ2VyID0gdGhpcy5lbnRpdHlNYW5hZ2VyITtcclxuICAgIC8vIHdlIGRvIG5vdCB3YW50IFByb3BlcnR5Q2hhbmdlIG9yIEVudGl0eUNoYW5nZSBldmVudHMgdG8gb2NjdXIgaGVyZVxyXG4gICAgY29yZS51c2luZyhlbnRpdHlNYW5hZ2VyLCBcImlzUmVqZWN0aW5nQ2hhbmdlc1wiLCB0cnVlLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHJlamVjdENoYW5nZXNDb3JlKGVudGl0eSk7XHJcbiAgICB9KTtcclxuICAgIGlmICh0aGlzLmVudGl0eVN0YXRlLmlzQWRkZWQoKSkge1xyXG4gICAgICAvLyBuZXh0IGxpbmUgaXMgbmVlZGVkIGJlY2F1c2UgdGhlIGZvbGxvd2luZyBsaW5lIHdpbGwgY2F1c2UgdGhpcy5lbnRpdHlNYW5hZ2VyIC0+IG51bGw7XHJcbiAgICAgIGVudGl0eU1hbmFnZXIuZGV0YWNoRW50aXR5KGVudGl0eSk7XHJcbiAgICAgIC8vIG5lZWQgdG8gdGVsbCBlbSB0aGF0IGFuIGVudGl0eSB0aGF0IG5lZWRlZCB0byBiZSBzYXZlZCBubyBsb25nZXIgZG9lcy5cclxuICAgICAgZW50aXR5TWFuYWdlci5fbm90aWZ5U3RhdGVDaGFuZ2UoZW50aXR5LCBmYWxzZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAodGhpcy5lbnRpdHlTdGF0ZS5pc0RlbGV0ZWQoKSkge1xyXG4gICAgICAgIGVudGl0eU1hbmFnZXIuX2xpbmtSZWxhdGVkRW50aXRpZXMoZW50aXR5KTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLnNldFVuY2hhbmdlZCgpO1xyXG4gICAgICAvLyBwcm9wZXJ0eUNoYW5nZWQgcHJvcGVydHlOYW1lIGlzIG5vdCBzcGVjaWZpZWQgYmVjYXVzZSBtb3JlIHRoYW4gb25lIHByb3BlcnR5IG1heSBoYXZlIGNoYW5nZWQuXHJcbiAgICAgIHRoaXMucHJvcGVydHlDaGFuZ2VkLnB1Ymxpc2goeyBlbnRpdHk6IGVudGl0eSwgcHJvcGVydHlOYW1lOiBudWxsIH0pO1xyXG4gICAgICBlbnRpdHlNYW5hZ2VyLmVudGl0eUNoYW5nZWQucHVibGlzaCh7IGVudGl0eUFjdGlvbjogRW50aXR5QWN0aW9uLlJlamVjdENoYW5nZXMsIGVudGl0eTogZW50aXR5IH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqICBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIC8vIFRPRE86IHJlbmFtZSAtIGFuZCB1c2UgJ18nOyB1c2VkIG9uIGJvdGggRW50aXR5QXNwZWN0IGFuZCBDb21wbGV4QXNwZWN0IGZvciBwb2x5bW9ycGhpYyByZWFzb25zLlxyXG4gIGdldFByb3BlcnR5UGF0aChwcm9wTmFtZTogc3RyaW5nKSB7XHJcbiAgICByZXR1cm4gcHJvcE5hbWU7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBTZXRzIHRoZSBlbnRpdHkgdG8gYW4gRW50aXR5U3RhdGUgb2YgJ0FkZGVkJy4gIFRoaXMgaXMgTk9UIHRoZSBlcXVpdmFsZW50IG9mIGNhbGxpbmcgW1tFbnRpdHlNYW5hZ2VyLmFkZEVudGl0eV1dXHJcbiAgYmVjYXVzZSBubyBrZXkgZ2VuZXJhdGlvbiB3aWxsIG9jY3VyIGZvciBhdXRvZ2VuZXJhdGVkIGtleXMgYXMgYSByZXN1bHQgb2YgdGhpcyBvcGVyYXRpb24uIEFzIGEgcmVzdWx0IHRoaXMgb3BlcmF0aW9uIGNhbiBiZSBwcm9ibGVtYXRpY1xyXG4gIHVubGVzcyB5b3UgYXJlIGNlcnRhaW4gdGhhdCB0aGUgZW50aXR5IGJlaW5nIG1hcmtlZCAnQWRkZWQnIGRvZXMgbm90IGFscmVhZHkgZXhpc3QgaW4gdGhlIGRhdGFiYXNlIGFuZCBkb2VzIG5vdCBoYXZlIGFuIGF1dG9nZW5lcmF0ZWQga2V5LlxyXG4gIFRoZSBzYW1lIG9wZXJhdGlvbiBjYW4gYmUgcGVyZm9ybWVkIGJ5IGNhbGxpbmcgW1tFbnRpdHlBc3BlY3Quc2V0RW50aXR5U3RhdGVdXS5cclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICBvcmRlci5lbnRpdHlBc3BlY3Quc2V0QWRkZWQoKTtcclxuICA+ICAgICAgLy8gVGhlICdvcmRlcicgZW50aXR5IHdpbGwgbm93IGJlIGluIGFuICdBZGRlZCcgc3RhdGUuXHJcbiAgKiovXHJcbiAgc2V0QWRkZWQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zZXRFbnRpdHlTdGF0ZShFbnRpdHlTdGF0ZS5BZGRlZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBTZXRzIHRoZSBlbnRpdHkgdG8gYW4gRW50aXR5U3RhdGUgb2YgJ1VuY2hhbmdlZCcuICBUaGlzIGlzIGFsc28gdGhlIGVxdWl2YWxlbnQgb2YgY2FsbGluZyBbW0VudGl0eUFzcGVjdC5hY2NlcHRDaGFuZ2VzXV0uXHJcbiAgVGhlIHNhbWUgb3BlcmF0aW9uIGNhbiBiZSBwZXJmb3JtZWQgYnkgY2FsbGluZyBbW0VudGl0eUFzcGVjdC5zZXRFbnRpdHlTdGF0ZV1dLlxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIG9yZGVyLmVudGl0eUFzcGVjdC5zZXRVbmNoYW5nZWQoKTtcclxuICA+ICAgICAgLy8gVGhlICdvcmRlcicgZW50aXR5IHdpbGwgbm93IGJlIGluIGFuICdVbmNoYW5nZWQnIHN0YXRlIHdpdGggYW55IGNoYW5nZXMgY29tbWl0dGVkLlxyXG4gICoqL1xyXG4gIHNldFVuY2hhbmdlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHJldHVybiB0aGlzLnNldEVudGl0eVN0YXRlKEVudGl0eVN0YXRlLlVuY2hhbmdlZCk7XHJcbiAgfTtcclxuXHJcblxyXG4gIC8qKlxyXG4gIFNldHMgdGhlIGVudGl0eSB0byBhbiBFbnRpdHlTdGF0ZSBvZiAnTW9kaWZpZWQnLiAgVGhpcyBjYW4gYWxzbyBiZSBhY2hpZXZlZCBieSBjaGFuZ2luZyB0aGUgdmFsdWUgb2YgYW55IHByb3BlcnR5IG9uIGFuICdVbmNoYW5nZWQnIGVudGl0eS5cclxuICBUaGUgc2FtZSBvcGVyYXRpb24gY2FuIGJlIHBlcmZvcm1lZCBieSBjYWxsaW5nIFtbRW50aXR5QXNwZWN0LnNldEVudGl0eVN0YXRlXV0uXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgb3JkZXIuZW50aXR5QXNwZWN0LnNldE1vZGlmaWVkKCk7XHJcbiAgPiAgICAgIC8vIFRoZSAnb3JkZXInIGVudGl0eSB3aWxsIG5vdyBiZSBpbiBhICdNb2RpZmllZCcgc3RhdGUuXHJcbiAgKiovXHJcbiAgc2V0TW9kaWZpZWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zZXRFbnRpdHlTdGF0ZShFbnRpdHlTdGF0ZS5Nb2RpZmllZCk7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgU2V0cyB0aGUgZW50aXR5IHRvIGFuIEVudGl0eVN0YXRlIG9mICdEZWxldGVkJy4gIFRoaXMgYm90aCBtYXJrcyB0aGUgZW50aXR5IGFzIGJlaW5nIHNjaGVkdWxlZCBmb3IgZGVsZXRpb24gZHVyaW5nIHRoZSBuZXh0ICdTYXZlJyBjYWxsXHJcbiAgYnV0IGFsc28gcmVtb3ZlcyB0aGUgZW50aXR5IGZyb20gYWxsIG9mIGl0cyByZWxhdGVkIGVudGl0aWVzLlxyXG4gIFRoZSBzYW1lIG9wZXJhdGlvbiBjYW4gYmUgcGVyZm9ybWVkIGJ5IGNhbGxpbmcgW1tFbnRpdHlBc3BlY3Quc2V0RW50aXR5U3RhdGVdXS5cclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICBvcmRlci5lbnRpdHlBc3BlY3Quc2V0RGVsZXRlZCgpO1xyXG4gID4gICAgICAvLyBUaGUgJ29yZGVyJyBlbnRpdHkgd2lsbCBub3cgYmUgaW4gYSAnRGVsZXRlZCcgc3RhdGUgYW5kIGl0IHdpbGwgbm8gbG9uZ2VyIGhhdmUgYW55ICdyZWxhdGVkJyBlbnRpdGllcy5cclxuICAqKi9cclxuICBzZXREZWxldGVkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc2V0RW50aXR5U3RhdGUoRW50aXR5U3RhdGUuRGVsZXRlZCk7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgU2V0cyB0aGUgZW50aXR5IHRvIGFuIEVudGl0eVN0YXRlIG9mICdEZXRhY2hlZCcuICBUaGlzIHJlbW92ZXMgdGhlIGVudGl0eSBmcm9tIGFsbCBvZiBpdHMgcmVsYXRlZCBlbnRpdGllcywgYnV0IGRvZXMgTk9UIGNoYW5nZSB0aGUgRW50aXR5U3RhdGUgb2YgYW55IGV4aXN0aW5nIGVudGl0aWVzLlxyXG4gIFRoZSBzYW1lIG9wZXJhdGlvbiBjYW4gYmUgcGVyZm9ybWVkIGJ5IGNhbGxpbmcgW1tFbnRpdHlBc3BlY3Quc2V0RW50aXR5U3RhdGVdXS5cclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICBvcmRlci5lbnRpdHlBc3BlY3Quc2V0RGV0YWNoZWQoKTtcclxuICA+ICAgICAgLy8gVGhlICdvcmRlcicgZW50aXR5IHdpbGwgbm93IGJlIGluIGEgJ0RldGFjaGVkJyBzdGF0ZSBhbmQgaXQgd2lsbCBubyBsb25nZXIgaGF2ZSBhbnkgJ3JlbGF0ZWQnIGVudGl0aWVzLlxyXG4gICoqL1xyXG4gIHNldERldGFjaGVkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc2V0RW50aXR5U3RhdGUoRW50aXR5U3RhdGUuRGV0YWNoZWQpO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gIFNldHMgdGhlIGVudGl0eSB0byB0aGUgc3BlY2lmaWVkIEVudGl0eVN0YXRlLiBTZWUgYWxzbyAnc2V0VW5jaGFuZ2VkJywgJ3NldE1vZGlmaWVkJywgJ3NldERldGFjaGVkJywgZXRjLlxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIG9yZGVyLmVudGl0eUFzcGVjdC5zZXRFbnRpdHlTdGF0ZShFbnRpdHlTdGF0ZS5VbmNoYW5nZWQpO1xyXG4gID4gICAgICAvLyBUaGUgJ29yZGVyJyBlbnRpdHkgd2lsbCBub3cgYmUgaW4gYSAnVW5jaGFuZ2VkJyBzdGF0ZS5cclxuICAqKi9cclxuICBzZXRFbnRpdHlTdGF0ZShlbnRpdHlTdGF0ZTogRW50aXR5U3RhdGUpIHtcclxuICAgIGlmICh0aGlzLmVudGl0eVN0YXRlID09PSBlbnRpdHlTdGF0ZSkgcmV0dXJuIGZhbHNlO1xyXG4gICAgdGhpcy5fY2hlY2tPcGVyYXRpb24oXCJzZXRFbnRpdHlTdGF0ZVwiKTtcclxuICAgIGlmICh0aGlzLmVudGl0eVN0YXRlLmlzRGV0YWNoZWQoKSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJZb3UgY2Fubm90IHNldCB0aGUgJ2VudGl0eVN0YXRlJyBvZiBhbiBlbnRpdHkgd2hlbiBpdCBpcyBkZXRhY2hlZCAtIGV4Y2VwdCBieSBmaXJzdCBhdHRhY2hpbmcgaXQgdG8gYW4gRW50aXR5TWFuYWdlclwiKTtcclxuICAgIH1cclxuICAgIGxldCBlbnRpdHkgPSB0aGlzLmVudGl0eSE7XHJcbiAgICBsZXQgZW0gPSB0aGlzLmVudGl0eU1hbmFnZXIhO1xyXG4gICAgbGV0IG5lZWRzU2F2ZSA9IHRydWU7XHJcbiAgICBpZiAoZW50aXR5U3RhdGUgPT09IEVudGl0eVN0YXRlLlVuY2hhbmdlZCkge1xyXG4gICAgICBjbGVhck9yaWdpbmFsVmFsdWVzKGVudGl0eSk7XHJcbiAgICAgIGRlbGV0ZSB0aGlzLmhhc1RlbXBLZXk7XHJcbiAgICAgIG5lZWRzU2F2ZSA9IGZhbHNlO1xyXG4gICAgfSBlbHNlIGlmIChlbnRpdHlTdGF0ZSA9PT0gRW50aXR5U3RhdGUuQWRkZWQpIHtcclxuICAgICAgY2xlYXJPcmlnaW5hbFZhbHVlcyhlbnRpdHkpO1xyXG4gICAgICAvLyBUT0RPOiBtb3JlIHRvIGRvIGhlcmUuLi4gbGlrZSByZWdlbmVyYXRpbmcga2V5ID8/P1xyXG4gICAgfSBlbHNlIGlmIChlbnRpdHlTdGF0ZSA9PT0gRW50aXR5U3RhdGUuRGVsZXRlZCkge1xyXG4gICAgICBpZiAodGhpcy5lbnRpdHlTdGF0ZS5pc0FkZGVkKCkpIHtcclxuICAgICAgICAvLyB0dXJuIGl0IGludG8gYSBkZXRhY2ggYW5kIGV4aXQgZWFybHlcclxuICAgICAgICB0aGlzLnNldEVudGl0eVN0YXRlKEVudGl0eVN0YXRlLkRldGFjaGVkKTtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBUT0RPOiB0aGluayBhYm91dCBjYXNjYWRlIGRlbGV0ZXNcclxuICAgICAgICAvLyBlbnRpdHlTdGF0ZSBuZWVkcyB0byBiZSBzZXQgaXQgZWFybHkgaW4gdGhpcyBvbmUgY2FzZSB0byBpbnN1cmUgdGhhdCBmaydzIGFyZSBub3QgY2xlYXJlZC5cclxuICAgICAgICB0aGlzLmVudGl0eVN0YXRlID0gRW50aXR5U3RhdGUuRGVsZXRlZDtcclxuICAgICAgICByZW1vdmVGcm9tUmVsYXRpb25zKGVudGl0eSwgRW50aXR5U3RhdGUuRGVsZXRlZCk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSBpZiAoZW50aXR5U3RhdGUgPT09IEVudGl0eVN0YXRlLk1vZGlmaWVkKSB7XHJcbiAgICAgIC8vIG5vdGhpbmcgZXh0cmEgbmVlZGVkXHJcbiAgICB9IGVsc2UgaWYgKGVudGl0eVN0YXRlID09PSBFbnRpdHlTdGF0ZS5EZXRhY2hlZCkge1xyXG4gICAgICBsZXQgZ3JvdXAgPSB0aGlzLmVudGl0eUdyb3VwO1xyXG4gICAgICAvLyBubyBncm91cCA9PT0gYWxyZWFkeSBkZXRhY2hlZC5cclxuICAgICAgaWYgKCFncm91cCkgcmV0dXJuIGZhbHNlO1xyXG4gICAgICBncm91cC5kZXRhY2hFbnRpdHkoZW50aXR5KTtcclxuICAgICAgLy8gbmVlZHMgdG8gb2NjdXIgZWFybHkgaGVyZSAtIHNvIHRoaXMgSVMgZGVsaWJlcmF0ZWx5IHJlZHVuZGVudCB3aXRoIHRoZSBzYW1lIGNvZGUgbGF0ZXIgaW4gdGhpcyBtZXRob2QuXHJcbiAgICAgIHRoaXMuZW50aXR5U3RhdGUgPSBlbnRpdHlTdGF0ZTtcclxuICAgICAgcmVtb3ZlRnJvbVJlbGF0aW9ucyhlbnRpdHksIEVudGl0eVN0YXRlLkRldGFjaGVkKTtcclxuICAgICAgdGhpcy5fZGV0YWNoKCk7XHJcbiAgICAgIGVtLmVudGl0eUNoYW5nZWQucHVibGlzaCh7IGVudGl0eUFjdGlvbjogRW50aXR5QWN0aW9uLkRldGFjaCwgZW50aXR5OiBlbnRpdHkgfSk7XHJcbiAgICAgIG5lZWRzU2F2ZSA9IGZhbHNlO1xyXG4gICAgfVxyXG4gICAgdGhpcy5lbnRpdHlTdGF0ZSA9IGVudGl0eVN0YXRlO1xyXG4gICAgZW0uX25vdGlmeVN0YXRlQ2hhbmdlKGVudGl0eSwgbmVlZHNTYXZlKTtcclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcbiAgbG9hZE5hdmlnYXRpb25Qcm9wZXJ0eShuYXZpZ2F0aW9uUHJvcGVydHk6IHN0cmluZywgY2FsbGJhY2s/OiBRdWVyeVN1Y2Nlc3NDYWxsYmFjaywgZXJyb3JDYWxsYmFjaz86IFF1ZXJ5RXJyb3JDYWxsYmFjayk6IFByb21pc2U8UXVlcnlSZXN1bHQ+O1xyXG4gIGxvYWROYXZpZ2F0aW9uUHJvcGVydHkobmF2aWdhdGlvblByb3BlcnR5OiBOYXZpZ2F0aW9uUHJvcGVydHksIGNhbGxiYWNrPzogUXVlcnlTdWNjZXNzQ2FsbGJhY2ssIGVycm9yQ2FsbGJhY2s/OiBRdWVyeUVycm9yQ2FsbGJhY2spOiBQcm9taXNlPFF1ZXJ5UmVzdWx0PjtcclxuICAvKipcclxuICBQZXJmb3JtcyBhIHF1ZXJ5IGZvciB0aGUgdmFsdWUgb2YgYSBzcGVjaWZpZWQgW1tOYXZpZ2F0aW9uUHJvcGVydHldXS4gX19Bc3luY19fXHJcbiAgPiAgICAgIGVtcC5lbnRpdHlBc3BlY3QubG9hZE5hdmlnYXRpb25Qcm9wZXJ0eShcIk9yZGVyc1wiKS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XHJcbiAgPiAgICAgICAgICB2YXIgb3JkZXJzID0gZGF0YS5yZXN1bHRzO1xyXG4gID4gICAgICB9KS5jYXRjaChmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XHJcbiAgPiAgICAgICAgICAvLyBoYW5kbGUgZXhjZXB0aW9uIGhlcmU7XHJcbiAgPiAgICAgIH0pO1xyXG4gIEBwYXJhbSBuYXZpZ2F0aW9uUHJvcGVydHkgLSBUaGUgTmF2aWdhdGlvblByb3BlcnR5IG9yIHRoZSBuYW1lIG9mIHRoZSBOYXZpZ2F0aW9uUHJvcGVydHkgdG8gJ2xvYWQnLlxyXG4gIEBwYXJhbSBjYWxsYmFjayAtIEZ1bmN0aW9uIHRvIGNhbGwgb24gc3VjY2Vzcy5cclxuICBAcGFyYW0gZXJyb3JDYWxsYmFjayAtIEZ1bmN0aW9uIHRvIGNhbGwgb24gZmFpbHVyZS5cclxuICBAcmV0dXJuIFByb21pc2Ugd2l0aCBzaGFwZVxyXG4gICAgLSByZXN1bHRzIHtBcnJheSBvZiBFbnRpdHl9XHJcbiAgICAtIHF1ZXJ5IHtFbnRpdHlRdWVyeX0gVGhlIG9yaWdpbmFsIHF1ZXJ5XHJcbiAgICAtIGh0dHBSZXNwb25zZSB7aHR0cFJlc3BvbnNlfSBUaGUgSHR0cFJlc3BvbnNlIHJldHVybmVkIGZyb20gdGhlIHNlcnZlci5cclxuICAqKi9cclxuICBsb2FkTmF2aWdhdGlvblByb3BlcnR5KG5hdmlnYXRpb25Qcm9wZXJ0eTogTmF2aWdhdGlvblByb3BlcnR5IHwgc3RyaW5nLCBjYWxsYmFjazogUXVlcnlTdWNjZXNzQ2FsbGJhY2ssIGVycm9yQ2FsbGJhY2s6IFF1ZXJ5RXJyb3JDYWxsYmFjaykge1xyXG4gICAgbGV0IGVudGl0eSA9IHRoaXMuZW50aXR5ITtcclxuICAgIGxldCBuYXZQcm9wZXJ0eSA9IGVudGl0eS5lbnRpdHlUeXBlLl9jaGVja05hdlByb3BlcnR5KG5hdmlnYXRpb25Qcm9wZXJ0eSk7XHJcbiAgICBsZXQgcXVlcnkgPSBFbnRpdHlRdWVyeS5mcm9tRW50aXR5TmF2aWdhdGlvbihlbnRpdHksIG5hdlByb3BlcnR5KTtcclxuICAgIC8vIHJldHVybiBlbnRpdHkuZW50aXR5QXNwZWN0LmVudGl0eU1hbmFnZXIuZXhlY3V0ZVF1ZXJ5KHF1ZXJ5LCBjYWxsYmFjaywgZXJyb3JDYWxsYmFjayk7XHJcbiAgICBsZXQgcHJvbWlzZSA9IGVudGl0eS5lbnRpdHlBc3BlY3QuZW50aXR5TWFuYWdlciEuZXhlY3V0ZVF1ZXJ5KHF1ZXJ5KTtcclxuXHJcbiAgICByZXR1cm4gcHJvbWlzZS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgIHRoaXMuX21hcmtBc0xvYWRlZChuYXZQcm9wZXJ0eS5uYW1lKTtcclxuICAgICAgaWYgKGNhbGxiYWNrKSBjYWxsYmFjayhkYXRhKTtcclxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShkYXRhKTtcclxuICAgIH0sIChlcnJvcikgPT4ge1xyXG4gICAgICBpZiAoZXJyb3JDYWxsYmFjaykgZXJyb3JDYWxsYmFjayhlcnJvcik7XHJcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcik7XHJcbiAgICB9KTtcclxuXHJcbiAgfVxyXG5cclxuICAvKipcclxuICBNYXJrcyB0aGlzIG5hdmlnYXRpb25Qcm9wZXJ0eSBvbiB0aGlzIGVudGl0eSBhcyBhbHJlYWR5IGhhdmluZyBiZWVuIGxvYWRlZC5cclxuICA+ICAgICAgZW1wLmVudGl0eUFzcGVjdC5tYXJrTmF2aWdhdGlvblByb3BlcnR5QXNMb2FkZWQoXCJPcmRlcnNcIik7XHJcbiAgQHBhcmFtIG5hdmlnYXRpb25Qcm9wZXJ0eSAtIFRoZSBOYXZpZ2F0aW9uUHJvcGVydHkgb3IgbmFtZSBvZiBOYXZpZ2F0aW9uUHJvcGVydHkgdG8gJ2xvYWQnLlxyXG4gICoqL1xyXG4gIG1hcmtOYXZpZ2F0aW9uUHJvcGVydHlBc0xvYWRlZChuYXZpZ2F0aW9uUHJvcGVydHk6IE5hdmlnYXRpb25Qcm9wZXJ0eSB8IHN0cmluZykge1xyXG4gICAgaWYgKCF0aGlzLmVudGl0eSkgcmV0dXJuO1xyXG4gICAgbGV0IG5hdlByb3BlcnR5ID0gdGhpcy5lbnRpdHkuZW50aXR5VHlwZS5fY2hlY2tOYXZQcm9wZXJ0eShuYXZpZ2F0aW9uUHJvcGVydHkpO1xyXG4gICAgdGhpcy5fbWFya0FzTG9hZGVkKG5hdlByb3BlcnR5Lm5hbWUpO1xyXG4gIH1cclxuXHJcbiAgaXNOYXZpZ2F0aW9uUHJvcGVydHlMb2FkZWQobmF2aWdhdGlvblByb3BlcnR5OiBzdHJpbmcpOiBib29sZWFuO1xyXG4gIGlzTmF2aWdhdGlvblByb3BlcnR5TG9hZGVkKG5hdmlnYXRpb25Qcm9wZXJ0eTogTmF2aWdhdGlvblByb3BlcnR5KTogYm9vbGVhbjtcclxuICAvKipcclxuICBEZXRlcm1pbmVzIHdoZXRoZXIgYSBuYXZpZ2F0aW9uUHJvcGVydHkgb24gdGhpcyBlbnRpdHkgaGFzIGFscmVhZHkgYmVlbiBsb2FkZWQuXHJcblxyXG4gIEEgbmF2aWdhdGlvbiBwcm9wZXJ0eSBpcyBjb25zaWRlcmVkIGxvYWRlZCB3aGVuIGFueSBvZiB0aGUgZm9sbG93aW5nIHRocmVlIGNvbmRpdGlvbnMgYXBwbGllczpcclxuXHJcbiAgICAxLiBJdCB3YXMgZmV0Y2hlZCBmcm9tIHRoZSBiYWNrZW5kIHNlcnZlci5cclxuICAgICAgICA8YnIvPiAgIFRoaXMgY2FuIGJlIHRoZSByZXN1bHQgb2YgYW4gZXhwYW5kIHF1ZXJ5IG9yIGEgY2FsbCB0byB0aGUgW1tFbnRpdHlBc3BlY3QubG9hZE5hdmlnYXRpb25Qcm9wZXJ0eV1dIG1ldGhvZC5cclxuICAgICAgICA8YnIvPiAgIE5vdGUgdGhhdCBldmVuIGlmIHRoZSBmZXRjaCByZXR1cm5zIG5vdGhpbmcgdGhlIHByb3BlcnR5IGlzIHN0aWxsIG1hcmtlZCBhcyBsb2FkZWQgaW4gdGhpcyBjYXNlLlxyXG4gICAgMS4gVGhlIHByb3BlcnR5IGlzIHNjYWxhciBhbmQgaGFzIGJlZW4gc2V0IHRvIGEgbm9ubnVsbCB2YWx1ZS5cclxuICAgIDEuIFRoZSBbW0VudGl0eUFzcGVjdC5tYXJrTmF2aWdhdGlvblByb3BlcnR5QXNMb2FkZWRdXSB3YXMgY2FsbGVkLlxyXG4gIFxyXG4gID4gICAgIHZhciB3YXNMb2FkZWQgPSBlbXAuZW50aXR5QXNwZWN0LmlzTmF2aWdhdGlvblByb3BlcnR5TG9hZGVkKFwiT3JkZXJzXCIpO1xyXG4gIEBwYXJhbSBuYXZpZ2F0aW9uUHJvcGVydHkgLSBUaGUgTmF2aWdhdGlvblByb3BlcnR5IG9yIG5hbWUgb2YgTmF2aWdhdGlvblByb3BlcnR5IHRvICdsb2FkJy5cclxuICAqKi9cclxuICBpc05hdmlnYXRpb25Qcm9wZXJ0eUxvYWRlZChuYXZpZ2F0aW9uUHJvcGVydHk6IE5hdmlnYXRpb25Qcm9wZXJ0eSB8IHN0cmluZykge1xyXG4gICAgaWYgKCF0aGlzLmVudGl0eSkgcmV0dXJuO1xyXG4gICAgbGV0IG5hdlByb3BlcnR5ID0gdGhpcy5lbnRpdHkuZW50aXR5VHlwZS5fY2hlY2tOYXZQcm9wZXJ0eShuYXZpZ2F0aW9uUHJvcGVydHkpO1xyXG4gICAgaWYgKG5hdlByb3BlcnR5LmlzU2NhbGFyICYmIHRoaXMuZW50aXR5LmdldFByb3BlcnR5KG5hdlByb3BlcnR5Lm5hbWUpICE9IG51bGwpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5fbG9hZGVkTnBzICYmIHRoaXMuX2xvYWRlZE5wcy5pbmRleE9mKG5hdlByb3BlcnR5Lm5hbWUpID49IDA7XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfbWFya0FzTG9hZGVkKG5hdlByb3BOYW1lOiBzdHJpbmcpIHtcclxuICAgIHRoaXMuX2xvYWRlZE5wcyA9IHRoaXMuX2xvYWRlZE5wcyB8fCBbXTtcclxuICAgIGNvcmUuYXJyYXlBZGRJdGVtVW5pcXVlKHRoaXMuX2xvYWRlZE5wcywgbmF2UHJvcE5hbWUpO1xyXG4gIH1cclxuXHJcblxyXG4gIC8qKlxyXG4gIFBlcmZvcm1zIHZhbGlkYXRpb24gb24gdGhlIGVudGl0eSwgYW55IGVycm9ycyBlbmNvdW50ZXJlZCBkdXJpbmcgdGhlIHZhbGlkYXRpb24gYXJlIGF2YWlsYWJsZSB2aWEgdGhlXHJcbiAgW1tFbnRpdHlBc3BlY3QuZ2V0VmFsaWRhdGlvbkVycm9yc11dIG1ldGhvZC4gVmFsaWRhdGluZyBhbiBlbnRpdHkgbWVhbnMgZXhlY3V0aW5nXHJcbiAgYWxsIG9mIHRoZSB2YWxpZGF0b3JzIG9uIGJvdGggdGhlIGVudGl0eSBpdHNlbGYgYXMgd2VsbCBhcyB0aG9zZSBvbiBlYWNoIG9mIGl0cyBwcm9wZXJ0aWVzLlxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIHZhciBpc09rID0gb3JkZXIuZW50aXR5QXNwZWN0LnZhbGlkYXRlRW50aXR5KCk7XHJcbiAgPiAgICAgIC8vIGlzT2sgd2lsbCBiZSAndHJ1ZScgaWYgdGhlcmUgYXJlIG5vIGVycm9ycyBvbiB0aGUgZW50aXR5LlxyXG4gID4gICAgICBpZiAoIWlzT2spIHtcclxuICA+ICAgICAgICAgIHZhciBlcnJvcnMgPSBvcmRlci5lbnRpdHlBc3BlY3QuZ2V0VmFsaWRhdGlvbkVycm9ycygpO1xyXG4gID4gICAgICB9XHJcbiAgQHJldHVybiBXaGV0aGVyIHRoZSBlbnRpdHkgcGFzc2VkIHZhbGlkYXRpb24uXHJcbiAgKiovXHJcbiAgdmFsaWRhdGVFbnRpdHkoKSB7XHJcbiAgICBsZXQgb2sgPSB0cnVlO1xyXG4gICAgdGhpcy5fcHJvY2Vzc1ZhbGlkYXRpb25PcEFuZFB1Ymxpc2goZnVuY3Rpb24gKHRoYXQ6IGFueSkge1xyXG4gICAgICBvayA9IHZhbGlkYXRlVGFyZ2V0KHRoYXQuZW50aXR5KTtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIG9rO1xyXG4gIH1cclxuXHJcbiAgdmFsaWRhdGVQcm9wZXJ0eShwcm9wZXJ0eTogc3RyaW5nLCBjb250ZXh0PzogYW55KTogYm9vbGVhbjtcclxuICB2YWxpZGF0ZVByb3BlcnR5KHByb3BlcnR5OiBEYXRhUHJvcGVydHksIGNvbnRleHQ/OiBhbnkpOiBib29sZWFuO1xyXG4gIHZhbGlkYXRlUHJvcGVydHkocHJvcGVydHk6IE5hdmlnYXRpb25Qcm9wZXJ0eSwgY29udGV4dD86IGFueSk6IGJvb2xlYW47XHJcbiAgLyoqXHJcbiAgUGVyZm9ybXMgdmFsaWRhdGlvbiBvbiBhIHNwZWNpZmljIHByb3BlcnR5IG9mIHRoaXMgZW50aXR5LCBhbnkgZXJyb3JzIGVuY291bnRlcmVkIGR1cmluZyB0aGUgdmFsaWRhdGlvbiBhcmUgYXZhaWxhYmxlIHZpYSB0aGVcclxuICBbW0VudGl0eUFzcGVjdC5nZXRWYWxpZGF0aW9uRXJyb3JzXV0gbWV0aG9kLiBWYWxpZGF0aW5nIGEgcHJvcGVydHkgbWVhbnMgZXhlY3V0aW5nXHJcbiAgYWxsIG9mIHRoZSB2YWxpZGF0b3JzIG9uIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkuICBUaGlzIGNhbGwgaXMgYWxzbyBtYWRlIGF1dG9tYXRpY2FsbHkgYW55dGltZSBhIHByb3BlcnR5XHJcbiAgb2YgYW4gZW50aXR5IGlzIGNoYW5nZWQuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgdmFyIGlzT2sgPSBvcmRlci5lbnRpdHlBc3BlY3QudmFsaWRhdGVQcm9wZXJ0eShcIk9yZGVyXCIpO1xyXG5cclxuICBvclxyXG4gID4gICAgICB2YXIgb3JkZXJEYXRlUHJvcGVydHkgPSBvcmRlci5lbnRpdHlUeXBlLmdldFByb3BlcnR5KFwiT3JkZXJEYXRlXCIpO1xyXG4gID4gICAgICB2YXIgaXNPayA9IG9yZGVyLmVudGl0eUFzcGVjdC52YWxpZGF0ZVByb3BlcnR5KE9yZGVyRGF0ZVByb3BlcnR5KTtcclxuICBAcGFyYW0gcHJvcGVydHkgLSBUaGUgW1tEYXRhUHJvcGVydHldXSBvciBbW05hdmlnYXRpb25Qcm9wZXJ0eV1dIHRvIHZhbGlkYXRlIG9yIGEgc3RyaW5nIFxyXG4gIHdpdGggdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IG9yIGEgcHJvcGVydHkgcGF0aCB3aXRoIHRoZSBwYXRoIHRvIGEgcHJvcGVydHkgb2YgYSBjb21wbGV4IG9iamVjdC5cclxuICBAcGFyYW0gY29udGV4dCAtICBBIGNvbnRleHQgb2JqZWN0IHVzZWQgdG8gcGFzcyBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRvIGVhY2ggW1tWYWxpZGF0b3JdXS5cclxuICBAcmV0dXJuIFdoZXRoZXIgdGhlIGVudGl0eSBwYXNzZWQgdmFsaWRhdGlvbi5cclxuICAqKi9cclxuICB2YWxpZGF0ZVByb3BlcnR5KHByb3BlcnR5OiBFbnRpdHlQcm9wZXJ0eSB8IHN0cmluZywgY29udGV4dDogYW55KSB7XHJcbiAgICBsZXQgdmFsdWUgPSB0aGlzLmdldFByb3BlcnR5VmFsdWUocHJvcGVydHkpOyAvLyBwZXJmb3JtcyB2YWxpZGF0aW9uc1xyXG4gICAgaWYgKHZhbHVlICYmIHZhbHVlLmNvbXBsZXhBc3BlY3QpIHtcclxuICAgICAgcmV0dXJuIHZhbGlkYXRlVGFyZ2V0KHZhbHVlKTtcclxuICAgIH1cclxuICAgIGNvbnRleHQgPSBjb250ZXh0IHx8IHt9O1xyXG4gICAgY29udGV4dC5lbnRpdHkgPSB0aGlzLmVudGl0eTtcclxuICAgIGlmICh0eXBlb2YgcHJvcGVydHkgPT09IFwic3RyaW5nXCIpIHtcclxuICAgICAgY29udGV4dC5wcm9wZXJ0eSA9IHRoaXMuZW50aXR5IS5lbnRpdHlUeXBlLmdldFByb3BlcnR5KHByb3BlcnR5LCB0cnVlKTtcclxuICAgICAgY29udGV4dC5wcm9wZXJ0eU5hbWUgPSBwcm9wZXJ0eTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnRleHQucHJvcGVydHkgPSBwcm9wZXJ0eTtcclxuICAgICAgY29udGV4dC5wcm9wZXJ0eU5hbWUgPSBwcm9wZXJ0eS5uYW1lO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLl92YWxpZGF0ZVByb3BlcnR5KHZhbHVlLCBjb250ZXh0KTtcclxuICB9XHJcblxyXG4gIGdldFZhbGlkYXRpb25FcnJvcnMoKTogVmFsaWRhdGlvbkVycm9yW107XHJcbiAgZ2V0VmFsaWRhdGlvbkVycm9ycyhwcm9wZXJ0eTogc3RyaW5nKTogVmFsaWRhdGlvbkVycm9yW107XHJcbiAgZ2V0VmFsaWRhdGlvbkVycm9ycyhwcm9wZXJ0eTogRW50aXR5UHJvcGVydHkpOiBWYWxpZGF0aW9uRXJyb3JbXTtcclxuICAvKipcclxuICBSZXR1cm5zIHRoZSB2YWxpZGF0aW9uIGVycm9ycyBhc3NvY2lhdGVkIHdpdGggZWl0aGVyIHRoZSBlbnRpcmUgZW50aXR5IG9yIGFueSBzcGVjaWZpZWQgcHJvcGVydHkuXHJcbiAgXHJcbiAgVGhpcyBtZXRob2QgY2FuIHJldHVybiBhbGwgb2YgdGhlIGVycm9ycyBmb3IgYW4gRW50aXR5XHJcbiAgPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgdmFyIHZhbEVycm9ycyA9IG9yZGVyLmVudGl0eUFzcGVjdC5nZXRWYWxpZGF0aW9uRXJyb3JzKCk7XHJcblxyXG4gIGFzIHdlbGwgYXMgdGhvc2UgZm9yIGp1c3QgYSBzcGVjaWZpYyBwcm9wZXJ0eS5cclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICB2YXIgb3JkZXJEYXRlRXJyb3JzID0gb3JkZXIuZW50aXR5QXNwZWN0LmdldFZhbGlkYXRpb25FcnJvcnMoXCJPcmRlckRhdGVcIik7XHJcblxyXG4gIHdoaWNoIGNhbiBhbHNvIGJlIGV4cHJlc3NlZCBhc1xyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIHZhciBvcmRlckRhdGVQcm9wZXJ0eSA9IG9yZGVyLmVudGl0eVR5cGUuZ2V0UHJvcGVydHkoXCJPcmRlckRhdGVcIik7XHJcbiAgPiAgICAgIHZhciBvcmRlckRhdGVFcnJvcnMgPSBvcmRlci5lbnRpdHlBc3BlY3QuZ2V0VmFsaWRhdGlvbkVycm9ycyhvcmRlckRhdGVQcm9wZXJ0eSk7XHJcbiAgQHBhcmFtIHByb3BlcnR5IC0gVGhlIHByb3BlcnR5IGZvciB3aGljaCB2YWxpZGF0aW9uIGVycm9ycyBzaG91bGQgYmUgcmV0cmlldmVkLlxyXG4gIElmIG9taXR0ZWQsIGFsbCBvZiB0aGUgdmFsaWRhdGlvbiBlcnJvcnMgZm9yIHRoaXMgZW50aXR5IHdpbGwgYmUgcmV0dXJuZWQuXHJcbiAgQHJldHVybiBBIGFycmF5IG9mIHZhbGlkYXRpb24gZXJyb3JzLlxyXG4gICoqL1xyXG4gIGdldFZhbGlkYXRpb25FcnJvcnMocHJvcGVydHk/OiBEYXRhUHJvcGVydHkgfCBOYXZpZ2F0aW9uUHJvcGVydHkgfCBzdHJpbmcpIHtcclxuICAgIGFzc2VydFBhcmFtKHByb3BlcnR5LCBcInByb3BlcnR5XCIpLmlzT3B0aW9uYWwoKS5pc0VudGl0eVByb3BlcnR5KCkub3IoKS5pc1N0cmluZygpLmNoZWNrKCk7XHJcbiAgICBsZXQgcmVzdWx0ID0gY29yZS5nZXRPd25Qcm9wZXJ0eVZhbHVlcyh0aGlzLl92YWxpZGF0aW9uRXJyb3JzKTtcclxuICAgIGlmIChwcm9wZXJ0eSkge1xyXG4gICAgICBsZXQgcHJvcGVydHlOYW1lID0gdHlwZW9mIChwcm9wZXJ0eSkgPT09ICdzdHJpbmcnID8gcHJvcGVydHkgOiBwcm9wZXJ0eS5uYW1lO1xyXG4gICAgICByZXN1bHQgPSByZXN1bHQuZmlsdGVyKGZ1bmN0aW9uICh2ZTogVmFsaWRhdGlvbkVycm9yKSB7XHJcbiAgICAgICAgcmV0dXJuIHZlLnByb3BlcnR5ICYmICh2ZS5wcm9wZXJ0eS5uYW1lID09PSBwcm9wZXJ0eU5hbWUgfHwgKHByb3BlcnR5TmFtZS5pbmRleE9mKFwiLlwiKSAhPT0gLTEgJiYgdmUucHJvcGVydHlOYW1lID09PSBwcm9wZXJ0eU5hbWUpKTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgQWRkcyBhIHZhbGlkYXRpb24gZXJyb3IuXHJcbiAgKiovXHJcbiAgYWRkVmFsaWRhdGlvbkVycm9yKHZhbGlkYXRpb25FcnJvcjogVmFsaWRhdGlvbkVycm9yKSB7XHJcbiAgICBhc3NlcnRQYXJhbSh2YWxpZGF0aW9uRXJyb3IsIFwidmFsaWRhdGlvbkVycm9yXCIpLmlzSW5zdGFuY2VPZihWYWxpZGF0aW9uRXJyb3IpLmNoZWNrKCk7XHJcbiAgICB0aGlzLl9wcm9jZXNzVmFsaWRhdGlvbk9wQW5kUHVibGlzaChmdW5jdGlvbiAodGhhdDogYW55KSB7XHJcbiAgICAgIHRoYXQuX2FkZFZhbGlkYXRpb25FcnJvcih2YWxpZGF0aW9uRXJyb3IpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICByZW1vdmVWYWxpZGF0aW9uRXJyb3IodmFsaWRhdGlvbkVycm9yOiBWYWxpZGF0aW9uRXJyb3IpOiB2b2lkO1xyXG4gIHJlbW92ZVZhbGlkYXRpb25FcnJvcih2YWxpZGF0aW9uS2V5OiBzdHJpbmcpOiB2b2lkO1xyXG4gIC8qKlxyXG4gIFJlbW92ZXMgYSB2YWxpZGF0aW9uIGVycm9yLlxyXG4gIEBwYXJhbSB2YWxpZGF0aW9uRXJyb3JPcktleSAtIEVpdGhlciBhIFZhbGlkYXRpb25FcnJvciBvciBhIFZhbGlkYXRpb25FcnJvciAna2V5JyB2YWx1ZVxyXG4gICoqL1xyXG4gIHJlbW92ZVZhbGlkYXRpb25FcnJvcih2YWxpZGF0aW9uRXJyb3JPcktleTogVmFsaWRhdGlvbkVycm9yIHwgc3RyaW5nKSB7XHJcbiAgICBhc3NlcnRQYXJhbSh2YWxpZGF0aW9uRXJyb3JPcktleSwgXCJ2YWxpZGF0aW9uRXJyb3JPcktleVwiKS5pc1N0cmluZygpLm9yKCkuaXNJbnN0YW5jZU9mKFZhbGlkYXRpb25FcnJvcikub3IoKS5pc0luc3RhbmNlT2YoVmFsaWRhdG9yKS5jaGVjaygpO1xyXG5cclxuICAgIGxldCBrZXkgPSAodHlwZW9mICh2YWxpZGF0aW9uRXJyb3JPcktleSkgPT09IFwic3RyaW5nXCIpID8gdmFsaWRhdGlvbkVycm9yT3JLZXkgOiB2YWxpZGF0aW9uRXJyb3JPcktleS5rZXk7XHJcbiAgICB0aGlzLl9wcm9jZXNzVmFsaWRhdGlvbk9wQW5kUHVibGlzaChmdW5jdGlvbiAodGhhdDogYW55KSB7XHJcbiAgICAgIHRoYXQuX3JlbW92ZVZhbGlkYXRpb25FcnJvcihrZXkpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZW1vdmVzIGFsbCBvZiB0aGUgdmFsaWRhdGlvbiBlcnJvcnMgZm9yIGEgc3BlY2lmaWVkIGVudGl0eVxyXG4gICoqL1xyXG4gIGNsZWFyVmFsaWRhdGlvbkVycm9ycygpIHtcclxuICAgIHRoaXMuX3Byb2Nlc3NWYWxpZGF0aW9uT3BBbmRQdWJsaXNoKGZ1bmN0aW9uICh0aGF0OiBhbnkpIHtcclxuICAgICAgY29yZS5vYmplY3RGb3JFYWNoKHRoYXQuX3ZhbGlkYXRpb25FcnJvcnMsIGZ1bmN0aW9uIChrZXk6IHN0cmluZywgdmFsRXJyb3I6IFZhbGlkYXRpb25FcnJvcikge1xyXG4gICAgICAgIGlmICh2YWxFcnJvcikge1xyXG4gICAgICAgICAgZGVsZXRlIHRoYXQuX3ZhbGlkYXRpb25FcnJvcnNba2V5XTtcclxuICAgICAgICAgIHRoYXQuX3BlbmRpbmdWYWxpZGF0aW9uUmVzdWx0LnJlbW92ZWQucHVzaCh2YWxFcnJvcik7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgICAgdGhhdC5oYXNWYWxpZGF0aW9uRXJyb3JzID0gIWNvcmUuaXNFbXB0eSh0aGF0Ll92YWxpZGF0aW9uRXJyb3JzKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhbiBbW0VudGl0eUtleV1dIGZvciB0aGUgZW50aXR5IHBvaW50ZWQgdG8gYnkgdGhlIHNwZWNpZmllZCBzY2FsYXIgTmF2aWdhdGlvblByb3BlcnR5LlxyXG4gIFRoaXMgb25seSByZXR1cm5zIGFuIEVudGl0eUtleSBpZiB0aGUgY3VycmVudCBlbnRpdHkgaXMgYSAnY2hpbGQnIGVudGl0eSBhbG9uZyB0aGUgc3BlY2lmaWVkIE5hdmlnYXRpb25Qcm9wZXJ0eS4gXHJcbiAgaS5lLiBoYXMgYSBzaW5nbGUgcGFyZW50LlxyXG5cclxuICBAcGFyYW0gbmF2aWdhdGlvblByb3BlcnR5IC0gVGhlIFtbTmF2aWdhdGlvblByb3BlcnR5XV0gKCBwb2ludGluZyB0byBhIHBhcmVudCkuIFxyXG4gIEByZXR1cm5zIEVpdGhlciBhIHBhcmVudCBFbnRpdHlLZXkgaWYgdGhpcyBpcyBhICdjaGlsZCcgZW50aXR5IG9yIG51bGw7ICBcclxuICAqL1xyXG4gIGdldFBhcmVudEtleShuYXZpZ2F0aW9uUHJvcGVydHk6IE5hdmlnYXRpb25Qcm9wZXJ0eSkge1xyXG4gICAgaWYgKCF0aGlzLmVudGl0eSkgcmV0dXJuIG51bGw7XHJcbiAgICAvLyBUT0RPOiByZXZpZXcgdGhpcyAtIG5vdCBzdXJlIGFib3V0IHRoZSBjb21tZW50LlxyXG4gICAgLy8gTmF2aWdhdGlvblByb3BlcnR5IGRvZXNuJ3QgeWV0IGV4aXN0XHJcbiAgICAvLyBhc3NlcnRQYXJhbShuYXZpZ2F0aW9uUHJvcGVydHksIFwibmF2aWdhdGlvblByb3BlcnR5XCIpLmlzSW5zdGFuY2VPZihOYXZpZ2F0aW9uUHJvcGVydHkpLmNoZWNrKCk7XHJcbiAgICBsZXQgZmtOYW1lcyA9IG5hdmlnYXRpb25Qcm9wZXJ0eS5mb3JlaWduS2V5TmFtZXM7XHJcbiAgICBpZiAoZmtOYW1lcy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xyXG4gICAgbGV0IHRoYXQgPSB0aGlzO1xyXG4gICAgbGV0IGZrVmFsdWVzID0gZmtOYW1lcy5tYXAoZnVuY3Rpb24gKGZrbikge1xyXG4gICAgICByZXR1cm4gdGhhdC5lbnRpdHkhLmdldFByb3BlcnR5KGZrbik7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBuZXcgRW50aXR5S2V5KG5hdmlnYXRpb25Qcm9wZXJ0eS5lbnRpdHlUeXBlLCBma1ZhbHVlcyk7XHJcbiAgfVxyXG5cclxuICAvLyBUT0RPOiByZWZhY3RvciB0aGlzIGFuZCB0aGUgc3RhdGljIGdldFByb3BlcnR5UGF0aFZhbHVlLlxyXG4gIC8qKlxyXG4gIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIERhdGFQcm9wZXJ0eSBvciBOYXZpZ2F0aW9uUHJvcGVydHkgb3IgJ3Byb3BlcnR5IHBhdGgnLiAgXHJcbiAgKiovXHJcbiAgZ2V0UHJvcGVydHlWYWx1ZShwcm9wZXJ0eTogc3RyaW5nIHwgRGF0YVByb3BlcnR5IHwgTmF2aWdhdGlvblByb3BlcnR5KSB7XHJcbiAgICBhc3NlcnRQYXJhbShwcm9wZXJ0eSwgXCJwcm9wZXJ0eVwiKS5pc1N0cmluZygpLm9yKCkuaXNFbnRpdHlQcm9wZXJ0eSgpLmNoZWNrKCk7XHJcbiAgICBsZXQgdmFsdWU6IGFueTtcclxuICAgIGlmICh0eXBlb2YgKHByb3BlcnR5KSA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgbGV0IHByb3BOYW1lcyA9IHByb3BlcnR5LnRyaW0oKS5zcGxpdChcIi5cIik7XHJcbiAgICAgIGxldCBwcm9wTmFtZSA9IHByb3BOYW1lcy5zaGlmdCgpO1xyXG4gICAgICB2YWx1ZSA9IHRoaXMuZW50aXR5O1xyXG4gICAgICB2YWx1ZSA9IHZhbHVlLmdldFByb3BlcnR5KHByb3BOYW1lKTtcclxuICAgICAgd2hpbGUgKHByb3BOYW1lcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgcHJvcE5hbWUgPSBwcm9wTmFtZXMuc2hpZnQoKTtcclxuICAgICAgICB2YWx1ZSA9IHZhbHVlLmdldFByb3BlcnR5KHByb3BOYW1lKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKCEocHJvcGVydHkucGFyZW50VHlwZSBpbnN0YW5jZW9mIEVudGl0eVR5cGUpKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHZhbGlkYXRlUHJvcGVydHkgbWV0aG9kIGRvZXMgbm90IGFjY2VwdCBhICdwcm9wZXJ0eScgcGFyYW1ldGVyIHdob3NlIHBhcmVudFR5cGUgaXMgYSBDb21wbGV4VHlwZTsgXCIgK1xyXG4gICAgICAgICAgXCJQYXNzIGEgJ3Byb3BlcnR5IHBhdGgnIHN0cmluZyBhcyB0aGUgJ3Byb3BlcnR5JyBwYXJhbWV0ZXIgaW5zdGVhZCBcIik7XHJcbiAgICAgIH1cclxuICAgICAgdmFsdWUgPSB0aGlzLmVudGl0eSEuZ2V0UHJvcGVydHkocHJvcGVydHkubmFtZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbiAgfVxyXG5cclxuICAvLyBpbnRlcm5hbCBtZXRob2RzXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2NoZWNrT3BlcmF0aW9uKG9wZXJhdGlvbk5hbWU6IHN0cmluZykge1xyXG4gICAgaWYgKHRoaXMuaXNCZWluZ1NhdmVkKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBwZXJmb3JtIGEgJ1wiICsgb3BlcmF0aW9uTmFtZSArIFwiJyBvbiBhbiBlbnRpdHkgdGhhdCBpcyBpbiB0aGUgcHJvY2VzcyBvZiBiZWluZyBzYXZlZFwiKTtcclxuICAgIH1cclxuICAgIC8vIGFsbG93cyBjaGFpbmluZ1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfZGV0YWNoKCkge1xyXG4gICAgdGhpcy5lbnRpdHlHcm91cCA9IHVuZGVmaW5lZDtcclxuICAgIHRoaXMuZW50aXR5TWFuYWdlciA9IHVuZGVmaW5lZDtcclxuICAgIHRoaXMuZW50aXR5U3RhdGUgPSBFbnRpdHlTdGF0ZS5EZXRhY2hlZDtcclxuICAgIHRoaXMub3JpZ2luYWxWYWx1ZXMgPSB7fTtcclxuICAgIHRoaXMuX3ZhbGlkYXRpb25FcnJvcnMgPSB7fTtcclxuICAgIHRoaXMuaGFzVmFsaWRhdGlvbkVycm9ycyA9IGZhbHNlO1xyXG4gICAgdGhpcy52YWxpZGF0aW9uRXJyb3JzQ2hhbmdlZC5jbGVhcigpO1xyXG4gICAgdGhpcy5wcm9wZXJ0eUNoYW5nZWQuY2xlYXIoKTtcclxuXHJcbiAgfVxyXG5cclxuXHJcbiAgLy8gY2FsbGVkIGZyb20gZGVmYXVsdEludGVyY2VwdG9yLlxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF92YWxpZGF0ZVByb3BlcnR5KHZhbHVlOiBhbnksIGNvbnRleHQ6IGFueSkge1xyXG4gICAgbGV0IG9rID0gdHJ1ZTtcclxuICAgIHRoaXMuX3Byb2Nlc3NWYWxpZGF0aW9uT3BBbmRQdWJsaXNoKGZ1bmN0aW9uICh0aGF0OiBhbnkpIHtcclxuICAgICAgY29udGV4dC5wcm9wZXJ0eS5nZXRBbGxWYWxpZGF0b3JzKCkuZm9yRWFjaChmdW5jdGlvbiAodmFsaWRhdG9yOiBWYWxpZGF0b3IpIHtcclxuICAgICAgICBvayA9IHZhbGlkYXRlKHRoYXQsIHZhbGlkYXRvciwgdmFsdWUsIGNvbnRleHQpICYmIG9rO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIG9rO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3Byb2Nlc3NWYWxpZGF0aW9uT3BBbmRQdWJsaXNoKHZhbGlkYXRpb25GbjogYW55KSB7XHJcbiAgICBpZiAodGhpcy5fcGVuZGluZ1ZhbGlkYXRpb25SZXN1bHQpIHtcclxuICAgICAgLy8gb25seSB0b3AgbGV2ZWwgcHJvY2Vzc1ZhbGlkYXRpb25zIGNhbGwgcHVibGlzaGVzXHJcbiAgICAgIHZhbGlkYXRpb25Gbih0aGlzKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgdGhpcy5fcGVuZGluZ1ZhbGlkYXRpb25SZXN1bHQgPSB7IGVudGl0eTogdGhpcy5lbnRpdHksIGFkZGVkOiBbXSwgcmVtb3ZlZDogW10gfTtcclxuICAgICAgICB2YWxpZGF0aW9uRm4odGhpcyk7XHJcbiAgICAgICAgaWYgKHRoaXMuX3BlbmRpbmdWYWxpZGF0aW9uUmVzdWx0LmFkZGVkLmxlbmd0aCA+IDAgfHwgdGhpcy5fcGVuZGluZ1ZhbGlkYXRpb25SZXN1bHQucmVtb3ZlZC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICB0aGlzLnZhbGlkYXRpb25FcnJvcnNDaGFuZ2VkLnB1Ymxpc2godGhpcy5fcGVuZGluZ1ZhbGlkYXRpb25SZXN1bHQpO1xyXG4gICAgICAgICAgLy8gdGhpcyBtaWdodCBiZSBhIGRldGFjaGVkIGVudGl0eSBoZW5jZSB0aGUgZ3VhcmQgYmVsb3cuXHJcbiAgICAgICAgICB0aGlzLmVudGl0eU1hbmFnZXIgJiYgdGhpcy5lbnRpdHlNYW5hZ2VyLnZhbGlkYXRpb25FcnJvcnNDaGFuZ2VkLnB1Ymxpc2godGhpcy5fcGVuZGluZ1ZhbGlkYXRpb25SZXN1bHQpO1xyXG5cclxuICAgICAgICB9XHJcbiAgICAgIH0gZmluYWxseSB7XHJcbiAgICAgICAgdGhpcy5fcGVuZGluZ1ZhbGlkYXRpb25SZXN1bHQgPSB1bmRlZmluZWQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIC8vIFRPRE86IGFkZC91c2UgYSBWYWxpZGF0aW9uRXJyb3IgdHlwZVxyXG4gIF9hZGRWYWxpZGF0aW9uRXJyb3IodmFsaWRhdGlvbkVycm9yOiBhbnkpIHtcclxuICAgIHRoaXMuX3ZhbGlkYXRpb25FcnJvcnNbdmFsaWRhdGlvbkVycm9yLmtleV0gPSB2YWxpZGF0aW9uRXJyb3I7XHJcbiAgICB0aGlzLmhhc1ZhbGlkYXRpb25FcnJvcnMgPSB0cnVlO1xyXG4gICAgdGhpcy5fcGVuZGluZ1ZhbGlkYXRpb25SZXN1bHQuYWRkZWQucHVzaCh2YWxpZGF0aW9uRXJyb3IpO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3JlbW92ZVZhbGlkYXRpb25FcnJvcihrZXk6IHN0cmluZykge1xyXG4gICAgbGV0IHZhbEVycm9yID0gdGhpcy5fdmFsaWRhdGlvbkVycm9yc1trZXldO1xyXG4gICAgaWYgKHZhbEVycm9yKSB7XHJcbiAgICAgIGRlbGV0ZSB0aGlzLl92YWxpZGF0aW9uRXJyb3JzW2tleV07XHJcbiAgICAgIHRoaXMuaGFzVmFsaWRhdGlvbkVycm9ycyA9ICFjb3JlLmlzRW1wdHkodGhpcy5fdmFsaWRhdGlvbkVycm9ycyk7XHJcbiAgICAgIHRoaXMuX3BlbmRpbmdWYWxpZGF0aW9uUmVzdWx0LnJlbW92ZWQucHVzaCh2YWxFcnJvcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxufVxyXG5cclxuQnJlZXplRXZlbnQuYnViYmxlRXZlbnQoRW50aXR5QXNwZWN0LnByb3RvdHlwZSwgZnVuY3Rpb24gKCkge1xyXG4gIHJldHVybiB0aGlzLmVudGl0eU1hbmFnZXI7XHJcbn0pO1xyXG5cclxuZnVuY3Rpb24gcmVqZWN0Q2hhbmdlc0NvcmUodGFyZ2V0OiBhbnkpIHtcclxuICBsZXQgYXNwZWN0ID0gdGFyZ2V0LmVudGl0eUFzcGVjdCB8fCB0YXJnZXQuY29tcGxleEFzcGVjdDtcclxuICBsZXQgc3R5cGUgPSB0YXJnZXQuZW50aXR5VHlwZSB8fCB0YXJnZXQuY29tcGxleFR5cGU7XHJcbiAgbGV0IG9yaWdpbmFsVmFsdWVzID0gYXNwZWN0Lm9yaWdpbmFsVmFsdWVzO1xyXG4gIGZvciAobGV0IHByb3BOYW1lIGluIG9yaWdpbmFsVmFsdWVzKSB7XHJcbiAgICB0YXJnZXQuc2V0UHJvcGVydHkocHJvcE5hbWUsIG9yaWdpbmFsVmFsdWVzW3Byb3BOYW1lXSk7XHJcbiAgfVxyXG4gIHN0eXBlLmNvbXBsZXhQcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24gKGNwOiBhbnkpIHtcclxuICAgIGxldCBjb3MgPSB0YXJnZXQuZ2V0UHJvcGVydHkoY3AubmFtZSk7XHJcbiAgICBpZiAoY3AuaXNTY2FsYXIpIHtcclxuICAgICAgcmVqZWN0Q2hhbmdlc0NvcmUoY29zKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvcy5fcmVqZWN0Q2hhbmdlcygpO1xyXG4gICAgICBjb3MuZm9yRWFjaChyZWplY3RDaGFuZ2VzQ29yZSk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlbW92ZUZyb21SZWxhdGlvbnMoZW50aXR5OiBFbnRpdHksIGVudGl0eVN0YXRlOiBFbnRpdHlTdGF0ZSkge1xyXG4gIC8vIHJlbW92ZSB0aGlzIGVudGl0eSBmcm9tIGFueSBjb2xsZWN0aW9ucy5cclxuICAvLyBtYXJrIHRoZSBlbnRpdHkgZGVsZXRlZCBvciBkZXRhY2hlZFxyXG5cclxuICBsZXQgaXNEZWxldGVkID0gZW50aXR5U3RhdGUuaXNEZWxldGVkKCk7XHJcbiAgaWYgKGlzRGVsZXRlZCkge1xyXG4gICAgcmVtb3ZlRnJvbVJlbGF0aW9uc0NvcmUoZW50aXR5KTtcclxuICB9IGVsc2Uge1xyXG4gICAgY29yZS51c2luZyhlbnRpdHkuZW50aXR5QXNwZWN0LmVudGl0eU1hbmFnZXIhLCBcImlzTG9hZGluZ1wiLCB0cnVlLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHJlbW92ZUZyb21SZWxhdGlvbnNDb3JlKGVudGl0eSk7XHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlbW92ZUZyb21SZWxhdGlvbnNDb3JlKGVudGl0eTogRW50aXR5KSB7XHJcbiAgZW50aXR5LmVudGl0eVR5cGUubmF2aWdhdGlvblByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbiAobnApIHtcclxuICAgIGxldCBpbnZlcnNlTnAgPSBucC5pbnZlcnNlO1xyXG4gICAgbGV0IG5wVmFsdWUgPSBlbnRpdHkuZ2V0UHJvcGVydHkobnAubmFtZSk7XHJcbiAgICBpZiAobnAuaXNTY2FsYXIpIHtcclxuICAgICAgaWYgKG5wVmFsdWUpIHtcclxuICAgICAgICBpZiAoaW52ZXJzZU5wKSB7XHJcbiAgICAgICAgICBpZiAoaW52ZXJzZU5wLmlzU2NhbGFyKSB7XHJcbiAgICAgICAgICAgIG5wVmFsdWUuc2V0UHJvcGVydHkoaW52ZXJzZU5wLm5hbWUsIG51bGwpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbGV0IGNvbGxlY3Rpb24gPSBucFZhbHVlLmdldFByb3BlcnR5KGludmVyc2VOcC5uYW1lKTtcclxuICAgICAgICAgICAgaWYgKGNvbGxlY3Rpb24ubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgY29yZS5hcnJheVJlbW92ZUl0ZW0oY29sbGVjdGlvbiwgZW50aXR5KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbnRpdHkuc2V0UHJvcGVydHkobnAubmFtZSwgbnVsbCk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmIChpbnZlcnNlTnAgIT0gbnVsbCkge1xyXG4gICAgICAgIC8vIG5wVmFsdWUgaXMgYSBsaXZlIGxpc3Qgc28gd2UgbmVlZCB0byBjb3B5IGl0IGZpcnN0LlxyXG4gICAgICAgIG5wVmFsdWUuc2xpY2UoMCkuZm9yRWFjaCgodjogYW55KSA9PiB7XHJcbiAgICAgICAgICBpZiAoaW52ZXJzZU5wIS5pc1NjYWxhcikge1xyXG4gICAgICAgICAgICB2LnNldFByb3BlcnR5KGludmVyc2VOcCEubmFtZSwgbnVsbCk7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBUT0RPOiBtYW55IHRvIG1hbnkgLSBub3QgeWV0IGhhbmRsZWQuXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgICAgLy8gbm93IGNsZWFyIGl0LlxyXG4gICAgICBucFZhbHVlLmxlbmd0aCA9IDA7XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG59XHJcblxyXG4vLyBub3RlIGVudGl0eUFzcGVjdCBvbmx5IC0gKCBubyBjb21wbGV4IGFzcGVjdCBhbGxvd2VkIG9uIHRoZSBjYWxsKS5cclxuZnVuY3Rpb24gdmFsaWRhdGUoZW50aXR5QXNwZWN0OiBFbnRpdHlBc3BlY3QsIHZhbGlkYXRvcjogVmFsaWRhdG9yLCB2YWx1ZTogYW55LCBjb250ZXh0PzogYW55KSB7XHJcbiAgbGV0IHZlID0gdmFsaWRhdG9yLnZhbGlkYXRlKHZhbHVlLCBjb250ZXh0KTtcclxuICBpZiAodmUpIHtcclxuICAgIGVudGl0eUFzcGVjdC5fYWRkVmFsaWRhdGlvbkVycm9yKHZlKTtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9IGVsc2Uge1xyXG4gICAgbGV0IGtleSA9IFZhbGlkYXRpb25FcnJvci5nZXRLZXkodmFsaWRhdG9yLCBjb250ZXh0ID8gY29udGV4dC5wcm9wZXJ0eU5hbWUgOiBudWxsKTtcclxuICAgIGVudGl0eUFzcGVjdC5fcmVtb3ZlVmFsaWRhdGlvbkVycm9yKGtleSk7XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcbn1cclxuXHJcbi8vIGNvSW5kZXggaXMgb25seSB1c2VkIHdoZXJlIHRhcmdldCBpcyBhIGNvbXBsZXggb2JqZWN0IHRoYXQgaXMgcGFydCBvZiBhbiBhcnJheSBvZiBjb21wbGV4IG9iamVjdHNcclxuLy8gaW4gd2hpY2ggY2FzZSBjdEluZGV4IGlzIHRoZSBpbmRleCBvZiB0aGUgdGFyZ2V0IHdpdGhpbiB0aGUgYXJyYXkuXHJcbmZ1bmN0aW9uIHZhbGlkYXRlVGFyZ2V0KHRhcmdldDogYW55LCBjb0luZGV4PzogbnVtYmVyKSB7XHJcbiAgbGV0IG9rID0gdHJ1ZTtcclxuICBsZXQgc3R5cGUgPSB0YXJnZXQuZW50aXR5VHlwZSB8fCB0YXJnZXQuY29tcGxleFR5cGU7XHJcbiAgbGV0IGFzcGVjdCA9IHRhcmdldC5lbnRpdHlBc3BlY3QgfHwgdGFyZ2V0LmNvbXBsZXhBc3BlY3Q7XHJcbiAgbGV0IGVudGl0eUFzcGVjdCA9IHRhcmdldC5lbnRpdHlBc3BlY3QgfHwgdGFyZ2V0LmNvbXBsZXhBc3BlY3QuZ2V0RW50aXR5QXNwZWN0KCk7XHJcbiAgbGV0IGNvbnRleHQgPSA8YW55PnsgZW50aXR5OiBlbnRpdHlBc3BlY3QuZW50aXR5IH07XHJcbiAgaWYgKGNvSW5kZXggIT09IHVuZGVmaW5lZCkge1xyXG4gICAgY29udGV4dC5pbmRleCA9IGNvSW5kZXg7XHJcbiAgfVxyXG5cclxuICBzdHlwZS5nZXRQcm9wZXJ0aWVzKCkuZm9yRWFjaChmdW5jdGlvbiAocDogYW55KSB7XHJcbiAgICBsZXQgdmFsdWUgPSB0YXJnZXQuZ2V0UHJvcGVydHkocC5uYW1lKTtcclxuICAgIGxldCB2YWxpZGF0b3JzID0gcC5nZXRBbGxWYWxpZGF0b3JzKCk7XHJcbiAgICBpZiAodmFsaWRhdG9ycy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGNvbnRleHQucHJvcGVydHkgPSBwO1xyXG4gICAgICBjb250ZXh0LnByb3BlcnR5TmFtZSA9IGFzcGVjdC5nZXRQcm9wZXJ0eVBhdGgocC5uYW1lKTtcclxuICAgICAgb2sgPSBlbnRpdHlBc3BlY3QuX3ZhbGlkYXRlUHJvcGVydHkodmFsdWUsIGNvbnRleHQpICYmIG9rO1xyXG4gICAgfVxyXG4gICAgaWYgKHAuaXNDb21wbGV4UHJvcGVydHkpIHtcclxuICAgICAgaWYgKHAuaXNTY2FsYXIpIHtcclxuICAgICAgICBvayA9IHZhbGlkYXRlVGFyZ2V0KHZhbHVlKSAmJiBvaztcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBvayA9IHZhbHVlLnJlZHVjZShmdW5jdGlvbiAocHY6IGFueSwgY3Y6IGFueSwgaXg6IG51bWJlcikge1xyXG4gICAgICAgICAgcmV0dXJuIHZhbGlkYXRlVGFyZ2V0KGN2LCBpeCkgJiYgcHY7XHJcbiAgICAgICAgfSwgb2spO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG5cclxuICAvLyB0aGVuIHRhcmdldCBsZXZlbFxyXG4gIHN0eXBlLmdldEFsbFZhbGlkYXRvcnMoKS5mb3JFYWNoKGZ1bmN0aW9uICh2YWxpZGF0b3I6IFZhbGlkYXRvcikge1xyXG4gICAgb2sgPSB2YWxpZGF0ZShlbnRpdHlBc3BlY3QsIHZhbGlkYXRvciwgdGFyZ2V0KSAmJiBvaztcclxuICB9KTtcclxuICByZXR1cm4gb2s7XHJcbn1cclxuXHJcbi8qKlxyXG5BbiBDb21wbGV4QXNwZWN0IGluc3RhbmNlIGlzIGFzc29jaWF0ZWQgd2l0aCBldmVyeSBjb21wbGV4IG9iamVjdCBpbnN0YW5jZSBhbmQgaXMgYWNjZXNzZWQgdmlhIHRoZSBjb21wbGV4IG9iamVjdCdzICdjb21wbGV4QXNwZWN0JyBwcm9wZXJ0eS5cclxuXHJcblRoZSBDb21wbGV4QXNwZWN0IGl0c2VsZiBwcm92aWRlcyBwcm9wZXJ0aWVzIHRvIGRldGVybWluZSB0aGUgcGFyZW50IG9iamVjdCwgcGFyZW50IHByb3BlcnR5IGFuZCBvcmlnaW5hbCB2YWx1ZXMgZm9yIHRoZSBjb21wbGV4IG9iamVjdC5cclxuXHJcbkEgQ29tcGxleEFzcGVjdCB3aWxsIGFsbW9zdCBuZXZlciBuZWVkIHRvIGJlIGNvbnN0cnVjdGVkIGRpcmVjdGx5LiBZb3Ugd2lsbCB1c3VhbGx5IGdldCBhbiBDb21wbGV4QXNwZWN0IGJ5IGFjY2Vzc2luZ1xyXG5hbiBlbnRpdGllcyAnY29tcGxleEFzcGVjdCcgcHJvcGVydHkuICBUaGlzIHByb3BlcnR5IHdpbGwgYmUgYXV0b21hdGljYWxseSBhdHRhY2hlZCB3aGVuIGFuIGNvbXBsZXggb2JqZWN0IGlzIGNyZWF0ZWQgYXMgcGFydCBvZiBhblxyXG5lbnRpdHkgdmlhIGVpdGhlciBhIHF1ZXJ5LCBpbXBvcnQgb3IgRW50aXR5TWFuYWdlci5jcmVhdGVFbnRpdHkgY2FsbC5cclxuPiAgICAgIC8vIGFzc3VtZSBhZGRyZXNzIGlzIGEgY29tcGxleCBwcm9wZXJ0eSBvbiB0aGUgJ0N1c3RvbWVyJyB0eXBlXHJcbj4gICAgICB2YXIgYXNwZWN0ID0gYUN1c3RvbWVyLmFkZHJlc3MuY29tcGxleEFzcGVjdDtcclxuPiAgICAgIC8vIGFDdXN0b21lciA9PT0gYXNwZWN0LnBhcmVudDtcclxuKiovXHJcbmV4cG9ydCBjbGFzcyBDb21wbGV4QXNwZWN0IHtcclxuXHJcbiAgLyoqIFRoZSBjb21wbGV4IG9iamVjdCB0aGF0IHRoaXMgYXNwZWN0IGlzIGFzc29jaWF0ZWQgd2l0aC4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGNvbXBsZXhPYmplY3Q6IENvbXBsZXhPYmplY3Q7XHJcbiAgLyoqIFRoZSAnb3JpZ2luYWwgdmFsdWVzJyBvZiB0aGlzIGNvbXBsZXggb2JqZWN0IHdoZXJlIHRoZXkgYXJlIGRpZmZlcmVudCBmcm9tIHRoZSAnY3VycmVudCB2YWx1ZXMnLlxyXG4gIFRoaXMgaXMgYSBtYXAgd2hlcmUgdGhlIGtleSBpcyBhIHByb3BlcnR5IG5hbWUgYW5kIHRoZSB2YWx1ZSBpcyB0aGUgJ29yaWdpbmFsIHZhbHVlJyBvZiB0aGUgcHJvcGVydHkuXHJcbiAgX19SZWFkIE9ubHlfXyAqL1xyXG4gIG9yaWdpbmFsVmFsdWVzOiB7fTtcclxuICAvKiogVGhlIHBhcmVudCBvYmplY3QgdGhhdCB0byB3aGljaCB0aGlzIGFzcGVjdCBiZWxvbmdzOyB0aGlzIHdpbGwgZWl0aGVyIGJlIGFuIGVudGl0eSBvciBhbm90aGVyIGNvbXBsZXggb2JqZWN0LiBfX1JlYWQgT25seV9fICovXHJcbiAgcGFyZW50PzogU3RydWN0dXJhbE9iamVjdDtcclxuICAvKiogVGhlIFtbRGF0YVByb3BlcnR5XV0gb24gdGhlICdwYXJlbnQnIHRoYXQgY29udGFpbnMgdGhpcyBjb21wbGV4IG9iamVjdC4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIHBhcmVudFByb3BlcnR5PzogRGF0YVByb3BlcnR5O1xyXG4gIGV4dHJhTWV0YWRhdGE/OiBhbnk7XHJcblxyXG4gIC8qKiBZb3Ugd2lsbCByYXJlbHksIGlmIGV2ZXIsIGNyZWF0ZSBhIENvbXBsZXhBc3BlY3QgZGlyZWN0bHkuICovXHJcbiAgY29uc3RydWN0b3IoY29tcGxleE9iamVjdDogQ29tcGxleE9iamVjdCwgcGFyZW50OiBTdHJ1Y3R1cmFsT2JqZWN0LCBwYXJlbnRQcm9wZXJ0eTogRGF0YVByb3BlcnR5KSB7XHJcbiAgICBpZiAoIWNvbXBsZXhPYmplY3QpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlICBDb21wbGV4QXNwZWN0IGN0b3IgcmVxdWlyZXMgYW4gZW50aXR5IGFzIGl0cyBvbmx5IGFyZ3VtZW50LlwiKTtcclxuICAgIH1cclxuICAgIGlmIChjb21wbGV4T2JqZWN0LmNvbXBsZXhBc3BlY3QpIHtcclxuICAgICAgcmV0dXJuIGNvbXBsZXhPYmplY3QuY29tcGxleEFzcGVjdDtcclxuICAgIH1cclxuICAgIC8vIGlmIGNhbGxlZCB3aXRob3V0IG5ld1xyXG4gICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIENvbXBsZXhBc3BlY3QpKSB7XHJcbiAgICAgIHJldHVybiBuZXcgQ29tcGxleEFzcGVjdChjb21wbGV4T2JqZWN0LCBwYXJlbnQsIHBhcmVudFByb3BlcnR5KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBlbnRpdHlUeXBlIHNob3VsZCBhbHJlYWR5IGJlIG9uIHRoZSBlbnRpdHkgZnJvbSAnd2F0Y2gnXHJcbiAgICB0aGlzLmNvbXBsZXhPYmplY3QgPSBjb21wbGV4T2JqZWN0O1xyXG4gICAgY29tcGxleE9iamVjdC5jb21wbGV4QXNwZWN0ID0gdGhpcztcclxuXHJcbiAgICAvLyBUT0RPOiBrZWVwIHB1YmxpYyBvciBub3Q/XHJcbiAgICB0aGlzLm9yaWdpbmFsVmFsdWVzID0ge307XHJcblxyXG4gICAgLy8gaWYgYSBzdGFuZGFsb25lIGNvbXBsZXhPYmplY3RcclxuICAgIGlmIChwYXJlbnQgIT0gbnVsbCkge1xyXG4gICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDtcclxuICAgICAgdGhpcy5wYXJlbnRQcm9wZXJ0eSA9IHBhcmVudFByb3BlcnR5O1xyXG4gICAgfVxyXG5cclxuICAgIGxldCBjb21wbGV4VHlwZSA9IGNvbXBsZXhPYmplY3QuY29tcGxleFR5cGU7XHJcbiAgICBpZiAoIWNvbXBsZXhUeXBlKSB7XHJcbiAgICAgIGxldCB0eXBlTmFtZSA9IGNvbXBsZXhPYmplY3QucHJvdG90eXBlLl8kdHlwZU5hbWU7XHJcbiAgICAgIGlmICghdHlwZU5hbWUpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIGVudGl0eSBpcyBub3QgcmVnaXN0ZXJlZCBhcyBhIHZhbGlkIENvbXBsZXhUeXBlXCIpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1ldGFkYXRhIGZvciB0aGlzIGNvbXBsZXhUeXBlIGhhcyBub3QgeWV0IGJlZW4gcmVzb2x2ZWQ6IFwiICsgdHlwZU5hbWUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBsZXQgY29tcGxleEN0b3IgPSBjb21wbGV4VHlwZS5nZXRDdG9yKCk7XHJcbiAgICBjb25maWcuaW50ZXJmYWNlUmVnaXN0cnkubW9kZWxMaWJyYXJ5LmdldERlZmF1bHRJbnN0YW5jZSgpLnN0YXJ0VHJhY2tpbmcoY29tcGxleE9iamVjdCwgY29tcGxleEN0b3IucHJvdG90eXBlKTtcclxuXHJcbiAgfVxyXG5cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyB0aGUgRW50aXR5QXNwZWN0IGZvciB0aGUgdG9wIGxldmVsIGVudGl0eSB0aGF0IGNvbnRhaW5zIHRoaXMgY29tcGxleCBvYmplY3QuXHJcbiAgKiovXHJcbiAgZ2V0RW50aXR5QXNwZWN0KCkge1xyXG4gICAgbGV0IHBhcmVudCA9IDxhbnk+dGhpcy5wYXJlbnQ7XHJcbiAgICBpZiAoIXBhcmVudCkgcmV0dXJuIG5ldyBFbnRpdHlBc3BlY3QoKTtcclxuICAgIGxldCBlbnRpdHlBc3BlY3QgPSBwYXJlbnQuZW50aXR5QXNwZWN0O1xyXG4gICAgd2hpbGUgKHBhcmVudCAmJiAhZW50aXR5QXNwZWN0KSB7XHJcbiAgICAgIHBhcmVudCA9IHBhcmVudC5jb21wbGV4QXNwZWN0ICYmIHBhcmVudC5jb21wbGV4QXNwZWN0LnBhcmVudDtcclxuICAgICAgZW50aXR5QXNwZWN0ID0gcGFyZW50ICYmIHBhcmVudC5lbnRpdHlBc3BlY3Q7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZW50aXR5QXNwZWN0IHx8IG5ldyBFbnRpdHlBc3BlY3QoKTtcclxuICB9XHJcblxyXG4gIC8qKiAgQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICAvLyBUT0RPOiByZW5hbWUgLSBhbmQgdXNlICdfJzsgdXNlZCBvbiBib3RoIEVudGl0eUFzcGVjdCBhbmQgQ29tcGxleEFzcGVjdCBmb3IgcG9seW1vcnBoaWMgcmVhc29ucy5cclxuICBnZXRQcm9wZXJ0eVBhdGgocHJvcE5hbWU6IHN0cmluZykge1xyXG4gICAgbGV0IHBhcmVudCA9IDxhbnk+dGhpcy5wYXJlbnQ7XHJcbiAgICBpZiAoIXBhcmVudCkgcmV0dXJuIG51bGw7XHJcbiAgICBsZXQgYXNwZWN0ID0gcGFyZW50LmNvbXBsZXhBc3BlY3QgfHwgcGFyZW50LmVudGl0eUFzcGVjdDtcclxuICAgIHJldHVybiBhc3BlY3QuZ2V0UHJvcGVydHlQYXRoKHRoaXMucGFyZW50UHJvcGVydHkhLm5hbWUgKyBcIi5cIiArIHByb3BOYW1lKTtcclxuICB9XHJcblxyXG59XHJcblxyXG5mdW5jdGlvbiBjbGVhck9yaWdpbmFsVmFsdWVzKHRhcmdldDogYW55KSB7XHJcbiAgbGV0IGFzcGVjdCA9IHRhcmdldC5lbnRpdHlBc3BlY3QgfHwgdGFyZ2V0LmNvbXBsZXhBc3BlY3Q7XHJcbiAgYXNwZWN0Lm9yaWdpbmFsVmFsdWVzID0ge307XHJcbiAgbGV0IHN0eXBlID0gdGFyZ2V0LmVudGl0eVR5cGUgfHwgdGFyZ2V0LmNvbXBsZXhUeXBlO1xyXG4gIHN0eXBlLmNvbXBsZXhQcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24gKGNwOiBhbnkpIHtcclxuICAgIGxldCBjb3MgPSB0YXJnZXQuZ2V0UHJvcGVydHkoY3AubmFtZSk7XHJcbiAgICBpZiAoY3AuaXNTY2FsYXIpIHtcclxuICAgICAgY2xlYXJPcmlnaW5hbFZhbHVlcyhjb3MpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29zLl9hY2NlcHRDaGFuZ2VzKCk7XHJcbiAgICAgIGNvcy5mb3JFYWNoKGNsZWFyT3JpZ2luYWxWYWx1ZXMpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG5cclxuIl19