breeze-client 2.1.2 → 2.1.3-mjs

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