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,1023 +0,0 @@
1
- import { __extends, __read, __spread } from "tslib";
2
- import { core } from './core';
3
- import { assertParam } from './assert-param';
4
- import { DataType } from './data-type';
5
- import { EntityAspect } from './entity-aspect';
6
- import { EntityKey } from './entity-key';
7
- import { BreezeEnum } from './enum';
8
- import { DataService } from './data-service';
9
- import { EntityType } from './entity-metadata';
10
- import { QueryOptions } from './query-options';
11
- import { Predicate } from './predicate';
12
- /**
13
- An EntityQuery instance is used to query entities either from a remote datasource or from a local [[EntityManager]].
14
-
15
- EntityQueries are immutable - this means that all EntityQuery methods that return an EntityQuery actually create a new EntityQuery. This means that
16
- EntityQueries can be 'modified' without affecting any current instances.
17
- @dynamic
18
- **/
19
- var EntityQuery = /** @class */ (function () {
20
- /** Constructor
21
- > let query = new EntityQuery("Customers")
22
-
23
- Usually this constructor will be followed by calls to filtering, ordering or selection methods
24
- > let query = new EntityQuery("Customers")
25
- > .where("CompanyName", "startsWith", "C")
26
- > .orderBy("Region");
27
- @param resourceName - either a resource name or a serialized EntityQuery ( created by [[EntityQuery.toJSON]])
28
- **/
29
- function EntityQuery(resourceName) {
30
- if (resourceName != null && (typeof resourceName !== 'string')) {
31
- return fromJSON(this, resourceName);
32
- }
33
- // TODO: cast as string below needed for early versions of TypeDoc - but not for regular compile - check later
34
- this.resourceName = resourceName;
35
- this.fromEntityType = undefined;
36
- this.wherePredicate = undefined;
37
- this.orderByClause = undefined;
38
- this.selectClause = undefined;
39
- this.skipCount = undefined;
40
- this.takeCount = undefined;
41
- this.expandClause = undefined;
42
- this.parameters = {};
43
- this.inlineCountEnabled = false;
44
- this.noTrackingEnabled = false;
45
- // default is to get queryOptions and dataService from the entityManager.
46
- // this.queryOptions = new QueryOptions();
47
- // this.dataService = new DataService();
48
- this.entityManager = undefined;
49
- }
50
- /**
51
- Specifies the resource to query for this EntityQuery.
52
- > let query = new EntityQuery()
53
- > .from("Customers");
54
-
55
- is the same as
56
- > let query = new EntityQuery("Customers");
57
- @param resourceName - The resource to query.
58
- **/
59
- EntityQuery.prototype.from = function (resourceName) {
60
- // TODO: think about allowing entityType as well
61
- assertParam(resourceName, "resourceName").isString().check();
62
- return clone(this, "resourceName", resourceName);
63
- };
64
- /**
65
- This is a static version of the "from" method and it creates a 'base' entityQuery for the specified resource name.
66
- > let query = EntityQuery.from("Customers");
67
-
68
- is the same as
69
- > let query = new EntityQuery("Customers");
70
- @param resourceName - The resource to query.
71
- **/
72
- EntityQuery.from = function (resourceName) {
73
- assertParam(resourceName, "resourceName").isString().check();
74
- return new EntityQuery(resourceName);
75
- };
76
- /**
77
- Specifies the top level EntityType that this query will return. Only needed when a query returns a json result that does not include type information,
78
- or when using a resource name that is not associated to an EntityType.
79
- > let query = new EntityQuery()
80
- > .from("MyCustomMethod")
81
- > .toType("Customer")
82
- @param entityType - The top level EntityType that this query will return.
83
- @summary If the json result consists of more than a simple entity or array of entities, consider using a [[JsonResultsAdapter]] instead.
84
- **/
85
- EntityQuery.prototype.toType = function (entityType) {
86
- assertParam(entityType, "entityType").isString().or().isInstanceOf(EntityType).check();
87
- return clone(this, "resultEntityType", entityType);
88
- };
89
- /**
90
- Returns a new query with an added filter criteria; Can be called multiple times which means to 'and' with any existing
91
- Predicate or can be called with null to clear all predicates.
92
- > let query = new EntityQuery("Customers")
93
- > .where("CompanyName", "startsWith", "C");
94
-
95
- This can also be expressed using an explicit [[FilterQueryOp]] as
96
- > let query = new EntityQuery("Customers")
97
- > .where("CompanyName", FilterQueryOp.StartsWith, "C");
98
-
99
- or a preconstructed [[Predicate]] may be used
100
- > let pred = new Predicate("CompanyName", FilterQueryOp.StartsWith, "C");
101
- > let query = new EntityQuery("Customers").where(pred);
102
-
103
- Predicates are often useful when you want to combine multiple conditions in a single filter, such as
104
- > let pred = Predicate.create("CompanyName", "startswith", "C").and("Region", FilterQueryOp.Equals, null);
105
- > let query = new EntityQuery("Customers")
106
- > .where(pred);
107
-
108
- More complicated queries can make use of nested property paths
109
- > let query = new EntityQuery("Products")
110
- > .where("Category.CategoryName", "startswith", "S");
111
-
112
- or OData functions - A list of valid OData functions can be found within the [[Predicate]] documentation.
113
-
114
- > let query = new EntityQuery("Customers")
115
- > .where("toLower(CompanyName)", "startsWith", "c");
116
-
117
- or to be even more baroque
118
- > let query = new EntityQuery("Customers")
119
- > .where("toUpper(substring(CompanyName, 1, 2))", FilterQueryOp.Equals, "OM");
120
- @param predicate - Can be either
121
- - a single [[Predicate]]
122
-
123
- - the parameters to create a 'simple' Predicate
124
- - - a property name, a property path with '.' as path seperators or a property expression {String}
125
- - - an operator - [[FilterQueryOp]] or it's string representation. Case is ignored
126
- when if a string is provided and any string that matches one of the FilterQueryOp aliases will be accepted.
127
- - - a value {Object} - This will be treated as either a property expression or a literal depending on context.
128
- In general, if the value can be interpreted as a property expression it will be, otherwise it will be treated as a literal.
129
- In most cases this works well, but you can also force the interpretation by making the value argument itself an object
130
- with a 'value' property and an 'isLiteral' property set to either true or false.
131
- Breeze also tries to infer the dataType of any literal based on context, if this fails you can force this inference by making the value argument
132
- an object with a 'value' property and a 'dataType'property set to one of the DataType enumeration instances.
133
-
134
- - a null or undefined ( this causes any existing where clause to be removed)
135
- **/
136
- EntityQuery.prototype.where = function () {
137
- var args = [];
138
- for (var _i = 0; _i < arguments.length; _i++) {
139
- args[_i] = arguments[_i];
140
- }
141
- var wherePredicate;
142
- if (args.length > 0 && args[0] != null) {
143
- wherePredicate = Predicate.create.apply(Predicate, __spread(args));
144
- if (this.fromEntityType)
145
- wherePredicate._validate(this.fromEntityType);
146
- if (this.wherePredicate) {
147
- wherePredicate = this.wherePredicate.and(wherePredicate);
148
- }
149
- }
150
- return clone(this, "wherePredicate", wherePredicate);
151
- };
152
- /**
153
- Returns a new query that orders the results of the query by property name. By default sorting occurs is ascending order, but sorting in descending order is supported as well.
154
- OrderBy clauses may be chained.
155
- > let query = new EntityQuery("Customers")
156
- > .orderBy("CompanyName");
157
-
158
- or to sort across multiple properties
159
- > let query = new EntityQuery("Customers")
160
- > .orderBy("Region, CompanyName");
161
-
162
- Nested property paths are also supported
163
- > let query = new EntityQuery("Products")
164
- > .orderBy("Category.CategoryName");
165
-
166
- Sorting in descending order is supported via the addition of ' desc' to the end of any property path.
167
- > let query = new EntityQuery("Customers")
168
- > .orderBy("CompanyName desc");
169
-
170
- or
171
- > let query = new EntityQuery("Customers")
172
- > .orderBy("Region desc, CompanyName desc");
173
- @param propertyPaths - A comma-separated (',') string of property paths or an array of property paths.
174
- Each property path can optionally end with " desc" to force a descending sort order. If 'propertyPaths' is either null or omitted then all ordering is removed.
175
- @param isDescending - If specified, overrides all of the embedded 'desc' tags in the previously specified property paths.
176
- **/
177
- EntityQuery.prototype.orderBy = function (propertyPaths, isDescending) {
178
- // propertyPaths: can pass in create("A.X,B") or create("A.X desc, B") or create("A.X desc,B", true])
179
- // isDesc parameter trumps isDesc in propertyName.
180
- var orderByClause = propertyPaths == null ? null : new OrderByClause(normalizePropertyPaths(propertyPaths), isDescending);
181
- if (this.orderByClause && orderByClause) {
182
- orderByClause = new OrderByClause([this.orderByClause, orderByClause]);
183
- }
184
- return clone(this, "orderByClause", orderByClause);
185
- };
186
- /**
187
- Returns a new query that orders the results of the query by property name in descending order.
188
- > let query = new EntityQuery("Customers")
189
- > .orderByDesc("CompanyName");
190
-
191
- or to sort across multiple properties
192
- > let query = new EntityQuery("Customers")
193
- > .orderByDesc("Region, CompanyName");
194
-
195
- Nested property paths are also supported
196
- > let query = new EntityQuery("Products")
197
- > .orderByDesc("Category.CategoryName");
198
- @param propertyPaths - A comma-separated (',') string of property paths or an array of property paths.
199
- If 'propertyPaths' is either null or omitted then all ordering is removed.
200
- **/
201
- EntityQuery.prototype.orderByDesc = function (propertyPaths) {
202
- return this.orderBy(propertyPaths, true);
203
- };
204
- /**
205
- Returns a new query that selects a list of properties from the results of the original query and returns the values of just these properties. This
206
- will be referred to as a projection.
207
- If the result of this selection "projection" contains entities, these entities will automatically be added to EntityManager's cache and will
208
- be made 'observable'.
209
- Any simple properties, i.e. strings, numbers or dates within a projection will not be cached are will NOT be made 'observable'.
210
-
211
- Simple data properties can be projected
212
- > let query = new EntityQuery("Customers")
213
- > .where("CompanyName", "startsWith", "C")
214
- > .select("CompanyName");
215
-
216
- This will return an array of objects each with a single "CompanyName" property of type string.
217
- A similar query could return a navigation property instead
218
- > let query = new EntityQuery("Customers")
219
- > .where("CompanyName", "startsWith", "C")
220
- > .select("Orders");
221
-
222
- where the result would be an array of objects each with a single "Orders" property that would itself be an array of "Order" entities.
223
- Composite projections are also possible:
224
- > let query = new EntityQuery("Customers")
225
- > .where("CompanyName", "startsWith", "C")
226
- > .select("CompanyName, Orders");
227
-
228
- As well as projections involving nested property paths
229
- > let query = EntityQuery("Orders")
230
- > .where("Customer.CompanyName", "startsWith", "C")
231
- > .select("Customer.CompanyName, Customer, OrderDate");
232
- @param propertyPaths - A comma-separated (',') string of property paths or an array of property paths.
233
- If 'propertyPaths' is either null or omitted then any existing projection on the query is removed.
234
- **/
235
- EntityQuery.prototype.select = function (propertyPaths) {
236
- var selectClause = propertyPaths == null ? null : new SelectClause(normalizePropertyPaths(propertyPaths));
237
- return clone(this, "selectClause", selectClause);
238
- };
239
- /**
240
- Returns a new query that skips the specified number of entities when returning results.
241
- Any existing 'skip' can be cleared by calling 'skip' with no arguments.
242
- > let query = new EntityQuery("Customers")
243
- > .where("CompanyName", "startsWith", "C")
244
- > .skip(5);
245
- @param count - The number of entities to skip over. If omitted or null any existing skip count on the query is removed.
246
- **/
247
- EntityQuery.prototype.skip = function (count) {
248
- assertParam(count, "count").isOptional().isNumber().check();
249
- return clone(this, "skipCount", (count == null) ? null : count);
250
- };
251
- /**
252
- Returns a new query that returns only the specified number of entities when returning results. - Same as 'take'.
253
- Any existing 'top' can be cleared by calling 'top' with no arguments.
254
- > let query = new EntityQuery("Customers")
255
- > .top(5);
256
- @param count - The number of entities to return.
257
- If 'count' is either null or omitted then any existing 'top' count on the query is removed.
258
- **/
259
- EntityQuery.prototype.top = function (count) {
260
- return this.take(count);
261
- };
262
- /**
263
- Returns a new query that returns only the specified number of entities when returning results - Same as 'top'.
264
- Any existing take can be cleared by calling take with no arguments.
265
- > let query = new EntityQuery("Customers")
266
- > .take(5);
267
- @param count - The number of entities to return.
268
- If 'count' is either null or omitted then any existing 'take' count on the query is removed.
269
- **/
270
- EntityQuery.prototype.take = function (count) {
271
- assertParam(count, "count").isOptional().isNumber().check();
272
- return clone(this, "takeCount", (count == null) ? null : count);
273
- };
274
- /**
275
- Returns a new query that will return related entities nested within its results. The expand method allows you to identify related entities, via navigation property
276
- names such that a graph of entities may be retrieved with a single request. Any filtering occurs before the results are 'expanded'.
277
- > let query = new EntityQuery("Customers")
278
- > .where("CompanyName", "startsWith", "C")
279
- > .expand("Orders");
280
-
281
- will return the filtered customers each with its "Orders" properties fully resolved.
282
- Multiple paths may be specified by separating the paths by a ','
283
- > let query = new EntityQuery("Orders")
284
- > .expand("Customer, Employee")
285
-
286
- and nested property paths my be specified as well
287
- > let query = new EntityQuery("Orders")
288
- > .expand("Customer, OrderDetails, OrderDetails.Product")
289
- @param propertyPaths - A comma-separated list of navigation property names or an array of navigation property names. Each Navigation Property name can be followed
290
- by a '.' and another navigation property name to enable identifying a multi-level relationship.
291
- If 'propertyPaths' is either null or omitted then any existing 'expand' clause on the query is removed.
292
- **/
293
- EntityQuery.prototype.expand = function (propertyPaths) {
294
- var expandClause = propertyPaths == null ? null : new ExpandClause(normalizePropertyPaths(propertyPaths));
295
- return clone(this, "expandClause", expandClause);
296
- };
297
- /**
298
- Returns a new query that includes a collection of parameters to pass to the server.
299
- > let query = EntityQuery.from("EmployeesFilteredByCountryAndBirthdate")
300
- > .withParameters({ BirthDate: "1/1/1960", Country: "USA" });
301
-
302
- will call the 'EmployeesFilteredByCountryAndBirthdate' method on the server and pass in 2 parameters. This
303
- query will be uri encoded as
304
- > {serviceApi}/EmployeesFilteredByCountryAndBirthdate?birthDate=1%2F1%2F1960&country=USA
305
-
306
- Parameters may also be mixed in with other query criteria.
307
- > let query = EntityQuery.from("EmployeesFilteredByCountryAndBirthdate")
308
- > .withParameters({ BirthDate: "1/1/1960", Country: "USA" })
309
- > .where("LastName", "startsWith", "S")
310
- > .orderBy("BirthDate");
311
- @param parameters - A parameters object where the keys are the parameter names and the values are the parameter values.
312
- **/
313
- EntityQuery.prototype.withParameters = function (parameters) {
314
- assertParam(parameters, "parameters").isObject().check();
315
- return clone(this, "parameters", parameters);
316
- };
317
- /**
318
- Returns a query with the 'inlineCount' capability either enabled or disabled. With 'inlineCount' enabled, an additional 'inlineCount' property
319
- will be returned with the query results that will contain the number of entities that would have been returned by this
320
- query with only the 'where'/'filter' clauses applied, i.e. without any 'skip'/'take' operators applied. For local queries this clause is ignored.
321
- > let query = new EntityQuery("Customers")
322
- > .take(20)
323
- > .orderBy("CompanyName")
324
- > .inlineCount(true);
325
-
326
- will return the first 20 customers as well as a count of all of the customers in the remote store.
327
- @param enabled - (default = true) Whether or not inlineCount capability should be enabled. If this parameter is omitted, true is assumed.
328
- **/
329
- EntityQuery.prototype.inlineCount = function (enabled) {
330
- assertParam(enabled, "enabled").isBoolean().isOptional().check();
331
- enabled = (enabled === undefined) ? true : !!enabled;
332
- return clone(this, "inlineCountEnabled", enabled);
333
- };
334
- EntityQuery.prototype.useNameOnServer = function (usesNameOnServer) {
335
- assertParam(usesNameOnServer, "usesNameOnServer").isBoolean().isOptional().check();
336
- usesNameOnServer = (usesNameOnServer === undefined) ? true : !!usesNameOnServer;
337
- return clone(this, "usesNameOnServer", usesNameOnServer);
338
- };
339
- /**
340
- Returns a query with the 'noTracking' capability either enabled or disabled. With 'noTracking' enabled, the results of this query
341
- will not be coerced into entities but will instead look like raw javascript projections. i.e. simple javascript objects.
342
- > let query = new EntityQuery("Customers")
343
- > .take(20)
344
- > .orderBy("CompanyName")
345
- > .noTracking(true);
346
- @param enabled - (default = true) Whether or not the noTracking capability should be enabled. If this parameter is omitted, true is assumed.
347
- **/
348
- EntityQuery.prototype.noTracking = function (enabled) {
349
- assertParam(enabled, "enabled").isBoolean().isOptional().check();
350
- enabled = (enabled === undefined) ? true : !!enabled;
351
- return clone(this, "noTrackingEnabled", enabled);
352
- };
353
- /**
354
- Returns a copy of this EntityQuery with the specified [[EntityManager]], [[DataService]],
355
- [[JsonResultsAdapter]], [[MergeStrategy]] or [[FetchStrategy]] applied.
356
- > // 'using' can be used to return a new query with a specified EntityManager.
357
- > let em = new EntityManager(serviceName);
358
- > let query = new EntityQuery("Orders")
359
- > .using(em);
360
-
361
- or with a specified [[MergeStrategy]]
362
- > let em = new EntityManager(serviceName);
363
- > let query = new EntityQuery("Orders")
364
- > .using(MergeStrategy.PreserveChanges);
365
-
366
- or with a specified [[FetchStrategy]]
367
- > let em = new EntityManager(serviceName);
368
- > let query = new EntityQuery("Orders")
369
- > .using(FetchStrategy.FromLocalCache);
370
- @param obj - The object to update in creating a new EntityQuery from an existing one.
371
- **/
372
- EntityQuery.prototype.using = function (obj) {
373
- if (!obj)
374
- return this;
375
- var eq = clone(this);
376
- processUsing(eq, {
377
- "entityManager": null,
378
- "dataService": null,
379
- "queryOptions": null,
380
- "fetchStrategy": function (eq, val) {
381
- eq.queryOptions = (eq.queryOptions || new QueryOptions()).using(val);
382
- },
383
- "mergeStrategy": function (eq, val) {
384
- eq.queryOptions = (eq.queryOptions || new QueryOptions()).using(val);
385
- },
386
- "jsonResultsAdapter": function (eq, val) {
387
- eq.dataService = (eq.dataService || new DataService()).using({ jsonResultsAdapter: val });
388
- }
389
- }, obj);
390
- return eq;
391
- };
392
- /**
393
- Executes this query. This method requires that an EntityManager has been previously specified via the "using" method.
394
-
395
- This method can be called using a 'promises' syntax ( recommended)
396
- > let em = new EntityManager(serviceName);
397
- > let query = new EntityQuery("Orders").using(em);
398
- > query.execute().then( function(data) {
399
- > ... query results processed here
400
- > }).catch( function(err) {
401
- > ... query failure processed here
402
- > });
403
-
404
- or with callbacks
405
- > let em = new EntityManager(serviceName);
406
- > let query = new EntityQuery("Orders").using(em);
407
- > query.execute(
408
- > function(data) {
409
- > let orders = data.results;
410
- > ... query results processed here
411
- > },
412
- > function(err) {
413
- > ... query failure processed here
414
- > });
415
-
416
- Either way this method is the same as calling the EntityManager 'execute' method.
417
- > let em = new EntityManager(serviceName);
418
- > let query = new EntityQuery("Orders");
419
- > em.executeQuery(query).then( function(data) {
420
- > let orders = data.results;
421
- > ... query results processed here
422
- > }).catch( function(err) {
423
- > ... query failure processed here
424
- > });
425
-
426
- @param callback - Function called on success.
427
- @param errorCallback - Function called on failure.
428
- @return Promise
429
- **/
430
- EntityQuery.prototype.execute = function (callback, errorCallback) {
431
- if (!this.entityManager) {
432
- throw new Error("An EntityQuery must have its EntityManager property set before calling 'execute'");
433
- }
434
- return this.entityManager.executeQuery(this, callback, errorCallback);
435
- };
436
- /**
437
- Executes this query against the local cache. This method requires that an EntityManager have been previously specified via the "using" method.
438
- > // assume em is an entityManager already filled with order entities;
439
- > let query = new EntityQuery("Orders").using(em);
440
- > let orders = query.executeLocally();
441
-
442
- Note that calling this method is the same as calling [[EntityManager.executeQueryLocally]].
443
- **/
444
- EntityQuery.prototype.executeLocally = function () {
445
- if (!this.entityManager) {
446
- throw new Error("An EntityQuery must have its EntityManager property set before calling 'executeLocally'");
447
- }
448
- return this.entityManager.executeQueryLocally(this);
449
- };
450
- EntityQuery.prototype.toJSON = function () {
451
- return this.toJSONExt();
452
- };
453
- /** Typically only for use when building UriBuilderAdapters.
454
- @hidden @internal
455
- */
456
- EntityQuery.prototype.toJSONExt = function (context) {
457
- context = context || {};
458
- context.entityType = context.entityType || this.fromEntityType;
459
- context.propertyPathFn = context.toNameOnServer ? context.entityType.clientPropertyPathToServer.bind(context.entityType) : core.identity;
460
- var toJSONExtFn = function (v) {
461
- return v ? v.toJSONExt(context) : undefined;
462
- };
463
- return core.toJson(this, {
464
- "from,resourceName": null,
465
- "toType,resultEntityType": function (v) {
466
- // resultEntityType can be either a string or an entityType
467
- return v ? (typeof v === 'string' ? v : v.name) : undefined;
468
- },
469
- "where,wherePredicate": toJSONExtFn,
470
- "orderBy,orderByClause": toJSONExtFn,
471
- "select,selectClause": toJSONExtFn,
472
- "expand,expandClause": toJSONExtFn,
473
- "skip,skipCount": null,
474
- "take,takeCount": null,
475
- parameters: function (v) {
476
- return core.isEmpty(v) ? undefined : v;
477
- },
478
- "inlineCount,inlineCountEnabled": false,
479
- "noTracking,noTrackingEnabled": false,
480
- queryOptions: null
481
- });
482
- };
483
- /**
484
- Static method that creates an EntityQuery that will allow 'requerying' an entity or a collection of entities by primary key. This can be useful
485
- to force a requery of selected entities, or to restrict an existing collection of entities according to some filter.
486
-
487
- Works for a single entity or an array of entities of the SAME type.
488
- Does not work for an array of entities of different types.
489
- > // assuming 'customers' is an array of 'Customer' entities retrieved earlier.
490
- > let customersQuery = EntityQuery.fromEntities(customers);
491
-
492
- The resulting query can, of course, be extended
493
- > // assuming 'customers' is an array of 'Customer' entities retrieved earlier.
494
- > let customersQuery = EntityQuery.fromEntities(customers)
495
- > .where("Region", FilterQueryOp.NotEquals, null);
496
-
497
- Single entities can requeried as well.
498
- > // assuming 'customer' is a 'Customer' entity retrieved earlier.
499
- > let customerQuery = EntityQuery.fromEntities(customer);
500
-
501
- will create a query that will return an array containing a single customer entity.
502
- @param entities - The entities for which we want to create an EntityQuery.
503
- **/
504
- EntityQuery.fromEntities = function (entities) {
505
- assertParam(entities, "entities").isEntity().or().isNonEmptyArray().isEntity().check();
506
- var ents = (Array.isArray(entities)) ? entities : [entities];
507
- var firstEntity = ents[0];
508
- var type = firstEntity.entityType;
509
- if (ents.some(function (e) {
510
- return e.entityType !== type;
511
- })) {
512
- throw new Error("All 'fromEntities' must be the same type; at least one is not of type " +
513
- type.name);
514
- }
515
- var q = new EntityQuery(type.defaultResourceName);
516
- var preds = ents.map(function (entity) {
517
- return buildPredicate(entity);
518
- });
519
- var pred = Predicate.or(preds);
520
- q = q.where(pred);
521
- var em = firstEntity.entityAspect.entityManager;
522
- if (em) {
523
- q = q.using(em);
524
- }
525
- return q;
526
- };
527
- /**
528
- Creates an EntityQuery for the specified [[EntityKey]].
529
- > let empType = metadataStore.getEntityType("Employee");
530
- > let entityKey = new EntityKey(empType, 1);
531
- > let query = EntityQuery.fromEntityKey(entityKey);
532
-
533
- or
534
- > // 'employee' is a previously queried employee
535
- > let entityKey = employee.entityAspect.getKey();
536
- > let query = EntityQuery.fromEntityKey(entityKey);
537
- @param entityKey - The [[EntityKey]] for which a query will be created.
538
- **/
539
- EntityQuery.fromEntityKey = function (entityKey) {
540
- assertParam(entityKey, "entityKey").isInstanceOf(EntityKey).check();
541
- var q = new EntityQuery(entityKey.entityType.defaultResourceName);
542
- var pred = buildKeyPredicate(entityKey);
543
- q = q.where(pred).toType(entityKey.entityType);
544
- return q;
545
- };
546
- // protected methods
547
- /** @hidden @internal */
548
- EntityQuery.prototype._getFromEntityType = function (metadataStore, throwErrorIfNotFound) {
549
- // Uncomment next two lines if we make this method public.
550
- // assertParam(metadataStore, "metadataStore").isInstanceOf(MetadataStore).check();
551
- // assertParam(throwErrorIfNotFound, "throwErrorIfNotFound").isBoolean().isOptional().check();
552
- var entityType = this.fromEntityType;
553
- if (entityType)
554
- return entityType;
555
- var resourceName = this.resourceName;
556
- if (!resourceName) {
557
- throw new Error("There is no resourceName for this query");
558
- }
559
- if (metadataStore.isEmpty()) {
560
- if (throwErrorIfNotFound) {
561
- throw new Error("There is no metadata available for this query. " +
562
- "Are you querying the local cache before you've fetched metadata?");
563
- }
564
- else {
565
- return undefined;
566
- }
567
- }
568
- var entityTypeName = metadataStore.getEntityTypeNameForResourceName(resourceName);
569
- if (entityTypeName) {
570
- entityType = metadataStore._getStructuralType(entityTypeName);
571
- }
572
- else {
573
- entityType = this._getToEntityType(metadataStore, true);
574
- }
575
- if (!entityType) {
576
- if (throwErrorIfNotFound) {
577
- throw new Error(core.formatString("Cannot find an entityType for resourceName: '%1'. ", resourceName) + core.strings.TO_TYPE);
578
- }
579
- else {
580
- return undefined;
581
- }
582
- }
583
- this.fromEntityType = entityType;
584
- return entityType;
585
- };
586
- /** @hidden @internal */
587
- EntityQuery.prototype._getToEntityType = function (metadataStore, skipFromCheck) {
588
- // skipFromCheck is to avoid recursion if called from _getFromEntityType;
589
- if (this.resultEntityType instanceof EntityType) {
590
- return this.resultEntityType;
591
- }
592
- else if (this.resultEntityType) {
593
- // resultEntityType is a string
594
- this.resultEntityType = metadataStore._getStructuralType(this.resultEntityType, false);
595
- return this.resultEntityType;
596
- }
597
- else {
598
- // resolve it, if possible, via the resourceName
599
- // do not cache this value in this case
600
- // cannot determine the resultEntityType if a selectClause is present.
601
- // return skipFromCheck ? null : (!this.selectClause) && this._getFromEntityType(metadataStore, false);
602
- if (skipFromCheck || this.selectClause) {
603
- return undefined;
604
- }
605
- else {
606
- this._getFromEntityType(metadataStore, false);
607
- }
608
- }
609
- };
610
- /** @hidden @internal */
611
- // for testing
612
- EntityQuery.prototype._toUri = function (em) {
613
- var ds = DataService.resolve([em.dataService]);
614
- return ds.uriBuilder.buildUri(this, em.metadataStore);
615
- };
616
- /**
617
- Creates an EntityQuery for the specified entity and [[NavigationProperty]].
618
- > // 'employee' is a previously queried employee
619
- > let ordersNavProp = employee.entityType.getProperty("Orders");
620
- > let query = EntityQuery.fromEntityNavigation(employee, ordersNavProp);
621
-
622
- will return a query for the "Orders" of the specified 'employee'.
623
- @param entity - The Entity whose navigation property will be queried.
624
- @param navigationProperty - The [[NavigationProperty]] or name of the NavigationProperty to be queried.
625
- **/
626
- EntityQuery.fromEntityNavigation = function (entity, navigationProperty) {
627
- assertParam(entity, "entity").isEntity().check();
628
- var navProperty = entity.entityType._checkNavProperty(navigationProperty);
629
- var q = new EntityQuery(navProperty.entityType.defaultResourceName);
630
- var pred = buildNavigationPredicate(entity, navProperty);
631
- if (pred == null) {
632
- throw new Error("Unable to create a NavigationQuery for navigationProperty: " + navProperty.name);
633
- }
634
- q = q.where(pred);
635
- var em = entity.entityAspect.entityManager;
636
- return em ? q.using(em) : q;
637
- };
638
- return EntityQuery;
639
- }());
640
- export { EntityQuery };
641
- EntityQuery.prototype._$typeName = "EntityQuery";
642
- // private functions
643
- function fromJSON(eq, json) {
644
- core.toJson(json, {
645
- "resourceName,from": null,
646
- // just the name comes back and will be resolved later
647
- "resultEntityType,toType": null,
648
- "wherePredicate,where": function (v) {
649
- return v ? new Predicate(v) : undefined;
650
- },
651
- "orderByClause,orderBy": function (v) {
652
- return v ? new OrderByClause(v) : undefined;
653
- },
654
- "selectClause,select": function (v) {
655
- return v ? new SelectClause(v) : undefined;
656
- },
657
- "expandClause,expand": function (v) {
658
- return v ? new ExpandClause(v) : undefined;
659
- },
660
- "skipCount,skip": null,
661
- "takeCount,take": null,
662
- parameters: function (v) {
663
- return core.isEmpty(v) ? undefined : v;
664
- },
665
- "inlineCountEnabled,inlineCount": false,
666
- "noTrackingEnabled,noTracking": false,
667
- queryOptions: function (v) {
668
- return v ? QueryOptions.fromJSON(v) : undefined;
669
- }
670
- }, eq);
671
- return eq;
672
- }
673
- function clone(eq, propName, value) {
674
- // immutable queries mean that we don't need to clone if no change in value.
675
- if (propName) {
676
- if (eq[propName] === value)
677
- return eq;
678
- }
679
- // copying QueryOptions is safe because they are are immutable;
680
- var copy = core.extend(new EntityQuery(), eq, [
681
- "resourceName",
682
- "fromEntityType",
683
- "wherePredicate",
684
- "orderByClause",
685
- "selectClause",
686
- "skipCount",
687
- "takeCount",
688
- "expandClause",
689
- "inlineCountEnabled",
690
- "noTrackingEnabled",
691
- "usesNameOnServer",
692
- "queryOptions",
693
- "entityManager",
694
- "dataService",
695
- "resultEntityType"
696
- ]);
697
- copy.parameters = core.extend({}, eq.parameters);
698
- if (propName) {
699
- copy[propName] = value;
700
- }
701
- return copy;
702
- }
703
- function processUsing(eq, map, value, propertyName) {
704
- var typeName = value._$typeName || ((value instanceof BreezeEnum) && value.constructor.name);
705
- var key = typeName && typeName.substr(0, 1).toLowerCase() + typeName.substr(1);
706
- if (propertyName && key !== propertyName) {
707
- throw new Error("Invalid value for property: " + propertyName);
708
- }
709
- if (key) {
710
- var fn = map[key];
711
- if (fn === undefined) {
712
- throw new Error("Invalid config property: " + key);
713
- }
714
- else if (fn === null) {
715
- eq[key] = value;
716
- }
717
- else {
718
- fn(eq, value);
719
- }
720
- }
721
- else {
722
- core.objectForEach(value, function (propName, val) {
723
- processUsing(eq, map, val, propName);
724
- });
725
- }
726
- }
727
- function normalizePropertyPaths(propertyPaths) {
728
- assertParam(propertyPaths, "propertyPaths").isOptional().isString().or().isArray().isString().check();
729
- if (typeof propertyPaths === 'string') {
730
- propertyPaths = propertyPaths.split(",");
731
- }
732
- propertyPaths = propertyPaths.map(function (pp) {
733
- return pp.trim();
734
- });
735
- return propertyPaths;
736
- }
737
- function buildPredicate(entity) {
738
- var entityType = entity.entityType;
739
- var predParts = entityType.keyProperties.map(function (kp) {
740
- return Predicate.create(kp.name, FilterQueryOp.Equals, entity.getProperty(kp.name));
741
- });
742
- var pred = Predicate.and(predParts);
743
- return pred;
744
- }
745
- function buildKeyPredicate(entityKey) {
746
- var keyProps = entityKey.entityType.keyProperties;
747
- var preds = core.arrayZip(keyProps, entityKey.values, function (kp, v) {
748
- return Predicate.create(kp.name, FilterQueryOp.Equals, v);
749
- });
750
- var pred = Predicate.and(preds);
751
- return pred;
752
- }
753
- function buildNavigationPredicate(entity, navigationProperty) {
754
- if (navigationProperty.isScalar) {
755
- if (navigationProperty.foreignKeyNames.length === 0)
756
- return null;
757
- var relatedKeyValues = navigationProperty.foreignKeyNames.map(function (fkName) {
758
- return entity.getProperty(fkName);
759
- });
760
- var entityKey = new EntityKey(navigationProperty.entityType, relatedKeyValues);
761
- return buildKeyPredicate(entityKey);
762
- }
763
- else {
764
- var inverseNp = navigationProperty.inverse;
765
- var foreignKeyNames = inverseNp ? inverseNp.foreignKeyNames : navigationProperty.invForeignKeyNames;
766
- if (foreignKeyNames.length === 0)
767
- return null;
768
- var keyValues = entity.entityAspect.getKey().values;
769
- var predParts = core.arrayZip(foreignKeyNames, keyValues, function (fkName, kv) {
770
- return Predicate.create(fkName, FilterQueryOp.Equals, kv);
771
- });
772
- return Predicate.and(predParts);
773
- }
774
- }
775
- /**
776
- FilterQueryOp is an 'Enum' containing all of the valid [[Predicate]]
777
- filter operators for an [[EntityQuery]].
778
- **/
779
- var FilterQueryOp = /** @class */ (function (_super) {
780
- __extends(FilterQueryOp, _super);
781
- function FilterQueryOp() {
782
- return _super !== null && _super.apply(this, arguments) || this;
783
- }
784
- /** Aliases: "eq", "==" **/
785
- FilterQueryOp.Equals = new FilterQueryOp({ operator: "eq" });
786
- /** Aliases: "ne", "!=" **/
787
- FilterQueryOp.NotEquals = new FilterQueryOp({ operator: "ne" });
788
- /** Aliases: "gt", ">" **/
789
- FilterQueryOp.GreaterThan = new FilterQueryOp({ operator: "gt" });
790
- /** Aliases: "lt", "<" **/
791
- FilterQueryOp.LessThan = new FilterQueryOp({ operator: "lt" });
792
- /** Aliases: "ge", ">=" **/
793
- FilterQueryOp.GreaterThanOrEqual = new FilterQueryOp({ operator: "ge" });
794
- /** Aliases: "le", "<=" **/
795
- FilterQueryOp.LessThanOrEqual = new FilterQueryOp({ operator: "le" });
796
- /** String operation: Is a string a substring of another string. Aliases: "substringof" **/
797
- FilterQueryOp.Contains = new FilterQueryOp({ operator: "contains" });
798
- /** No aliases */
799
- FilterQueryOp.StartsWith = new FilterQueryOp({ operator: "startswith" });
800
- /** No aliases */
801
- FilterQueryOp.EndsWith = new FilterQueryOp({ operator: "endswith" });
802
- /** Aliases: "some" **/
803
- FilterQueryOp.Any = new FilterQueryOp({ operator: "any" });
804
- /** Aliases: "every" **/
805
- FilterQueryOp.All = new FilterQueryOp({ operator: "all" });
806
- /** No aliases */
807
- FilterQueryOp.In = new FilterQueryOp({ operator: "in" });
808
- /** No aliases */
809
- FilterQueryOp.IsTypeOf = new FilterQueryOp({ operator: "isof" });
810
- return FilterQueryOp;
811
- }(BreezeEnum));
812
- export { FilterQueryOp };
813
- FilterQueryOp.prototype._$typeName = "FilterQueryOp";
814
- Error['x'] = FilterQueryOp.resolveSymbols();
815
- /**
816
- BooleanQueryOp is an 'Enum' containing all of the valid boolean
817
- operators for an [[EntityQuery]].
818
- **/
819
- var BooleanQueryOp = /** @class */ (function (_super) {
820
- __extends(BooleanQueryOp, _super);
821
- function BooleanQueryOp() {
822
- return _super !== null && _super.apply(this, arguments) || this;
823
- }
824
- BooleanQueryOp.And = new BooleanQueryOp({ operator: "and" });
825
- BooleanQueryOp.Or = new BooleanQueryOp({ operator: "or" });
826
- BooleanQueryOp.Not = new BooleanQueryOp({ operator: "not" });
827
- return BooleanQueryOp;
828
- }(BreezeEnum));
829
- export { BooleanQueryOp };
830
- BooleanQueryOp.prototype._$typeName = "BooleanQueryOp";
831
- Error['x'] = BooleanQueryOp.resolveSymbols();
832
- /** For use by breeze plugin authors only. The class is used in most [[IUriBuilderAdapter]] implementations
833
- @adapter (see [[IUriBuilderAdapter]])
834
- @hidden
835
-
836
- An OrderByClause is a description of the properties and direction that the result
837
- of a query should be sorted in. OrderByClauses are immutable, which means that any
838
- method that would modify an OrderByClause actually returns a new OrderByClause.
839
-
840
- For example for an Employee object with properties of 'Company' and 'LastName' the following would be valid expressions:
841
- > let obc = new OrderByClause("Company.CompanyName, LastName")
842
-
843
- or
844
- > let obc = new OrderByClause("Company.CompanyName desc, LastName")
845
-
846
- or
847
- > let obc = new OrderByClause("Company.CompanyName, LastName", true);
848
- */
849
- var OrderByClause = /** @class */ (function () {
850
- function OrderByClause(propertyPaths, isDesc) {
851
- if (propertyPaths.length === 0) {
852
- throw new Error("OrderByClause cannot be empty");
853
- }
854
- // you can also pass in an array of orderByClauses
855
- if (propertyPaths[0] instanceof OrderByClause) {
856
- var clauses = propertyPaths;
857
- this.items = core.arrayFlatMap(clauses, function (c) { return c.items; });
858
- // this.items = Array.prototype.concat.apply(clauses[0].items, clauses.slice(1).map(core.pluck("items")));
859
- // this.items = Array.prototype.concat.apply([], clauses.map(core.pluck("items")));
860
- }
861
- else {
862
- this.items = propertyPaths.map(function (pp) {
863
- return new OrderByItem(pp, isDesc);
864
- });
865
- }
866
- }
867
- OrderByClause.prototype.validate = function (entityType) {
868
- if (entityType == null || entityType.isAnonymous)
869
- return;
870
- this.items.forEach(function (item) {
871
- item.validate(entityType);
872
- });
873
- };
874
- OrderByClause.prototype.getComparer = function (entityType) {
875
- var orderByFuncs = this.items.map(function (obc) {
876
- return obc.getComparer(entityType);
877
- });
878
- return function (entity1, entity2) {
879
- for (var i = 0; i < orderByFuncs.length; i++) {
880
- var result = orderByFuncs[i](entity1, entity2);
881
- if (result !== 0) {
882
- return result;
883
- }
884
- }
885
- return 0;
886
- };
887
- };
888
- OrderByClause.prototype.toJSONExt = function (context) {
889
- return this.items.map(function (item) {
890
- return context.propertyPathFn(item.propertyPath) + (item.isDesc ? " desc" : "");
891
- });
892
- };
893
- return OrderByClause;
894
- }());
895
- export { OrderByClause };
896
- /** @hidden @internal */
897
- var OrderByItem = /** @class */ (function () {
898
- function OrderByItem(propertyPath, isDesc) {
899
- if (!(typeof propertyPath === 'string')) {
900
- throw new Error("propertyPath is not a string");
901
- }
902
- propertyPath = propertyPath.trim();
903
- var parts = propertyPath.split(' ');
904
- // parts[0] is the propertyPath; [1] would be whether descending or not.
905
- // if (parts.length > 1 && isDesc !== true && isDesc !== false) {
906
- if (parts.length > 1 && isDesc == null) {
907
- isDesc = core.stringStartsWith(parts[1].toLowerCase(), "desc");
908
- if (!isDesc) {
909
- // isDesc is false but check to make sure its intended.
910
- var isAsc = core.stringStartsWith(parts[1].toLowerCase(), "asc");
911
- if (!isAsc) {
912
- throw new Error("the second word in the propertyPath must begin with 'desc' or 'asc'");
913
- }
914
- }
915
- }
916
- this.propertyPath = parts[0];
917
- this.isDesc = isDesc || false;
918
- }
919
- OrderByItem.prototype.validate = function (entityType) {
920
- if (entityType == null || entityType.isAnonymous)
921
- return;
922
- // will throw an exception on bad propertyPath
923
- this.lastProperty = entityType.getProperty(this.propertyPath, true);
924
- return this.lastProperty;
925
- };
926
- OrderByItem.prototype.getComparer = function (entityType) {
927
- var propDataType;
928
- var isCaseSensitive;
929
- if (!this.lastProperty)
930
- this.validate(entityType);
931
- if (this.lastProperty) {
932
- propDataType = this.lastProperty.dataType;
933
- isCaseSensitive = this.lastProperty.parentType.metadataStore.localQueryComparisonOptions.isCaseSensitive;
934
- }
935
- var propertyPath = this.propertyPath;
936
- var isDesc = this.isDesc;
937
- return function (entity1, entity2) {
938
- var value1 = EntityAspect.getPropertyPathValue(entity1, propertyPath);
939
- var value2 = EntityAspect.getPropertyPathValue(entity2, propertyPath);
940
- var dataType = propDataType || (value1 && DataType.fromValue(value1)) || DataType.fromValue(value2);
941
- if (dataType === DataType.String) {
942
- if (isCaseSensitive) {
943
- value1 = value1 || "";
944
- value2 = value2 || "";
945
- }
946
- else {
947
- value1 = (value1 || "").toLowerCase();
948
- value2 = (value2 || "").toLowerCase();
949
- }
950
- }
951
- else {
952
- var normalize = DataType.getComparableFn(dataType);
953
- value1 = normalize(value1);
954
- value2 = normalize(value2);
955
- }
956
- if (value1 === value2) {
957
- return 0;
958
- }
959
- else if (value1 > value2 || value2 === undefined) {
960
- return isDesc ? -1 : 1;
961
- }
962
- else {
963
- return isDesc ? 1 : -1;
964
- }
965
- };
966
- };
967
- return OrderByItem;
968
- }());
969
- export { OrderByItem };
970
- /** For use by breeze plugin authors only. The class is used in most [[IUriBuilderAdapter]] implementations
971
- @adapter (see [[IUriBuilderAdapter]])
972
- @hidden
973
- **/
974
- var SelectClause = /** @class */ (function () {
975
- function SelectClause(propertyPaths) {
976
- this.propertyPaths = propertyPaths;
977
- this._pathNames = propertyPaths.map(function (pp) {
978
- return pp.replace(".", "_");
979
- });
980
- }
981
- SelectClause.prototype.validate = function (entityType) {
982
- if (entityType == null || entityType.isAnonymous)
983
- return; // can't validate yet
984
- // will throw an exception on bad propertyPath
985
- this.propertyPaths.forEach(function (path) {
986
- entityType.getProperty(path, true);
987
- });
988
- };
989
- SelectClause.prototype.toFunction = function ( /* config */) {
990
- var that = this;
991
- return function (entity) {
992
- var result = {};
993
- that.propertyPaths.forEach(function (path, i) {
994
- result[that._pathNames[i]] = EntityAspect.getPropertyPathValue(entity, path);
995
- });
996
- return result;
997
- };
998
- };
999
- SelectClause.prototype.toJSONExt = function (context) {
1000
- return this.propertyPaths.map(function (pp) {
1001
- return context.propertyPathFn(pp);
1002
- });
1003
- };
1004
- return SelectClause;
1005
- }());
1006
- export { SelectClause };
1007
- /** For use by breeze plugin authors only. The class is used in most [[IUriBuilderAdapter]] implementations
1008
- @adapter (see [[IUriBuilderAdapter]])
1009
- @hidden
1010
- **/
1011
- var ExpandClause = /** @class */ (function () {
1012
- function ExpandClause(propertyPaths) {
1013
- this.propertyPaths = propertyPaths;
1014
- }
1015
- ExpandClause.prototype.toJSONExt = function (context) {
1016
- return this.propertyPaths.map(function (pp) {
1017
- return context.propertyPathFn(pp);
1018
- });
1019
- };
1020
- return ExpandClause;
1021
- }());
1022
- export { ExpandClause };
1023
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LXF1ZXJ5LmpzIiwic291cmNlUm9vdCI6Im5nOi8vYnJlZXplLWNsaWVudC8iLCJzb3VyY2VzIjpbInNyYy9lbnRpdHktcXVlcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxJQUFJLEVBQTJCLE1BQU0sUUFBUSxDQUFDO0FBQ3ZELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxZQUFZLEVBQVUsTUFBTSxpQkFBaUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDcEMsT0FBTyxFQUFFLFdBQVcsRUFBc0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUVqRSxPQUFPLEVBQWlCLFVBQVUsRUFBc0MsTUFBTSxtQkFBbUIsQ0FBQztBQUNsRyxPQUFPLEVBQUUsWUFBWSxFQUFnQyxNQUFNLGlCQUFpQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFXeEM7Ozs7OztHQU1HO0FBQ0g7SUF3Q0U7Ozs7Ozs7O09BUUc7SUFDSCxxQkFBWSxZQUE4QjtRQUN4QyxJQUFJLFlBQVksSUFBSSxJQUFJLElBQUksQ0FBQyxPQUFPLFlBQVksS0FBSyxRQUFRLENBQUMsRUFBRTtZQUM5RCxPQUFPLFFBQVEsQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLENBQUM7U0FDckM7UUFDRCw4R0FBOEc7UUFDOUcsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFzQixDQUFDO1FBQzNDLElBQUksQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxhQUFhLEdBQUcsU0FBUyxDQUFDO1FBQy9CLElBQUksQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDO1FBQzlCLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO1FBQzNCLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO1FBQzNCLElBQUksQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDO1FBQzlCLElBQUksQ0FBQyxVQUFVLEdBQUcsRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUM7UUFDaEMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEtBQUssQ0FBQztRQUMvQix5RUFBeUU7UUFDekUsMENBQTBDO1FBQzFDLHdDQUF3QztRQUN4QyxJQUFJLENBQUMsYUFBYSxHQUFHLFNBQVMsQ0FBQztJQUVqQyxDQUFDO0lBR0Q7Ozs7Ozs7O09BUUc7SUFDSCwwQkFBSSxHQUFKLFVBQUssWUFBb0I7UUFDdkIsZ0RBQWdEO1FBQ2hELFdBQVcsQ0FBQyxZQUFZLEVBQUUsY0FBYyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDN0QsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLGdCQUFJLEdBQVgsVUFBWSxZQUFvQjtRQUM5QixXQUFXLENBQUMsWUFBWSxFQUFFLGNBQWMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzdELE9BQU8sSUFBSSxXQUFXLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0gsNEJBQU0sR0FBTixVQUFPLFVBQStCO1FBQ3BDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3ZGLE9BQU8sS0FBSyxDQUFDLElBQUksRUFBRSxrQkFBa0IsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBV0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0E4Q0c7SUFDSCwyQkFBSyxHQUFMO1FBQU0sY0FBYzthQUFkLFVBQWMsRUFBZCxxQkFBYyxFQUFkLElBQWM7WUFBZCx5QkFBYzs7UUFDbEIsSUFBSSxjQUFxQyxDQUFDO1FBQzFDLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRTtZQUN0QyxjQUFjLEdBQUcsU0FBUyxDQUFDLE1BQU0sT0FBaEIsU0FBUyxXQUFnQixJQUFJLEVBQUMsQ0FBQztZQUNoRCxJQUFJLElBQUksQ0FBQyxjQUFjO2dCQUFFLGNBQWMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3ZFLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtnQkFDdkIsY0FBYyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO2FBQzFEO1NBQ0Y7UUFDRCxPQUFPLEtBQUssQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsY0FBYyxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUtEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0F3Qkc7SUFDSCw2QkFBTyxHQUFQLFVBQVEsYUFBZ0MsRUFBRSxZQUFzQjtRQUM5RCxxR0FBcUc7UUFDckcsa0RBQWtEO1FBQ2xELElBQUksYUFBYSxHQUFHLGFBQWEsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxhQUFhLENBQUMsc0JBQXNCLENBQUMsYUFBYSxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDMUgsSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLGFBQWEsRUFBRTtZQUN2QyxhQUFhLEdBQUcsSUFBSSxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUM7U0FDeEU7UUFDRCxPQUFPLEtBQUssQ0FBQyxJQUFJLEVBQUUsZUFBZSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ3JELENBQUM7SUFLRDs7Ozs7Ozs7Ozs7Ozs7T0FjRztJQUNILGlDQUFXLEdBQVgsVUFBWSxhQUFnQztRQUMxQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBb0IsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQThCRztJQUNILDRCQUFNLEdBQU4sVUFBTyxhQUFpQztRQUN0QyxJQUFJLFlBQVksR0FBRyxhQUFhLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksWUFBWSxDQUFDLHNCQUFzQixDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7UUFDMUcsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILDBCQUFJLEdBQUosVUFBSyxLQUFjO1FBQ2pCLFdBQVcsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDNUQsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILHlCQUFHLEdBQUgsVUFBSSxLQUFjO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILDBCQUFJLEdBQUosVUFBSyxLQUFjO1FBQ2pCLFdBQVcsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDNUQsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQWtCRztJQUNILDRCQUFNLEdBQU4sVUFBTyxhQUFpQztRQUN0QyxJQUFJLFlBQVksR0FBRyxhQUFhLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksWUFBWSxDQUFDLHNCQUFzQixDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7UUFDMUcsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0gsb0NBQWMsR0FBZCxVQUFlLFVBQWtCO1FBQy9CLFdBQVcsQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDekQsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxVQUFVLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDSCxpQ0FBVyxHQUFYLFVBQVksT0FBaUI7UUFDM0IsV0FBVyxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNqRSxPQUFPLEdBQUcsQ0FBQyxPQUFPLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUNyRCxPQUFPLEtBQUssQ0FBQyxJQUFJLEVBQUUsb0JBQW9CLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELHFDQUFlLEdBQWYsVUFBZ0IsZ0JBQTBCO1FBQ3hDLFdBQVcsQ0FBQyxnQkFBZ0IsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLFVBQVUsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ25GLGdCQUFnQixHQUFHLENBQUMsZ0JBQWdCLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDO1FBQ2hGLE9BQU8sS0FBSyxDQUFDLElBQUksRUFBRSxrQkFBa0IsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILGdDQUFVLEdBQVYsVUFBVyxPQUFpQjtRQUMxQixXQUFXLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLFVBQVUsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2pFLE9BQU8sR0FBRyxDQUFDLE9BQU8sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO1FBQ3JELE9BQU8sS0FBSyxDQUFDLElBQUksRUFBRSxtQkFBbUIsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBUUQ7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQWtCRztJQUNILDJCQUFLLEdBQUwsVUFBTSxHQUFRO1FBQ1osSUFBSSxDQUFDLEdBQUc7WUFBRSxPQUFPLElBQUksQ0FBQztRQUN0QixJQUFJLEVBQUUsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckIsWUFBWSxDQUFDLEVBQUUsRUFBRTtZQUNmLGVBQWUsRUFBRSxJQUFJO1lBQ3JCLGFBQWEsRUFBRSxJQUFJO1lBQ25CLGNBQWMsRUFBRSxJQUFJO1lBQ3BCLGVBQWUsRUFBRSxVQUFDLEVBQWUsRUFBRSxHQUFRO2dCQUN6QyxFQUFFLENBQUMsWUFBWSxHQUFHLENBQUMsRUFBRSxDQUFDLFlBQVksSUFBSSxJQUFJLFlBQVksRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3ZFLENBQUM7WUFDRCxlQUFlLEVBQUUsVUFBQyxFQUFlLEVBQUUsR0FBUTtnQkFDekMsRUFBRSxDQUFDLFlBQVksR0FBRyxDQUFDLEVBQUUsQ0FBQyxZQUFZLElBQUksSUFBSSxZQUFZLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN2RSxDQUFDO1lBQ0Qsb0JBQW9CLEVBQUUsVUFBQyxFQUFlLEVBQUUsR0FBUTtnQkFDOUMsRUFBRSxDQUFDLFdBQVcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxXQUFXLElBQUksSUFBSSxXQUFXLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLGtCQUFrQixFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDNUYsQ0FBQztTQUNGLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDUixPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXFDRztJQUNILDZCQUFPLEdBQVAsVUFBUSxRQUFtQixFQUFFLGFBQTZCO1FBQ3hELElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsa0ZBQWtGLENBQUMsQ0FBQztTQUNyRztRQUNELE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxhQUFhLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILG9DQUFjLEdBQWQ7UUFDRSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLHlGQUF5RixDQUFDLENBQUM7U0FDNUc7UUFDRCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVELDRCQUFNLEdBQU47UUFDRSxPQUFPLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQ7O01BRUU7SUFDRiwrQkFBUyxHQUFULFVBQVUsT0FBZ0M7UUFDeEMsT0FBTyxHQUFHLE9BQU8sSUFBSSxFQUFFLENBQUM7UUFDeEIsT0FBTyxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDL0QsT0FBTyxDQUFDLGNBQWMsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBVyxDQUFDLDBCQUEwQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUM7UUFFMUksSUFBSSxXQUFXLEdBQUcsVUFBVSxDQUFNO1lBQ2hDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDOUMsQ0FBQyxDQUFDO1FBQ0YsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRTtZQUN2QixtQkFBbUIsRUFBRSxJQUFJO1lBQ3pCLHlCQUF5QixFQUFFLFVBQVUsQ0FBTTtnQkFDekMsMkRBQTJEO2dCQUMzRCxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDOUQsQ0FBQztZQUNELHNCQUFzQixFQUFFLFdBQVc7WUFDbkMsdUJBQXVCLEVBQUUsV0FBVztZQUNwQyxxQkFBcUIsRUFBRSxXQUFXO1lBQ2xDLHFCQUFxQixFQUFFLFdBQVc7WUFDbEMsZ0JBQWdCLEVBQUUsSUFBSTtZQUN0QixnQkFBZ0IsRUFBRSxJQUFJO1lBQ3RCLFVBQVUsRUFBRSxVQUFVLENBQU07Z0JBQzFCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekMsQ0FBQztZQUNELGdDQUFnQyxFQUFFLEtBQUs7WUFDdkMsOEJBQThCLEVBQUUsS0FBSztZQUNyQyxZQUFZLEVBQUUsSUFBSTtTQUNuQixDQUFDLENBQUM7SUFFTCxDQUFDO0lBSUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09Bb0JHO0lBQ0ksd0JBQVksR0FBbkIsVUFBb0IsUUFBMkI7UUFDN0MsV0FBVyxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN2RixJQUFJLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRTdELElBQUksV0FBVyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxQixJQUFJLElBQUksR0FBRyxXQUFXLENBQUMsVUFBVSxDQUFDO1FBQ2xDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7WUFDdkIsT0FBTyxDQUFDLENBQUMsVUFBVSxLQUFLLElBQUksQ0FBQztRQUMvQixDQUFDLENBQUMsRUFBRTtZQUNGLE1BQU0sSUFBSSxLQUFLLENBQUMsd0VBQXdFO2dCQUN0RixJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDZDtRQUNELElBQUksQ0FBQyxHQUFHLElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ2xELElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxNQUFNO1lBQ25DLE9BQU8sY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxJQUFJLEdBQUcsU0FBUyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMvQixDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsQixJQUFJLEVBQUUsR0FBRyxXQUFXLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQztRQUNoRCxJQUFJLEVBQUUsRUFBRTtZQUNOLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQ2pCO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7O09BV0c7SUFDSSx5QkFBYSxHQUFwQixVQUFxQixTQUFvQjtRQUN2QyxXQUFXLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNwRSxJQUFJLENBQUMsR0FBRyxJQUFJLFdBQVcsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDbEUsSUFBSSxJQUFJLEdBQUcsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDeEMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMvQyxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7SUF5QkQsb0JBQW9CO0lBQ3BCLHdCQUF3QjtJQUN4Qix3Q0FBa0IsR0FBbEIsVUFBbUIsYUFBNEIsRUFBRSxvQkFBOEI7UUFDN0UsMERBQTBEO1FBQzFELG1GQUFtRjtRQUNuRiw4RkFBOEY7UUFDOUYsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUNyQyxJQUFJLFVBQVU7WUFBRSxPQUFPLFVBQVUsQ0FBQztRQUVsQyxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQ3JDLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO1NBQzVEO1FBRUQsSUFBSSxhQUFhLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDM0IsSUFBSSxvQkFBb0IsRUFBRTtnQkFDeEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxpREFBaUQ7b0JBQy9ELGtFQUFrRSxDQUFDLENBQUM7YUFDdkU7aUJBQU07Z0JBQ0wsT0FBTyxTQUFTLENBQUM7YUFDbEI7U0FDRjtRQUVELElBQUksY0FBYyxHQUFHLGFBQWEsQ0FBQyxnQ0FBZ0MsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNsRixJQUFJLGNBQWMsRUFBRTtZQUNsQixVQUFVLEdBQUcsYUFBYSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsQ0FBZSxDQUFDO1NBQzdFO2FBQU07WUFDTCxVQUFVLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQztTQUN6RDtRQUVELElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDZixJQUFJLG9CQUFvQixFQUFFO2dCQUN4QixNQUFNLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsb0RBQW9ELEVBQUUsWUFBWSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUMvSDtpQkFBTTtnQkFDTCxPQUFPLFNBQVMsQ0FBQzthQUNsQjtTQUNGO1FBRUQsSUFBSSxDQUFDLGNBQWMsR0FBRyxVQUFVLENBQUM7UUFDakMsT0FBTyxVQUFVLENBQUM7SUFFcEIsQ0FBQztJQUVELHdCQUF3QjtJQUN4QixzQ0FBZ0IsR0FBaEIsVUFBaUIsYUFBNEIsRUFBRSxhQUF1QjtRQUNwRSx5RUFBeUU7UUFDekUsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLFlBQVksVUFBVSxFQUFFO1lBQy9DLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDO1NBQzlCO2FBQU0sSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDaEMsK0JBQStCO1lBQy9CLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxhQUFhLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEtBQUssQ0FBZSxDQUFDO1lBQ3JHLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDO1NBQzlCO2FBQU07WUFDTCxnREFBZ0Q7WUFDaEQsdUNBQXVDO1lBQ3ZDLHNFQUFzRTtZQUN0RSx1R0FBdUc7WUFDdkcsSUFBSSxhQUFhLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtnQkFDdEMsT0FBTyxTQUFTLENBQUM7YUFDbEI7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQzthQUMvQztTQUVGO0lBQ0gsQ0FBQztJQUVELHdCQUF3QjtJQUN4QixjQUFjO0lBQ2QsNEJBQU0sR0FBTixVQUFPLEVBQWlCO1FBQ3RCLElBQUksRUFBRSxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUMvQyxPQUFPLEVBQUcsQ0FBQyxVQUFXLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQTlGRDs7Ozs7Ozs7O09BU0c7SUFDSSxnQ0FBb0IsR0FBRyxVQUFVLE1BQWMsRUFBRSxrQkFBK0M7UUFDckcsV0FBVyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNqRCxJQUFJLFdBQVcsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLGlCQUFpQixDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDMUUsSUFBSSxDQUFDLEdBQUcsSUFBSSxXQUFXLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3BFLElBQUksSUFBSSxHQUFHLHdCQUF3QixDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsQ0FBQztRQUN6RCxJQUFJLElBQUksSUFBSSxJQUFJLEVBQUU7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyw2REFBNkQsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFFLENBQUM7U0FDcEc7UUFDRCxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsQixJQUFJLEVBQUUsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQztRQUMzQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzlCLENBQUMsQ0FBQztJQTJFSixrQkFBQztDQUFBLEFBbnNCRCxJQW1zQkM7U0Fuc0JZLFdBQVc7QUFvc0J4QixXQUFXLENBQUMsU0FBUyxDQUFDLFVBQVUsR0FBRyxhQUFhLENBQUM7QUFFakQsb0JBQW9CO0FBRXBCLFNBQVMsUUFBUSxDQUFDLEVBQWUsRUFBRSxJQUFZO0lBQzdDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFO1FBQ2hCLG1CQUFtQixFQUFFLElBQUk7UUFDekIsc0RBQXNEO1FBQ3RELHlCQUF5QixFQUFFLElBQUk7UUFDL0Isc0JBQXNCLEVBQUUsVUFBVSxDQUFNO1lBQ3RDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQzFDLENBQUM7UUFDRCx1QkFBdUIsRUFBRSxVQUFVLENBQU07WUFDdkMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDOUMsQ0FBQztRQUNELHFCQUFxQixFQUFFLFVBQVUsQ0FBTTtZQUNyQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUM3QyxDQUFDO1FBQ0QscUJBQXFCLEVBQUUsVUFBVSxDQUFNO1lBQ3JDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQzdDLENBQUM7UUFDRCxnQkFBZ0IsRUFBRSxJQUFJO1FBQ3RCLGdCQUFnQixFQUFFLElBQUk7UUFDdEIsVUFBVSxFQUFFLFVBQVUsQ0FBTTtZQUMxQixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pDLENBQUM7UUFDRCxnQ0FBZ0MsRUFBRSxLQUFLO1FBQ3ZDLDhCQUE4QixFQUFFLEtBQUs7UUFDckMsWUFBWSxFQUFFLFVBQVUsQ0FBTTtZQUM1QixPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ2xELENBQUM7S0FDRixFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ1AsT0FBTyxFQUFFLENBQUM7QUFDWixDQUFDO0FBRUQsU0FBUyxLQUFLLENBQUMsRUFBZSxFQUFFLFFBQWlCLEVBQUUsS0FBVztJQUM1RCw0RUFBNEU7SUFDNUUsSUFBSSxRQUFRLEVBQUU7UUFDWixJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxLQUFLO1lBQUUsT0FBTyxFQUFFLENBQUM7S0FDdkM7SUFDRCwrREFBK0Q7SUFDL0QsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLFdBQVcsRUFBRSxFQUFFLEVBQUUsRUFBRTtRQUM1QyxjQUFjO1FBQ2QsZ0JBQWdCO1FBQ2hCLGdCQUFnQjtRQUNoQixlQUFlO1FBQ2YsY0FBYztRQUNkLFdBQVc7UUFDWCxXQUFXO1FBQ1gsY0FBYztRQUNkLG9CQUFvQjtRQUNwQixtQkFBbUI7UUFDbkIsa0JBQWtCO1FBQ2xCLGNBQWM7UUFDZCxlQUFlO1FBQ2YsYUFBYTtRQUNiLGtCQUFrQjtLQUNuQixDQUFnQixDQUFDO0lBQ2xCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2pELElBQUksUUFBUSxFQUFFO1FBQ1osSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEtBQUssQ0FBQztLQUN4QjtJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLEVBQWUsRUFBRSxHQUFXLEVBQUUsS0FBVSxFQUFFLFlBQXFCO0lBQ25GLElBQUksUUFBUSxHQUFHLEtBQUssQ0FBQyxVQUFVLElBQUksQ0FBQyxDQUFDLEtBQUssWUFBWSxVQUFVLENBQUMsSUFBSyxLQUFLLENBQUMsV0FBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN0RyxJQUFJLEdBQUcsR0FBRyxRQUFRLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMvRSxJQUFJLFlBQVksSUFBSSxHQUFHLEtBQUssWUFBWSxFQUFFO1FBQ3hDLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLEdBQUcsWUFBWSxDQUFDLENBQUM7S0FDaEU7SUFDRCxJQUFJLEdBQUcsRUFBRTtRQUNQLElBQUksRUFBRSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNsQixJQUFJLEVBQUUsS0FBSyxTQUFTLEVBQUU7WUFDcEIsTUFBTSxJQUFJLEtBQUssQ0FBQywyQkFBMkIsR0FBRyxHQUFHLENBQUMsQ0FBQztTQUNwRDthQUFNLElBQUksRUFBRSxLQUFLLElBQUksRUFBRTtZQUN0QixFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDO1NBQ2pCO2FBQU07WUFDTCxFQUFFLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ2Y7S0FDRjtTQUFNO1FBQ0wsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsVUFBQyxRQUFRLEVBQUUsR0FBRztZQUN0QyxZQUFZLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDdkMsQ0FBQyxDQUFDLENBQUM7S0FDSjtBQUNILENBQUM7QUFFRCxTQUFTLHNCQUFzQixDQUFDLGFBQWdDO0lBQzlELFdBQVcsQ0FBQyxhQUFhLEVBQUUsZUFBZSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDdEcsSUFBSSxPQUFPLGFBQWEsS0FBSyxRQUFRLEVBQUU7UUFDckMsYUFBYSxHQUFHLGFBQWEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDMUM7SUFFRCxhQUFhLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUU7UUFDNUMsT0FBTyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDbkIsQ0FBQyxDQUFDLENBQUM7SUFDSCxPQUFPLGFBQWEsQ0FBQztBQUN2QixDQUFDO0FBRUQsU0FBUyxjQUFjLENBQUMsTUFBYztJQUNwQyxJQUFJLFVBQVUsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDO0lBQ25DLElBQUksU0FBUyxHQUFHLFVBQVUsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRTtRQUN2RCxPQUFPLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxhQUFhLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDdEYsQ0FBQyxDQUFDLENBQUM7SUFDSCxJQUFJLElBQUksR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3BDLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVELFNBQVMsaUJBQWlCLENBQUMsU0FBb0I7SUFDN0MsSUFBSSxRQUFRLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUM7SUFDbEQsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsRUFBRSxDQUFDO1FBQ25FLE9BQU8sU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDNUQsQ0FBQyxDQUFDLENBQUM7SUFDSCxJQUFJLElBQUksR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVELFNBQVMsd0JBQXdCLENBQUMsTUFBYyxFQUFFLGtCQUFzQztJQUN0RixJQUFJLGtCQUFrQixDQUFDLFFBQVEsRUFBRTtRQUMvQixJQUFJLGtCQUFrQixDQUFDLGVBQWUsQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ2pFLElBQUksZ0JBQWdCLEdBQUcsa0JBQWtCLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxVQUFDLE1BQU07WUFDbkUsT0FBTyxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxTQUFTLEdBQUcsSUFBSSxTQUFTLENBQUMsa0JBQWtCLENBQUMsVUFBVSxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFDL0UsT0FBTyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztLQUNyQztTQUFNO1FBQ0wsSUFBSSxTQUFTLEdBQUcsa0JBQWtCLENBQUMsT0FBTyxDQUFDO1FBQzNDLElBQUksZUFBZSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsa0JBQWtCLENBQUM7UUFDcEcsSUFBSSxlQUFlLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUM5QyxJQUFJLFNBQVMsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQztRQUNwRCxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsRUFBRSxTQUFTLEVBQUUsVUFBQyxNQUFNLEVBQUUsRUFBRTtZQUNuRSxPQUFPLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDNUQsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLFNBQVMsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7S0FDakM7QUFDSCxDQUFDO0FBVUQ7OztHQUdHO0FBQ0g7SUFBbUMsaUNBQVU7SUFBN0M7O0lBOEJBLENBQUM7SUExQkMsMkJBQTJCO0lBQ3BCLG9CQUFNLEdBQUcsSUFBSSxhQUFhLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN0RCw2QkFBNkI7SUFDdEIsdUJBQVMsR0FBRyxJQUFJLGFBQWEsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3pELDRCQUE0QjtJQUNyQix5QkFBVyxHQUFHLElBQUksYUFBYSxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDM0QsMkJBQTJCO0lBQ3BCLHNCQUFRLEdBQUcsSUFBSSxhQUFhLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN4RCw2QkFBNkI7SUFDdEIsZ0NBQWtCLEdBQUcsSUFBSSxhQUFhLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUNsRSw2QkFBNkI7SUFDdEIsNkJBQWUsR0FBRyxJQUFJLGFBQWEsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQy9ELCtGQUErRjtJQUN4RixzQkFBUSxHQUFHLElBQUksYUFBYSxDQUFDLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUM7SUFDOUQsaUJBQWlCO0lBQ1Ysd0JBQVUsR0FBRyxJQUFJLGFBQWEsQ0FBQyxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDO0lBQ2xFLGlCQUFpQjtJQUNWLHNCQUFRLEdBQUcsSUFBSSxhQUFhLENBQUMsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztJQUM5RCx5QkFBeUI7SUFDbEIsaUJBQUcsR0FBRyxJQUFJLGFBQWEsQ0FBQyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQ3BELDBCQUEwQjtJQUNuQixpQkFBRyxHQUFHLElBQUksYUFBYSxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDcEQsaUJBQWlCO0lBQ1YsZ0JBQUUsR0FBRyxJQUFJLGFBQWEsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ2xELGlCQUFpQjtJQUNWLHNCQUFRLEdBQUcsSUFBSSxhQUFhLENBQUMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUM1RCxvQkFBQztDQUFBLEFBOUJELENBQW1DLFVBQVUsR0E4QjVDO1NBOUJZLGFBQWE7QUErQjFCLGFBQWEsQ0FBQyxTQUFTLENBQUMsVUFBVSxHQUFHLGVBQWUsQ0FBQztBQUNyRCxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsYUFBYSxDQUFDLGNBQWMsRUFBRSxDQUFDO0FBRzVDOzs7R0FHRztBQUNIO0lBQW9DLGtDQUFVO0lBQTlDOztJQVFBLENBQUM7SUFKUSxrQkFBRyxHQUFHLElBQUksY0FBYyxDQUFDLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDOUMsaUJBQUUsR0FBRyxJQUFJLGNBQWMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzVDLGtCQUFHLEdBQUcsSUFBSSxjQUFjLENBQUMsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUV2RCxxQkFBQztDQUFBLEFBUkQsQ0FBb0MsVUFBVSxHQVE3QztTQVJZLGNBQWM7QUFTM0IsY0FBYyxDQUFDLFNBQVMsQ0FBQyxVQUFVLEdBQUcsZ0JBQWdCLENBQUM7QUFDdkQsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLGNBQWMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztBQUc3Qzs7Ozs7Ozs7Ozs7Ozs7OztFQWdCRTtBQUNGO0lBSUUsdUJBQVksYUFBeUMsRUFBRSxNQUFnQjtRQUNyRSxJQUFJLGFBQWEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1lBQzlCLE1BQU0sSUFBSSxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQztTQUNsRDtRQUVELGtEQUFrRDtRQUNsRCxJQUFJLGFBQWEsQ0FBQyxDQUFDLENBQUMsWUFBWSxhQUFhLEVBQUU7WUFDN0MsSUFBSSxPQUFPLEdBQUcsYUFBZ0MsQ0FBQztZQUMvQyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLFVBQUEsQ0FBQyxJQUFJLE9BQUEsQ0FBQyxDQUFDLEtBQUssRUFBUCxDQUFPLENBQUMsQ0FBQztZQUN0RCwwR0FBMEc7WUFDMUcsbUZBQW1GO1NBQ3BGO2FBQU07WUFDTCxJQUFJLENBQUMsS0FBSyxHQUFJLGFBQTBCLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRTtnQkFDdkQsT0FBTyxJQUFJLFdBQVcsQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDckMsQ0FBQyxDQUFDLENBQUM7U0FDSjtJQUVILENBQUM7SUFFRCxnQ0FBUSxHQUFSLFVBQVMsVUFBc0I7UUFDN0IsSUFBSSxVQUFVLElBQUksSUFBSSxJQUFJLFVBQVUsQ0FBQyxXQUFXO1lBQUUsT0FBTztRQUN6RCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFDLElBQUk7WUFDdEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxtQ0FBVyxHQUFYLFVBQVksVUFBc0I7UUFDaEMsSUFBSSxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsVUFBVSxHQUFHO1lBQzdDLE9BQU8sR0FBRyxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNyQyxDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sVUFBVSxPQUFZLEVBQUUsT0FBWTtZQUN6QyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDNUMsSUFBSSxNQUFNLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDL0MsSUFBSSxNQUFNLEtBQUssQ0FBQyxFQUFFO29CQUNoQixPQUFPLE1BQU0sQ0FBQztpQkFDZjthQUNGO1lBQ0QsT0FBTyxDQUFDLENBQUM7UUFDWCxDQUFDLENBQUM7SUFDSixDQUFDO0lBRUQsaUNBQVMsR0FBVCxVQUFVLE9BQStCO1FBQ3ZDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJO1lBQ2xDLE9BQU8sT0FBTyxDQUFDLGNBQWUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ25GLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVILG9CQUFDO0FBQUQsQ0FBQyxBQW5ERCxJQW1EQzs7QUFFRCx3QkFBd0I7QUFDeEI7SUFLRSxxQkFBWSxZQUFvQixFQUFFLE1BQWdCO1FBQ2hELElBQUksQ0FBQyxDQUFDLE9BQU8sWUFBWSxLQUFLLFFBQVEsQ0FBQyxFQUFFO1lBQ3ZDLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQztTQUNqRDtRQUNELFlBQVksR0FBRyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFbkMsSUFBSSxLQUFLLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNwQyx3RUFBd0U7UUFDeEUsaUVBQWlFO1FBQ2pFLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksTUFBTSxJQUFJLElBQUksRUFBRTtZQUN0QyxNQUFNLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMvRCxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUNYLHVEQUF1RDtnQkFDdkQsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDakUsSUFBSSxDQUFDLEtBQUssRUFBRTtvQkFDVixNQUFNLElBQUksS0FBSyxDQUFDLHFFQUFxRSxDQUFDLENBQUM7aUJBQ3hGO2FBRUY7U0FDRjtRQUNELElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzdCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxJQUFJLEtBQUssQ0FBQztJQUNoQyxDQUFDO0lBRUQsOEJBQVEsR0FBUixVQUFTLFVBQXNCO1FBQzdCLElBQUksVUFBVSxJQUFJLElBQUksSUFBSSxVQUFVLENBQUMsV0FBVztZQUFFLE9BQU87UUFDekQsOENBQThDO1FBQzlDLElBQUksQ0FBQyxZQUFZLEdBQUcsVUFBVSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBbUIsQ0FBQztRQUN0RixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUM7SUFDM0IsQ0FBQztJQUVELGlDQUFXLEdBQVgsVUFBWSxVQUFzQjtRQUNoQyxJQUFJLFlBQXNCLENBQUM7UUFDM0IsSUFBSSxlQUF3QixDQUFDO1FBQzdCLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWTtZQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbEQsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFO1lBQ3JCLFlBQVksR0FBSSxJQUFJLENBQUMsWUFBb0IsQ0FBQyxRQUFRLENBQUM7WUFDbkQsZUFBZSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQywyQkFBMkIsQ0FBQyxlQUFlLENBQUM7U0FDMUc7UUFFRCxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQ3JDLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFFekIsT0FBTyxVQUFVLE9BQVksRUFBRSxPQUFZO1lBQ3pDLElBQUksTUFBTSxHQUFHLFlBQVksQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFDdEUsSUFBSSxNQUFNLEdBQUcsWUFBWSxDQUFDLG9CQUFvQixDQUFDLE9BQU8sRUFBRSxZQUFZLENBQUMsQ0FBQztZQUN0RSxJQUFJLFFBQVEsR0FBRyxZQUFZLElBQUksQ0FBQyxNQUFNLElBQUksUUFBUSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDcEcsSUFBSSxRQUFRLEtBQUssUUFBUSxDQUFDLE1BQU0sRUFBRTtnQkFDaEMsSUFBSSxlQUFlLEVBQUU7b0JBQ25CLE1BQU0sR0FBRyxNQUFNLElBQUksRUFBRSxDQUFDO29CQUN0QixNQUFNLEdBQUcsTUFBTSxJQUFJLEVBQUUsQ0FBQztpQkFDdkI7cUJBQU07b0JBQ0wsTUFBTSxHQUFHLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO29CQUN0QyxNQUFNLEdBQUcsQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7aUJBQ3ZDO2FBQ0Y7aUJBQU07Z0JBQ0wsSUFBSSxTQUFTLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDbkQsTUFBTSxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDM0IsTUFBTSxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUM1QjtZQUNELElBQUksTUFBTSxLQUFLLE1BQU0sRUFBRTtnQkFDckIsT0FBTyxDQUFDLENBQUM7YUFDVjtpQkFBTSxJQUFJLE1BQU0sR0FBRyxNQUFNLElBQUksTUFBTSxLQUFLLFNBQVMsRUFBRTtnQkFDbEQsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDeEI7aUJBQU07Z0JBQ0wsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDeEI7UUFDSCxDQUFDLENBQUM7SUFDSixDQUFDO0lBQ0gsa0JBQUM7QUFBRCxDQUFDLEFBMUVELElBMEVDOztBQUVEOzs7R0FHRztBQUNIO0lBS0Usc0JBQVksYUFBdUI7UUFDakMsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7UUFDbkMsSUFBSSxDQUFDLFVBQVUsR0FBRyxhQUFhLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRTtZQUM5QyxPQUFPLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzlCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELCtCQUFRLEdBQVIsVUFBUyxVQUFzQjtRQUM3QixJQUFJLFVBQVUsSUFBSSxJQUFJLElBQUksVUFBVSxDQUFDLFdBQVc7WUFBRSxPQUFPLENBQUMscUJBQXFCO1FBQy9FLDhDQUE4QztRQUM5QyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxVQUFVLElBQUk7WUFDdkMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsaUNBQVUsR0FBVixXQUFXLFlBQVk7UUFDckIsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2hCLE9BQU8sVUFBVSxNQUFjO1lBQzdCLElBQUksTUFBTSxHQUFHLEVBQUUsQ0FBQztZQUNoQixJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxVQUFVLElBQUksRUFBRSxDQUFDO2dCQUMxQyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLFlBQVksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDL0UsQ0FBQyxDQUFDLENBQUM7WUFDSCxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDLENBQUM7SUFDSixDQUFDO0lBRUQsZ0NBQVMsR0FBVCxVQUFVLE9BQStCO1FBQ3ZDLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFO1lBQ3hDLE9BQU8sT0FBTyxDQUFDLGNBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNyQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFDSCxtQkFBQztBQUFELENBQUMsQUFwQ0QsSUFvQ0M7O0FBRUQ7OztHQUdHO0FBQ0g7SUFHRSxzQkFBWSxhQUF1QjtRQUNqQyxJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztJQUNyQyxDQUFDO0lBRUQsZ0NBQVMsR0FBVCxVQUFVLE9BQStCO1FBQ3ZDLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFO1lBQ3hDLE9BQU8sT0FBTyxDQUFDLGNBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNyQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFSCxtQkFBQztBQUFELENBQUMsQUFiRCxJQWFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29yZSwgQ2FsbGJhY2ssIEVycm9yQ2FsbGJhY2sgfSBmcm9tICcuL2NvcmUnO1xyXG5pbXBvcnQgeyBhc3NlcnRQYXJhbSB9IGZyb20gJy4vYXNzZXJ0LXBhcmFtJztcclxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuL2RhdGEtdHlwZSc7XHJcbmltcG9ydCB7IEVudGl0eUFzcGVjdCwgRW50aXR5IH0gZnJvbSAnLi9lbnRpdHktYXNwZWN0JztcclxuaW1wb3J0IHsgRW50aXR5S2V5IH0gZnJvbSAnLi9lbnRpdHkta2V5JztcclxuaW1wb3J0IHsgQnJlZXplRW51bSB9IGZyb20gJy4vZW51bSc7XHJcbmltcG9ydCB7IERhdGFTZXJ2aWNlLCBKc29uUmVzdWx0c0FkYXB0ZXIgfSBmcm9tICcuL2RhdGEtc2VydmljZSc7XHJcbmltcG9ydCB7IEVudGl0eU1hbmFnZXIsIFF1ZXJ5UmVzdWx0IH0gZnJvbSAnLi9lbnRpdHktbWFuYWdlcic7XHJcbmltcG9ydCB7IE1ldGFkYXRhU3RvcmUsIEVudGl0eVR5cGUsIE5hdmlnYXRpb25Qcm9wZXJ0eSwgRW50aXR5UHJvcGVydHkgfSBmcm9tICcuL2VudGl0eS1tZXRhZGF0YSc7XHJcbmltcG9ydCB7IFF1ZXJ5T3B0aW9ucywgTWVyZ2VTdHJhdGVneSwgRmV0Y2hTdHJhdGVneSB9IGZyb20gJy4vcXVlcnktb3B0aW9ucyc7XHJcbmltcG9ydCB7IFByZWRpY2F0ZSB9IGZyb20gJy4vcHJlZGljYXRlJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgUmVjdXJzaXZlQXJyYXk8VD4ge1xyXG4gIFtpOiBudW1iZXJdOiBUIHwgUmVjdXJzaXZlQXJyYXk8VD47XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRW50aXR5UXVlcnlKc29uQ29udGV4dCB7XHJcbiAgZW50aXR5VHlwZT86IEVudGl0eVR5cGU7XHJcbiAgcHJvcGVydHlQYXRoRm4/OiBGdW5jdGlvbjsgLy8gVE9ET1xyXG4gIHRvTmFtZU9uU2VydmVyPzogYm9vbGVhbjtcclxufVxyXG4vKipcclxuQW4gRW50aXR5UXVlcnkgaW5zdGFuY2UgaXMgdXNlZCB0byBxdWVyeSBlbnRpdGllcyBlaXRoZXIgZnJvbSBhIHJlbW90ZSBkYXRhc291cmNlIG9yIGZyb20gYSBsb2NhbCBbW0VudGl0eU1hbmFnZXJdXS5cclxuXHJcbkVudGl0eVF1ZXJpZXMgYXJlIGltbXV0YWJsZSAtIHRoaXMgbWVhbnMgdGhhdCBhbGwgRW50aXR5UXVlcnkgbWV0aG9kcyB0aGF0IHJldHVybiBhbiBFbnRpdHlRdWVyeSBhY3R1YWxseSBjcmVhdGUgYSBuZXcgRW50aXR5UXVlcnkuICBUaGlzIG1lYW5zIHRoYXRcclxuRW50aXR5UXVlcmllcyBjYW4gYmUgJ21vZGlmaWVkJyB3aXRob3V0IGFmZmVjdGluZyBhbnkgY3VycmVudCBpbnN0YW5jZXMuXHJcbkBkeW5hbWljXHJcbioqL1xyXG5leHBvcnQgY2xhc3MgRW50aXR5UXVlcnkge1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF8kdHlwZU5hbWU6IHN0cmluZzsgLy8gYWN0dWFsbHkgcGxhY2VkIG9uIHByb3RvdHlwZVxyXG4gIC8vIHRvcCA9IHRoaXMudGFrZTsgLy8gVE9ETzogY29uc2lkZXJcclxuICAvKiogVGhlIHJlc291cmNlIG5hbWUgdXNlZCBieSB0aGlzIHF1ZXJ5LiBfX1JlYWQgT25seV9fICovXHJcbiAgcmVzb3VyY2VOYW1lPzogc3RyaW5nO1xyXG4gIC8qKiBUaGUgW1tFbnRpdHlUeXBlXV0gdGhhdCBpcyBhc3NvY2lhdGVkIHdpdGggdGhlICdmcm9tJyBjbGF1c2UgKCByZXNvdXJjZU5hbWUpIG9mIHRoZSBxdWVyeS4gIFRoaXMgaXMgb25seSBndWFyYW50ZWVkIHRvIGJlIGJlIHNldCBBRlRFUiB0aGUgcXVlcnlcclxuICBoYXMgYmVlbiBleGVjdXRlZCBiZWNhdXNlIGl0IGRlcGVuZHMgb24gdGhlIFtbTWV0YWRhdGFTdG9yZV1dIGFzc29jaWF0ZWQgd2l0aCB0aGUgW1tFbnRpdHlNYW5hZ2VyXV0gdGhhdCB0aGUgcXVlcnkgd2FzIGV4ZWN1dGVkIGFnYWluc3QuXHJcbiAgVGhpcyB2YWx1ZSBtYXkgYmUgbnVsbCBpZiB0aGUgZW50aXR5VHlwZSBjYW5ub3QgYmUgYXNzb2NpYXRlZCB3aXRoIGEgcmVzb3VyY2VOYW1lLiBfX1JlYWQgT25seV9fICovXHJcbiAgZnJvbUVudGl0eVR5cGU/OiBFbnRpdHlUeXBlO1xyXG4gIC8qKiBUaGUgJ3doZXJlJyBbW1ByZWRpY2F0ZV1dIHVzZWQgYnkgdGhpcyBxdWVyeS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIHdoZXJlUHJlZGljYXRlOiBQcmVkaWNhdGU7IC8vIFRPRE9cclxuICAvKiogVGhlIFtbT3JkZXJCeUNsYXVzZV1dIHVzZWQgYnkgdGhpcyBxdWVyeS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIG9yZGVyQnlDbGF1c2U/OiBPcmRlckJ5Q2xhdXNlO1xyXG4gIC8qKiBUaGUgW1tFeHBhbmRDbGF1c2VdXSB1c2VkIGJ5IHRoaXMgcXVlcnkuIF9fUmVhZCBPbmx5X18gKi9cclxuICBleHBhbmRDbGF1c2U/OiBFeHBhbmRDbGF1c2U7XHJcbiAgLyoqIFRoZSBbW1NlbGVjdENsYXVzZV1dIHVzZWQgYnkgdGhpcyBxdWVyeS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIHNlbGVjdENsYXVzZT86IFNlbGVjdENsYXVzZTtcclxuICAvKiogVGhlIG51bWJlciBvZiBlbnRpdGllcyB0byAnc2tpcCcgZm9yIHRoaXMgcXVlcnkuIF9fUmVhZCBPbmx5X18gKi9cclxuICBza2lwQ291bnQ/OiBudW1iZXI7XHJcbiAgLyoqIFRoZSBudW1iZXIgb2YgZW50aXRpZXMgdG8gJ3Rha2UnIGZvciB0aGlzIHF1ZXJ5LiBfX1JlYWQgT25seV9fICovXHJcbiAgdGFrZUNvdW50PzogbnVtYmVyO1xyXG4gIC8qKiBBbnkgYWRkaXRpb25hbCBwYXJhbWV0ZXJzIHRoYXQgd2VyZSBhZGRlZCB0byB0aGUgcXVlcnkgdmlhIHRoZSAnd2l0aFBhcmFtZXRlcnMnIG1ldGhvZC4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIHBhcmFtZXRlcnM6IE9iamVjdDtcclxuICAvKiogV2hldGhlciBhbiBpbmxpbmUgY291bnQgaXMgcmV0dXJuZWQgZm9yIHRoaXMgcXVlcnkuIF9fUmVhZCBPbmx5X18gKi9cclxuICBpbmxpbmVDb3VudEVuYWJsZWQ6IGJvb2xlYW47XHJcbiAgLyoqIFdoZXRoZXIgZW50aXR5IHRyYWNraW5nIGhhcyBiZWVuIGRpc2FibGVkIGZvciB0aGlzIHF1ZXJ5LiBfX1JlYWQgT25seV9fICovXHJcbiAgbm9UcmFja2luZ0VuYWJsZWQ6IGJvb2xlYW47XHJcbiAgLyoqIFRoZSBbW1F1ZXJ5T3B0aW9uc11dIGZvciB0aGlzIHF1ZXJ5LiBfX1JlYWQgT25seV9fICAqKi9cclxuICAvLyBkZWZhdWx0IGlzIHRvIGdldCBxdWVyeU9wdGlvbnMgYW5kIGRhdGFTZXJ2aWNlIGZyb20gdGhlIGVudGl0eU1hbmFnZXIuXHJcbiAgcXVlcnlPcHRpb25zPzogUXVlcnlPcHRpb25zO1xyXG4gIC8qKiBUaGUgW1tEYXRhU2VydmljZV1dIGZvciB0aGlzIHF1ZXJ5LiBfX1JlYWQgT25seV9fICAqKi9cclxuICBkYXRhU2VydmljZT86IERhdGFTZXJ2aWNlO1xyXG4gIC8qKiBUaGUgW1tFbnRpdHlNYW5hZ2VyXV0gZm9yIHRoaXMgcXVlcnkuIFRoaXMgbWF5IGJlIG51bGwgYW5kIGNhbiBiZSBzZXQgdmlhIHRoZSAndXNpbmcnIG1ldGhvZC4gICoqL1xyXG4gIGVudGl0eU1hbmFnZXI/OiBFbnRpdHlNYW5hZ2VyO1xyXG4gIC8qKiAgVGhlIGVudGl0eVR5cGUgdGhhdCB3aWxsIGJlIHJldHVybmVkIGJ5IHRoaXMgcXVlcnkuIFxyXG4gIFRoaXMgcHJvcGVydHkgd2lsbCBvbmx5IGJlIHNldCBpZiB0aGUgJ3RvVHlwZScgbWV0aG9kIHdhcyBjYWxsZWQuIF9fUmVhZCBPbmx5X18gKi9cclxuICByZXN1bHRFbnRpdHlUeXBlOiBFbnRpdHlUeXBlIHwgc3RyaW5nO1xyXG4gIHVzZXNOYW1lT25TZXJ2ZXI/OiBib29sZWFuO1xyXG5cclxuICAvKiogQ29uc3RydWN0b3JcclxuICA+ICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG5cclxuICBVc3VhbGx5IHRoaXMgY29uc3RydWN0b3Igd2lsbCBiZSBmb2xsb3dlZCBieSBjYWxscyB0byBmaWx0ZXJpbmcsIG9yZGVyaW5nIG9yIHNlbGVjdGlvbiBtZXRob2RzXHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgIC53aGVyZShcIkNvbXBhbnlOYW1lXCIsIFwic3RhcnRzV2l0aFwiLCBcIkNcIilcclxuICA+ICAgICAgICAub3JkZXJCeShcIlJlZ2lvblwiKTtcclxuICBAcGFyYW0gcmVzb3VyY2VOYW1lIC0gZWl0aGVyIGEgcmVzb3VyY2UgbmFtZSBvciBhIHNlcmlhbGl6ZWQgRW50aXR5UXVlcnkgKCBjcmVhdGVkIGJ5IFtbRW50aXR5UXVlcnkudG9KU09OXV0pXHJcbiAgKiovXHJcbiAgY29uc3RydWN0b3IocmVzb3VyY2VOYW1lPzogc3RyaW5nIHwgT2JqZWN0KSB7XHJcbiAgICBpZiAocmVzb3VyY2VOYW1lICE9IG51bGwgJiYgKHR5cGVvZiByZXNvdXJjZU5hbWUgIT09ICdzdHJpbmcnKSkge1xyXG4gICAgICByZXR1cm4gZnJvbUpTT04odGhpcywgcmVzb3VyY2VOYW1lKTtcclxuICAgIH1cclxuICAgIC8vIFRPRE86IGNhc3QgYXMgc3RyaW5nIGJlbG93IG5lZWRlZCBmb3IgZWFybHkgdmVyc2lvbnMgb2YgVHlwZURvYyAtIGJ1dCBub3QgZm9yIHJlZ3VsYXIgY29tcGlsZSAtIGNoZWNrIGxhdGVyXHJcbiAgICB0aGlzLnJlc291cmNlTmFtZSA9IHJlc291cmNlTmFtZSBhcyBzdHJpbmc7XHJcbiAgICB0aGlzLmZyb21FbnRpdHlUeXBlID0gdW5kZWZpbmVkO1xyXG4gICAgdGhpcy53aGVyZVByZWRpY2F0ZSA9IHVuZGVmaW5lZDtcclxuICAgIHRoaXMub3JkZXJCeUNsYXVzZSA9IHVuZGVmaW5lZDtcclxuICAgIHRoaXMuc2VsZWN0Q2xhdXNlID0gdW5kZWZpbmVkO1xyXG4gICAgdGhpcy5za2lwQ291bnQgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLnRha2VDb3VudCA9IHVuZGVmaW5lZDtcclxuICAgIHRoaXMuZXhwYW5kQ2xhdXNlID0gdW5kZWZpbmVkO1xyXG4gICAgdGhpcy5wYXJhbWV0ZXJzID0ge307XHJcbiAgICB0aGlzLmlubGluZUNvdW50RW5hYmxlZCA9IGZhbHNlO1xyXG4gICAgdGhpcy5ub1RyYWNraW5nRW5hYmxlZCA9IGZhbHNlO1xyXG4gICAgLy8gZGVmYXVsdCBpcyB0byBnZXQgcXVlcnlPcHRpb25zIGFuZCBkYXRhU2VydmljZSBmcm9tIHRoZSBlbnRpdHlNYW5hZ2VyLlxyXG4gICAgLy8gdGhpcy5xdWVyeU9wdGlvbnMgPSBuZXcgUXVlcnlPcHRpb25zKCk7XHJcbiAgICAvLyB0aGlzLmRhdGFTZXJ2aWNlID0gbmV3IERhdGFTZXJ2aWNlKCk7XHJcbiAgICB0aGlzLmVudGl0eU1hbmFnZXIgPSB1bmRlZmluZWQ7XHJcblxyXG4gIH1cclxuXHJcblxyXG4gIC8qKlxyXG4gIFNwZWNpZmllcyB0aGUgcmVzb3VyY2UgdG8gcXVlcnkgZm9yIHRoaXMgRW50aXR5UXVlcnkuXHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeSgpXHJcbiAgPiAgICAgICAgLmZyb20oXCJDdXN0b21lcnNcIik7XHJcblxyXG4gIGlzIHRoZSBzYW1lIGFzXHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKTtcclxuICBAcGFyYW0gcmVzb3VyY2VOYW1lIC0gVGhlIHJlc291cmNlIHRvIHF1ZXJ5LlxyXG4gICoqL1xyXG4gIGZyb20ocmVzb3VyY2VOYW1lOiBzdHJpbmcpIHtcclxuICAgIC8vIFRPRE86IHRoaW5rIGFib3V0IGFsbG93aW5nIGVudGl0eVR5cGUgYXMgd2VsbFxyXG4gICAgYXNzZXJ0UGFyYW0ocmVzb3VyY2VOYW1lLCBcInJlc291cmNlTmFtZVwiKS5pc1N0cmluZygpLmNoZWNrKCk7XHJcbiAgICByZXR1cm4gY2xvbmUodGhpcywgXCJyZXNvdXJjZU5hbWVcIiwgcmVzb3VyY2VOYW1lKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFRoaXMgaXMgYSBzdGF0aWMgdmVyc2lvbiBvZiB0aGUgXCJmcm9tXCIgbWV0aG9kIGFuZCBpdCBjcmVhdGVzIGEgJ2Jhc2UnIGVudGl0eVF1ZXJ5IGZvciB0aGUgc3BlY2lmaWVkIHJlc291cmNlIG5hbWUuXHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IEVudGl0eVF1ZXJ5LmZyb20oXCJDdXN0b21lcnNcIik7XHJcblxyXG4gIGlzIHRoZSBzYW1lIGFzXHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKTtcclxuICBAcGFyYW0gcmVzb3VyY2VOYW1lIC0gVGhlIHJlc291cmNlIHRvIHF1ZXJ5LlxyXG4gICoqL1xyXG4gIHN0YXRpYyBmcm9tKHJlc291cmNlTmFtZTogc3RyaW5nKSB7XHJcbiAgICBhc3NlcnRQYXJhbShyZXNvdXJjZU5hbWUsIFwicmVzb3VyY2VOYW1lXCIpLmlzU3RyaW5nKCkuY2hlY2soKTtcclxuICAgIHJldHVybiBuZXcgRW50aXR5UXVlcnkocmVzb3VyY2VOYW1lKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFNwZWNpZmllcyB0aGUgdG9wIGxldmVsIEVudGl0eVR5cGUgdGhhdCB0aGlzIHF1ZXJ5IHdpbGwgcmV0dXJuLiAgT25seSBuZWVkZWQgd2hlbiBhIHF1ZXJ5IHJldHVybnMgYSBqc29uIHJlc3VsdCB0aGF0IGRvZXMgbm90IGluY2x1ZGUgdHlwZSBpbmZvcm1hdGlvbixcclxuICBvciB3aGVuIHVzaW5nIGEgcmVzb3VyY2UgbmFtZSB0aGF0IGlzIG5vdCBhc3NvY2lhdGVkIHRvIGFuIEVudGl0eVR5cGUuXHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeSgpXHJcbiAgPiAgICAgICAgLmZyb20oXCJNeUN1c3RvbU1ldGhvZFwiKVxyXG4gID4gICAgICAgIC50b1R5cGUoXCJDdXN0b21lclwiKVxyXG4gIEBwYXJhbSBlbnRpdHlUeXBlIC0gVGhlIHRvcCBsZXZlbCBFbnRpdHlUeXBlIHRoYXQgdGhpcyBxdWVyeSB3aWxsIHJldHVybi5cclxuICBAc3VtbWFyeSBJZiB0aGUganNvbiByZXN1bHQgY29uc2lzdHMgb2YgbW9yZSB0aGFuIGEgc2ltcGxlIGVudGl0eSBvciBhcnJheSBvZiBlbnRpdGllcywgY29uc2lkZXIgdXNpbmcgYSBbW0pzb25SZXN1bHRzQWRhcHRlcl1dIGluc3RlYWQuXHJcbiAgKiovXHJcbiAgdG9UeXBlKGVudGl0eVR5cGU6IHN0cmluZyB8IEVudGl0eVR5cGUpIHtcclxuICAgIGFzc2VydFBhcmFtKGVudGl0eVR5cGUsIFwiZW50aXR5VHlwZVwiKS5pc1N0cmluZygpLm9yKCkuaXNJbnN0YW5jZU9mKEVudGl0eVR5cGUpLmNoZWNrKCk7XHJcbiAgICByZXR1cm4gY2xvbmUodGhpcywgXCJyZXN1bHRFbnRpdHlUeXBlXCIsIGVudGl0eVR5cGUpO1xyXG4gIH1cclxuXHJcblxyXG4gIHdoZXJlKHByZWRpY2F0ZT86IFByZWRpY2F0ZSk6IEVudGl0eVF1ZXJ5O1xyXG4gIHdoZXJlKHByZWRpY2F0ZTogT2JqZWN0KTogRW50aXR5UXVlcnk7XHJcbiAgd2hlcmUocHJvcGVydHk6IHN0cmluZywgb3BlcmF0b3I6IHN0cmluZywgdmFsdWU6IGFueSk6IEVudGl0eVF1ZXJ5O1xyXG4gIHdoZXJlKHByb3BlcnR5OiBzdHJpbmcsIG9wZXJhdG9yOiBGaWx0ZXJRdWVyeU9wLCB2YWx1ZTogYW55KTogRW50aXR5UXVlcnk7XHJcbiAgd2hlcmUocHJvcGVydHk6IHN0cmluZywgZmlsdGVyb3A6IEZpbHRlclF1ZXJ5T3AsIHByb3BlcnR5Mjogc3RyaW5nLCBmaWx0ZXJvcDI6IEZpbHRlclF1ZXJ5T3AsIHZhbHVlOiBhbnkpOiBFbnRpdHlRdWVyeTsgIC8vIGZvciBhbnkvYWxsIGNsYXVzZXNcclxuICB3aGVyZShwcm9wZXJ0eTogc3RyaW5nLCBmaWx0ZXJvcDogc3RyaW5nLCBwcm9wZXJ0eTI6IHN0cmluZywgZmlsdGVyb3AyOiBzdHJpbmcsIHZhbHVlOiBhbnkpOiBFbnRpdHlRdWVyeTsgIC8vIGZvciBhbnkvYWxsIGNsYXVzZXNcclxuICB3aGVyZShwcm9wZXJ0eTogc3RyaW5nLCBmaWx0ZXJvcDogc3RyaW5nLCBwcm9wZXJ0eTI6IHN0cmluZywgZmlsdGVyb3AyOiBzdHJpbmcsIHByb3BlcnR5Mzogc3RyaW5nLCBmaWx0ZXJvcDM6IHN0cmluZywgdmFsdWU6IGFueSk6IEVudGl0eVF1ZXJ5OyAgLy8gZm9yIGFueS9hbGwgY2xhdXNlc1xyXG4gIHdoZXJlKGFuQXJyYXk6IFJlY3Vyc2l2ZUFycmF5PHN0cmluZyB8IG51bWJlciB8IEZpbHRlclF1ZXJ5T3AgfCBQcmVkaWNhdGU+KTogRW50aXR5UXVlcnk7XHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIG5ldyBxdWVyeSB3aXRoIGFuIGFkZGVkIGZpbHRlciBjcml0ZXJpYTsgQ2FuIGJlIGNhbGxlZCBtdWx0aXBsZSB0aW1lcyB3aGljaCBtZWFucyB0byAnYW5kJyB3aXRoIGFueSBleGlzdGluZ1xyXG4gIFByZWRpY2F0ZSBvciBjYW4gYmUgY2FsbGVkIHdpdGggbnVsbCB0byBjbGVhciBhbGwgcHJlZGljYXRlcy5cclxuICA+ICAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiQ3VzdG9tZXJzXCIpXHJcbiAgPiAgICAgICAgICAud2hlcmUoXCJDb21wYW55TmFtZVwiLCBcInN0YXJ0c1dpdGhcIiwgXCJDXCIpO1xyXG5cclxuICBUaGlzIGNhbiBhbHNvIGJlIGV4cHJlc3NlZCB1c2luZyBhbiBleHBsaWNpdCBbW0ZpbHRlclF1ZXJ5T3BdXSBhc1xyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIilcclxuICA+ICAgICAgICAgIC53aGVyZShcIkNvbXBhbnlOYW1lXCIsIEZpbHRlclF1ZXJ5T3AuU3RhcnRzV2l0aCwgXCJDXCIpO1xyXG5cclxuICBvciBhIHByZWNvbnN0cnVjdGVkIFtbUHJlZGljYXRlXV0gbWF5IGJlIHVzZWRcclxuICA+ICAgICAgbGV0IHByZWQgPSBuZXcgUHJlZGljYXRlKFwiQ29tcGFueU5hbWVcIiwgRmlsdGVyUXVlcnlPcC5TdGFydHNXaXRoLCBcIkNcIik7XHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKS53aGVyZShwcmVkKTtcclxuXHJcbiAgUHJlZGljYXRlcyBhcmUgb2Z0ZW4gdXNlZnVsIHdoZW4geW91IHdhbnQgdG8gY29tYmluZSBtdWx0aXBsZSBjb25kaXRpb25zIGluIGEgc2luZ2xlIGZpbHRlciwgc3VjaCBhc1xyXG4gID4gICAgICBsZXQgcHJlZCA9IFByZWRpY2F0ZS5jcmVhdGUoXCJDb21wYW55TmFtZVwiLCBcInN0YXJ0c3dpdGhcIiwgXCJDXCIpLmFuZChcIlJlZ2lvblwiLCBGaWx0ZXJRdWVyeU9wLkVxdWFscywgbnVsbCk7XHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgICAgLndoZXJlKHByZWQpO1xyXG5cclxuICBNb3JlIGNvbXBsaWNhdGVkIHF1ZXJpZXMgY2FuIG1ha2UgdXNlIG9mIG5lc3RlZCBwcm9wZXJ0eSBwYXRoc1xyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJQcm9kdWN0c1wiKVxyXG4gID4gICAgICAgICAgLndoZXJlKFwiQ2F0ZWdvcnkuQ2F0ZWdvcnlOYW1lXCIsIFwic3RhcnRzd2l0aFwiLCBcIlNcIik7XHJcblxyXG4gIG9yIE9EYXRhIGZ1bmN0aW9ucyAtIEEgbGlzdCBvZiB2YWxpZCBPRGF0YSBmdW5jdGlvbnMgY2FuIGJlIGZvdW5kIHdpdGhpbiB0aGUgW1tQcmVkaWNhdGVdXSBkb2N1bWVudGF0aW9uLlxyXG4gIFxyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIilcclxuICA+ICAgICAgICAgIC53aGVyZShcInRvTG93ZXIoQ29tcGFueU5hbWUpXCIsIFwic3RhcnRzV2l0aFwiLCBcImNcIik7XHJcblxyXG4gIG9yIHRvIGJlIGV2ZW4gbW9yZSBiYXJvcXVlXHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgICAgLndoZXJlKFwidG9VcHBlcihzdWJzdHJpbmcoQ29tcGFueU5hbWUsIDEsIDIpKVwiLCBGaWx0ZXJRdWVyeU9wLkVxdWFscywgXCJPTVwiKTtcclxuICBAcGFyYW0gcHJlZGljYXRlIC0gIENhbiBiZSBlaXRoZXJcclxuICAgIC0gYSBzaW5nbGUgW1tQcmVkaWNhdGVdXVxyXG5cclxuICAgIC0gdGhlIHBhcmFtZXRlcnMgdG8gY3JlYXRlIGEgJ3NpbXBsZScgUHJlZGljYXRlXHJcbiAgICAtIC0gIGEgcHJvcGVydHkgbmFtZSwgYSBwcm9wZXJ0eSBwYXRoIHdpdGggJy4nIGFzIHBhdGggc2VwZXJhdG9ycyBvciBhIHByb3BlcnR5IGV4cHJlc3Npb24ge1N0cmluZ31cclxuICAgIC0gLSAgYW4gb3BlcmF0b3IgLSBbW0ZpbHRlclF1ZXJ5T3BdXSBvciBpdCdzIHN0cmluZyByZXByZXNlbnRhdGlvbi4gQ2FzZSBpcyBpZ25vcmVkXHJcbiAgICB3aGVuIGlmIGEgc3RyaW5nIGlzIHByb3ZpZGVkIGFuZCBhbnkgc3RyaW5nIHRoYXQgbWF0Y2hlcyBvbmUgb2YgdGhlIEZpbHRlclF1ZXJ5T3AgYWxpYXNlcyB3aWxsIGJlIGFjY2VwdGVkLlxyXG4gICAgLSAtICBhIHZhbHVlIHtPYmplY3R9IC0gVGhpcyB3aWxsIGJlIHRyZWF0ZWQgYXMgZWl0aGVyIGEgcHJvcGVydHkgZXhwcmVzc2lvbiBvciBhIGxpdGVyYWwgZGVwZW5kaW5nIG9uIGNvbnRleHQuICBcclxuICAgIEluIGdlbmVyYWwsIGlmIHRoZSB2YWx1ZSBjYW4gYmUgaW50ZXJwcmV0ZWQgYXMgYSBwcm9wZXJ0eSBleHByZXNzaW9uIGl0IHdpbGwgYmUsIG90aGVyd2lzZSBpdCB3aWxsIGJlIHRyZWF0ZWQgYXMgYSBsaXRlcmFsLlxyXG4gICAgSW4gbW9zdCBjYXNlcyB0aGlzIHdvcmtzIHdlbGwsIGJ1dCB5b3UgY2FuIGFsc28gZm9yY2UgdGhlIGludGVycHJldGF0aW9uIGJ5IG1ha2luZyB0aGUgdmFsdWUgYXJndW1lbnQgaXRzZWxmIGFuIG9iamVjdCBcclxuICAgIHdpdGggYSAndmFsdWUnIHByb3BlcnR5IGFuZCBhbiAnaXNMaXRlcmFsJyBwcm9wZXJ0eSBzZXQgdG8gZWl0aGVyIHRydWUgb3IgZmFsc2UuXHJcbiAgICBCcmVlemUgYWxzbyB0cmllcyB0byBpbmZlciB0aGUgZGF0YVR5cGUgb2YgYW55IGxpdGVyYWwgYmFzZWQgb24gY29udGV4dCwgaWYgdGhpcyBmYWlscyB5b3UgY2FuIGZvcmNlIHRoaXMgaW5mZXJlbmNlIGJ5IG1ha2luZyB0aGUgdmFsdWUgYXJndW1lbnQgXHJcbiAgICBhbiBvYmplY3Qgd2l0aCBhICd2YWx1ZScgcHJvcGVydHkgYW5kIGEgJ2RhdGFUeXBlJ3Byb3BlcnR5IHNldCB0byBvbmUgb2YgdGhlIERhdGFUeXBlIGVudW1lcmF0aW9uIGluc3RhbmNlcy5cclxuXHJcbiAgICAtIGEgbnVsbCBvciB1bmRlZmluZWQgKCB0aGlzIGNhdXNlcyBhbnkgZXhpc3Rpbmcgd2hlcmUgY2xhdXNlIHRvIGJlIHJlbW92ZWQpXHJcbiAgKiovXHJcbiAgd2hlcmUoLi4uYXJnczogYW55W10pIHtcclxuICAgIGxldCB3aGVyZVByZWRpY2F0ZTogUHJlZGljYXRlIHwgdW5kZWZpbmVkO1xyXG4gICAgaWYgKGFyZ3MubGVuZ3RoID4gMCAmJiBhcmdzWzBdICE9IG51bGwpIHtcclxuICAgICAgd2hlcmVQcmVkaWNhdGUgPSBQcmVkaWNhdGUuY3JlYXRlKC4uLjxhbnk+YXJncyk7XHJcbiAgICAgIGlmICh0aGlzLmZyb21FbnRpdHlUeXBlKSB3aGVyZVByZWRpY2F0ZS5fdmFsaWRhdGUodGhpcy5mcm9tRW50aXR5VHlwZSk7XHJcbiAgICAgIGlmICh0aGlzLndoZXJlUHJlZGljYXRlKSB7XHJcbiAgICAgICAgd2hlcmVQcmVkaWNhdGUgPSB0aGlzLndoZXJlUHJlZGljYXRlLmFuZCh3aGVyZVByZWRpY2F0ZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBjbG9uZSh0aGlzLCBcIndoZXJlUHJlZGljYXRlXCIsIHdoZXJlUHJlZGljYXRlKTtcclxuICB9XHJcblxyXG5cclxuICBvcmRlckJ5KHByb3BlcnR5UGF0aHM/OiBzdHJpbmcsIGlzRGVzY2VuZGluZz86IGJvb2xlYW4pOiBFbnRpdHlRdWVyeTtcclxuICBvcmRlckJ5KHByb3BlcnR5UGF0aHM6IHN0cmluZ1tdLCBpc0Rlc2NlbmRpbmc/OiBib29sZWFuKTogRW50aXR5UXVlcnk7XHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIG5ldyBxdWVyeSB0aGF0IG9yZGVycyB0aGUgcmVzdWx0cyBvZiB0aGUgcXVlcnkgYnkgcHJvcGVydHkgbmFtZS4gIEJ5IGRlZmF1bHQgc29ydGluZyBvY2N1cnMgaXMgYXNjZW5kaW5nIG9yZGVyLCBidXQgc29ydGluZyBpbiBkZXNjZW5kaW5nIG9yZGVyIGlzIHN1cHBvcnRlZCBhcyB3ZWxsLlxyXG4gIE9yZGVyQnkgY2xhdXNlcyBtYXkgYmUgY2hhaW5lZC5cclxuICA+ICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIilcclxuICA+ICAgICAgICAub3JkZXJCeShcIkNvbXBhbnlOYW1lXCIpO1xyXG5cclxuICBvciB0byBzb3J0IGFjcm9zcyBtdWx0aXBsZSBwcm9wZXJ0aWVzXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiQ3VzdG9tZXJzXCIpXHJcbiAgPiAgICAgICAgLm9yZGVyQnkoXCJSZWdpb24sIENvbXBhbnlOYW1lXCIpO1xyXG5cclxuICBOZXN0ZWQgcHJvcGVydHkgcGF0aHMgYXJlIGFsc28gc3VwcG9ydGVkXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiUHJvZHVjdHNcIilcclxuICA+ICAgICAgICAub3JkZXJCeShcIkNhdGVnb3J5LkNhdGVnb3J5TmFtZVwiKTtcclxuXHJcbiAgU29ydGluZyBpbiBkZXNjZW5kaW5nIG9yZGVyIGlzIHN1cHBvcnRlZCB2aWEgdGhlIGFkZGl0aW9uIG9mICcgZGVzYycgdG8gdGhlIGVuZCBvZiBhbnkgcHJvcGVydHkgcGF0aC5cclxuICA+ICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIilcclxuICA+ICAgICAgICAub3JkZXJCeShcIkNvbXBhbnlOYW1lIGRlc2NcIik7XHJcblxyXG4gIG9yXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiQ3VzdG9tZXJzXCIpXHJcbiAgPiAgICAgICAgLm9yZGVyQnkoXCJSZWdpb24gZGVzYywgQ29tcGFueU5hbWUgZGVzY1wiKTtcclxuICBAcGFyYW0gcHJvcGVydHlQYXRocyAtIEEgY29tbWEtc2VwYXJhdGVkICgnLCcpIHN0cmluZyBvZiBwcm9wZXJ0eSBwYXRocyBvciBhbiBhcnJheSBvZiBwcm9wZXJ0eSBwYXRocy5cclxuICBFYWNoIHByb3BlcnR5IHBhdGggY2FuIG9wdGlvbmFsbHkgZW5kIHdpdGggXCIgZGVzY1wiIHRvIGZvcmNlIGEgZGVzY2VuZGluZyBzb3J0IG9yZGVyLiBJZiAncHJvcGVydHlQYXRocycgaXMgZWl0aGVyIG51bGwgb3Igb21pdHRlZCB0aGVuIGFsbCBvcmRlcmluZyBpcyByZW1vdmVkLlxyXG4gIEBwYXJhbSBpc0Rlc2NlbmRpbmcgLSBJZiBzcGVjaWZpZWQsIG92ZXJyaWRlcyBhbGwgb2YgdGhlIGVtYmVkZGVkICdkZXNjJyB0YWdzIGluIHRoZSBwcmV2aW91c2x5IHNwZWNpZmllZCBwcm9wZXJ0eSBwYXRocy5cclxuICAqKi9cclxuICBvcmRlckJ5KHByb3BlcnR5UGF0aHM6IHN0cmluZyB8IHN0cmluZ1tdLCBpc0Rlc2NlbmRpbmc/OiBib29sZWFuKSB7XHJcbiAgICAvLyBwcm9wZXJ0eVBhdGhzOiBjYW4gcGFzcyBpbiBjcmVhdGUoXCJBLlgsQlwiKSBvciBjcmVhdGUoXCJBLlggZGVzYywgQlwiKSBvciBjcmVhdGUoXCJBLlggZGVzYyxCXCIsIHRydWVdKVxyXG4gICAgLy8gaXNEZXNjIHBhcmFtZXRlciB0cnVtcHMgaXNEZXNjIGluIHByb3BlcnR5TmFtZS5cclxuICAgIGxldCBvcmRlckJ5Q2xhdXNlID0gcHJvcGVydHlQYXRocyA9PSBudWxsID8gbnVsbCA6IG5ldyBPcmRlckJ5Q2xhdXNlKG5vcm1hbGl6ZVByb3BlcnR5UGF0aHMocHJvcGVydHlQYXRocyksIGlzRGVzY2VuZGluZyk7XHJcbiAgICBpZiAodGhpcy5vcmRlckJ5Q2xhdXNlICYmIG9yZGVyQnlDbGF1c2UpIHtcclxuICAgICAgb3JkZXJCeUNsYXVzZSA9IG5ldyBPcmRlckJ5Q2xhdXNlKFt0aGlzLm9yZGVyQnlDbGF1c2UsIG9yZGVyQnlDbGF1c2VdKTtcclxuICAgIH1cclxuICAgIHJldHVybiBjbG9uZSh0aGlzLCBcIm9yZGVyQnlDbGF1c2VcIiwgb3JkZXJCeUNsYXVzZSk7XHJcbiAgfVxyXG5cclxuXHJcbiAgb3JkZXJCeURlc2MocHJvcGVydHlQYXRoczogc3RyaW5nKTogRW50aXR5UXVlcnk7XHJcbiAgb3JkZXJCeURlc2MocHJvcGVydHlQYXRoczogc3RyaW5nW10pOiBFbnRpdHlRdWVyeTtcclxuICAvKipcclxuICBSZXR1cm5zIGEgbmV3IHF1ZXJ5IHRoYXQgb3JkZXJzIHRoZSByZXN1bHRzIG9mIHRoZSBxdWVyeSBieSBwcm9wZXJ0eSBuYW1lIGluIGRlc2NlbmRpbmcgb3JkZXIuXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiQ3VzdG9tZXJzXCIpXHJcbiAgPiAgICAgICAgLm9yZGVyQnlEZXNjKFwiQ29tcGFueU5hbWVcIik7XHJcblxyXG4gIG9yIHRvIHNvcnQgYWNyb3NzIG11bHRpcGxlIHByb3BlcnRpZXNcclxuICA+ICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIilcclxuICA+ICAgICAgICAub3JkZXJCeURlc2MoXCJSZWdpb24sIENvbXBhbnlOYW1lXCIpO1xyXG5cclxuICBOZXN0ZWQgcHJvcGVydHkgcGF0aHMgYXJlIGFsc28gc3VwcG9ydGVkXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiUHJvZHVjdHNcIilcclxuICA+ICAgICAgICAub3JkZXJCeURlc2MoXCJDYXRlZ29yeS5DYXRlZ29yeU5hbWVcIik7XHJcbiAgQHBhcmFtIHByb3BlcnR5UGF0aHMgLSBBIGNvbW1hLXNlcGFyYXRlZCAoJywnKSBzdHJpbmcgb2YgcHJvcGVydHkgcGF0aHMgb3IgYW4gYXJyYXkgb2YgcHJvcGVydHkgcGF0aHMuXHJcbiAgSWYgJ3Byb3BlcnR5UGF0aHMnIGlzIGVpdGhlciBudWxsIG9yIG9taXR0ZWQgdGhlbiBhbGwgb3JkZXJpbmcgaXMgcmVtb3ZlZC5cclxuICAqKi9cclxuICBvcmRlckJ5RGVzYyhwcm9wZXJ0eVBhdGhzOiBzdHJpbmcgfCBzdHJpbmdbXSkge1xyXG4gICAgcmV0dXJuIHRoaXMub3JkZXJCeShwcm9wZXJ0eVBhdGhzIGFzIGFueSwgdHJ1ZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIGEgbmV3IHF1ZXJ5IHRoYXQgc2VsZWN0cyBhIGxpc3Qgb2YgcHJvcGVydGllcyBmcm9tIHRoZSByZXN1bHRzIG9mIHRoZSBvcmlnaW5hbCBxdWVyeSBhbmQgcmV0dXJucyB0aGUgdmFsdWVzIG9mIGp1c3QgdGhlc2UgcHJvcGVydGllcy4gVGhpc1xyXG4gIHdpbGwgYmUgcmVmZXJyZWQgdG8gYXMgYSBwcm9qZWN0aW9uLlxyXG4gIElmIHRoZSByZXN1bHQgb2YgdGhpcyBzZWxlY3Rpb24gXCJwcm9qZWN0aW9uXCIgY29udGFpbnMgZW50aXRpZXMsIHRoZXNlIGVudGl0aWVzIHdpbGwgYXV0b21hdGljYWxseSBiZSBhZGRlZCB0byBFbnRpdHlNYW5hZ2VyJ3MgY2FjaGUgYW5kIHdpbGxcclxuICBiZSBtYWRlICdvYnNlcnZhYmxlJy5cclxuICBBbnkgc2ltcGxlIHByb3BlcnRpZXMsIGkuZS4gc3RyaW5ncywgbnVtYmVycyBvciBkYXRlcyB3aXRoaW4gYSBwcm9qZWN0aW9uIHdpbGwgbm90IGJlIGNhY2hlZCBhcmUgd2lsbCBOT1QgYmUgbWFkZSAnb2JzZXJ2YWJsZScuXHJcbiAgXHJcbiAgU2ltcGxlIGRhdGEgcHJvcGVydGllcyBjYW4gYmUgcHJvamVjdGVkXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiQ3VzdG9tZXJzXCIpXHJcbiAgPiAgICAgICAgIC53aGVyZShcIkNvbXBhbnlOYW1lXCIsIFwic3RhcnRzV2l0aFwiLCBcIkNcIilcclxuICA+ICAgICAgICAgLnNlbGVjdChcIkNvbXBhbnlOYW1lXCIpO1xyXG5cclxuICBUaGlzIHdpbGwgcmV0dXJuIGFuIGFycmF5IG9mIG9iamVjdHMgZWFjaCB3aXRoIGEgc2luZ2xlIFwiQ29tcGFueU5hbWVcIiBwcm9wZXJ0eSBvZiB0eXBlIHN0cmluZy5cclxuICBBIHNpbWlsYXIgcXVlcnkgY291bGQgcmV0dXJuIGEgbmF2aWdhdGlvbiBwcm9wZXJ0eSBpbnN0ZWFkXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiQ3VzdG9tZXJzXCIpXHJcbiAgPiAgICAgICAgLndoZXJlKFwiQ29tcGFueU5hbWVcIiwgXCJzdGFydHNXaXRoXCIsIFwiQ1wiKVxyXG4gID4gICAgICAgIC5zZWxlY3QoXCJPcmRlcnNcIik7XHJcblxyXG4gIHdoZXJlIHRoZSByZXN1bHQgd291bGQgYmUgYW4gYXJyYXkgb2Ygb2JqZWN0cyBlYWNoIHdpdGggYSBzaW5nbGUgXCJPcmRlcnNcIiBwcm9wZXJ0eSB0aGF0IHdvdWxkIGl0c2VsZiBiZSBhbiBhcnJheSBvZiBcIk9yZGVyXCIgZW50aXRpZXMuXHJcbiAgQ29tcG9zaXRlIHByb2plY3Rpb25zIGFyZSBhbHNvIHBvc3NpYmxlOlxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgIC53aGVyZShcIkNvbXBhbnlOYW1lXCIsIFwic3RhcnRzV2l0aFwiLCBcIkNcIilcclxuICA+ICAgICAgICAuc2VsZWN0KFwiQ29tcGFueU5hbWUsIE9yZGVyc1wiKTtcclxuXHJcbiAgQXMgd2VsbCBhcyBwcm9qZWN0aW9ucyBpbnZvbHZpbmcgbmVzdGVkIHByb3BlcnR5IHBhdGhzXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gRW50aXR5UXVlcnkoXCJPcmRlcnNcIilcclxuICA+ICAgICAgICAud2hlcmUoXCJDdXN0b21lci5Db21wYW55TmFtZVwiLCBcInN0YXJ0c1dpdGhcIiwgXCJDXCIpXHJcbiAgPiAgICAgICAgLnNlbGVjdChcIkN1c3RvbWVyLkNvbXBhbnlOYW1lLCBDdXN0b21lciwgT3JkZXJEYXRlXCIpO1xyXG4gIEBwYXJhbSBwcm9wZXJ0eVBhdGhzIC0gQSBjb21tYS1zZXBhcmF0ZWQgKCcsJykgc3RyaW5nIG9mIHByb3BlcnR5IHBhdGhzIG9yIGFuIGFycmF5IG9mIHByb3BlcnR5IHBhdGhzLlxyXG4gIElmICdwcm9wZXJ0eVBhdGhzJyBpcyBlaXRoZXIgbnVsbCBvciBvbWl0dGVkIHRoZW4gYW55IGV4aXN0aW5nIHByb2plY3Rpb24gb24gdGhlIHF1ZXJ5IGlzIHJlbW92ZWQuXHJcbiAgKiovXHJcbiAgc2VsZWN0KHByb3BlcnR5UGF0aHM/OiBzdHJpbmcgfCBzdHJpbmdbXSkge1xyXG4gICAgbGV0IHNlbGVjdENsYXVzZSA9IHByb3BlcnR5UGF0aHMgPT0gbnVsbCA/IG51bGwgOiBuZXcgU2VsZWN0Q2xhdXNlKG5vcm1hbGl6ZVByb3BlcnR5UGF0aHMocHJvcGVydHlQYXRocykpO1xyXG4gICAgcmV0dXJuIGNsb25lKHRoaXMsIFwic2VsZWN0Q2xhdXNlXCIsIHNlbGVjdENsYXVzZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIGEgbmV3IHF1ZXJ5IHRoYXQgc2tpcHMgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgZW50aXRpZXMgd2hlbiByZXR1cm5pbmcgcmVzdWx0cy5cclxuICBBbnkgZXhpc3RpbmcgJ3NraXAnIGNhbiBiZSBjbGVhcmVkIGJ5IGNhbGxpbmcgJ3NraXAnIHdpdGggbm8gYXJndW1lbnRzLlxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgLndoZXJlKFwiQ29tcGFueU5hbWVcIiwgXCJzdGFydHNXaXRoXCIsIFwiQ1wiKVxyXG4gID4gICAgICAgLnNraXAoNSk7XHJcbiAgQHBhcmFtIGNvdW50IC0gVGhlIG51bWJlciBvZiBlbnRpdGllcyB0byBza2lwIG92ZXIuIElmIG9taXR0ZWQgb3IgbnVsbCBhbnkgZXhpc3Rpbmcgc2tpcCBjb3VudCBvbiB0aGUgcXVlcnkgaXMgcmVtb3ZlZC5cclxuICAqKi9cclxuICBza2lwKGNvdW50PzogbnVtYmVyKSB7XHJcbiAgICBhc3NlcnRQYXJhbShjb3VudCwgXCJjb3VudFwiKS5pc09wdGlvbmFsKCkuaXNOdW1iZXIoKS5jaGVjaygpO1xyXG4gICAgcmV0dXJuIGNsb25lKHRoaXMsIFwic2tpcENvdW50XCIsIChjb3VudCA9PSBudWxsKSA/IG51bGwgOiBjb3VudCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIGEgbmV3IHF1ZXJ5IHRoYXQgcmV0dXJucyBvbmx5IHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGVudGl0aWVzIHdoZW4gcmV0dXJuaW5nIHJlc3VsdHMuIC0gU2FtZSBhcyAndGFrZScuXHJcbiAgQW55IGV4aXN0aW5nICd0b3AnIGNhbiBiZSBjbGVhcmVkIGJ5IGNhbGxpbmcgJ3RvcCcgd2l0aCBubyBhcmd1bWVudHMuXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiQ3VzdG9tZXJzXCIpXHJcbiAgPiAgICAgICAgLnRvcCg1KTtcclxuICBAcGFyYW0gY291bnQgLSBUaGUgbnVtYmVyIG9mIGVudGl0aWVzIHRvIHJldHVybi5cclxuICBJZiAnY291bnQnIGlzIGVpdGhlciBudWxsIG9yIG9taXR0ZWQgdGhlbiBhbnkgZXhpc3RpbmcgJ3RvcCcgY291bnQgb24gdGhlIHF1ZXJ5IGlzIHJlbW92ZWQuXHJcbiAgKiovXHJcbiAgdG9wKGNvdW50PzogbnVtYmVyKSB7XHJcbiAgICByZXR1cm4gdGhpcy50YWtlKGNvdW50KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgYSBuZXcgcXVlcnkgdGhhdCByZXR1cm5zIG9ubHkgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgZW50aXRpZXMgd2hlbiByZXR1cm5pbmcgcmVzdWx0cyAtIFNhbWUgYXMgJ3RvcCcuXHJcbiAgQW55IGV4aXN0aW5nIHRha2UgY2FuIGJlIGNsZWFyZWQgYnkgY2FsbGluZyB0YWtlIHdpdGggbm8gYXJndW1lbnRzLlxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgIC50YWtlKDUpO1xyXG4gIEBwYXJhbSBjb3VudCAtIFRoZSBudW1iZXIgb2YgZW50aXRpZXMgdG8gcmV0dXJuLlxyXG4gIElmICdjb3VudCcgaXMgZWl0aGVyIG51bGwgb3Igb21pdHRlZCB0aGVuIGFueSBleGlzdGluZyAndGFrZScgY291bnQgb24gdGhlIHF1ZXJ5IGlzIHJlbW92ZWQuXHJcbiAgKiovXHJcbiAgdGFrZShjb3VudD86IG51bWJlcikge1xyXG4gICAgYXNzZXJ0UGFyYW0oY291bnQsIFwiY291bnRcIikuaXNPcHRpb25hbCgpLmlzTnVtYmVyKCkuY2hlY2soKTtcclxuICAgIHJldHVybiBjbG9uZSh0aGlzLCBcInRha2VDb3VudFwiLCAoY291bnQgPT0gbnVsbCkgPyBudWxsIDogY291bnQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIG5ldyBxdWVyeSB0aGF0IHdpbGwgcmV0dXJuIHJlbGF0ZWQgZW50aXRpZXMgbmVzdGVkIHdpdGhpbiBpdHMgcmVzdWx0cy4gVGhlIGV4cGFuZCBtZXRob2QgYWxsb3dzIHlvdSB0byBpZGVudGlmeSByZWxhdGVkIGVudGl0aWVzLCB2aWEgbmF2aWdhdGlvbiBwcm9wZXJ0eVxyXG4gIG5hbWVzIHN1Y2ggdGhhdCBhIGdyYXBoIG9mIGVudGl0aWVzIG1heSBiZSByZXRyaWV2ZWQgd2l0aCBhIHNpbmdsZSByZXF1ZXN0LiBBbnkgZmlsdGVyaW5nIG9jY3VycyBiZWZvcmUgdGhlIHJlc3VsdHMgYXJlICdleHBhbmRlZCcuXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiQ3VzdG9tZXJzXCIpXHJcbiAgPiAgICAgICAgLndoZXJlKFwiQ29tcGFueU5hbWVcIiwgXCJzdGFydHNXaXRoXCIsIFwiQ1wiKVxyXG4gID4gICAgICAgIC5leHBhbmQoXCJPcmRlcnNcIik7XHJcblxyXG4gIHdpbGwgcmV0dXJuIHRoZSBmaWx0ZXJlZCBjdXN0b21lcnMgZWFjaCB3aXRoIGl0cyBcIk9yZGVyc1wiIHByb3BlcnRpZXMgZnVsbHkgcmVzb2x2ZWQuXHJcbiAgTXVsdGlwbGUgcGF0aHMgbWF5IGJlIHNwZWNpZmllZCBieSBzZXBhcmF0aW5nIHRoZSBwYXRocyBieSBhICcsJ1xyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIk9yZGVyc1wiKVxyXG4gID4gICAgICAgIC5leHBhbmQoXCJDdXN0b21lciwgRW1wbG95ZWVcIilcclxuXHJcbiAgYW5kIG5lc3RlZCBwcm9wZXJ0eSBwYXRocyBteSBiZSBzcGVjaWZpZWQgYXMgd2VsbFxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIk9yZGVyc1wiKVxyXG4gID4gICAgICAgIC5leHBhbmQoXCJDdXN0b21lciwgT3JkZXJEZXRhaWxzLCBPcmRlckRldGFpbHMuUHJvZHVjdFwiKVxyXG4gIEBwYXJhbSBwcm9wZXJ0eVBhdGhzIC0gQSBjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBuYXZpZ2F0aW9uIHByb3BlcnR5IG5hbWVzIG9yIGFuIGFycmF5IG9mIG5hdmlnYXRpb24gcHJvcGVydHkgbmFtZXMuIEVhY2ggTmF2aWdhdGlvbiBQcm9wZXJ0eSBuYW1lIGNhbiBiZSBmb2xsb3dlZFxyXG4gIGJ5IGEgJy4nIGFuZCBhbm90aGVyIG5hdmlnYXRpb24gcHJvcGVydHkgbmFtZSB0byBlbmFibGUgaWRlbnRpZnlpbmcgYSBtdWx0aS1sZXZlbCByZWxhdGlvbnNoaXAuXHJcbiAgSWYgJ3Byb3BlcnR5UGF0aHMnIGlzIGVpdGhlciBudWxsIG9yIG9taXR0ZWQgdGhlbiBhbnkgZXhpc3RpbmcgJ2V4cGFuZCcgY2xhdXNlIG9uIHRoZSBxdWVyeSBpcyByZW1vdmVkLlxyXG4gICoqL1xyXG4gIGV4cGFuZChwcm9wZXJ0eVBhdGhzPzogc3RyaW5nIHwgc3RyaW5nW10pIHtcclxuICAgIGxldCBleHBhbmRDbGF1c2UgPSBwcm9wZXJ0eVBhdGhzID09IG51bGwgPyBudWxsIDogbmV3IEV4cGFuZENsYXVzZShub3JtYWxpemVQcm9wZXJ0eVBhdGhzKHByb3BlcnR5UGF0aHMpKTtcclxuICAgIHJldHVybiBjbG9uZSh0aGlzLCBcImV4cGFuZENsYXVzZVwiLCBleHBhbmRDbGF1c2UpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIG5ldyBxdWVyeSB0aGF0IGluY2x1ZGVzIGEgY29sbGVjdGlvbiBvZiBwYXJhbWV0ZXJzIHRvIHBhc3MgdG8gdGhlIHNlcnZlci5cclxuICA+ICAgICBsZXQgcXVlcnkgPSBFbnRpdHlRdWVyeS5mcm9tKFwiRW1wbG95ZWVzRmlsdGVyZWRCeUNvdW50cnlBbmRCaXJ0aGRhdGVcIilcclxuICA+ICAgICAgICAud2l0aFBhcmFtZXRlcnMoeyBCaXJ0aERhdGU6IFwiMS8xLzE5NjBcIiwgQ291bnRyeTogXCJVU0FcIiB9KTtcclxuICAgXHJcbiAgd2lsbCBjYWxsIHRoZSAnRW1wbG95ZWVzRmlsdGVyZWRCeUNvdW50cnlBbmRCaXJ0aGRhdGUnIG1ldGhvZCBvbiB0aGUgc2VydmVyIGFuZCBwYXNzIGluIDIgcGFyYW1ldGVycy4gVGhpc1xyXG4gIHF1ZXJ5IHdpbGwgYmUgdXJpIGVuY29kZWQgYXNcclxuICA+ICAgICAge3NlcnZpY2VBcGl9L0VtcGxveWVlc0ZpbHRlcmVkQnlDb3VudHJ5QW5kQmlydGhkYXRlP2JpcnRoRGF0ZT0xJTJGMSUyRjE5NjAmY291bnRyeT1VU0FcclxuXHJcbiAgUGFyYW1ldGVycyBtYXkgYWxzbyBiZSBtaXhlZCBpbiB3aXRoIG90aGVyIHF1ZXJ5IGNyaXRlcmlhLlxyXG4gID4gICAgIGxldCBxdWVyeSA9IEVudGl0eVF1ZXJ5LmZyb20oXCJFbXBsb3llZXNGaWx0ZXJlZEJ5Q291bnRyeUFuZEJpcnRoZGF0ZVwiKVxyXG4gID4gICAgICAgIC53aXRoUGFyYW1ldGVycyh7IEJpcnRoRGF0ZTogXCIxLzEvMTk2MFwiLCBDb3VudHJ5OiBcIlVTQVwiIH0pXHJcbiAgPiAgICAgICAgLndoZXJlKFwiTGFzdE5hbWVcIiwgXCJzdGFydHNXaXRoXCIsIFwiU1wiKVxyXG4gID4gICAgICAgIC5vcmRlckJ5KFwiQmlydGhEYXRlXCIpO1xyXG4gIEBwYXJhbSBwYXJhbWV0ZXJzIC0gQSBwYXJhbWV0ZXJzIG9iamVjdCB3aGVyZSB0aGUga2V5cyBhcmUgdGhlIHBhcmFtZXRlciBuYW1lcyBhbmQgdGhlIHZhbHVlcyBhcmUgdGhlIHBhcmFtZXRlciB2YWx1ZXMuXHJcbiAgKiovXHJcbiAgd2l0aFBhcmFtZXRlcnMocGFyYW1ldGVyczogT2JqZWN0KSB7XHJcbiAgICBhc3NlcnRQYXJhbShwYXJhbWV0ZXJzLCBcInBhcmFtZXRlcnNcIikuaXNPYmplY3QoKS5jaGVjaygpO1xyXG4gICAgcmV0dXJuIGNsb25lKHRoaXMsIFwicGFyYW1ldGVyc1wiLCBwYXJhbWV0ZXJzKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgYSBxdWVyeSB3aXRoIHRoZSAnaW5saW5lQ291bnQnIGNhcGFiaWxpdHkgZWl0aGVyIGVuYWJsZWQgb3IgZGlzYWJsZWQuICBXaXRoICdpbmxpbmVDb3VudCcgZW5hYmxlZCwgYW4gYWRkaXRpb25hbCAnaW5saW5lQ291bnQnIHByb3BlcnR5XHJcbiAgd2lsbCBiZSByZXR1cm5lZCB3aXRoIHRoZSBxdWVyeSByZXN1bHRzIHRoYXQgd2lsbCBjb250YWluIHRoZSBudW1iZXIgb2YgZW50aXRpZXMgdGhhdCB3b3VsZCBoYXZlIGJlZW4gcmV0dXJuZWQgYnkgdGhpc1xyXG4gIHF1ZXJ5IHdpdGggb25seSB0aGUgJ3doZXJlJy8nZmlsdGVyJyBjbGF1c2VzIGFwcGxpZWQsIGkuZS4gd2l0aG91dCBhbnkgJ3NraXAnLyd0YWtlJyBvcGVyYXRvcnMgYXBwbGllZC4gRm9yIGxvY2FsIHF1ZXJpZXMgdGhpcyBjbGF1c2UgaXMgaWdub3JlZC5cclxuICA+ICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIilcclxuICA+ICAgICAgICAudGFrZSgyMClcclxuICA+ICAgICAgICAub3JkZXJCeShcIkNvbXBhbnlOYW1lXCIpXHJcbiAgPiAgICAgICAgLmlubGluZUNvdW50KHRydWUpO1xyXG5cclxuICB3aWxsIHJldHVybiB0aGUgZmlyc3QgMjAgY3VzdG9tZXJzIGFzIHdlbGwgYXMgYSBjb3VudCBvZiBhbGwgb2YgdGhlIGN1c3RvbWVycyBpbiB0aGUgcmVtb3RlIHN0b3JlLlxyXG4gIEBwYXJhbSBlbmFibGVkIC0gKGRlZmF1bHQgPSB0cnVlKSBXaGV0aGVyIG9yIG5vdCBpbmxpbmVDb3VudCBjYXBhYmlsaXR5IHNob3VsZCBiZSBlbmFibGVkLiBJZiB0aGlzIHBhcmFtZXRlciBpcyBvbWl0dGVkLCB0cnVlIGlzIGFzc3VtZWQuXHJcbiAgKiovXHJcbiAgaW5saW5lQ291bnQoZW5hYmxlZD86IGJvb2xlYW4pIHtcclxuICAgIGFzc2VydFBhcmFtKGVuYWJsZWQsIFwiZW5hYmxlZFwiKS5pc0Jvb2xlYW4oKS5pc09wdGlvbmFsKCkuY2hlY2soKTtcclxuICAgIGVuYWJsZWQgPSAoZW5hYmxlZCA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiAhIWVuYWJsZWQ7XHJcbiAgICByZXR1cm4gY2xvbmUodGhpcywgXCJpbmxpbmVDb3VudEVuYWJsZWRcIiwgZW5hYmxlZCk7XHJcbiAgfVxyXG5cclxuICB1c2VOYW1lT25TZXJ2ZXIodXNlc05hbWVPblNlcnZlcj86IGJvb2xlYW4pIHtcclxuICAgIGFzc2VydFBhcmFtKHVzZXNOYW1lT25TZXJ2ZXIsIFwidXNlc05hbWVPblNlcnZlclwiKS5pc0Jvb2xlYW4oKS5pc09wdGlvbmFsKCkuY2hlY2soKTtcclxuICAgIHVzZXNOYW1lT25TZXJ2ZXIgPSAodXNlc05hbWVPblNlcnZlciA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiAhIXVzZXNOYW1lT25TZXJ2ZXI7XHJcbiAgICByZXR1cm4gY2xvbmUodGhpcywgXCJ1c2VzTmFtZU9uU2VydmVyXCIsIHVzZXNOYW1lT25TZXJ2ZXIpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIHF1ZXJ5IHdpdGggdGhlICdub1RyYWNraW5nJyBjYXBhYmlsaXR5IGVpdGhlciBlbmFibGVkIG9yIGRpc2FibGVkLiAgV2l0aCAnbm9UcmFja2luZycgZW5hYmxlZCwgdGhlIHJlc3VsdHMgb2YgdGhpcyBxdWVyeVxyXG4gIHdpbGwgbm90IGJlIGNvZXJjZWQgaW50byBlbnRpdGllcyBidXQgd2lsbCBpbnN0ZWFkIGxvb2sgbGlrZSByYXcgamF2YXNjcmlwdCBwcm9qZWN0aW9ucy4gaS5lLiBzaW1wbGUgamF2YXNjcmlwdCBvYmplY3RzLlxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgICAudGFrZSgyMClcclxuICA+ICAgICAgICAgLm9yZGVyQnkoXCJDb21wYW55TmFtZVwiKVxyXG4gID4gICAgICAgICAubm9UcmFja2luZyh0cnVlKTtcclxuICBAcGFyYW0gZW5hYmxlZCAtIChkZWZhdWx0ID0gdHJ1ZSkgV2hldGhlciBvciBub3QgdGhlIG5vVHJhY2tpbmcgY2FwYWJpbGl0eSBzaG91bGQgYmUgZW5hYmxlZC4gSWYgdGhpcyBwYXJhbWV0ZXIgaXMgb21pdHRlZCwgdHJ1ZSBpcyBhc3N1bWVkLlxyXG4gICoqL1xyXG4gIG5vVHJhY2tpbmcoZW5hYmxlZD86IGJvb2xlYW4pIHtcclxuICAgIGFzc2VydFBhcmFtKGVuYWJsZWQsIFwiZW5hYmxlZFwiKS5pc0Jvb2xlYW4oKS5pc09wdGlvbmFsKCkuY2hlY2soKTtcclxuICAgIGVuYWJsZWQgPSAoZW5hYmxlZCA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiAhIWVuYWJsZWQ7XHJcbiAgICByZXR1cm4gY2xvbmUodGhpcywgXCJub1RyYWNraW5nRW5hYmxlZFwiLCBlbmFibGVkKTtcclxuICB9XHJcblxyXG4gIHVzaW5nKG9iajogRW50aXR5TWFuYWdlcik6IEVudGl0eVF1ZXJ5O1xyXG4gIHVzaW5nKG9iajogRGF0YVNlcnZpY2UpOiBFbnRpdHlRdWVyeTtcclxuICB1c2luZyhvYmo6IEpzb25SZXN1bHRzQWRhcHRlcik6IEVudGl0eVF1ZXJ5O1xyXG4gIHVzaW5nKG9iajogUXVlcnlPcHRpb25zKTogRW50aXR5UXVlcnk7XHJcbiAgdXNpbmcob2JqOiBNZXJnZVN0cmF0ZWd5KTogRW50aXR5UXVlcnk7XHJcbiAgdXNpbmcob2JqOiBGZXRjaFN0cmF0ZWd5KTogRW50aXR5UXVlcnk7XHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIGNvcHkgb2YgdGhpcyBFbnRpdHlRdWVyeSB3aXRoIHRoZSBzcGVjaWZpZWQgW1tFbnRpdHlNYW5hZ2VyXV0sIFtbRGF0YVNlcnZpY2VdXSxcclxuICBbW0pzb25SZXN1bHRzQWRhcHRlcl1dLCBbW01lcmdlU3RyYXRlZ3ldXSBvciBbW0ZldGNoU3RyYXRlZ3ldXSBhcHBsaWVkLlxyXG4gID4gICAgICAvLyAndXNpbmcnIGNhbiBiZSB1c2VkIHRvIHJldHVybiBhIG5ldyBxdWVyeSB3aXRoIGEgc3BlY2lmaWVkIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIGxldCBlbSA9IG5ldyBFbnRpdHlNYW5hZ2VyKHNlcnZpY2VOYW1lKTtcclxuICA+ICAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiT3JkZXJzXCIpXHJcbiAgPiAgICAgICAgLnVzaW5nKGVtKTtcclxuXHJcbiAgb3Igd2l0aCBhIHNwZWNpZmllZCBbW01lcmdlU3RyYXRlZ3ldXVxyXG4gID4gICAgICBsZXQgZW0gPSBuZXcgRW50aXR5TWFuYWdlcihzZXJ2aWNlTmFtZSk7XHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIk9yZGVyc1wiKVxyXG4gID4gICAgICAgIC51c2luZyhNZXJnZVN0cmF0ZWd5LlByZXNlcnZlQ2hhbmdlcyk7XHJcblxyXG4gIG9yIHdpdGggYSBzcGVjaWZpZWQgW1tGZXRjaFN0cmF0ZWd5XV1cclxuICA+ICAgICAgbGV0IGVtID0gbmV3IEVudGl0eU1hbmFnZXIoc2VydmljZU5hbWUpO1xyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJPcmRlcnNcIilcclxuICA+ICAgICAgICAudXNpbmcoRmV0Y2hTdHJhdGVneS5Gcm9tTG9jYWxDYWNoZSk7XHJcbiAgQHBhcmFtIG9iaiAtIFRoZSBvYmplY3QgdG8gdXBkYXRlIGluIGNyZWF0aW5nIGEgbmV3IEVudGl0eVF1ZXJ5IGZyb20gYW4gZXhpc3Rpbmcgb25lLlxyXG4gICoqL1xyXG4gIHVzaW5nKG9iajogYW55KSB7XHJcbiAgICBpZiAoIW9iaikgcmV0dXJuIHRoaXM7XHJcbiAgICBsZXQgZXEgPSBjbG9uZSh0aGlzKTtcclxuICAgIHByb2Nlc3NVc2luZyhlcSwge1xyXG4gICAgICBcImVudGl0eU1hbmFnZXJcIjogbnVsbCxcclxuICAgICAgXCJkYXRhU2VydmljZVwiOiBudWxsLFxyXG4gICAgICBcInF1ZXJ5T3B0aW9uc1wiOiBudWxsLFxyXG4gICAgICBcImZldGNoU3RyYXRlZ3lcIjogKGVxOiBFbnRpdHlRdWVyeSwgdmFsOiBhbnkpID0+IHtcclxuICAgICAgICBlcS5xdWVyeU9wdGlvbnMgPSAoZXEucXVlcnlPcHRpb25zIHx8IG5ldyBRdWVyeU9wdGlvbnMoKSkudXNpbmcodmFsKTtcclxuICAgICAgfSxcclxuICAgICAgXCJtZXJnZVN0cmF0ZWd5XCI6IChlcTogRW50aXR5UXVlcnksIHZhbDogYW55KSA9PiB7XHJcbiAgICAgICAgZXEucXVlcnlPcHRpb25zID0gKGVxLnF1ZXJ5T3B0aW9ucyB8fCBuZXcgUXVlcnlPcHRpb25zKCkpLnVzaW5nKHZhbCk7XHJcbiAgICAgIH0sXHJcbiAgICAgIFwianNvblJlc3VsdHNBZGFwdGVyXCI6IChlcTogRW50aXR5UXVlcnksIHZhbDogYW55KSA9PiB7XHJcbiAgICAgICAgZXEuZGF0YVNlcnZpY2UgPSAoZXEuZGF0YVNlcnZpY2UgfHwgbmV3IERhdGFTZXJ2aWNlKCkpLnVzaW5nKHsganNvblJlc3VsdHNBZGFwdGVyOiB2YWwgfSk7XHJcbiAgICAgIH1cclxuICAgIH0sIG9iaik7XHJcbiAgICByZXR1cm4gZXE7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBFeGVjdXRlcyB0aGlzIHF1ZXJ5LiAgVGhpcyBtZXRob2QgcmVxdWlyZXMgdGhhdCBhbiBFbnRpdHlNYW5hZ2VyIGhhcyBiZWVuIHByZXZpb3VzbHkgc3BlY2lmaWVkIHZpYSB0aGUgXCJ1c2luZ1wiIG1ldGhvZC5cclxuICBcclxuICBUaGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkIHVzaW5nIGEgJ3Byb21pc2VzJyBzeW50YXggKCByZWNvbW1lbmRlZClcclxuICA+ICAgICAgbGV0IGVtID0gbmV3IEVudGl0eU1hbmFnZXIoc2VydmljZU5hbWUpO1xyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJPcmRlcnNcIikudXNpbmcoZW0pO1xyXG4gID4gICAgICBxdWVyeS5leGVjdXRlKCkudGhlbiggZnVuY3Rpb24oZGF0YSkge1xyXG4gID4gICAgICAgICAgLi4uIHF1ZXJ5IHJlc3VsdHMgcHJvY2Vzc2VkIGhlcmVcclxuICA+ICAgICAgfSkuY2F0Y2goIGZ1bmN0aW9uKGVycikge1xyXG4gID4gICAgICAgICAgLi4uIHF1ZXJ5IGZhaWx1cmUgcHJvY2Vzc2VkIGhlcmVcclxuICA+ICAgICAgfSk7XHJcblxyXG4gIG9yIHdpdGggY2FsbGJhY2tzXHJcbiAgPiAgICAgIGxldCBlbSA9IG5ldyBFbnRpdHlNYW5hZ2VyKHNlcnZpY2VOYW1lKTtcclxuICA+ICAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiT3JkZXJzXCIpLnVzaW5nKGVtKTtcclxuICA+ICAgICAgcXVlcnkuZXhlY3V0ZShcclxuICA+ICAgICAgICBmdW5jdGlvbihkYXRhKSB7XHJcbiAgPiAgICAgICAgICAgICAgICAgICAgbGV0IG9yZGVycyA9IGRhdGEucmVzdWx0cztcclxuICA+ICAgICAgICAgICAgICAgICAgICAuLi4gcXVlcnkgcmVzdWx0cyBwcm9jZXNzZWQgaGVyZVxyXG4gID4gICAgICAgICAgICAgICAgfSxcclxuICA+ICAgICAgICBmdW5jdGlvbihlcnIpIHtcclxuICA+ICAgICAgICAgICAgICAgICAgICAuLi4gcXVlcnkgZmFpbHVyZSBwcm9jZXNzZWQgaGVyZVxyXG4gID4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gIEVpdGhlciB3YXkgdGhpcyBtZXRob2QgaXMgdGhlIHNhbWUgYXMgY2FsbGluZyB0aGUgRW50aXR5TWFuYWdlciAnZXhlY3V0ZScgbWV0aG9kLlxyXG4gID4gICAgICBsZXQgZW0gPSBuZXcgRW50aXR5TWFuYWdlcihzZXJ2aWNlTmFtZSk7XHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIk9yZGVyc1wiKTtcclxuICA+ICAgICAgZW0uZXhlY3V0ZVF1ZXJ5KHF1ZXJ5KS50aGVuKCBmdW5jdGlvbihkYXRhKSB7XHJcbiAgPiAgICAgICAgIGxldCBvcmRlcnMgPSBkYXRhLnJlc3VsdHM7XHJcbiAgPiAgICAgICAgICAuLi4gcXVlcnkgcmVzdWx0cyBwcm9jZXNzZWQgaGVyZVxyXG4gID4gICAgICB9KS5jYXRjaCggZnVuY3Rpb24oZXJyKSB7XHJcbiAgPiAgICAgICAgIC4uLiBxdWVyeSBmYWlsdXJlIHByb2Nlc3NlZCBoZXJlXHJcbiAgPiAgICAgIH0pO1xyXG5cclxuICBAcGFyYW0gY2FsbGJhY2sgLSAgRnVuY3Rpb24gY2FsbGVkIG9uIHN1Y2Nlc3MuXHJcbiAgQHBhcmFtIGVycm9yQ2FsbGJhY2sgLSBGdW5jdGlvbiBjYWxsZWQgb24gZmFpbHVyZS5cclxuICBAcmV0dXJuIFByb21pc2VcclxuICAqKi9cclxuICBleGVjdXRlKGNhbGxiYWNrPzogQ2FsbGJhY2ssIGVycm9yQ2FsbGJhY2s/OiBFcnJvckNhbGxiYWNrKTogUHJvbWlzZTxRdWVyeVJlc3VsdD4ge1xyXG4gICAgaWYgKCF0aGlzLmVudGl0eU1hbmFnZXIpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQW4gRW50aXR5UXVlcnkgbXVzdCBoYXZlIGl0cyBFbnRpdHlNYW5hZ2VyIHByb3BlcnR5IHNldCBiZWZvcmUgY2FsbGluZyAnZXhlY3V0ZSdcIik7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5lbnRpdHlNYW5hZ2VyLmV4ZWN1dGVRdWVyeSh0aGlzLCBjYWxsYmFjaywgZXJyb3JDYWxsYmFjayk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBFeGVjdXRlcyB0aGlzIHF1ZXJ5IGFnYWluc3QgdGhlIGxvY2FsIGNhY2hlLiAgVGhpcyBtZXRob2QgcmVxdWlyZXMgdGhhdCBhbiBFbnRpdHlNYW5hZ2VyIGhhdmUgYmVlbiBwcmV2aW91c2x5IHNwZWNpZmllZCB2aWEgdGhlIFwidXNpbmdcIiBtZXRob2QuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBlbSBpcyBhbiBlbnRpdHlNYW5hZ2VyIGFscmVhZHkgZmlsbGVkIHdpdGggb3JkZXIgZW50aXRpZXM7XHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIk9yZGVyc1wiKS51c2luZyhlbSk7XHJcbiAgPiAgICAgIGxldCBvcmRlcnMgPSBxdWVyeS5leGVjdXRlTG9jYWxseSgpO1xyXG5cclxuICBOb3RlIHRoYXQgY2FsbGluZyB0aGlzIG1ldGhvZCBpcyB0aGUgc2FtZSBhcyBjYWxsaW5nIFtbRW50aXR5TWFuYWdlci5leGVjdXRlUXVlcnlMb2NhbGx5XV0uXHJcbiAgKiovXHJcbiAgZXhlY3V0ZUxvY2FsbHkoKSB7XHJcbiAgICBpZiAoIXRoaXMuZW50aXR5TWFuYWdlcikge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBbiBFbnRpdHlRdWVyeSBtdXN0IGhhdmUgaXRzIEVudGl0eU1hbmFnZXIgcHJvcGVydHkgc2V0IGJlZm9yZSBjYWxsaW5nICdleGVjdXRlTG9jYWxseSdcIik7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5lbnRpdHlNYW5hZ2VyLmV4ZWN1dGVRdWVyeUxvY2FsbHkodGhpcyk7XHJcbiAgfVxyXG5cclxuICB0b0pTT04oKSB7XHJcbiAgICByZXR1cm4gdGhpcy50b0pTT05FeHQoKTtcclxuICB9XHJcblxyXG4gIC8qKiBUeXBpY2FsbHkgb25seSBmb3IgdXNlIHdoZW4gYnVpbGRpbmcgVXJpQnVpbGRlckFkYXB0ZXJzLiAgXHJcbiAgQGhpZGRlbiBAaW50ZXJuYWwgIFxyXG4gICovXHJcbiAgdG9KU09ORXh0KGNvbnRleHQ/OiBFbnRpdHlRdWVyeUpzb25Db250ZXh0KSB7XHJcbiAgICBjb250ZXh0ID0gY29udGV4dCB8fCB7fTtcclxuICAgIGNvbnRleHQuZW50aXR5VHlwZSA9IGNvbnRleHQuZW50aXR5VHlwZSB8fCB0aGlzLmZyb21FbnRpdHlUeXBlO1xyXG4gICAgY29udGV4dC5wcm9wZXJ0eVBhdGhGbiA9IGNvbnRleHQudG9OYW1lT25TZXJ2ZXIgPyBjb250ZXh0LmVudGl0eVR5cGUhLmNsaWVudFByb3BlcnR5UGF0aFRvU2VydmVyLmJpbmQoY29udGV4dC5lbnRpdHlUeXBlKSA6IGNvcmUuaWRlbnRpdHk7XHJcblxyXG4gICAgbGV0IHRvSlNPTkV4dEZuID0gZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICByZXR1cm4gdiA/IHYudG9KU09ORXh0KGNvbnRleHQpIDogdW5kZWZpbmVkO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBjb3JlLnRvSnNvbih0aGlzLCB7XHJcbiAgICAgIFwiZnJvbSxyZXNvdXJjZU5hbWVcIjogbnVsbCxcclxuICAgICAgXCJ0b1R5cGUscmVzdWx0RW50aXR5VHlwZVwiOiBmdW5jdGlvbiAodjogYW55KSB7XHJcbiAgICAgICAgLy8gcmVzdWx0RW50aXR5VHlwZSBjYW4gYmUgZWl0aGVyIGEgc3RyaW5nIG9yIGFuIGVudGl0eVR5cGVcclxuICAgICAgICByZXR1cm4gdiA/ICh0eXBlb2YgdiA9PT0gJ3N0cmluZycgPyB2IDogdi5uYW1lKSA6IHVuZGVmaW5lZDtcclxuICAgICAgfSxcclxuICAgICAgXCJ3aGVyZSx3aGVyZVByZWRpY2F0ZVwiOiB0b0pTT05FeHRGbixcclxuICAgICAgXCJvcmRlckJ5LG9yZGVyQnlDbGF1c2VcIjogdG9KU09ORXh0Rm4sXHJcbiAgICAgIFwic2VsZWN0LHNlbGVjdENsYXVzZVwiOiB0b0pTT05FeHRGbixcclxuICAgICAgXCJleHBhbmQsZXhwYW5kQ2xhdXNlXCI6IHRvSlNPTkV4dEZuLFxyXG4gICAgICBcInNraXAsc2tpcENvdW50XCI6IG51bGwsXHJcbiAgICAgIFwidGFrZSx0YWtlQ291bnRcIjogbnVsbCxcclxuICAgICAgcGFyYW1ldGVyczogZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICAgIHJldHVybiBjb3JlLmlzRW1wdHkodikgPyB1bmRlZmluZWQgOiB2O1xyXG4gICAgICB9LFxyXG4gICAgICBcImlubGluZUNvdW50LGlubGluZUNvdW50RW5hYmxlZFwiOiBmYWxzZSxcclxuICAgICAgXCJub1RyYWNraW5nLG5vVHJhY2tpbmdFbmFibGVkXCI6IGZhbHNlLFxyXG4gICAgICBxdWVyeU9wdGlvbnM6IG51bGxcclxuICAgIH0pO1xyXG5cclxuICB9XHJcblxyXG4gIHN0YXRpYyBmcm9tRW50aXRpZXMoZW50aXR5OiBFbnRpdHkpOiBFbnRpdHlRdWVyeTtcclxuICBzdGF0aWMgZnJvbUVudGl0aWVzKGVudGl0aWVzOiBFbnRpdHlbXSk6IEVudGl0eVF1ZXJ5O1xyXG4gIC8qKlxyXG4gIFN0YXRpYyBtZXRob2QgdGhhdCBjcmVhdGVzIGFuIEVudGl0eVF1ZXJ5IHRoYXQgd2lsbCBhbGxvdyAncmVxdWVyeWluZycgYW4gZW50aXR5IG9yIGEgY29sbGVjdGlvbiBvZiBlbnRpdGllcyBieSBwcmltYXJ5IGtleS4gVGhpcyBjYW4gYmUgdXNlZnVsXHJcbiAgdG8gZm9yY2UgYSByZXF1ZXJ5IG9mIHNlbGVjdGVkIGVudGl0aWVzLCBvciB0byByZXN0cmljdCBhbiBleGlzdGluZyBjb2xsZWN0aW9uIG9mIGVudGl0aWVzIGFjY29yZGluZyB0byBzb21lIGZpbHRlci5cclxuXHJcbiAgV29ya3MgZm9yIGEgc2luZ2xlIGVudGl0eSBvciBhbiBhcnJheSBvZiBlbnRpdGllcyBvZiB0aGUgU0FNRSB0eXBlLlxyXG4gIERvZXMgbm90IHdvcmsgZm9yIGFuIGFycmF5IG9mIGVudGl0aWVzIG9mIGRpZmZlcmVudCB0eXBlcy5cclxuICA+ICAgICAgLy8gYXNzdW1pbmcgJ2N1c3RvbWVycycgaXMgYW4gYXJyYXkgb2YgJ0N1c3RvbWVyJyBlbnRpdGllcyByZXRyaWV2ZWQgZWFybGllci5cclxuICA+ICAgICAgbGV0IGN1c3RvbWVyc1F1ZXJ5ID0gRW50aXR5UXVlcnkuZnJvbUVudGl0aWVzKGN1c3RvbWVycyk7XHJcblxyXG4gIFRoZSByZXN1bHRpbmcgcXVlcnkgY2FuLCBvZiBjb3Vyc2UsIGJlIGV4dGVuZGVkXHJcbiAgPiAgICAgIC8vIGFzc3VtaW5nICdjdXN0b21lcnMnIGlzIGFuIGFycmF5IG9mICdDdXN0b21lcicgZW50aXRpZXMgcmV0cmlldmVkIGVhcmxpZXIuXHJcbiAgPiAgICAgIGxldCBjdXN0b21lcnNRdWVyeSA9IEVudGl0eVF1ZXJ5LmZyb21FbnRpdGllcyhjdXN0b21lcnMpXHJcbiAgPiAgICAgICAgLndoZXJlKFwiUmVnaW9uXCIsIEZpbHRlclF1ZXJ5T3AuTm90RXF1YWxzLCBudWxsKTtcclxuXHJcbiAgU2luZ2xlIGVudGl0aWVzIGNhbiByZXF1ZXJpZWQgYXMgd2VsbC5cclxuICA+ICAgICAgLy8gYXNzdW1pbmcgJ2N1c3RvbWVyJyBpcyBhICdDdXN0b21lcicgZW50aXR5IHJldHJpZXZlZCBlYXJsaWVyLlxyXG4gID4gICAgICBsZXQgY3VzdG9tZXJRdWVyeSA9IEVudGl0eVF1ZXJ5LmZyb21FbnRpdGllcyhjdXN0b21lcik7XHJcblxyXG4gIHdpbGwgY3JlYXRlIGEgcXVlcnkgdGhhdCB3aWxsIHJldHVybiBhbiBhcnJheSBjb250YWluaW5nIGEgc2luZ2xlIGN1c3RvbWVyIGVudGl0eS5cclxuICBAcGFyYW0gZW50aXRpZXMgLSBUaGUgZW50aXRpZXMgZm9yIHdoaWNoIHdlIHdhbnQgdG8gY3JlYXRlIGFuIEVudGl0eVF1ZXJ5LlxyXG4gICoqL1xyXG4gIHN0YXRpYyBmcm9tRW50aXRpZXMoZW50aXRpZXM6IEVudGl0eSB8IEVudGl0eVtdKSB7XHJcbiAgICBhc3NlcnRQYXJhbShlbnRpdGllcywgXCJlbnRpdGllc1wiKS5pc0VudGl0eSgpLm9yKCkuaXNOb25FbXB0eUFycmF5KCkuaXNFbnRpdHkoKS5jaGVjaygpO1xyXG4gICAgbGV0IGVudHMgPSAoQXJyYXkuaXNBcnJheShlbnRpdGllcykpID8gZW50aXRpZXMgOiBbZW50aXRpZXNdO1xyXG5cclxuICAgIGxldCBmaXJzdEVudGl0eSA9IGVudHNbMF07XHJcbiAgICBsZXQgdHlwZSA9IGZpcnN0RW50aXR5LmVudGl0eVR5cGU7XHJcbiAgICBpZiAoZW50cy5zb21lKGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgIHJldHVybiBlLmVudGl0eVR5cGUgIT09IHR5cGU7XHJcbiAgICB9KSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBbGwgJ2Zyb21FbnRpdGllcycgbXVzdCBiZSB0aGUgc2FtZSB0eXBlOyBhdCBsZWFzdCBvbmUgaXMgbm90IG9mIHR5cGUgXCIgK1xyXG4gICAgICAgIHR5cGUubmFtZSk7XHJcbiAgICB9XHJcbiAgICBsZXQgcSA9IG5ldyBFbnRpdHlRdWVyeSh0eXBlLmRlZmF1bHRSZXNvdXJjZU5hbWUpO1xyXG4gICAgbGV0IHByZWRzID0gZW50cy5tYXAoZnVuY3Rpb24gKGVudGl0eSkge1xyXG4gICAgICByZXR1cm4gYnVpbGRQcmVkaWNhdGUoZW50aXR5KTtcclxuICAgIH0pO1xyXG4gICAgbGV0IHByZWQgPSBQcmVkaWNhdGUub3IocHJlZHMpO1xyXG4gICAgcSA9IHEud2hlcmUocHJlZCk7XHJcbiAgICBsZXQgZW0gPSBmaXJzdEVudGl0eS5lbnRpdHlBc3BlY3QuZW50aXR5TWFuYWdlcjtcclxuICAgIGlmIChlbSkge1xyXG4gICAgICBxID0gcS51c2luZyhlbSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIENyZWF0ZXMgYW4gRW50aXR5UXVlcnkgZm9yIHRoZSBzcGVjaWZpZWQgW1tFbnRpdHlLZXldXS5cclxuICA+ICAgICAgbGV0IGVtcFR5cGUgPSBtZXRhZGF0YVN0b3JlLmdldEVudGl0eVR5cGUoXCJFbXBsb3llZVwiKTtcclxuICA+ICAgICAgbGV0IGVudGl0eUtleSA9IG5ldyBFbnRpdHlLZXkoZW1wVHlwZSwgMSk7XHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IEVudGl0eVF1ZXJ5LmZyb21FbnRpdHlLZXkoZW50aXR5S2V5KTtcclxuXHJcbiAgb3JcclxuICA+ICAgICAgLy8gJ2VtcGxveWVlJyBpcyBhIHByZXZpb3VzbHkgcXVlcmllZCBlbXBsb3llZVxyXG4gID4gICAgICBsZXQgZW50aXR5S2V5ID0gZW1wbG95ZWUuZW50aXR5QXNwZWN0LmdldEtleSgpO1xyXG4gID4gICAgICBsZXQgcXVlcnkgPSBFbnRpdHlRdWVyeS5mcm9tRW50aXR5S2V5KGVudGl0eUtleSk7XHJcbiAgQHBhcmFtIGVudGl0eUtleSAtIFRoZSBbW0VudGl0eUtleV1dIGZvciB3aGljaCBhIHF1ZXJ5IHdpbGwgYmUgY3JlYXRlZC5cclxuICAqKi9cclxuICBzdGF0aWMgZnJvbUVudGl0eUtleShlbnRpdHlLZXk6IEVudGl0eUtleSkge1xyXG4gICAgYXNzZXJ0UGFyYW0oZW50aXR5S2V5LCBcImVudGl0eUtleVwiKS5pc0luc3RhbmNlT2YoRW50aXR5S2V5KS5jaGVjaygpO1xyXG4gICAgbGV0IHEgPSBuZXcgRW50aXR5UXVlcnkoZW50aXR5S2V5LmVudGl0eVR5cGUuZGVmYXVsdFJlc291cmNlTmFtZSk7XHJcbiAgICBsZXQgcHJlZCA9IGJ1aWxkS2V5UHJlZGljYXRlKGVudGl0eUtleSk7XHJcbiAgICBxID0gcS53aGVyZShwcmVkKS50b1R5cGUoZW50aXR5S2V5LmVudGl0eVR5cGUpO1xyXG4gICAgcmV0dXJuIHE7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBDcmVhdGVzIGFuIEVudGl0eVF1ZXJ5IGZvciB0aGUgc3BlY2lmaWVkIGVudGl0eSBhbmQgW1tOYXZpZ2F0aW9uUHJvcGVydHldXS5cclxuICA+ICAgICAgLy8gJ2VtcGxveWVlJyBpcyBhIHByZXZpb3VzbHkgcXVlcmllZCBlbXBsb3llZVxyXG4gID4gICAgICBsZXQgb3JkZXJzTmF2UHJvcCA9IGVtcGxveWVlLmVudGl0eVR5cGUuZ2V0UHJvcGVydHkoXCJPcmRlcnNcIik7XHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IEVudGl0eVF1ZXJ5LmZyb21FbnRpdHlOYXZpZ2F0aW9uKGVtcGxveWVlLCBvcmRlcnNOYXZQcm9wKTtcclxuXHJcbiAgd2lsbCByZXR1cm4gYSBxdWVyeSBmb3IgdGhlIFwiT3JkZXJzXCIgb2YgdGhlIHNwZWNpZmllZCAnZW1wbG95ZWUnLlxyXG4gIEBwYXJhbSBlbnRpdHkgLSBUaGUgRW50aXR5IHdob3NlIG5hdmlnYXRpb24gcHJvcGVydHkgd2lsbCBiZSBxdWVyaWVkLlxyXG4gIEBwYXJhbSBuYXZpZ2F0aW9uUHJvcGVydHkgLSBUaGUgW1tOYXZpZ2F0aW9uUHJvcGVydHldXSBvciBuYW1lIG9mIHRoZSBOYXZpZ2F0aW9uUHJvcGVydHkgdG8gYmUgcXVlcmllZC5cclxuICAqKi9cclxuICBzdGF0aWMgZnJvbUVudGl0eU5hdmlnYXRpb24gPSBmdW5jdGlvbiAoZW50aXR5OiBFbnRpdHksIG5hdmlnYXRpb25Qcm9wZXJ0eTogTmF2aWdhdGlvblByb3BlcnR5IHwgc3RyaW5nKSB7XHJcbiAgICBhc3NlcnRQYXJhbShlbnRpdHksIFwiZW50aXR5XCIpLmlzRW50aXR5KCkuY2hlY2soKTtcclxuICAgIGxldCBuYXZQcm9wZXJ0eSA9IGVudGl0eS5lbnRpdHlUeXBlLl9jaGVja05hdlByb3BlcnR5KG5hdmlnYXRpb25Qcm9wZXJ0eSk7XHJcbiAgICBsZXQgcSA9IG5ldyBFbnRpdHlRdWVyeShuYXZQcm9wZXJ0eS5lbnRpdHlUeXBlLmRlZmF1bHRSZXNvdXJjZU5hbWUpO1xyXG4gICAgbGV0IHByZWQgPSBidWlsZE5hdmlnYXRpb25QcmVkaWNhdGUoZW50aXR5LCBuYXZQcm9wZXJ0eSk7XHJcbiAgICBpZiAocHJlZCA9PSBudWxsKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVuYWJsZSB0byBjcmVhdGUgYSBOYXZpZ2F0aW9uUXVlcnkgZm9yIG5hdmlnYXRpb25Qcm9wZXJ0eTogXCIgKyBuYXZQcm9wZXJ0eS5uYW1lICk7XHJcbiAgICB9XHJcbiAgICBxID0gcS53aGVyZShwcmVkKTtcclxuICAgIGxldCBlbSA9IGVudGl0eS5lbnRpdHlBc3BlY3QuZW50aXR5TWFuYWdlcjtcclxuICAgIHJldHVybiBlbSA/IHEudXNpbmcoZW0pIDogcTtcclxuICB9O1xyXG5cclxuICAvLyBwcm90ZWN0ZWQgbWV0aG9kc1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9nZXRGcm9tRW50aXR5VHlwZShtZXRhZGF0YVN0b3JlOiBNZXRhZGF0YVN0b3JlLCB0aHJvd0Vycm9ySWZOb3RGb3VuZD86IGJvb2xlYW4pIHtcclxuICAgIC8vIFVuY29tbWVudCBuZXh0IHR3byBsaW5lcyBpZiB3ZSBtYWtlIHRoaXMgbWV0aG9kIHB1YmxpYy5cclxuICAgIC8vIGFzc2VydFBhcmFtKG1ldGFkYXRhU3RvcmUsIFwibWV0YWRhdGFTdG9yZVwiKS5pc0luc3RhbmNlT2YoTWV0YWRhdGFTdG9yZSkuY2hlY2soKTtcclxuICAgIC8vIGFzc2VydFBhcmFtKHRocm93RXJyb3JJZk5vdEZvdW5kLCBcInRocm93RXJyb3JJZk5vdEZvdW5kXCIpLmlzQm9vbGVhbigpLmlzT3B0aW9uYWwoKS5jaGVjaygpO1xyXG4gICAgbGV0IGVudGl0eVR5cGUgPSB0aGlzLmZyb21FbnRpdHlUeXBlO1xyXG4gICAgaWYgKGVudGl0eVR5cGUpIHJldHVybiBlbnRpdHlUeXBlO1xyXG5cclxuICAgIGxldCByZXNvdXJjZU5hbWUgPSB0aGlzLnJlc291cmNlTmFtZTtcclxuICAgIGlmICghcmVzb3VyY2VOYW1lKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZXJlIGlzIG5vIHJlc291cmNlTmFtZSBmb3IgdGhpcyBxdWVyeVwiKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAobWV0YWRhdGFTdG9yZS5pc0VtcHR5KCkpIHtcclxuICAgICAgaWYgKHRocm93RXJyb3JJZk5vdEZvdW5kKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlcmUgaXMgbm8gbWV0YWRhdGEgYXZhaWxhYmxlIGZvciB0aGlzIHF1ZXJ5LiBcIiArXHJcbiAgICAgICAgICBcIkFyZSB5b3UgcXVlcnlpbmcgdGhlIGxvY2FsIGNhY2hlIGJlZm9yZSB5b3UndmUgZmV0Y2hlZCBtZXRhZGF0YT9cIik7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGxldCBlbnRpdHlUeXBlTmFtZSA9IG1ldGFkYXRhU3RvcmUuZ2V0RW50aXR5VHlwZU5hbWVGb3JSZXNvdXJjZU5hbWUocmVzb3VyY2VOYW1lKTtcclxuICAgIGlmIChlbnRpdHlUeXBlTmFtZSkge1xyXG4gICAgICBlbnRpdHlUeXBlID0gbWV0YWRhdGFTdG9yZS5fZ2V0U3RydWN0dXJhbFR5cGUoZW50aXR5VHlwZU5hbWUpIGFzIEVudGl0eVR5cGU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBlbnRpdHlUeXBlID0gdGhpcy5fZ2V0VG9FbnRpdHlUeXBlKG1ldGFkYXRhU3RvcmUsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghZW50aXR5VHlwZSkge1xyXG4gICAgICBpZiAodGhyb3dFcnJvcklmTm90Rm91bmQpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoY29yZS5mb3JtYXRTdHJpbmcoXCJDYW5ub3QgZmluZCBhbiBlbnRpdHlUeXBlIGZvciByZXNvdXJjZU5hbWU6ICclMScuIFwiLCByZXNvdXJjZU5hbWUpICsgY29yZS5zdHJpbmdzLlRPX1RZUEUpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmZyb21FbnRpdHlUeXBlID0gZW50aXR5VHlwZTtcclxuICAgIHJldHVybiBlbnRpdHlUeXBlO1xyXG5cclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9nZXRUb0VudGl0eVR5cGUobWV0YWRhdGFTdG9yZTogTWV0YWRhdGFTdG9yZSwgc2tpcEZyb21DaGVjaz86IGJvb2xlYW4pOiBFbnRpdHlUeXBlIHwgdW5kZWZpbmVkIHtcclxuICAgIC8vIHNraXBGcm9tQ2hlY2sgaXMgdG8gYXZvaWQgcmVjdXJzaW9uIGlmIGNhbGxlZCBmcm9tIF9nZXRGcm9tRW50aXR5VHlwZTtcclxuICAgIGlmICh0aGlzLnJlc3VsdEVudGl0eVR5cGUgaW5zdGFuY2VvZiBFbnRpdHlUeXBlKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLnJlc3VsdEVudGl0eVR5cGU7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMucmVzdWx0RW50aXR5VHlwZSkge1xyXG4gICAgICAvLyByZXN1bHRFbnRpdHlUeXBlIGlzIGEgc3RyaW5nXHJcbiAgICAgIHRoaXMucmVzdWx0RW50aXR5VHlwZSA9IG1ldGFkYXRhU3RvcmUuX2dldFN0cnVjdHVyYWxUeXBlKHRoaXMucmVzdWx0RW50aXR5VHlwZSwgZmFsc2UpIGFzIEVudGl0eVR5cGU7XHJcbiAgICAgIHJldHVybiB0aGlzLnJlc3VsdEVudGl0eVR5cGU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyByZXNvbHZlIGl0LCBpZiBwb3NzaWJsZSwgdmlhIHRoZSByZXNvdXJjZU5hbWVcclxuICAgICAgLy8gZG8gbm90IGNhY2hlIHRoaXMgdmFsdWUgaW4gdGhpcyBjYXNlXHJcbiAgICAgIC8vIGNhbm5vdCBkZXRlcm1pbmUgdGhlIHJlc3VsdEVudGl0eVR5cGUgaWYgYSBzZWxlY3RDbGF1c2UgaXMgcHJlc2VudC5cclxuICAgICAgLy8gcmV0dXJuIHNraXBGcm9tQ2hlY2sgPyBudWxsIDogKCF0aGlzLnNlbGVjdENsYXVzZSkgJiYgdGhpcy5fZ2V0RnJvbUVudGl0eVR5cGUobWV0YWRhdGFTdG9yZSwgZmFsc2UpO1xyXG4gICAgICBpZiAoc2tpcEZyb21DaGVjayB8fCB0aGlzLnNlbGVjdENsYXVzZSkge1xyXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5fZ2V0RnJvbUVudGl0eVR5cGUobWV0YWRhdGFTdG9yZSwgZmFsc2UpO1xyXG4gICAgICB9XHJcblxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgLy8gZm9yIHRlc3RpbmdcclxuICBfdG9VcmkoZW06IEVudGl0eU1hbmFnZXIpIHtcclxuICAgIGxldCBkcyA9IERhdGFTZXJ2aWNlLnJlc29sdmUoW2VtLmRhdGFTZXJ2aWNlXSk7XHJcbiAgICByZXR1cm4gZHMhLnVyaUJ1aWxkZXIhLmJ1aWxkVXJpKHRoaXMsIGVtLm1ldGFkYXRhU3RvcmUpO1xyXG4gIH1cclxuXHJcbn1cclxuRW50aXR5UXVlcnkucHJvdG90eXBlLl8kdHlwZU5hbWUgPSBcIkVudGl0eVF1ZXJ5XCI7XHJcblxyXG4vLyBwcml2YXRlIGZ1bmN0aW9uc1xyXG5cclxuZnVuY3Rpb24gZnJvbUpTT04oZXE6IEVudGl0eVF1ZXJ5LCBqc29uOiBPYmplY3QpIHtcclxuICBjb3JlLnRvSnNvbihqc29uLCB7XHJcbiAgICBcInJlc291cmNlTmFtZSxmcm9tXCI6IG51bGwsXHJcbiAgICAvLyBqdXN0IHRoZSBuYW1lIGNvbWVzIGJhY2sgYW5kIHdpbGwgYmUgcmVzb2x2ZWQgbGF0ZXJcclxuICAgIFwicmVzdWx0RW50aXR5VHlwZSx0b1R5cGVcIjogbnVsbCxcclxuICAgIFwid2hlcmVQcmVkaWNhdGUsd2hlcmVcIjogZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICByZXR1cm4gdiA/IG5ldyBQcmVkaWNhdGUodikgOiB1bmRlZmluZWQ7XHJcbiAgICB9LFxyXG4gICAgXCJvcmRlckJ5Q2xhdXNlLG9yZGVyQnlcIjogZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICByZXR1cm4gdiA/IG5ldyBPcmRlckJ5Q2xhdXNlKHYpIDogdW5kZWZpbmVkO1xyXG4gICAgfSxcclxuICAgIFwic2VsZWN0Q2xhdXNlLHNlbGVjdFwiOiBmdW5jdGlvbiAodjogYW55KSB7XHJcbiAgICAgIHJldHVybiB2ID8gbmV3IFNlbGVjdENsYXVzZSh2KSA6IHVuZGVmaW5lZDtcclxuICAgIH0sXHJcbiAgICBcImV4cGFuZENsYXVzZSxleHBhbmRcIjogZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICByZXR1cm4gdiA/IG5ldyBFeHBhbmRDbGF1c2UodikgOiB1bmRlZmluZWQ7XHJcbiAgICB9LFxyXG4gICAgXCJza2lwQ291bnQsc2tpcFwiOiBudWxsLFxyXG4gICAgXCJ0YWtlQ291bnQsdGFrZVwiOiBudWxsLFxyXG4gICAgcGFyYW1ldGVyczogZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICByZXR1cm4gY29yZS5pc0VtcHR5KHYpID8gdW5kZWZpbmVkIDogdjtcclxuICAgIH0sXHJcbiAgICBcImlubGluZUNvdW50RW5hYmxlZCxpbmxpbmVDb3VudFwiOiBmYWxzZSxcclxuICAgIFwibm9UcmFja2luZ0VuYWJsZWQsbm9UcmFja2luZ1wiOiBmYWxzZSxcclxuICAgIHF1ZXJ5T3B0aW9uczogZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICByZXR1cm4gdiA/IFF1ZXJ5T3B0aW9ucy5mcm9tSlNPTih2KSA6IHVuZGVmaW5lZDtcclxuICAgIH1cclxuICB9LCBlcSk7XHJcbiAgcmV0dXJuIGVxO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjbG9uZShlcTogRW50aXR5UXVlcnksIHByb3BOYW1lPzogc3RyaW5nLCB2YWx1ZT86IGFueSkge1xyXG4gIC8vIGltbXV0YWJsZSBxdWVyaWVzIG1lYW4gdGhhdCB3ZSBkb24ndCBuZWVkIHRvIGNsb25lIGlmIG5vIGNoYW5nZSBpbiB2YWx1ZS5cclxuICBpZiAocHJvcE5hbWUpIHtcclxuICAgIGlmIChlcVtwcm9wTmFtZV0gPT09IHZhbHVlKSByZXR1cm4gZXE7XHJcbiAgfVxyXG4gIC8vIGNvcHlpbmcgUXVlcnlPcHRpb25zIGlzIHNhZmUgYmVjYXVzZSB0aGV5IGFyZSBhcmUgaW1tdXRhYmxlO1xyXG4gIGxldCBjb3B5ID0gY29yZS5leHRlbmQobmV3IEVudGl0eVF1ZXJ5KCksIGVxLCBbXHJcbiAgICBcInJlc291cmNlTmFtZVwiLFxyXG4gICAgXCJmcm9tRW50aXR5VHlwZVwiLFxyXG4gICAgXCJ3aGVyZVByZWRpY2F0ZVwiLFxyXG4gICAgXCJvcmRlckJ5Q2xhdXNlXCIsXHJcbiAgICBcInNlbGVjdENsYXVzZVwiLFxyXG4gICAgXCJza2lwQ291bnRcIixcclxuICAgIFwidGFrZUNvdW50XCIsXHJcbiAgICBcImV4cGFuZENsYXVzZVwiLFxyXG4gICAgXCJpbmxpbmVDb3VudEVuYWJsZWRcIixcclxuICAgIFwibm9UcmFja2luZ0VuYWJsZWRcIixcclxuICAgIFwidXNlc05hbWVPblNlcnZlclwiLFxyXG4gICAgXCJxdWVyeU9wdGlvbnNcIixcclxuICAgIFwiZW50aXR5TWFuYWdlclwiLFxyXG4gICAgXCJkYXRhU2VydmljZVwiLFxyXG4gICAgXCJyZXN1bHRFbnRpdHlUeXBlXCJcclxuICBdKSBhcyBFbnRpdHlRdWVyeTtcclxuICBjb3B5LnBhcmFtZXRlcnMgPSBjb3JlLmV4dGVuZCh7fSwgZXEucGFyYW1ldGVycyk7XHJcbiAgaWYgKHByb3BOYW1lKSB7XHJcbiAgICBjb3B5W3Byb3BOYW1lXSA9IHZhbHVlO1xyXG4gIH1cclxuICByZXR1cm4gY29weTtcclxufVxyXG5cclxuZnVuY3Rpb24gcHJvY2Vzc1VzaW5nKGVxOiBFbnRpdHlRdWVyeSwgbWFwOiBPYmplY3QsIHZhbHVlOiBhbnksIHByb3BlcnR5TmFtZT86IHN0cmluZykge1xyXG4gIGxldCB0eXBlTmFtZSA9IHZhbHVlLl8kdHlwZU5hbWUgfHwgKCh2YWx1ZSBpbnN0YW5jZW9mIEJyZWV6ZUVudW0pICYmICh2YWx1ZS5jb25zdHJ1Y3RvciBhcyBhbnkpLm5hbWUpO1xyXG4gIGxldCBrZXkgPSB0eXBlTmFtZSAmJiB0eXBlTmFtZS5zdWJzdHIoMCwgMSkudG9Mb3dlckNhc2UoKSArIHR5cGVOYW1lLnN1YnN0cigxKTtcclxuICBpZiAocHJvcGVydHlOYW1lICYmIGtleSAhPT0gcHJvcGVydHlOYW1lKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHZhbHVlIGZvciBwcm9wZXJ0eTogXCIgKyBwcm9wZXJ0eU5hbWUpO1xyXG4gIH1cclxuICBpZiAoa2V5KSB7XHJcbiAgICBsZXQgZm4gPSBtYXBba2V5XTtcclxuICAgIGlmIChmbiA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgY29uZmlnIHByb3BlcnR5OiBcIiArIGtleSk7XHJcbiAgICB9IGVsc2UgaWYgKGZuID09PSBudWxsKSB7XHJcbiAgICAgIGVxW2tleV0gPSB2YWx1ZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGZuKGVxLCB2YWx1ZSk7XHJcbiAgICB9XHJcbiAgfSBlbHNlIHtcclxuICAgIGNvcmUub2JqZWN0Rm9yRWFjaCh2YWx1ZSwgKHByb3BOYW1lLCB2YWwpID0+IHtcclxuICAgICAgcHJvY2Vzc1VzaW5nKGVxLCBtYXAsIHZhbCwgcHJvcE5hbWUpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBub3JtYWxpemVQcm9wZXJ0eVBhdGhzKHByb3BlcnR5UGF0aHM6IHN0cmluZyB8IHN0cmluZ1tdKSB7XHJcbiAgYXNzZXJ0UGFyYW0ocHJvcGVydHlQYXRocywgXCJwcm9wZXJ0eVBhdGhzXCIpLmlzT3B0aW9uYWwoKS5pc1N0cmluZygpLm9yKCkuaXNBcnJheSgpLmlzU3RyaW5nKCkuY2hlY2soKTtcclxuICBpZiAodHlwZW9mIHByb3BlcnR5UGF0aHMgPT09ICdzdHJpbmcnKSB7XHJcbiAgICBwcm9wZXJ0eVBhdGhzID0gcHJvcGVydHlQYXRocy5zcGxpdChcIixcIik7XHJcbiAgfVxyXG5cclxuICBwcm9wZXJ0eVBhdGhzID0gcHJvcGVydHlQYXRocy5tYXAoZnVuY3Rpb24gKHBwKSB7XHJcbiAgICByZXR1cm4gcHAudHJpbSgpO1xyXG4gIH0pO1xyXG4gIHJldHVybiBwcm9wZXJ0eVBhdGhzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBidWlsZFByZWRpY2F0ZShlbnRpdHk6IEVudGl0eSkge1xyXG4gIGxldCBlbnRpdHlUeXBlID0gZW50aXR5LmVudGl0eVR5cGU7XHJcbiAgbGV0IHByZWRQYXJ0cyA9IGVudGl0eVR5cGUua2V5UHJvcGVydGllcy5tYXAoZnVuY3Rpb24gKGtwKSB7XHJcbiAgICByZXR1cm4gUHJlZGljYXRlLmNyZWF0ZShrcC5uYW1lLCBGaWx0ZXJRdWVyeU9wLkVxdWFscywgZW50aXR5LmdldFByb3BlcnR5KGtwLm5hbWUpKTtcclxuICB9KTtcclxuICBsZXQgcHJlZCA9IFByZWRpY2F0ZS5hbmQocHJlZFBhcnRzKTtcclxuICByZXR1cm4gcHJlZDtcclxufVxyXG5cclxuZnVuY3Rpb24gYnVpbGRLZXlQcmVkaWNhdGUoZW50aXR5S2V5OiBFbnRpdHlLZXkpIHtcclxuICBsZXQga2V5UHJvcHMgPSBlbnRpdHlLZXkuZW50aXR5VHlwZS5rZXlQcm9wZXJ0aWVzO1xyXG4gIGxldCBwcmVkcyA9IGNvcmUuYXJyYXlaaXAoa2V5UHJvcHMsIGVudGl0eUtleS52YWx1ZXMsIGZ1bmN0aW9uIChrcCwgdikge1xyXG4gICAgcmV0dXJuIFByZWRpY2F0ZS5jcmVhdGUoa3AubmFtZSwgRmlsdGVyUXVlcnlPcC5FcXVhbHMsIHYpO1xyXG4gIH0pO1xyXG4gIGxldCBwcmVkID0gUHJlZGljYXRlLmFuZChwcmVkcyk7XHJcbiAgcmV0dXJuIHByZWQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGJ1aWxkTmF2aWdhdGlvblByZWRpY2F0ZShlbnRpdHk6IEVudGl0eSwgbmF2aWdhdGlvblByb3BlcnR5OiBOYXZpZ2F0aW9uUHJvcGVydHkpIHtcclxuICBpZiAobmF2aWdhdGlvblByb3BlcnR5LmlzU2NhbGFyKSB7XHJcbiAgICBpZiAobmF2aWdhdGlvblByb3BlcnR5LmZvcmVpZ25LZXlOYW1lcy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xyXG4gICAgbGV0IHJlbGF0ZWRLZXlWYWx1ZXMgPSBuYXZpZ2F0aW9uUHJvcGVydHkuZm9yZWlnbktleU5hbWVzLm1hcCgoZmtOYW1lKSA9PiB7XHJcbiAgICAgIHJldHVybiBlbnRpdHkuZ2V0UHJvcGVydHkoZmtOYW1lKTtcclxuICAgIH0pO1xyXG4gICAgbGV0IGVudGl0eUtleSA9IG5ldyBFbnRpdHlLZXkobmF2aWdhdGlvblByb3BlcnR5LmVudGl0eVR5cGUsIHJlbGF0ZWRLZXlWYWx1ZXMpO1xyXG4gICAgcmV0dXJuIGJ1aWxkS2V5UHJlZGljYXRlKGVudGl0eUtleSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIGxldCBpbnZlcnNlTnAgPSBuYXZpZ2F0aW9uUHJvcGVydHkuaW52ZXJzZTtcclxuICAgIGxldCBmb3JlaWduS2V5TmFtZXMgPSBpbnZlcnNlTnAgPyBpbnZlcnNlTnAuZm9yZWlnbktleU5hbWVzIDogbmF2aWdhdGlvblByb3BlcnR5LmludkZvcmVpZ25LZXlOYW1lcztcclxuICAgIGlmIChmb3JlaWduS2V5TmFtZXMubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcclxuICAgIGxldCBrZXlWYWx1ZXMgPSBlbnRpdHkuZW50aXR5QXNwZWN0LmdldEtleSgpLnZhbHVlcztcclxuICAgIGxldCBwcmVkUGFydHMgPSBjb3JlLmFycmF5WmlwKGZvcmVpZ25LZXlOYW1lcywga2V5VmFsdWVzLCAoZmtOYW1lLCBrdikgPT4ge1xyXG4gICAgICByZXR1cm4gUHJlZGljYXRlLmNyZWF0ZShma05hbWUsIEZpbHRlclF1ZXJ5T3AuRXF1YWxzLCBrdik7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBQcmVkaWNhdGUuYW5kKHByZWRQYXJ0cyk7XHJcbiAgfVxyXG59XHJcblxyXG4vKiogQmFzZSBjbGFzcyBmb3IgQm9vbGVhblF1ZXJ5T3AgYW5kIEZpbHRlclF1ZXJ5T3AgKi9cclxuZXhwb3J0IGludGVyZmFjZSBRdWVyeU9wIHtcclxuICAvKiogVGhlIG9wZXJhdG9yIGZvciB0aGlzIGVudW0uICovXHJcbiAgb3BlcmF0b3I6IHN0cmluZztcclxufVxyXG5cclxuXHJcblxyXG4vKipcclxuRmlsdGVyUXVlcnlPcCBpcyBhbiAnRW51bScgY29udGFpbmluZyBhbGwgb2YgdGhlIHZhbGlkICBbW1ByZWRpY2F0ZV1dXHJcbmZpbHRlciBvcGVyYXRvcnMgZm9yIGFuIFtbRW50aXR5UXVlcnldXS5cclxuKiovXHJcbmV4cG9ydCBjbGFzcyBGaWx0ZXJRdWVyeU9wIGV4dGVuZHMgQnJlZXplRW51bSBpbXBsZW1lbnRzIFF1ZXJ5T3Age1xyXG4gIC8qKiBUaGUgb3BlcmF0b3IgZm9yIHRoaXMgZW51bS4gKi9cclxuICBvcGVyYXRvcjogc3RyaW5nO1xyXG5cclxuICAvKiogQWxpYXNlczogXCJlcVwiLCBcIj09XCIgKiovXHJcbiAgc3RhdGljIEVxdWFscyA9IG5ldyBGaWx0ZXJRdWVyeU9wKHsgb3BlcmF0b3I6IFwiZXFcIiB9KTtcclxuICAvKiogIEFsaWFzZXM6IFwibmVcIiwgXCIhPVwiICAqKi9cclxuICBzdGF0aWMgTm90RXF1YWxzID0gbmV3IEZpbHRlclF1ZXJ5T3AoeyBvcGVyYXRvcjogXCJuZVwiIH0pO1xyXG4gIC8qKiBBbGlhc2VzOiBcImd0XCIsIFwiPlwiICAgKiovXHJcbiAgc3RhdGljIEdyZWF0ZXJUaGFuID0gbmV3IEZpbHRlclF1ZXJ5T3AoeyBvcGVyYXRvcjogXCJndFwiIH0pO1xyXG4gIC8qKiBBbGlhc2VzOiBcImx0XCIsIFwiPFwiICAqKi9cclxuICBzdGF0aWMgTGVzc1RoYW4gPSBuZXcgRmlsdGVyUXVlcnlPcCh7IG9wZXJhdG9yOiBcImx0XCIgfSk7XHJcbiAgLyoqICBBbGlhc2VzOiBcImdlXCIsIFwiPj1cIiAgKiovXHJcbiAgc3RhdGljIEdyZWF0ZXJUaGFuT3JFcXVhbCA9IG5ldyBGaWx0ZXJRdWVyeU9wKHsgb3BlcmF0b3I6IFwiZ2VcIiB9KTtcclxuICAvKiogIEFsaWFzZXM6IFwibGVcIiwgXCI8PVwiICAqKi9cclxuICBzdGF0aWMgTGVzc1RoYW5PckVxdWFsID0gbmV3IEZpbHRlclF1ZXJ5T3AoeyBvcGVyYXRvcjogXCJsZVwiIH0pO1xyXG4gIC8qKiAgU3RyaW5nIG9wZXJhdGlvbjogSXMgYSBzdHJpbmcgYSBzdWJzdHJpbmcgb2YgYW5vdGhlciBzdHJpbmcuICBBbGlhc2VzOiBcInN1YnN0cmluZ29mXCIgICAqKi9cclxuICBzdGF0aWMgQ29udGFpbnMgPSBuZXcgRmlsdGVyUXVlcnlPcCh7IG9wZXJhdG9yOiBcImNvbnRhaW5zXCIgfSk7XHJcbiAgLyoqIE5vIGFsaWFzZXMgKi9cclxuICBzdGF0aWMgU3RhcnRzV2l0aCA9IG5ldyBGaWx0ZXJRdWVyeU9wKHsgb3BlcmF0b3I6IFwic3RhcnRzd2l0aFwiIH0pO1xyXG4gIC8qKiBObyBhbGlhc2VzICovXHJcbiAgc3RhdGljIEVuZHNXaXRoID0gbmV3IEZpbHRlclF1ZXJ5T3AoeyBvcGVyYXRvcjogXCJlbmRzd2l0aFwiIH0pO1xyXG4gIC8qKiAgQWxpYXNlczogXCJzb21lXCIgICoqL1xyXG4gIHN0YXRpYyBBbnkgPSBuZXcgRmlsdGVyUXVlcnlPcCh7IG9wZXJhdG9yOiBcImFueVwiIH0pO1xyXG4gIC8qKiAgQWxpYXNlczogXCJldmVyeVwiICAqKi9cclxuICBzdGF0aWMgQWxsID0gbmV3IEZpbHRlclF1ZXJ5T3AoeyBvcGVyYXRvcjogXCJhbGxcIiB9KTtcclxuICAvKiogTm8gYWxpYXNlcyAqL1xyXG4gIHN0YXRpYyBJbiA9IG5ldyBGaWx0ZXJRdWVyeU9wKHsgb3BlcmF0b3I6IFwiaW5cIiB9KTtcclxuICAvKiogTm8gYWxpYXNlcyAqL1xyXG4gIHN0YXRpYyBJc1R5cGVPZiA9IG5ldyBGaWx0ZXJRdWVyeU9wKHsgb3BlcmF0b3I6IFwiaXNvZlwiIH0pO1xyXG59XHJcbkZpbHRlclF1ZXJ5T3AucHJvdG90eXBlLl8kdHlwZU5hbWUgPSBcIkZpbHRlclF1ZXJ5T3BcIjtcclxuRXJyb3JbJ3gnXSA9IEZpbHRlclF1ZXJ5T3AucmVzb2x2ZVN5bWJvbHMoKTtcclxuXHJcblxyXG4vKipcclxuIEJvb2xlYW5RdWVyeU9wIGlzIGFuICdFbnVtJyBjb250YWluaW5nIGFsbCBvZiB0aGUgdmFsaWQgIGJvb2xlYW5cclxub3BlcmF0b3JzIGZvciBhbiBbW0VudGl0eVF1ZXJ5XV0uXHJcbioqL1xyXG5leHBvcnQgY2xhc3MgQm9vbGVhblF1ZXJ5T3AgZXh0ZW5kcyBCcmVlemVFbnVtIGltcGxlbWVudHMgUXVlcnlPcCB7XHJcbiAgLyoqIFRoZSBvcGVyYXRvciBmb3IgdGhpcyBlbnVtLiAqL1xyXG4gIG9wZXJhdG9yOiBzdHJpbmc7XHJcblxyXG4gIHN0YXRpYyBBbmQgPSBuZXcgQm9vbGVhblF1ZXJ5T3AoeyBvcGVyYXRvcjogXCJhbmRcIiB9KTtcclxuICBzdGF0aWMgT3IgPSBuZXcgQm9vbGVhblF1ZXJ5T3AoeyBvcGVyYXRvcjogXCJvclwiIH0pO1xyXG4gIHN0YXRpYyBOb3QgPSBuZXcgQm9vbGVhblF1ZXJ5T3AoeyBvcGVyYXRvcjogXCJub3RcIiB9KTtcclxuXHJcbn1cclxuQm9vbGVhblF1ZXJ5T3AucHJvdG90eXBlLl8kdHlwZU5hbWUgPSBcIkJvb2xlYW5RdWVyeU9wXCI7XHJcbkVycm9yWyd4J10gPSBCb29sZWFuUXVlcnlPcC5yZXNvbHZlU3ltYm9scygpO1xyXG5cclxuXHJcbi8qKiBGb3IgdXNlIGJ5IGJyZWV6ZSBwbHVnaW4gYXV0aG9ycyBvbmx5LiAgVGhlIGNsYXNzIGlzIHVzZWQgaW4gbW9zdCBbW0lVcmlCdWlsZGVyQWRhcHRlcl1dIGltcGxlbWVudGF0aW9uc1xyXG5AYWRhcHRlciAoc2VlIFtbSVVyaUJ1aWxkZXJBZGFwdGVyXV0pICAgIFxyXG5AaGlkZGVuXHJcblxyXG5BbiBPcmRlckJ5Q2xhdXNlIGlzIGEgZGVzY3JpcHRpb24gb2YgdGhlIHByb3BlcnRpZXMgYW5kIGRpcmVjdGlvbiB0aGF0IHRoZSByZXN1bHRcclxub2YgYSBxdWVyeSBzaG91bGQgYmUgc29ydGVkIGluLiAgT3JkZXJCeUNsYXVzZXMgYXJlIGltbXV0YWJsZSwgd2hpY2ggbWVhbnMgdGhhdCBhbnlcclxubWV0aG9kIHRoYXQgd291bGQgbW9kaWZ5IGFuIE9yZGVyQnlDbGF1c2UgYWN0dWFsbHkgcmV0dXJucyBhIG5ldyBPcmRlckJ5Q2xhdXNlLlxyXG5cclxuRm9yIGV4YW1wbGUgZm9yIGFuIEVtcGxveWVlIG9iamVjdCB3aXRoIHByb3BlcnRpZXMgb2YgJ0NvbXBhbnknIGFuZCAnTGFzdE5hbWUnIHRoZSBmb2xsb3dpbmcgd291bGQgYmUgdmFsaWQgZXhwcmVzc2lvbnM6XHJcbj4gICAgIGxldCBvYmMgPSBuZXcgT3JkZXJCeUNsYXVzZShcIkNvbXBhbnkuQ29tcGFueU5hbWUsIExhc3ROYW1lXCIpXHJcblxyXG5vclxyXG4+ICAgICBsZXQgb2JjID0gbmV3IE9yZGVyQnlDbGF1c2UoXCJDb21wYW55LkNvbXBhbnlOYW1lIGRlc2MsIExhc3ROYW1lXCIpXHJcblxyXG5vclxyXG4+ICAgICBsZXQgb2JjID0gbmV3IE9yZGVyQnlDbGF1c2UoXCJDb21wYW55LkNvbXBhbnlOYW1lLCBMYXN0TmFtZVwiLCB0cnVlKTtcclxuKi9cclxuZXhwb3J0IGNsYXNzIE9yZGVyQnlDbGF1c2Uge1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIGl0ZW1zOiBPcmRlckJ5SXRlbVtdO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcm9wZXJ0eVBhdGhzOiBzdHJpbmdbXSB8IE9yZGVyQnlDbGF1c2VbXSwgaXNEZXNjPzogYm9vbGVhbikge1xyXG4gICAgaWYgKHByb3BlcnR5UGF0aHMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk9yZGVyQnlDbGF1c2UgY2Fubm90IGJlIGVtcHR5XCIpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHlvdSBjYW4gYWxzbyBwYXNzIGluIGFuIGFycmF5IG9mIG9yZGVyQnlDbGF1c2VzXHJcbiAgICBpZiAocHJvcGVydHlQYXRoc1swXSBpbnN0YW5jZW9mIE9yZGVyQnlDbGF1c2UpIHtcclxuICAgICAgbGV0IGNsYXVzZXMgPSBwcm9wZXJ0eVBhdGhzIGFzIE9yZGVyQnlDbGF1c2VbXTtcclxuICAgICAgdGhpcy5pdGVtcyA9IGNvcmUuYXJyYXlGbGF0TWFwKGNsYXVzZXMsIGMgPT4gYy5pdGVtcyk7XHJcbiAgICAgIC8vIHRoaXMuaXRlbXMgPSBBcnJheS5wcm90b3R5cGUuY29uY2F0LmFwcGx5KGNsYXVzZXNbMF0uaXRlbXMsIGNsYXVzZXMuc2xpY2UoMSkubWFwKGNvcmUucGx1Y2soXCJpdGVtc1wiKSkpO1xyXG4gICAgICAvLyB0aGlzLml0ZW1zID0gQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShbXSwgY2xhdXNlcy5tYXAoY29yZS5wbHVjayhcIml0ZW1zXCIpKSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLml0ZW1zID0gKHByb3BlcnR5UGF0aHMgYXMgc3RyaW5nW10pLm1hcChmdW5jdGlvbiAocHApIHtcclxuICAgICAgICByZXR1cm4gbmV3IE9yZGVyQnlJdGVtKHBwLCBpc0Rlc2MpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICB2YWxpZGF0ZShlbnRpdHlUeXBlOiBFbnRpdHlUeXBlKSB7XHJcbiAgICBpZiAoZW50aXR5VHlwZSA9PSBudWxsIHx8IGVudGl0eVR5cGUuaXNBbm9ueW1vdXMpIHJldHVybjtcclxuICAgIHRoaXMuaXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4ge1xyXG4gICAgICBpdGVtLnZhbGlkYXRlKGVudGl0eVR5cGUpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBnZXRDb21wYXJlcihlbnRpdHlUeXBlOiBFbnRpdHlUeXBlKSB7XHJcbiAgICBsZXQgb3JkZXJCeUZ1bmNzID0gdGhpcy5pdGVtcy5tYXAoZnVuY3Rpb24gKG9iYykge1xyXG4gICAgICByZXR1cm4gb2JjLmdldENvbXBhcmVyKGVudGl0eVR5cGUpO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGVudGl0eTE6IGFueSwgZW50aXR5MjogYW55KSB7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3JkZXJCeUZ1bmNzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgbGV0IHJlc3VsdCA9IG9yZGVyQnlGdW5jc1tpXShlbnRpdHkxLCBlbnRpdHkyKTtcclxuICAgICAgICBpZiAocmVzdWx0ICE9PSAwKSB7XHJcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gMDtcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICB0b0pTT05FeHQoY29udGV4dDogRW50aXR5UXVlcnlKc29uQ29udGV4dCkge1xyXG4gICAgcmV0dXJuIHRoaXMuaXRlbXMubWFwKGZ1bmN0aW9uIChpdGVtKSB7XHJcbiAgICAgIHJldHVybiBjb250ZXh0LnByb3BlcnR5UGF0aEZuIShpdGVtLnByb3BlcnR5UGF0aCkgKyAoaXRlbS5pc0Rlc2MgPyBcIiBkZXNjXCIgOiBcIlwiKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbn1cclxuXHJcbi8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgY2xhc3MgT3JkZXJCeUl0ZW0ge1xyXG4gIHByb3BlcnR5UGF0aDogc3RyaW5nO1xyXG4gIGlzRGVzYzogYm9vbGVhbjtcclxuICBsYXN0UHJvcGVydHk6IEVudGl0eVByb3BlcnR5O1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcm9wZXJ0eVBhdGg6IHN0cmluZywgaXNEZXNjPzogYm9vbGVhbikge1xyXG4gICAgaWYgKCEodHlwZW9mIHByb3BlcnR5UGF0aCA9PT0gJ3N0cmluZycpKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcInByb3BlcnR5UGF0aCBpcyBub3QgYSBzdHJpbmdcIik7XHJcbiAgICB9XHJcbiAgICBwcm9wZXJ0eVBhdGggPSBwcm9wZXJ0eVBhdGgudHJpbSgpO1xyXG5cclxuICAgIGxldCBwYXJ0cyA9IHByb3BlcnR5UGF0aC5zcGxpdCgnICcpO1xyXG4gICAgLy8gcGFydHNbMF0gaXMgdGhlIHByb3BlcnR5UGF0aDsgWzFdIHdvdWxkIGJlIHdoZXRoZXIgZGVzY2VuZGluZyBvciBub3QuXHJcbiAgICAvLyBpZiAocGFydHMubGVuZ3RoID4gMSAmJiBpc0Rlc2MgIT09IHRydWUgJiYgaXNEZXNjICE9PSBmYWxzZSkge1xyXG4gICAgaWYgKHBhcnRzLmxlbmd0aCA+IDEgJiYgaXNEZXNjID09IG51bGwpIHtcclxuICAgICAgaXNEZXNjID0gY29yZS5zdHJpbmdTdGFydHNXaXRoKHBhcnRzWzFdLnRvTG93ZXJDYXNlKCksIFwiZGVzY1wiKTtcclxuICAgICAgaWYgKCFpc0Rlc2MpIHtcclxuICAgICAgICAvLyBpc0Rlc2MgaXMgZmFsc2UgYnV0IGNoZWNrIHRvIG1ha2Ugc3VyZSBpdHMgaW50ZW5kZWQuXHJcbiAgICAgICAgbGV0IGlzQXNjID0gY29yZS5zdHJpbmdTdGFydHNXaXRoKHBhcnRzWzFdLnRvTG93ZXJDYXNlKCksIFwiYXNjXCIpO1xyXG4gICAgICAgIGlmICghaXNBc2MpIHtcclxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInRoZSBzZWNvbmQgd29yZCBpbiB0aGUgcHJvcGVydHlQYXRoIG11c3QgYmVnaW4gd2l0aCAnZGVzYycgb3IgJ2FzYydcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgdGhpcy5wcm9wZXJ0eVBhdGggPSBwYXJ0c1swXTtcclxuICAgIHRoaXMuaXNEZXNjID0gaXNEZXNjIHx8IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgdmFsaWRhdGUoZW50aXR5VHlwZTogRW50aXR5VHlwZSk6IEVudGl0eVByb3BlcnR5IHwgdW5kZWZpbmVkIHtcclxuICAgIGlmIChlbnRpdHlUeXBlID09IG51bGwgfHwgZW50aXR5VHlwZS5pc0Fub255bW91cykgcmV0dXJuO1xyXG4gICAgLy8gd2lsbCB0aHJvdyBhbiBleGNlcHRpb24gb24gYmFkIHByb3BlcnR5UGF0aFxyXG4gICAgdGhpcy5sYXN0UHJvcGVydHkgPSBlbnRpdHlUeXBlLmdldFByb3BlcnR5KHRoaXMucHJvcGVydHlQYXRoLCB0cnVlKSBhcyBFbnRpdHlQcm9wZXJ0eTtcclxuICAgIHJldHVybiB0aGlzLmxhc3RQcm9wZXJ0eTtcclxuICB9XHJcblxyXG4gIGdldENvbXBhcmVyKGVudGl0eVR5cGU6IEVudGl0eVR5cGUpIHtcclxuICAgIGxldCBwcm9wRGF0YVR5cGU6IERhdGFUeXBlO1xyXG4gICAgbGV0IGlzQ2FzZVNlbnNpdGl2ZTogYm9vbGVhbjtcclxuICAgIGlmICghdGhpcy5sYXN0UHJvcGVydHkpIHRoaXMudmFsaWRhdGUoZW50aXR5VHlwZSk7XHJcbiAgICBpZiAodGhpcy5sYXN0UHJvcGVydHkpIHtcclxuICAgICAgcHJvcERhdGFUeXBlID0gKHRoaXMubGFzdFByb3BlcnR5IGFzIGFueSkuZGF0YVR5cGU7XHJcbiAgICAgIGlzQ2FzZVNlbnNpdGl2ZSA9IHRoaXMubGFzdFByb3BlcnR5LnBhcmVudFR5cGUubWV0YWRhdGFTdG9yZS5sb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnMuaXNDYXNlU2Vuc2l0aXZlO1xyXG4gICAgfVxyXG5cclxuICAgIGxldCBwcm9wZXJ0eVBhdGggPSB0aGlzLnByb3BlcnR5UGF0aDtcclxuICAgIGxldCBpc0Rlc2MgPSB0aGlzLmlzRGVzYztcclxuXHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGVudGl0eTE6IGFueSwgZW50aXR5MjogYW55KSB7XHJcbiAgICAgIGxldCB2YWx1ZTEgPSBFbnRpdHlBc3BlY3QuZ2V0UHJvcGVydHlQYXRoVmFsdWUoZW50aXR5MSwgcHJvcGVydHlQYXRoKTtcclxuICAgICAgbGV0IHZhbHVlMiA9IEVudGl0eUFzcGVjdC5nZXRQcm9wZXJ0eVBhdGhWYWx1ZShlbnRpdHkyLCBwcm9wZXJ0eVBhdGgpO1xyXG4gICAgICBsZXQgZGF0YVR5cGUgPSBwcm9wRGF0YVR5cGUgfHwgKHZhbHVlMSAmJiBEYXRhVHlwZS5mcm9tVmFsdWUodmFsdWUxKSkgfHwgRGF0YVR5cGUuZnJvbVZhbHVlKHZhbHVlMik7XHJcbiAgICAgIGlmIChkYXRhVHlwZSA9PT0gRGF0YVR5cGUuU3RyaW5nKSB7XHJcbiAgICAgICAgaWYgKGlzQ2FzZVNlbnNpdGl2ZSkge1xyXG4gICAgICAgICAgdmFsdWUxID0gdmFsdWUxIHx8IFwiXCI7XHJcbiAgICAgICAgICB2YWx1ZTIgPSB2YWx1ZTIgfHwgXCJcIjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdmFsdWUxID0gKHZhbHVlMSB8fCBcIlwiKS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgICAgdmFsdWUyID0gKHZhbHVlMiB8fCBcIlwiKS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBsZXQgbm9ybWFsaXplID0gRGF0YVR5cGUuZ2V0Q29tcGFyYWJsZUZuKGRhdGFUeXBlKTtcclxuICAgICAgICB2YWx1ZTEgPSBub3JtYWxpemUodmFsdWUxKTtcclxuICAgICAgICB2YWx1ZTIgPSBub3JtYWxpemUodmFsdWUyKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAodmFsdWUxID09PSB2YWx1ZTIpIHtcclxuICAgICAgICByZXR1cm4gMDtcclxuICAgICAgfSBlbHNlIGlmICh2YWx1ZTEgPiB2YWx1ZTIgfHwgdmFsdWUyID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICByZXR1cm4gaXNEZXNjID8gLTEgOiAxO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJldHVybiBpc0Rlc2MgPyAxIDogLTE7XHJcbiAgICAgIH1cclxuICAgIH07XHJcbiAgfVxyXG59XHJcblxyXG4vKiogRm9yIHVzZSBieSBicmVlemUgcGx1Z2luIGF1dGhvcnMgb25seS4gIFRoZSBjbGFzcyBpcyB1c2VkIGluIG1vc3QgW1tJVXJpQnVpbGRlckFkYXB0ZXJdXSBpbXBsZW1lbnRhdGlvbnNcclxuQGFkYXB0ZXIgKHNlZSBbW0lVcmlCdWlsZGVyQWRhcHRlcl1dKSAgICBcclxuQGhpZGRlbiBcclxuKiovXHJcbmV4cG9ydCBjbGFzcyBTZWxlY3RDbGF1c2Uge1xyXG4gIHByb3BlcnR5UGF0aHM6IHN0cmluZ1tdO1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9wYXRoTmFtZXM6IHN0cmluZ1tdO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcm9wZXJ0eVBhdGhzOiBzdHJpbmdbXSkge1xyXG4gICAgdGhpcy5wcm9wZXJ0eVBhdGhzID0gcHJvcGVydHlQYXRocztcclxuICAgIHRoaXMuX3BhdGhOYW1lcyA9IHByb3BlcnR5UGF0aHMubWFwKGZ1bmN0aW9uIChwcCkge1xyXG4gICAgICByZXR1cm4gcHAucmVwbGFjZShcIi5cIiwgXCJfXCIpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICB2YWxpZGF0ZShlbnRpdHlUeXBlOiBFbnRpdHlUeXBlKSB7XHJcbiAgICBpZiAoZW50aXR5VHlwZSA9PSBudWxsIHx8IGVudGl0eVR5cGUuaXNBbm9ueW1vdXMpIHJldHVybjsgLy8gY2FuJ3QgdmFsaWRhdGUgeWV0XHJcbiAgICAvLyB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiBvbiBiYWQgcHJvcGVydHlQYXRoXHJcbiAgICB0aGlzLnByb3BlcnR5UGF0aHMuZm9yRWFjaChmdW5jdGlvbiAocGF0aCkge1xyXG4gICAgICBlbnRpdHlUeXBlLmdldFByb3BlcnR5KHBhdGgsIHRydWUpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICB0b0Z1bmN0aW9uKC8qIGNvbmZpZyAqLykge1xyXG4gICAgbGV0IHRoYXQgPSB0aGlzO1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChlbnRpdHk6IEVudGl0eSkge1xyXG4gICAgICBsZXQgcmVzdWx0ID0ge307XHJcbiAgICAgIHRoYXQucHJvcGVydHlQYXRocy5mb3JFYWNoKGZ1bmN0aW9uIChwYXRoLCBpKSB7XHJcbiAgICAgICAgcmVzdWx0W3RoYXQuX3BhdGhOYW1lc1tpXV0gPSBFbnRpdHlBc3BlY3QuZ2V0UHJvcGVydHlQYXRoVmFsdWUoZW50aXR5LCBwYXRoKTtcclxuICAgICAgfSk7XHJcbiAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgdG9KU09ORXh0KGNvbnRleHQ6IEVudGl0eVF1ZXJ5SnNvbkNvbnRleHQpIHtcclxuICAgIHJldHVybiB0aGlzLnByb3BlcnR5UGF0aHMubWFwKGZ1bmN0aW9uIChwcCkge1xyXG4gICAgICByZXR1cm4gY29udGV4dC5wcm9wZXJ0eVBhdGhGbiEocHApO1xyXG4gICAgfSk7XHJcbiAgfVxyXG59XHJcblxyXG4vKiogRm9yIHVzZSBieSBicmVlemUgcGx1Z2luIGF1dGhvcnMgb25seS4gIFRoZSBjbGFzcyBpcyB1c2VkIGluIG1vc3QgW1tJVXJpQnVpbGRlckFkYXB0ZXJdXSBpbXBsZW1lbnRhdGlvbnNcclxuQGFkYXB0ZXIgKHNlZSBbW0lVcmlCdWlsZGVyQWRhcHRlcl1dKSAgICBcclxuQGhpZGRlbiBcclxuKiovXHJcbmV4cG9ydCBjbGFzcyBFeHBhbmRDbGF1c2Uge1xyXG4gIHByb3BlcnR5UGF0aHM6IHN0cmluZ1tdO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcm9wZXJ0eVBhdGhzOiBzdHJpbmdbXSkge1xyXG4gICAgdGhpcy5wcm9wZXJ0eVBhdGhzID0gcHJvcGVydHlQYXRocztcclxuICB9XHJcblxyXG4gIHRvSlNPTkV4dChjb250ZXh0OiBFbnRpdHlRdWVyeUpzb25Db250ZXh0KSB7XHJcbiAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eVBhdGhzLm1hcChmdW5jdGlvbiAocHApIHtcclxuICAgICAgcmV0dXJuIGNvbnRleHQucHJvcGVydHlQYXRoRm4hKHBwKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbn1cclxuXHJcblxyXG4iXX0=