@sinequa/assistant 3.10.4 → 3.10.10

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 (839) hide show
  1. package/chat/index.d.ts +2155 -3
  2. package/fesm2022/sinequa-assistant-chat.mjs +764 -593
  3. package/fesm2022/sinequa-assistant-chat.mjs.map +1 -1
  4. package/index.d.ts +3 -5
  5. package/node_modules/zod/LICENSE +21 -0
  6. package/node_modules/zod/README.md +208 -0
  7. package/node_modules/zod/index.cjs +33 -0
  8. package/node_modules/zod/index.d.cts +4 -0
  9. package/node_modules/zod/index.d.ts +4 -0
  10. package/node_modules/zod/index.js +4 -0
  11. package/node_modules/zod/locales/index.cjs +17 -0
  12. package/node_modules/zod/locales/index.d.cts +1 -0
  13. package/node_modules/zod/locales/index.d.ts +1 -0
  14. package/node_modules/zod/locales/index.js +1 -0
  15. package/node_modules/zod/locales/package.json +6 -0
  16. package/node_modules/zod/mini/index.cjs +32 -0
  17. package/node_modules/zod/mini/index.d.cts +3 -0
  18. package/node_modules/zod/mini/index.d.ts +3 -0
  19. package/node_modules/zod/mini/index.js +3 -0
  20. package/node_modules/zod/mini/package.json +6 -0
  21. package/node_modules/zod/package.json +135 -0
  22. package/node_modules/zod/src/index.ts +4 -0
  23. package/node_modules/zod/src/locales/index.ts +1 -0
  24. package/node_modules/zod/src/mini/index.ts +3 -0
  25. package/node_modules/zod/src/v3/ZodError.ts +330 -0
  26. package/node_modules/zod/src/v3/benchmarks/datetime.ts +58 -0
  27. package/node_modules/zod/src/v3/benchmarks/discriminatedUnion.ts +80 -0
  28. package/node_modules/zod/src/v3/benchmarks/index.ts +59 -0
  29. package/node_modules/zod/src/v3/benchmarks/ipv4.ts +57 -0
  30. package/node_modules/zod/src/v3/benchmarks/object.ts +69 -0
  31. package/node_modules/zod/src/v3/benchmarks/primitives.ts +162 -0
  32. package/node_modules/zod/src/v3/benchmarks/realworld.ts +63 -0
  33. package/node_modules/zod/src/v3/benchmarks/string.ts +55 -0
  34. package/node_modules/zod/src/v3/benchmarks/union.ts +80 -0
  35. package/node_modules/zod/src/v3/errors.ts +13 -0
  36. package/node_modules/zod/src/v3/external.ts +6 -0
  37. package/node_modules/zod/src/v3/helpers/enumUtil.ts +17 -0
  38. package/node_modules/zod/src/v3/helpers/errorUtil.ts +8 -0
  39. package/node_modules/zod/src/v3/helpers/parseUtil.ts +176 -0
  40. package/node_modules/zod/src/v3/helpers/partialUtil.ts +34 -0
  41. package/node_modules/zod/src/v3/helpers/typeAliases.ts +2 -0
  42. package/node_modules/zod/src/v3/helpers/util.ts +224 -0
  43. package/node_modules/zod/src/v3/index.ts +4 -0
  44. package/node_modules/zod/src/v3/locales/en.ts +124 -0
  45. package/node_modules/zod/src/v3/standard-schema.ts +113 -0
  46. package/node_modules/zod/src/v3/tests/Mocker.ts +54 -0
  47. package/node_modules/zod/src/v3/tests/all-errors.test.ts +157 -0
  48. package/node_modules/zod/src/v3/tests/anyunknown.test.ts +28 -0
  49. package/node_modules/zod/src/v3/tests/array.test.ts +71 -0
  50. package/node_modules/zod/src/v3/tests/async-parsing.test.ts +388 -0
  51. package/node_modules/zod/src/v3/tests/async-refinements.test.ts +46 -0
  52. package/node_modules/zod/src/v3/tests/base.test.ts +29 -0
  53. package/node_modules/zod/src/v3/tests/bigint.test.ts +55 -0
  54. package/node_modules/zod/src/v3/tests/branded.test.ts +53 -0
  55. package/node_modules/zod/src/v3/tests/catch.test.ts +220 -0
  56. package/node_modules/zod/src/v3/tests/coerce.test.ts +133 -0
  57. package/node_modules/zod/src/v3/tests/complex.test.ts +70 -0
  58. package/node_modules/zod/src/v3/tests/custom.test.ts +31 -0
  59. package/node_modules/zod/src/v3/tests/date.test.ts +32 -0
  60. package/node_modules/zod/src/v3/tests/deepmasking.test.ts +186 -0
  61. package/node_modules/zod/src/v3/tests/default.test.ts +112 -0
  62. package/node_modules/zod/src/v3/tests/description.test.ts +33 -0
  63. package/node_modules/zod/src/v3/tests/discriminated-unions.test.ts +315 -0
  64. package/node_modules/zod/src/v3/tests/enum.test.ts +80 -0
  65. package/node_modules/zod/src/v3/tests/error.test.ts +551 -0
  66. package/node_modules/zod/src/v3/tests/firstparty.test.ts +87 -0
  67. package/node_modules/zod/src/v3/tests/firstpartyschematypes.test.ts +21 -0
  68. package/node_modules/zod/src/v3/tests/function.test.ts +261 -0
  69. package/node_modules/zod/src/v3/tests/generics.test.ts +48 -0
  70. package/node_modules/zod/src/v3/tests/instanceof.test.ts +37 -0
  71. package/node_modules/zod/src/v3/tests/intersection.test.ts +110 -0
  72. package/node_modules/zod/src/v3/tests/language-server.source.ts +76 -0
  73. package/node_modules/zod/src/v3/tests/language-server.test.ts +207 -0
  74. package/node_modules/zod/src/v3/tests/literal.test.ts +36 -0
  75. package/node_modules/zod/src/v3/tests/map.test.ts +110 -0
  76. package/node_modules/zod/src/v3/tests/masking.test.ts +4 -0
  77. package/node_modules/zod/src/v3/tests/mocker.test.ts +19 -0
  78. package/node_modules/zod/src/v3/tests/nan.test.ts +24 -0
  79. package/node_modules/zod/src/v3/tests/nativeEnum.test.ts +87 -0
  80. package/node_modules/zod/src/v3/tests/nullable.test.ts +42 -0
  81. package/node_modules/zod/src/v3/tests/number.test.ts +176 -0
  82. package/node_modules/zod/src/v3/tests/object-augmentation.test.ts +29 -0
  83. package/node_modules/zod/src/v3/tests/object-in-es5-env.test.ts +29 -0
  84. package/node_modules/zod/src/v3/tests/object.test.ts +434 -0
  85. package/node_modules/zod/src/v3/tests/optional.test.ts +42 -0
  86. package/node_modules/zod/src/v3/tests/parseUtil.test.ts +23 -0
  87. package/node_modules/zod/src/v3/tests/parser.test.ts +41 -0
  88. package/node_modules/zod/src/v3/tests/partials.test.ts +243 -0
  89. package/node_modules/zod/src/v3/tests/pickomit.test.ts +111 -0
  90. package/node_modules/zod/src/v3/tests/pipeline.test.ts +29 -0
  91. package/node_modules/zod/src/v3/tests/preprocess.test.ts +186 -0
  92. package/node_modules/zod/src/v3/tests/primitive.test.ts +440 -0
  93. package/node_modules/zod/src/v3/tests/promise.test.ts +90 -0
  94. package/node_modules/zod/src/v3/tests/readonly.test.ts +194 -0
  95. package/node_modules/zod/src/v3/tests/record.test.ts +171 -0
  96. package/node_modules/zod/src/v3/tests/recursive.test.ts +197 -0
  97. package/node_modules/zod/src/v3/tests/refine.test.ts +313 -0
  98. package/node_modules/zod/src/v3/tests/safeparse.test.ts +27 -0
  99. package/node_modules/zod/src/v3/tests/set.test.ts +142 -0
  100. package/node_modules/zod/src/v3/tests/standard-schema.test.ts +83 -0
  101. package/node_modules/zod/src/v3/tests/string.test.ts +916 -0
  102. package/node_modules/zod/src/v3/tests/transformer.test.ts +233 -0
  103. package/node_modules/zod/src/v3/tests/tuple.test.ts +90 -0
  104. package/node_modules/zod/src/v3/tests/unions.test.ts +57 -0
  105. package/node_modules/zod/src/v3/tests/validations.test.ts +133 -0
  106. package/node_modules/zod/src/v3/tests/void.test.ts +15 -0
  107. package/node_modules/zod/src/v3/types.ts +5138 -0
  108. package/node_modules/zod/src/v4/classic/checks.ts +32 -0
  109. package/node_modules/zod/src/v4/classic/coerce.ts +27 -0
  110. package/node_modules/zod/src/v4/classic/compat.ts +70 -0
  111. package/node_modules/zod/src/v4/classic/errors.ts +82 -0
  112. package/node_modules/zod/src/v4/classic/external.ts +51 -0
  113. package/node_modules/zod/src/v4/classic/from-json-schema.ts +643 -0
  114. package/node_modules/zod/src/v4/classic/index.ts +5 -0
  115. package/node_modules/zod/src/v4/classic/iso.ts +90 -0
  116. package/node_modules/zod/src/v4/classic/parse.ts +82 -0
  117. package/node_modules/zod/src/v4/classic/schemas.ts +2409 -0
  118. package/node_modules/zod/src/v4/classic/tests/anyunknown.test.ts +26 -0
  119. package/node_modules/zod/src/v4/classic/tests/apply.test.ts +59 -0
  120. package/node_modules/zod/src/v4/classic/tests/array.test.ts +264 -0
  121. package/node_modules/zod/src/v4/classic/tests/assignability.test.ts +210 -0
  122. package/node_modules/zod/src/v4/classic/tests/async-parsing.test.ts +381 -0
  123. package/node_modules/zod/src/v4/classic/tests/async-refinements.test.ts +68 -0
  124. package/node_modules/zod/src/v4/classic/tests/base.test.ts +7 -0
  125. package/node_modules/zod/src/v4/classic/tests/bigint.test.ts +54 -0
  126. package/node_modules/zod/src/v4/classic/tests/brand.test.ts +106 -0
  127. package/node_modules/zod/src/v4/classic/tests/catch.test.ts +276 -0
  128. package/node_modules/zod/src/v4/classic/tests/coalesce.test.ts +20 -0
  129. package/node_modules/zod/src/v4/classic/tests/codec-examples.test.ts +573 -0
  130. package/node_modules/zod/src/v4/classic/tests/codec.test.ts +562 -0
  131. package/node_modules/zod/src/v4/classic/tests/coerce.test.ts +160 -0
  132. package/node_modules/zod/src/v4/classic/tests/continuability.test.ts +374 -0
  133. package/node_modules/zod/src/v4/classic/tests/custom.test.ts +40 -0
  134. package/node_modules/zod/src/v4/classic/tests/date.test.ts +62 -0
  135. package/node_modules/zod/src/v4/classic/tests/datetime.test.ts +302 -0
  136. package/node_modules/zod/src/v4/classic/tests/default.test.ts +365 -0
  137. package/node_modules/zod/src/v4/classic/tests/describe-meta-checks.test.ts +27 -0
  138. package/node_modules/zod/src/v4/classic/tests/description.test.ts +32 -0
  139. package/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +661 -0
  140. package/node_modules/zod/src/v4/classic/tests/enum.test.ts +285 -0
  141. package/node_modules/zod/src/v4/classic/tests/error-utils.test.ts +595 -0
  142. package/node_modules/zod/src/v4/classic/tests/error.test.ts +711 -0
  143. package/node_modules/zod/src/v4/classic/tests/file.test.ts +96 -0
  144. package/node_modules/zod/src/v4/classic/tests/firstparty.test.ts +179 -0
  145. package/node_modules/zod/src/v4/classic/tests/fix-json-issue.test.ts +26 -0
  146. package/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +734 -0
  147. package/node_modules/zod/src/v4/classic/tests/function.test.ts +360 -0
  148. package/node_modules/zod/src/v4/classic/tests/generics.test.ts +72 -0
  149. package/node_modules/zod/src/v4/classic/tests/hash.test.ts +68 -0
  150. package/node_modules/zod/src/v4/classic/tests/index.test.ts +939 -0
  151. package/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +60 -0
  152. package/node_modules/zod/src/v4/classic/tests/intersection.test.ts +198 -0
  153. package/node_modules/zod/src/v4/classic/tests/json.test.ts +109 -0
  154. package/node_modules/zod/src/v4/classic/tests/lazy.test.ts +227 -0
  155. package/node_modules/zod/src/v4/classic/tests/literal.test.ts +117 -0
  156. package/node_modules/zod/src/v4/classic/tests/map.test.ts +330 -0
  157. package/node_modules/zod/src/v4/classic/tests/nan.test.ts +21 -0
  158. package/node_modules/zod/src/v4/classic/tests/nested-refine.test.ts +168 -0
  159. package/node_modules/zod/src/v4/classic/tests/nonoptional.test.ts +101 -0
  160. package/node_modules/zod/src/v4/classic/tests/nullable.test.ts +22 -0
  161. package/node_modules/zod/src/v4/classic/tests/number.test.ts +270 -0
  162. package/node_modules/zod/src/v4/classic/tests/object.test.ts +640 -0
  163. package/node_modules/zod/src/v4/classic/tests/optional.test.ts +223 -0
  164. package/node_modules/zod/src/v4/classic/tests/partial.test.ts +427 -0
  165. package/node_modules/zod/src/v4/classic/tests/pickomit.test.ts +211 -0
  166. package/node_modules/zod/src/v4/classic/tests/pipe.test.ts +101 -0
  167. package/node_modules/zod/src/v4/classic/tests/prefault.test.ts +74 -0
  168. package/node_modules/zod/src/v4/classic/tests/preprocess.test.ts +282 -0
  169. package/node_modules/zod/src/v4/classic/tests/primitive.test.ts +175 -0
  170. package/node_modules/zod/src/v4/classic/tests/promise.test.ts +81 -0
  171. package/node_modules/zod/src/v4/classic/tests/prototypes.test.ts +23 -0
  172. package/node_modules/zod/src/v4/classic/tests/readonly.test.ts +252 -0
  173. package/node_modules/zod/src/v4/classic/tests/record.test.ts +632 -0
  174. package/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +582 -0
  175. package/node_modules/zod/src/v4/classic/tests/refine.test.ts +570 -0
  176. package/node_modules/zod/src/v4/classic/tests/registries.test.ts +243 -0
  177. package/node_modules/zod/src/v4/classic/tests/set.test.ts +181 -0
  178. package/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts +134 -0
  179. package/node_modules/zod/src/v4/classic/tests/string-formats.test.ts +125 -0
  180. package/node_modules/zod/src/v4/classic/tests/string.test.ts +1175 -0
  181. package/node_modules/zod/src/v4/classic/tests/stringbool.test.ts +106 -0
  182. package/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +771 -0
  183. package/node_modules/zod/src/v4/classic/tests/to-json-schema-methods.test.ts +438 -0
  184. package/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +2990 -0
  185. package/node_modules/zod/src/v4/classic/tests/transform.test.ts +361 -0
  186. package/node_modules/zod/src/v4/classic/tests/tuple.test.ts +183 -0
  187. package/node_modules/zod/src/v4/classic/tests/union.test.ts +219 -0
  188. package/node_modules/zod/src/v4/classic/tests/url.test.ts +13 -0
  189. package/node_modules/zod/src/v4/classic/tests/validations.test.ts +283 -0
  190. package/node_modules/zod/src/v4/classic/tests/void.test.ts +12 -0
  191. package/node_modules/zod/src/v4/core/api.ts +1798 -0
  192. package/node_modules/zod/src/v4/core/checks.ts +1293 -0
  193. package/node_modules/zod/src/v4/core/config.ts +15 -0
  194. package/node_modules/zod/src/v4/core/core.ts +138 -0
  195. package/node_modules/zod/src/v4/core/doc.ts +44 -0
  196. package/node_modules/zod/src/v4/core/errors.ts +448 -0
  197. package/node_modules/zod/src/v4/core/index.ts +16 -0
  198. package/node_modules/zod/src/v4/core/json-schema-generator.ts +126 -0
  199. package/node_modules/zod/src/v4/core/json-schema-processors.ts +667 -0
  200. package/node_modules/zod/src/v4/core/json-schema.ts +147 -0
  201. package/node_modules/zod/src/v4/core/parse.ts +195 -0
  202. package/node_modules/zod/src/v4/core/regexes.ts +183 -0
  203. package/node_modules/zod/src/v4/core/registries.ts +105 -0
  204. package/node_modules/zod/src/v4/core/schemas.ts +4538 -0
  205. package/node_modules/zod/src/v4/core/standard-schema.ts +159 -0
  206. package/node_modules/zod/src/v4/core/tests/extend.test.ts +59 -0
  207. package/node_modules/zod/src/v4/core/tests/index.test.ts +46 -0
  208. package/node_modules/zod/src/v4/core/tests/locales/be.test.ts +124 -0
  209. package/node_modules/zod/src/v4/core/tests/locales/en.test.ts +22 -0
  210. package/node_modules/zod/src/v4/core/tests/locales/es.test.ts +181 -0
  211. package/node_modules/zod/src/v4/core/tests/locales/he.test.ts +379 -0
  212. package/node_modules/zod/src/v4/core/tests/locales/nl.test.ts +46 -0
  213. package/node_modules/zod/src/v4/core/tests/locales/ru.test.ts +128 -0
  214. package/node_modules/zod/src/v4/core/tests/locales/tr.test.ts +69 -0
  215. package/node_modules/zod/src/v4/core/tests/locales/uz.test.ts +83 -0
  216. package/node_modules/zod/src/v4/core/tests/record-constructor.test.ts +67 -0
  217. package/node_modules/zod/src/v4/core/tests/recursive-tuples.test.ts +45 -0
  218. package/node_modules/zod/src/v4/core/to-json-schema.ts +613 -0
  219. package/node_modules/zod/src/v4/core/util.ts +966 -0
  220. package/node_modules/zod/src/v4/core/versions.ts +5 -0
  221. package/node_modules/zod/src/v4/core/zsf.ts +323 -0
  222. package/node_modules/zod/src/v4/index.ts +4 -0
  223. package/node_modules/zod/src/v4/locales/ar.ts +115 -0
  224. package/node_modules/zod/src/v4/locales/az.ts +111 -0
  225. package/node_modules/zod/src/v4/locales/be.ts +176 -0
  226. package/node_modules/zod/src/v4/locales/bg.ts +128 -0
  227. package/node_modules/zod/src/v4/locales/ca.ts +116 -0
  228. package/node_modules/zod/src/v4/locales/cs.ts +118 -0
  229. package/node_modules/zod/src/v4/locales/da.ts +123 -0
  230. package/node_modules/zod/src/v4/locales/de.ts +116 -0
  231. package/node_modules/zod/src/v4/locales/en.ts +119 -0
  232. package/node_modules/zod/src/v4/locales/eo.ts +118 -0
  233. package/node_modules/zod/src/v4/locales/es.ts +141 -0
  234. package/node_modules/zod/src/v4/locales/fa.ts +126 -0
  235. package/node_modules/zod/src/v4/locales/fi.ts +121 -0
  236. package/node_modules/zod/src/v4/locales/fr-CA.ts +116 -0
  237. package/node_modules/zod/src/v4/locales/fr.ts +116 -0
  238. package/node_modules/zod/src/v4/locales/he.ts +246 -0
  239. package/node_modules/zod/src/v4/locales/hu.ts +117 -0
  240. package/node_modules/zod/src/v4/locales/hy.ts +164 -0
  241. package/node_modules/zod/src/v4/locales/id.ts +115 -0
  242. package/node_modules/zod/src/v4/locales/index.ts +49 -0
  243. package/node_modules/zod/src/v4/locales/is.ts +119 -0
  244. package/node_modules/zod/src/v4/locales/it.ts +116 -0
  245. package/node_modules/zod/src/v4/locales/ja.ts +114 -0
  246. package/node_modules/zod/src/v4/locales/ka.ts +123 -0
  247. package/node_modules/zod/src/v4/locales/kh.ts +7 -0
  248. package/node_modules/zod/src/v4/locales/km.ts +119 -0
  249. package/node_modules/zod/src/v4/locales/ko.ts +121 -0
  250. package/node_modules/zod/src/v4/locales/lt.ts +239 -0
  251. package/node_modules/zod/src/v4/locales/mk.ts +118 -0
  252. package/node_modules/zod/src/v4/locales/ms.ts +115 -0
  253. package/node_modules/zod/src/v4/locales/nl.ts +121 -0
  254. package/node_modules/zod/src/v4/locales/no.ts +116 -0
  255. package/node_modules/zod/src/v4/locales/ota.ts +117 -0
  256. package/node_modules/zod/src/v4/locales/pl.ts +118 -0
  257. package/node_modules/zod/src/v4/locales/ps.ts +126 -0
  258. package/node_modules/zod/src/v4/locales/pt.ts +116 -0
  259. package/node_modules/zod/src/v4/locales/ru.ts +176 -0
  260. package/node_modules/zod/src/v4/locales/sl.ts +118 -0
  261. package/node_modules/zod/src/v4/locales/sv.ts +119 -0
  262. package/node_modules/zod/src/v4/locales/ta.ts +118 -0
  263. package/node_modules/zod/src/v4/locales/th.ts +119 -0
  264. package/node_modules/zod/src/v4/locales/tr.ts +111 -0
  265. package/node_modules/zod/src/v4/locales/ua.ts +7 -0
  266. package/node_modules/zod/src/v4/locales/uk.ts +117 -0
  267. package/node_modules/zod/src/v4/locales/ur.ts +119 -0
  268. package/node_modules/zod/src/v4/locales/uz.ts +116 -0
  269. package/node_modules/zod/src/v4/locales/vi.ts +117 -0
  270. package/node_modules/zod/src/v4/locales/yo.ts +124 -0
  271. package/node_modules/zod/src/v4/locales/zh-CN.ts +116 -0
  272. package/node_modules/zod/src/v4/locales/zh-TW.ts +115 -0
  273. package/node_modules/zod/src/v4/mini/checks.ts +32 -0
  274. package/node_modules/zod/src/v4/mini/coerce.ts +27 -0
  275. package/node_modules/zod/src/v4/mini/external.ts +40 -0
  276. package/node_modules/zod/src/v4/mini/index.ts +3 -0
  277. package/node_modules/zod/src/v4/mini/iso.ts +66 -0
  278. package/node_modules/zod/src/v4/mini/parse.ts +14 -0
  279. package/node_modules/zod/src/v4/mini/schemas.ts +1916 -0
  280. package/node_modules/zod/src/v4/mini/tests/apply.test.ts +24 -0
  281. package/node_modules/zod/src/v4/mini/tests/assignability.test.ts +129 -0
  282. package/node_modules/zod/src/v4/mini/tests/brand.test.ts +94 -0
  283. package/node_modules/zod/src/v4/mini/tests/checks.test.ts +144 -0
  284. package/node_modules/zod/src/v4/mini/tests/codec.test.ts +529 -0
  285. package/node_modules/zod/src/v4/mini/tests/computed.test.ts +36 -0
  286. package/node_modules/zod/src/v4/mini/tests/error.test.ts +22 -0
  287. package/node_modules/zod/src/v4/mini/tests/functions.test.ts +5 -0
  288. package/node_modules/zod/src/v4/mini/tests/index.test.ts +963 -0
  289. package/node_modules/zod/src/v4/mini/tests/number.test.ts +95 -0
  290. package/node_modules/zod/src/v4/mini/tests/object.test.ts +227 -0
  291. package/node_modules/zod/src/v4/mini/tests/prototypes.test.ts +43 -0
  292. package/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +275 -0
  293. package/node_modules/zod/src/v4/mini/tests/standard-schema.test.ts +50 -0
  294. package/node_modules/zod/src/v4/mini/tests/string.test.ts +347 -0
  295. package/node_modules/zod/src/v4-mini/index.ts +3 -0
  296. package/node_modules/zod/v3/ZodError.cjs +138 -0
  297. package/node_modules/zod/v3/ZodError.d.cts +164 -0
  298. package/node_modules/zod/v3/ZodError.d.ts +164 -0
  299. package/node_modules/zod/v3/ZodError.js +133 -0
  300. package/node_modules/zod/v3/errors.cjs +17 -0
  301. package/node_modules/zod/v3/errors.d.cts +5 -0
  302. package/node_modules/zod/v3/errors.d.ts +5 -0
  303. package/node_modules/zod/v3/errors.js +9 -0
  304. package/node_modules/zod/v3/external.cjs +22 -0
  305. package/node_modules/zod/v3/external.d.cts +6 -0
  306. package/node_modules/zod/v3/external.d.ts +6 -0
  307. package/node_modules/zod/v3/external.js +6 -0
  308. package/node_modules/zod/v3/helpers/enumUtil.cjs +2 -0
  309. package/node_modules/zod/v3/helpers/enumUtil.d.cts +8 -0
  310. package/node_modules/zod/v3/helpers/enumUtil.d.ts +8 -0
  311. package/node_modules/zod/v3/helpers/enumUtil.js +1 -0
  312. package/node_modules/zod/v3/helpers/errorUtil.cjs +9 -0
  313. package/node_modules/zod/v3/helpers/errorUtil.d.cts +9 -0
  314. package/node_modules/zod/v3/helpers/errorUtil.d.ts +9 -0
  315. package/node_modules/zod/v3/helpers/errorUtil.js +6 -0
  316. package/node_modules/zod/v3/helpers/parseUtil.cjs +124 -0
  317. package/node_modules/zod/v3/helpers/parseUtil.d.cts +78 -0
  318. package/node_modules/zod/v3/helpers/parseUtil.d.ts +78 -0
  319. package/node_modules/zod/v3/helpers/parseUtil.js +109 -0
  320. package/node_modules/zod/v3/helpers/partialUtil.cjs +2 -0
  321. package/node_modules/zod/v3/helpers/partialUtil.d.cts +8 -0
  322. package/node_modules/zod/v3/helpers/partialUtil.d.ts +8 -0
  323. package/node_modules/zod/v3/helpers/partialUtil.js +1 -0
  324. package/node_modules/zod/v3/helpers/typeAliases.cjs +2 -0
  325. package/node_modules/zod/v3/helpers/typeAliases.d.cts +2 -0
  326. package/node_modules/zod/v3/helpers/typeAliases.d.ts +2 -0
  327. package/node_modules/zod/v3/helpers/typeAliases.js +1 -0
  328. package/node_modules/zod/v3/helpers/util.cjs +137 -0
  329. package/node_modules/zod/v3/helpers/util.d.cts +85 -0
  330. package/node_modules/zod/v3/helpers/util.d.ts +85 -0
  331. package/node_modules/zod/v3/helpers/util.js +133 -0
  332. package/node_modules/zod/v3/index.cjs +33 -0
  333. package/node_modules/zod/v3/index.d.cts +4 -0
  334. package/node_modules/zod/v3/index.d.ts +4 -0
  335. package/node_modules/zod/v3/index.js +4 -0
  336. package/node_modules/zod/v3/locales/en.cjs +112 -0
  337. package/node_modules/zod/v3/locales/en.d.cts +3 -0
  338. package/node_modules/zod/v3/locales/en.d.ts +3 -0
  339. package/node_modules/zod/v3/locales/en.js +109 -0
  340. package/node_modules/zod/v3/package.json +6 -0
  341. package/node_modules/zod/v3/standard-schema.cjs +2 -0
  342. package/node_modules/zod/v3/standard-schema.d.cts +102 -0
  343. package/node_modules/zod/v3/standard-schema.d.ts +102 -0
  344. package/node_modules/zod/v3/standard-schema.js +1 -0
  345. package/node_modules/zod/v3/types.cjs +3777 -0
  346. package/node_modules/zod/v3/types.d.cts +1034 -0
  347. package/node_modules/zod/v3/types.d.ts +1034 -0
  348. package/node_modules/zod/v3/types.js +3695 -0
  349. package/node_modules/zod/v4/classic/checks.cjs +33 -0
  350. package/node_modules/zod/v4/classic/checks.d.cts +1 -0
  351. package/node_modules/zod/v4/classic/checks.d.ts +1 -0
  352. package/node_modules/zod/v4/classic/checks.js +1 -0
  353. package/node_modules/zod/v4/classic/coerce.cjs +47 -0
  354. package/node_modules/zod/v4/classic/coerce.d.cts +17 -0
  355. package/node_modules/zod/v4/classic/coerce.d.ts +17 -0
  356. package/node_modules/zod/v4/classic/coerce.js +17 -0
  357. package/node_modules/zod/v4/classic/compat.cjs +61 -0
  358. package/node_modules/zod/v4/classic/compat.d.cts +50 -0
  359. package/node_modules/zod/v4/classic/compat.d.ts +50 -0
  360. package/node_modules/zod/v4/classic/compat.js +31 -0
  361. package/node_modules/zod/v4/classic/errors.cjs +74 -0
  362. package/node_modules/zod/v4/classic/errors.d.cts +30 -0
  363. package/node_modules/zod/v4/classic/errors.d.ts +30 -0
  364. package/node_modules/zod/v4/classic/errors.js +48 -0
  365. package/node_modules/zod/v4/classic/external.cjs +73 -0
  366. package/node_modules/zod/v4/classic/external.d.cts +15 -0
  367. package/node_modules/zod/v4/classic/external.d.ts +15 -0
  368. package/node_modules/zod/v4/classic/external.js +20 -0
  369. package/node_modules/zod/v4/classic/from-json-schema.cjs +610 -0
  370. package/node_modules/zod/v4/classic/from-json-schema.d.cts +12 -0
  371. package/node_modules/zod/v4/classic/from-json-schema.d.ts +12 -0
  372. package/node_modules/zod/v4/classic/from-json-schema.js +584 -0
  373. package/node_modules/zod/v4/classic/index.cjs +33 -0
  374. package/node_modules/zod/v4/classic/index.d.cts +4 -0
  375. package/node_modules/zod/v4/classic/index.d.ts +4 -0
  376. package/node_modules/zod/v4/classic/index.js +4 -0
  377. package/node_modules/zod/v4/classic/iso.cjs +60 -0
  378. package/node_modules/zod/v4/classic/iso.d.cts +22 -0
  379. package/node_modules/zod/v4/classic/iso.d.ts +22 -0
  380. package/node_modules/zod/v4/classic/iso.js +30 -0
  381. package/node_modules/zod/v4/classic/package.json +6 -0
  382. package/node_modules/zod/v4/classic/parse.cjs +41 -0
  383. package/node_modules/zod/v4/classic/parse.d.cts +31 -0
  384. package/node_modules/zod/v4/classic/parse.d.ts +31 -0
  385. package/node_modules/zod/v4/classic/parse.js +15 -0
  386. package/node_modules/zod/v4/classic/schemas.cjs +1272 -0
  387. package/node_modules/zod/v4/classic/schemas.d.cts +739 -0
  388. package/node_modules/zod/v4/classic/schemas.d.ts +739 -0
  389. package/node_modules/zod/v4/classic/schemas.js +1157 -0
  390. package/node_modules/zod/v4/core/api.cjs +1222 -0
  391. package/node_modules/zod/v4/core/api.d.cts +304 -0
  392. package/node_modules/zod/v4/core/api.d.ts +304 -0
  393. package/node_modules/zod/v4/core/api.js +1082 -0
  394. package/node_modules/zod/v4/core/checks.cjs +601 -0
  395. package/node_modules/zod/v4/core/checks.d.cts +278 -0
  396. package/node_modules/zod/v4/core/checks.d.ts +278 -0
  397. package/node_modules/zod/v4/core/checks.js +575 -0
  398. package/node_modules/zod/v4/core/core.cjs +83 -0
  399. package/node_modules/zod/v4/core/core.d.cts +70 -0
  400. package/node_modules/zod/v4/core/core.d.ts +70 -0
  401. package/node_modules/zod/v4/core/core.js +76 -0
  402. package/node_modules/zod/v4/core/doc.cjs +39 -0
  403. package/node_modules/zod/v4/core/doc.d.cts +14 -0
  404. package/node_modules/zod/v4/core/doc.d.ts +14 -0
  405. package/node_modules/zod/v4/core/doc.js +35 -0
  406. package/node_modules/zod/v4/core/errors.cjs +213 -0
  407. package/node_modules/zod/v4/core/errors.d.cts +220 -0
  408. package/node_modules/zod/v4/core/errors.d.ts +220 -0
  409. package/node_modules/zod/v4/core/errors.js +182 -0
  410. package/node_modules/zod/v4/core/index.cjs +47 -0
  411. package/node_modules/zod/v4/core/index.d.cts +16 -0
  412. package/node_modules/zod/v4/core/index.d.ts +16 -0
  413. package/node_modules/zod/v4/core/index.js +16 -0
  414. package/node_modules/zod/v4/core/json-schema-generator.cjs +99 -0
  415. package/node_modules/zod/v4/core/json-schema-generator.d.cts +65 -0
  416. package/node_modules/zod/v4/core/json-schema-generator.d.ts +65 -0
  417. package/node_modules/zod/v4/core/json-schema-generator.js +95 -0
  418. package/node_modules/zod/v4/core/json-schema-processors.cjs +648 -0
  419. package/node_modules/zod/v4/core/json-schema-processors.d.cts +49 -0
  420. package/node_modules/zod/v4/core/json-schema-processors.d.ts +49 -0
  421. package/node_modules/zod/v4/core/json-schema-processors.js +605 -0
  422. package/node_modules/zod/v4/core/json-schema.cjs +2 -0
  423. package/node_modules/zod/v4/core/json-schema.d.cts +88 -0
  424. package/node_modules/zod/v4/core/json-schema.d.ts +88 -0
  425. package/node_modules/zod/v4/core/json-schema.js +1 -0
  426. package/node_modules/zod/v4/core/package.json +6 -0
  427. package/node_modules/zod/v4/core/parse.cjs +131 -0
  428. package/node_modules/zod/v4/core/parse.d.cts +49 -0
  429. package/node_modules/zod/v4/core/parse.d.ts +49 -0
  430. package/node_modules/zod/v4/core/parse.js +93 -0
  431. package/node_modules/zod/v4/core/regexes.cjs +166 -0
  432. package/node_modules/zod/v4/core/regexes.d.cts +79 -0
  433. package/node_modules/zod/v4/core/regexes.d.ts +79 -0
  434. package/node_modules/zod/v4/core/regexes.js +133 -0
  435. package/node_modules/zod/v4/core/registries.cjs +56 -0
  436. package/node_modules/zod/v4/core/registries.d.cts +35 -0
  437. package/node_modules/zod/v4/core/registries.d.ts +35 -0
  438. package/node_modules/zod/v4/core/registries.js +51 -0
  439. package/node_modules/zod/v4/core/schemas.cjs +2124 -0
  440. package/node_modules/zod/v4/core/schemas.d.cts +1146 -0
  441. package/node_modules/zod/v4/core/schemas.d.ts +1146 -0
  442. package/node_modules/zod/v4/core/schemas.js +2093 -0
  443. package/node_modules/zod/v4/core/standard-schema.cjs +2 -0
  444. package/node_modules/zod/v4/core/standard-schema.d.cts +126 -0
  445. package/node_modules/zod/v4/core/standard-schema.d.ts +126 -0
  446. package/node_modules/zod/v4/core/standard-schema.js +1 -0
  447. package/node_modules/zod/v4/core/to-json-schema.cjs +446 -0
  448. package/node_modules/zod/v4/core/to-json-schema.d.cts +114 -0
  449. package/node_modules/zod/v4/core/to-json-schema.d.ts +114 -0
  450. package/node_modules/zod/v4/core/to-json-schema.js +437 -0
  451. package/node_modules/zod/v4/core/util.cjs +710 -0
  452. package/node_modules/zod/v4/core/util.d.cts +199 -0
  453. package/node_modules/zod/v4/core/util.d.ts +199 -0
  454. package/node_modules/zod/v4/core/util.js +651 -0
  455. package/node_modules/zod/v4/core/versions.cjs +8 -0
  456. package/node_modules/zod/v4/core/versions.d.cts +5 -0
  457. package/node_modules/zod/v4/core/versions.d.ts +5 -0
  458. package/node_modules/zod/v4/core/versions.js +5 -0
  459. package/node_modules/zod/v4/index.cjs +22 -0
  460. package/node_modules/zod/v4/index.d.cts +3 -0
  461. package/node_modules/zod/v4/index.d.ts +3 -0
  462. package/node_modules/zod/v4/index.js +3 -0
  463. package/node_modules/zod/v4/locales/ar.cjs +133 -0
  464. package/node_modules/zod/v4/locales/ar.d.cts +5 -0
  465. package/node_modules/zod/v4/locales/ar.d.ts +4 -0
  466. package/node_modules/zod/v4/locales/ar.js +106 -0
  467. package/node_modules/zod/v4/locales/az.cjs +132 -0
  468. package/node_modules/zod/v4/locales/az.d.cts +5 -0
  469. package/node_modules/zod/v4/locales/az.d.ts +4 -0
  470. package/node_modules/zod/v4/locales/az.js +105 -0
  471. package/node_modules/zod/v4/locales/be.cjs +183 -0
  472. package/node_modules/zod/v4/locales/be.d.cts +5 -0
  473. package/node_modules/zod/v4/locales/be.d.ts +4 -0
  474. package/node_modules/zod/v4/locales/be.js +156 -0
  475. package/node_modules/zod/v4/locales/bg.cjs +147 -0
  476. package/node_modules/zod/v4/locales/bg.d.cts +5 -0
  477. package/node_modules/zod/v4/locales/bg.d.ts +4 -0
  478. package/node_modules/zod/v4/locales/bg.js +120 -0
  479. package/node_modules/zod/v4/locales/ca.cjs +134 -0
  480. package/node_modules/zod/v4/locales/ca.d.cts +5 -0
  481. package/node_modules/zod/v4/locales/ca.d.ts +4 -0
  482. package/node_modules/zod/v4/locales/ca.js +107 -0
  483. package/node_modules/zod/v4/locales/cs.cjs +138 -0
  484. package/node_modules/zod/v4/locales/cs.d.cts +5 -0
  485. package/node_modules/zod/v4/locales/cs.d.ts +4 -0
  486. package/node_modules/zod/v4/locales/cs.js +111 -0
  487. package/node_modules/zod/v4/locales/da.cjs +142 -0
  488. package/node_modules/zod/v4/locales/da.d.cts +5 -0
  489. package/node_modules/zod/v4/locales/da.d.ts +4 -0
  490. package/node_modules/zod/v4/locales/da.js +115 -0
  491. package/node_modules/zod/v4/locales/de.cjs +135 -0
  492. package/node_modules/zod/v4/locales/de.d.cts +5 -0
  493. package/node_modules/zod/v4/locales/de.d.ts +4 -0
  494. package/node_modules/zod/v4/locales/de.js +108 -0
  495. package/node_modules/zod/v4/locales/en.cjs +136 -0
  496. package/node_modules/zod/v4/locales/en.d.cts +5 -0
  497. package/node_modules/zod/v4/locales/en.d.ts +4 -0
  498. package/node_modules/zod/v4/locales/en.js +109 -0
  499. package/node_modules/zod/v4/locales/eo.cjs +136 -0
  500. package/node_modules/zod/v4/locales/eo.d.cts +5 -0
  501. package/node_modules/zod/v4/locales/eo.d.ts +4 -0
  502. package/node_modules/zod/v4/locales/eo.js +109 -0
  503. package/node_modules/zod/v4/locales/es.cjs +159 -0
  504. package/node_modules/zod/v4/locales/es.d.cts +5 -0
  505. package/node_modules/zod/v4/locales/es.d.ts +4 -0
  506. package/node_modules/zod/v4/locales/es.js +132 -0
  507. package/node_modules/zod/v4/locales/fa.cjs +141 -0
  508. package/node_modules/zod/v4/locales/fa.d.cts +5 -0
  509. package/node_modules/zod/v4/locales/fa.d.ts +4 -0
  510. package/node_modules/zod/v4/locales/fa.js +114 -0
  511. package/node_modules/zod/v4/locales/fi.cjs +139 -0
  512. package/node_modules/zod/v4/locales/fi.d.cts +5 -0
  513. package/node_modules/zod/v4/locales/fi.d.ts +4 -0
  514. package/node_modules/zod/v4/locales/fi.js +112 -0
  515. package/node_modules/zod/v4/locales/fr-CA.cjs +134 -0
  516. package/node_modules/zod/v4/locales/fr-CA.d.cts +5 -0
  517. package/node_modules/zod/v4/locales/fr-CA.d.ts +4 -0
  518. package/node_modules/zod/v4/locales/fr-CA.js +107 -0
  519. package/node_modules/zod/v4/locales/fr.cjs +135 -0
  520. package/node_modules/zod/v4/locales/fr.d.cts +5 -0
  521. package/node_modules/zod/v4/locales/fr.d.ts +4 -0
  522. package/node_modules/zod/v4/locales/fr.js +108 -0
  523. package/node_modules/zod/v4/locales/he.cjs +241 -0
  524. package/node_modules/zod/v4/locales/he.d.cts +5 -0
  525. package/node_modules/zod/v4/locales/he.d.ts +4 -0
  526. package/node_modules/zod/v4/locales/he.js +214 -0
  527. package/node_modules/zod/v4/locales/hu.cjs +135 -0
  528. package/node_modules/zod/v4/locales/hu.d.cts +5 -0
  529. package/node_modules/zod/v4/locales/hu.d.ts +4 -0
  530. package/node_modules/zod/v4/locales/hu.js +108 -0
  531. package/node_modules/zod/v4/locales/hy.cjs +174 -0
  532. package/node_modules/zod/v4/locales/hy.d.cts +5 -0
  533. package/node_modules/zod/v4/locales/hy.d.ts +4 -0
  534. package/node_modules/zod/v4/locales/hy.js +147 -0
  535. package/node_modules/zod/v4/locales/id.cjs +133 -0
  536. package/node_modules/zod/v4/locales/id.d.cts +5 -0
  537. package/node_modules/zod/v4/locales/id.d.ts +4 -0
  538. package/node_modules/zod/v4/locales/id.js +106 -0
  539. package/node_modules/zod/v4/locales/index.cjs +104 -0
  540. package/node_modules/zod/v4/locales/index.d.cts +49 -0
  541. package/node_modules/zod/v4/locales/index.d.ts +49 -0
  542. package/node_modules/zod/v4/locales/index.js +49 -0
  543. package/node_modules/zod/v4/locales/is.cjs +136 -0
  544. package/node_modules/zod/v4/locales/is.d.cts +5 -0
  545. package/node_modules/zod/v4/locales/is.d.ts +4 -0
  546. package/node_modules/zod/v4/locales/is.js +109 -0
  547. package/node_modules/zod/v4/locales/it.cjs +135 -0
  548. package/node_modules/zod/v4/locales/it.d.cts +5 -0
  549. package/node_modules/zod/v4/locales/it.d.ts +4 -0
  550. package/node_modules/zod/v4/locales/it.js +108 -0
  551. package/node_modules/zod/v4/locales/ja.cjs +134 -0
  552. package/node_modules/zod/v4/locales/ja.d.cts +5 -0
  553. package/node_modules/zod/v4/locales/ja.d.ts +4 -0
  554. package/node_modules/zod/v4/locales/ja.js +107 -0
  555. package/node_modules/zod/v4/locales/ka.cjs +139 -0
  556. package/node_modules/zod/v4/locales/ka.d.cts +5 -0
  557. package/node_modules/zod/v4/locales/ka.d.ts +4 -0
  558. package/node_modules/zod/v4/locales/ka.js +112 -0
  559. package/node_modules/zod/v4/locales/kh.cjs +12 -0
  560. package/node_modules/zod/v4/locales/kh.d.cts +5 -0
  561. package/node_modules/zod/v4/locales/kh.d.ts +5 -0
  562. package/node_modules/zod/v4/locales/kh.js +5 -0
  563. package/node_modules/zod/v4/locales/km.cjs +137 -0
  564. package/node_modules/zod/v4/locales/km.d.cts +5 -0
  565. package/node_modules/zod/v4/locales/km.d.ts +4 -0
  566. package/node_modules/zod/v4/locales/km.js +110 -0
  567. package/node_modules/zod/v4/locales/ko.cjs +138 -0
  568. package/node_modules/zod/v4/locales/ko.d.cts +5 -0
  569. package/node_modules/zod/v4/locales/ko.d.ts +4 -0
  570. package/node_modules/zod/v4/locales/ko.js +111 -0
  571. package/node_modules/zod/v4/locales/lt.cjs +230 -0
  572. package/node_modules/zod/v4/locales/lt.d.cts +5 -0
  573. package/node_modules/zod/v4/locales/lt.d.ts +4 -0
  574. package/node_modules/zod/v4/locales/lt.js +203 -0
  575. package/node_modules/zod/v4/locales/mk.cjs +136 -0
  576. package/node_modules/zod/v4/locales/mk.d.cts +5 -0
  577. package/node_modules/zod/v4/locales/mk.d.ts +4 -0
  578. package/node_modules/zod/v4/locales/mk.js +109 -0
  579. package/node_modules/zod/v4/locales/ms.cjs +134 -0
  580. package/node_modules/zod/v4/locales/ms.d.cts +5 -0
  581. package/node_modules/zod/v4/locales/ms.d.ts +4 -0
  582. package/node_modules/zod/v4/locales/ms.js +107 -0
  583. package/node_modules/zod/v4/locales/nl.cjs +137 -0
  584. package/node_modules/zod/v4/locales/nl.d.cts +5 -0
  585. package/node_modules/zod/v4/locales/nl.d.ts +4 -0
  586. package/node_modules/zod/v4/locales/nl.js +110 -0
  587. package/node_modules/zod/v4/locales/no.cjs +135 -0
  588. package/node_modules/zod/v4/locales/no.d.cts +5 -0
  589. package/node_modules/zod/v4/locales/no.d.ts +4 -0
  590. package/node_modules/zod/v4/locales/no.js +108 -0
  591. package/node_modules/zod/v4/locales/ota.cjs +136 -0
  592. package/node_modules/zod/v4/locales/ota.d.cts +5 -0
  593. package/node_modules/zod/v4/locales/ota.d.ts +4 -0
  594. package/node_modules/zod/v4/locales/ota.js +109 -0
  595. package/node_modules/zod/v4/locales/package.json +6 -0
  596. package/node_modules/zod/v4/locales/pl.cjs +136 -0
  597. package/node_modules/zod/v4/locales/pl.d.cts +5 -0
  598. package/node_modules/zod/v4/locales/pl.d.ts +4 -0
  599. package/node_modules/zod/v4/locales/pl.js +109 -0
  600. package/node_modules/zod/v4/locales/ps.cjs +141 -0
  601. package/node_modules/zod/v4/locales/ps.d.cts +5 -0
  602. package/node_modules/zod/v4/locales/ps.d.ts +4 -0
  603. package/node_modules/zod/v4/locales/ps.js +114 -0
  604. package/node_modules/zod/v4/locales/pt.cjs +135 -0
  605. package/node_modules/zod/v4/locales/pt.d.cts +5 -0
  606. package/node_modules/zod/v4/locales/pt.d.ts +4 -0
  607. package/node_modules/zod/v4/locales/pt.js +108 -0
  608. package/node_modules/zod/v4/locales/ru.cjs +183 -0
  609. package/node_modules/zod/v4/locales/ru.d.cts +5 -0
  610. package/node_modules/zod/v4/locales/ru.d.ts +4 -0
  611. package/node_modules/zod/v4/locales/ru.js +156 -0
  612. package/node_modules/zod/v4/locales/sl.cjs +136 -0
  613. package/node_modules/zod/v4/locales/sl.d.cts +5 -0
  614. package/node_modules/zod/v4/locales/sl.d.ts +4 -0
  615. package/node_modules/zod/v4/locales/sl.js +109 -0
  616. package/node_modules/zod/v4/locales/sv.cjs +137 -0
  617. package/node_modules/zod/v4/locales/sv.d.cts +5 -0
  618. package/node_modules/zod/v4/locales/sv.d.ts +4 -0
  619. package/node_modules/zod/v4/locales/sv.js +110 -0
  620. package/node_modules/zod/v4/locales/ta.cjs +137 -0
  621. package/node_modules/zod/v4/locales/ta.d.cts +5 -0
  622. package/node_modules/zod/v4/locales/ta.d.ts +4 -0
  623. package/node_modules/zod/v4/locales/ta.js +110 -0
  624. package/node_modules/zod/v4/locales/th.cjs +137 -0
  625. package/node_modules/zod/v4/locales/th.d.cts +5 -0
  626. package/node_modules/zod/v4/locales/th.d.ts +4 -0
  627. package/node_modules/zod/v4/locales/th.js +110 -0
  628. package/node_modules/zod/v4/locales/tr.cjs +132 -0
  629. package/node_modules/zod/v4/locales/tr.d.cts +5 -0
  630. package/node_modules/zod/v4/locales/tr.d.ts +4 -0
  631. package/node_modules/zod/v4/locales/tr.js +105 -0
  632. package/node_modules/zod/v4/locales/ua.cjs +12 -0
  633. package/node_modules/zod/v4/locales/ua.d.cts +5 -0
  634. package/node_modules/zod/v4/locales/ua.d.ts +5 -0
  635. package/node_modules/zod/v4/locales/ua.js +5 -0
  636. package/node_modules/zod/v4/locales/uk.cjs +135 -0
  637. package/node_modules/zod/v4/locales/uk.d.cts +5 -0
  638. package/node_modules/zod/v4/locales/uk.d.ts +4 -0
  639. package/node_modules/zod/v4/locales/uk.js +108 -0
  640. package/node_modules/zod/v4/locales/ur.cjs +137 -0
  641. package/node_modules/zod/v4/locales/ur.d.cts +5 -0
  642. package/node_modules/zod/v4/locales/ur.d.ts +4 -0
  643. package/node_modules/zod/v4/locales/ur.js +110 -0
  644. package/node_modules/zod/v4/locales/uz.cjs +136 -0
  645. package/node_modules/zod/v4/locales/uz.d.cts +5 -0
  646. package/node_modules/zod/v4/locales/uz.d.ts +4 -0
  647. package/node_modules/zod/v4/locales/uz.js +109 -0
  648. package/node_modules/zod/v4/locales/vi.cjs +135 -0
  649. package/node_modules/zod/v4/locales/vi.d.cts +5 -0
  650. package/node_modules/zod/v4/locales/vi.d.ts +4 -0
  651. package/node_modules/zod/v4/locales/vi.js +108 -0
  652. package/node_modules/zod/v4/locales/yo.cjs +134 -0
  653. package/node_modules/zod/v4/locales/yo.d.cts +5 -0
  654. package/node_modules/zod/v4/locales/yo.d.ts +4 -0
  655. package/node_modules/zod/v4/locales/yo.js +107 -0
  656. package/node_modules/zod/v4/locales/zh-CN.cjs +136 -0
  657. package/node_modules/zod/v4/locales/zh-CN.d.cts +5 -0
  658. package/node_modules/zod/v4/locales/zh-CN.d.ts +4 -0
  659. package/node_modules/zod/v4/locales/zh-CN.js +109 -0
  660. package/node_modules/zod/v4/locales/zh-TW.cjs +134 -0
  661. package/node_modules/zod/v4/locales/zh-TW.d.cts +5 -0
  662. package/node_modules/zod/v4/locales/zh-TW.d.ts +4 -0
  663. package/node_modules/zod/v4/locales/zh-TW.js +107 -0
  664. package/node_modules/zod/v4/mini/checks.cjs +34 -0
  665. package/node_modules/zod/v4/mini/checks.d.cts +1 -0
  666. package/node_modules/zod/v4/mini/checks.d.ts +1 -0
  667. package/node_modules/zod/v4/mini/checks.js +1 -0
  668. package/node_modules/zod/v4/mini/coerce.cjs +52 -0
  669. package/node_modules/zod/v4/mini/coerce.d.cts +7 -0
  670. package/node_modules/zod/v4/mini/coerce.d.ts +7 -0
  671. package/node_modules/zod/v4/mini/coerce.js +22 -0
  672. package/node_modules/zod/v4/mini/external.cjs +63 -0
  673. package/node_modules/zod/v4/mini/external.d.cts +12 -0
  674. package/node_modules/zod/v4/mini/external.d.ts +12 -0
  675. package/node_modules/zod/v4/mini/external.js +14 -0
  676. package/node_modules/zod/v4/mini/index.cjs +32 -0
  677. package/node_modules/zod/v4/mini/index.d.cts +3 -0
  678. package/node_modules/zod/v4/mini/index.d.ts +3 -0
  679. package/node_modules/zod/v4/mini/index.js +3 -0
  680. package/node_modules/zod/v4/mini/iso.cjs +64 -0
  681. package/node_modules/zod/v4/mini/iso.d.cts +22 -0
  682. package/node_modules/zod/v4/mini/iso.d.ts +22 -0
  683. package/node_modules/zod/v4/mini/iso.js +34 -0
  684. package/node_modules/zod/v4/mini/package.json +6 -0
  685. package/node_modules/zod/v4/mini/parse.cjs +16 -0
  686. package/node_modules/zod/v4/mini/parse.d.cts +1 -0
  687. package/node_modules/zod/v4/mini/parse.d.ts +1 -0
  688. package/node_modules/zod/v4/mini/parse.js +1 -0
  689. package/node_modules/zod/v4/mini/schemas.cjs +1046 -0
  690. package/node_modules/zod/v4/mini/schemas.d.cts +427 -0
  691. package/node_modules/zod/v4/mini/schemas.d.ts +427 -0
  692. package/node_modules/zod/v4/mini/schemas.js +925 -0
  693. package/node_modules/zod/v4/package.json +6 -0
  694. package/node_modules/zod/v4-mini/index.cjs +32 -0
  695. package/node_modules/zod/v4-mini/index.d.cts +3 -0
  696. package/node_modules/zod/v4-mini/index.d.ts +3 -0
  697. package/node_modules/zod/v4-mini/index.js +3 -0
  698. package/node_modules/zod/v4-mini/package.json +6 -0
  699. package/package.json +11 -10
  700. package/chat/charts/chart/chart.component.d.ts +0 -13
  701. package/chat/chat-message/chat-message.component.d.ts +0 -75
  702. package/chat/chat-settings-v3/chat-settings-v3.component.d.ts +0 -48
  703. package/chat/chat.component.d.ts +0 -387
  704. package/chat/chat.service.d.ts +0 -370
  705. package/chat/custom-elements/components/code-block.component.d.ts +0 -11
  706. package/chat/custom-elements/components/document-reference.component.d.ts +0 -13
  707. package/chat/custom-elements/components/image-reference.component.d.ts +0 -14
  708. package/chat/custom-elements/components/page-reference.component.d.ts +0 -14
  709. package/chat/custom-elements/components/table-tools.component.d.ts +0 -11
  710. package/chat/custom-elements/custom-elements.config.d.ts +0 -2
  711. package/chat/custom-elements/custom-elements.service.d.ts +0 -14
  712. package/chat/debug-message/debug-message-details/debug-message-details.component.d.ts +0 -18
  713. package/chat/debug-message/debug-message.component.d.ts +0 -14
  714. package/chat/debug-message/debug-message.service.d.ts +0 -15
  715. package/chat/dialogs/delete-saved-chat.component.d.ts +0 -22
  716. package/chat/dialogs/rename-saved-chat.component.d.ts +0 -21
  717. package/chat/dialogs/updates.component.d.ts +0 -15
  718. package/chat/documents-upload/document-list/document-list.component.d.ts +0 -64
  719. package/chat/documents-upload/document-overview/document-overview.component.d.ts +0 -17
  720. package/chat/documents-upload/document-upload/document-upload.component.d.ts +0 -91
  721. package/chat/documents-upload/documents-upload.model.d.ts +0 -66
  722. package/chat/documents-upload/documents-upload.service.d.ts +0 -161
  723. package/chat/fetch-patcher/app-injector.d.ts +0 -9
  724. package/chat/fetch-patcher/fetch-patcher.d.ts +0 -31
  725. package/chat/fetch-patcher/global-error-handler.service.d.ts +0 -36
  726. package/chat/fetch-patcher/handle-unauthorized-logic.d.ts +0 -13
  727. package/chat/format-icon/format-icon.component.d.ts +0 -10
  728. package/chat/format-icon/icons.d.ts +0 -5
  729. package/chat/initials-avatar/initials-avatar.component.d.ts +0 -35
  730. package/chat/instance-manager.service.d.ts +0 -28
  731. package/chat/markdown-it/markdown-it.config.d.ts +0 -4
  732. package/chat/markdown-it/plugins/code-block.plugin.d.ts +0 -2
  733. package/chat/markdown-it/plugins/document-reference.plugin.d.ts +0 -8
  734. package/chat/markdown-it/plugins/image-reference.plugin.d.ts +0 -9
  735. package/chat/markdown-it/plugins/link.plugin.d.ts +0 -5
  736. package/chat/markdown-it/plugins/page-reference.plugin.d.ts +0 -9
  737. package/chat/markdown-it/plugins/table-tools.plugin.d.ts +0 -2
  738. package/chat/pipes/message-content.pipe.d.ts +0 -16
  739. package/chat/public-api.d.ts +0 -35
  740. package/chat/references/chat-reference/chat-reference.component.d.ts +0 -24
  741. package/chat/references/chat-reference-image/chat-reference-image.component.d.ts +0 -20
  742. package/chat/references/chat-reference-page/chat-reference-page.component.d.ts +0 -20
  743. package/chat/saved-chats/saved-chats.component.d.ts +0 -37
  744. package/chat/saved-chats/saved-chats.service.d.ts +0 -29
  745. package/chat/services/app.service.d.ts +0 -9
  746. package/chat/services/assistant-configuration.service.d.ts +0 -34
  747. package/chat/services/assistant-metadata.service.d.ts +0 -20
  748. package/chat/services/assistant-tokens-tracking.service.d.ts +0 -23
  749. package/chat/services/assistant-ws-frames.service.d.ts +0 -50
  750. package/chat/services/dialog.service.d.ts +0 -12
  751. package/chat/services/notification.service.d.ts +0 -10
  752. package/chat/services/principal.service.d.ts +0 -7
  753. package/chat/services/search.service.d.ts +0 -7
  754. package/chat/services/signalR-connection.service.d.ts +0 -25
  755. package/chat/services/signalR.web.service.d.ts +0 -35
  756. package/chat/services/ui.service.d.ts +0 -13
  757. package/chat/services/user-settings.service.d.ts +0 -7
  758. package/chat/smart-renderer/smart-renderer.d.ts +0 -25
  759. package/chat/token-progress-bar/token-progress-bar.component.d.ts +0 -24
  760. package/chat/tooltip/tooltip.component.d.ts +0 -12
  761. package/chat/tooltip/tooltip.directive.d.ts +0 -81
  762. package/chat/types/message-content.types.d.ts +0 -54
  763. package/chat/types/message-reference.types.d.ts +0 -14
  764. package/chat/types.d.ts +0 -920
  765. package/chat/utils/assistant-json.d.ts +0 -2
  766. package/chat/utils/utils.service.d.ts +0 -67
  767. package/chat/version.d.ts +0 -1
  768. package/esm2022/chat/charts/chart/chart.component.mjs +0 -40
  769. package/esm2022/chat/chat-message/chat-message.component.mjs +0 -252
  770. package/esm2022/chat/chat-settings-v3/chat-settings-v3.component.mjs +0 -121
  771. package/esm2022/chat/chat.component.mjs +0 -1115
  772. package/esm2022/chat/chat.service.mjs +0 -636
  773. package/esm2022/chat/custom-elements/components/code-block.component.mjs +0 -97
  774. package/esm2022/chat/custom-elements/components/document-reference.component.mjs +0 -85
  775. package/esm2022/chat/custom-elements/components/image-reference.component.mjs +0 -79
  776. package/esm2022/chat/custom-elements/components/page-reference.component.mjs +0 -79
  777. package/esm2022/chat/custom-elements/components/table-tools.component.mjs +0 -111
  778. package/esm2022/chat/custom-elements/custom-elements.config.mjs +0 -6
  779. package/esm2022/chat/custom-elements/custom-elements.service.mjs +0 -35
  780. package/esm2022/chat/debug-message/debug-message-details/debug-message-details.component.mjs +0 -43
  781. package/esm2022/chat/debug-message/debug-message.component.mjs +0 -40
  782. package/esm2022/chat/debug-message/debug-message.service.mjs +0 -49
  783. package/esm2022/chat/dialogs/delete-saved-chat.component.mjs +0 -81
  784. package/esm2022/chat/dialogs/rename-saved-chat.component.mjs +0 -85
  785. package/esm2022/chat/dialogs/updates.component.mjs +0 -61
  786. package/esm2022/chat/documents-upload/document-list/document-list.component.mjs +0 -141
  787. package/esm2022/chat/documents-upload/document-overview/document-overview.component.mjs +0 -42
  788. package/esm2022/chat/documents-upload/document-upload/document-upload.component.mjs +0 -254
  789. package/esm2022/chat/documents-upload/documents-upload.model.mjs +0 -2
  790. package/esm2022/chat/documents-upload/documents-upload.service.mjs +0 -274
  791. package/esm2022/chat/fetch-patcher/app-injector.mjs +0 -19
  792. package/esm2022/chat/fetch-patcher/fetch-patcher.mjs +0 -62
  793. package/esm2022/chat/fetch-patcher/global-error-handler.service.mjs +0 -92
  794. package/esm2022/chat/fetch-patcher/handle-unauthorized-logic.mjs +0 -19
  795. package/esm2022/chat/format-icon/format-icon.component.mjs +0 -23
  796. package/esm2022/chat/format-icon/icons.mjs +0 -138
  797. package/esm2022/chat/initials-avatar/initials-avatar.component.mjs +0 -60
  798. package/esm2022/chat/instance-manager.service.mjs +0 -46
  799. package/esm2022/chat/markdown-it/markdown-it.config.mjs +0 -6
  800. package/esm2022/chat/markdown-it/plugins/code-block.plugin.mjs +0 -14
  801. package/esm2022/chat/markdown-it/plugins/document-reference.plugin.mjs +0 -66
  802. package/esm2022/chat/markdown-it/plugins/image-reference.plugin.mjs +0 -67
  803. package/esm2022/chat/markdown-it/plugins/link.plugin.mjs +0 -15
  804. package/esm2022/chat/markdown-it/plugins/page-reference.plugin.mjs +0 -67
  805. package/esm2022/chat/markdown-it/plugins/table-tools.plugin.mjs +0 -12
  806. package/esm2022/chat/pipes/message-content.pipe.mjs +0 -37
  807. package/esm2022/chat/public-api.mjs +0 -37
  808. package/esm2022/chat/references/chat-reference/chat-reference.component.mjs +0 -72
  809. package/esm2022/chat/references/chat-reference-image/chat-reference-image.component.mjs +0 -42
  810. package/esm2022/chat/references/chat-reference-page/chat-reference-page.component.mjs +0 -42
  811. package/esm2022/chat/saved-chats/saved-chats.component.mjs +0 -115
  812. package/esm2022/chat/saved-chats/saved-chats.service.mjs +0 -170
  813. package/esm2022/chat/services/app.service.mjs +0 -30
  814. package/esm2022/chat/services/assistant-configuration.service.mjs +0 -158
  815. package/esm2022/chat/services/assistant-metadata.service.mjs +0 -85
  816. package/esm2022/chat/services/assistant-tokens-tracking.service.mjs +0 -50
  817. package/esm2022/chat/services/assistant-ws-frames.service.mjs +0 -391
  818. package/esm2022/chat/services/dialog.service.mjs +0 -40
  819. package/esm2022/chat/services/notification.service.mjs +0 -25
  820. package/esm2022/chat/services/principal.service.mjs +0 -16
  821. package/esm2022/chat/services/search.service.mjs +0 -13
  822. package/esm2022/chat/services/signalR-connection.service.mjs +0 -102
  823. package/esm2022/chat/services/signalR.web.service.mjs +0 -69
  824. package/esm2022/chat/services/ui.service.mjs +0 -61
  825. package/esm2022/chat/services/user-settings.service.mjs +0 -25
  826. package/esm2022/chat/sinequa-assistant-chat.mjs +0 -5
  827. package/esm2022/chat/smart-renderer/smart-renderer.mjs +0 -104
  828. package/esm2022/chat/token-progress-bar/token-progress-bar.component.mjs +0 -52
  829. package/esm2022/chat/tooltip/tooltip.component.mjs +0 -44
  830. package/esm2022/chat/tooltip/tooltip.directive.mjs +0 -203
  831. package/esm2022/chat/types/message-content.types.mjs +0 -2
  832. package/esm2022/chat/types/message-reference.types.mjs +0 -2
  833. package/esm2022/chat/types.mjs +0 -130
  834. package/esm2022/chat/utils/assistant-json.mjs +0 -12
  835. package/esm2022/chat/utils/utils.service.mjs +0 -170
  836. package/esm2022/chat/version.mjs +0 -3
  837. package/esm2022/public-api.mjs +0 -3
  838. package/esm2022/sinequa-assistant.mjs +0 -5
  839. package/public-api.d.ts +0 -1
@@ -1,1115 +0,0 @@
1
- import { CommonModule } from "@angular/common";
2
- import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, DestroyRef, EventEmitter, Input, Output, ViewChild, inject } from "@angular/core";
3
- import { FormsModule } from "@angular/forms";
4
- import { TranslocoPipe, TranslocoService, provideTranslocoScope } from '@jsverse/transloco';
5
- import { HubConnectionState } from "@microsoft/signalr";
6
- import { BehaviorSubject, combineLatest, filter, fromEvent, merge, of, switchMap, take, tap } from "rxjs";
7
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
8
- import { guid, isAuthenticated, setGlobalConfig } from "@sinequa/atomic";
9
- import { ChatMessageComponent } from "./chat-message/chat-message.component";
10
- import { ChatService } from "./chat.service";
11
- import { DebugMessageComponent } from "./debug-message/debug-message.component";
12
- import { InstanceManagerService } from "./instance-manager.service";
13
- import { NotificationsService } from "./services/notification.service";
14
- import { PrincipalService } from "./services/principal.service";
15
- import { SearchService } from "./services/search.service";
16
- import { TokenProgressBarComponent } from "./token-progress-bar/token-progress-bar.component";
17
- import { TooltipDirective } from "./tooltip/tooltip.directive";
18
- import { AssistantUtils } from "./utils/utils.service";
19
- import { AssistantConfigurationService } from "./services/assistant-configuration.service";
20
- import { AssistantTokensTrackingService } from "./services/assistant-tokens-tracking.service";
21
- import { SavedChatsService } from "./saved-chats/saved-chats.service";
22
- import { DebugMessageService } from "./debug-message/debug-message.service";
23
- import * as i0 from "@angular/core";
24
- import * as i1 from "@angular/common";
25
- import * as i2 from "@angular/forms";
26
- export class ChatComponent {
27
- constructor() {
28
- this.chatService = inject(ChatService);
29
- this.instanceManagerService = inject(InstanceManagerService);
30
- this.searchService = inject(SearchService);
31
- this.principalService = inject(PrincipalService);
32
- this.cdr = inject(ChangeDetectorRef);
33
- this.notificationsService = inject(NotificationsService);
34
- this.transloco = inject(TranslocoService);
35
- this.assistantUtils = inject(AssistantUtils);
36
- this.destroyRef = inject(DestroyRef);
37
- /** Define the query to use to fetch answers */
38
- this.query = this.searchService.query;
39
- /** Map of listeners overriding default registered ones*/
40
- this.messageHandlers = new Map();
41
- /** When the assistant answer a user question, automatically scroll down to the bottom of the discussion */
42
- this.automaticScrollToLastResponse = false;
43
- /** When the assistant answer a user question, automatically focus to the chat input */
44
- this.focusAfterResponse = false;
45
- /** Icon to use for the assistant messages */
46
- this.assistantMessageIcon = 'sq-sinequa';
47
- // Add custom additionalWorkflowProperties to the user query message
48
- this.additionalWorkflowProperties = {};
49
- /** Event emitter triggered once the signalR connection is established */
50
- this.connection = new EventEmitter();
51
- /** Event emitter triggered each time the assistant updates the current chat */
52
- /** Event emitter triggered when the chat is loading new content */
53
- this.loading$ = new EventEmitter(false);
54
- /** Emits the assistant configuration used when instantiating the component */
55
- this._config = new EventEmitter();
56
- this.data = new EventEmitter();
57
- /** Event emitter triggered when the user clicks to open the original document representing the context attachment*/
58
- this.openDocument = new EventEmitter();
59
- /** Event emitter triggered when the user clicks to open the preview of a document representing the context attachment */
60
- this.openPreview = new EventEmitter();
61
- /** Event emitter triggered when the user clicks on a suggested action */
62
- this.suggestAction = new EventEmitter();
63
- this.messages$ = new BehaviorSubject(undefined);
64
- this.isAdminOrDeletedAdmin = false;
65
- this.question = '';
66
- this.changes$ = new BehaviorSubject(undefined);
67
- this.firstChangesHandled = false;
68
- this.isAtBottom = true;
69
- this.initializationError = false;
70
- this.enabledUserInput = false;
71
- this.isConnected = true; // By default, the chat is considered connected
72
- // Flag to track whether the 'reconnected' listener is already registered
73
- this._isReconnectedListenerRegistered = false;
74
- this.defaultIssueTypes = [
75
- 'chat.userInterfaceBug',
76
- 'chat.incorrectResponse',
77
- 'chat.incompleteResponse',
78
- 'chat.technicalIssue',
79
- 'chat.privacyDataSecurityIssue',
80
- 'chat.otherIssue'
81
- ];
82
- this.issueType = '';
83
- this.reportType = 'dislike';
84
- this.showReport = false;
85
- this.showDebugMessages = false;
86
- this._reloadSubscription = undefined;
87
- this.destroyRef.onDestroy(async () => {
88
- console.log(`Destroying ChatComponent: ${this.instanceId} \n along with ChatService: ${this.chatService.chatInstanceId} \n and stopping connection: ${this.chatService.connection?.connectionId}`);
89
- if (this.chatService.connection && this.chatService.connection.state !== HubConnectionState.Disconnected && this.chatService.connection.state !== HubConnectionState.Disconnecting) {
90
- try {
91
- await this.chatService.stopConnection();
92
- }
93
- catch (error) {
94
- console.error(`Error during the destruction of ChatComponent: ${this.instanceId}`, error);
95
- }
96
- }
97
- });
98
- }
99
- ngOnInit() {
100
- if (this.appConfig) {
101
- setGlobalConfig(this.appConfig);
102
- }
103
- of(isAuthenticated()).pipe(takeUntilDestroyed(this.destroyRef), tap(_ => this.instantiateChatService()), switchMap(_ => this.chatService.init()), switchMap(_ => this.chatService.initProcess$.pipe(filter(Boolean))), tap(_ => {
104
- this.connection.emit(this.chatService.connection);
105
- this.onLoadChat();
106
- }), tap(_ => this.chatService.overrideUser()), switchMap(_ => this.chatService.userOverride$), switchMap(_ => this.chatService.assistantConfig$), tap(config => {
107
- this.isAdminOrDeletedAdmin = this.principalService.principal.isAdministrator || this.principalService.principal.isDelegatedAdmin || false;
108
- this.config = config;
109
- this.enabledUserInput = this.config.modeSettings.enabledUserInput;
110
- this.issueTypes = this.config.auditSettings?.issueTypes?.length ? this.config.auditSettings.issueTypes : undefined;
111
- this._config.emit(config);
112
- try {
113
- this.updateModelDescription();
114
- if (!this.firstChangesHandled) {
115
- this._previousQuery = JSON.parse(JSON.stringify(this.query)); // Initialize the previous query
116
- this._handleChanges();
117
- this._addScrollListener();
118
- this.firstChangesHandled = true;
119
- }
120
- }
121
- catch (error) {
122
- this.initializationError = true;
123
- throw error;
124
- }
125
- })).subscribe();
126
- // Example of listening to custom events from the web element and handling them in the Angular component
127
- addEventListener('onOpenPreview', (event) => {
128
- this.openPreview.emit(event.detail.reference);
129
- });
130
- addEventListener('onOpenDocument', (event) => {
131
- this.openDocument.emit(event.detail.reference.record);
132
- });
133
- }
134
- ngOnChanges(changes) {
135
- this.changes$.next(changes);
136
- if (this.config) {
137
- this._handleChanges();
138
- }
139
- }
140
- ngOnDestroy() {
141
- this._dataSubscription?.unsubscribe();
142
- this._reloadSubscription?.unsubscribe();
143
- }
144
- get isAdmin() {
145
- return this.principalService.principal?.isAdministrator || false;
146
- }
147
- /**
148
- * This chat service instance is stored in the instanceManagerService with provided @input instanceId as a key
149
- */
150
- instantiateChatService() {
151
- this.chatService.setChatInstanceId(this.instanceId);
152
- this.instanceManagerService.storeInstance(this.instanceId, this.chatService);
153
- }
154
- /**
155
- * Handles the changes in the chat component.
156
- * If the chat service is a WebSocketChatService, it handles the override of the message handlers if they exist.
157
- * Initializes the chat with the provided chat messages if they exist, otherwise loads the default chat.
158
- * If the chat is initialized, the initialization event is "Query", the query changes, and the queryChangeShouldTriggerReload function is provided,
159
- * then the chat should be reloaded if the function returns true. Otherwise, the chat should be reloaded by default.
160
- * It takes into account the ongoing streaming process and the ongoing stopping process to trigger that conditionally define the logic
161
- * of the reload :
162
- * - If the chat is streaming, then stop the generation and wait for the fetch to complete before reloading the chat.
163
- * - If the chat is stopping the generation, then wait for the fetch to complete before reloading the chat.
164
- */
165
- _handleChanges() {
166
- const changes = this.changes$.value;
167
- // If the chat service is a WebSocketChatService, handle the override of the message handlers if exists
168
- if (changes?.messageHandlers && this.messageHandlers) {
169
- this.chatService.overrideMessageHandlers(this.messageHandlers);
170
- }
171
- /**
172
- * Initialize the chat with the provided chat messages if exists, otherwise load the default chat
173
- * Once the chat is initialized (firstChangesHandled is true), allow opening the chat with the new provided messages (if exists)
174
- */
175
- if (!this.firstChangesHandled || changes?.chat) {
176
- const openChat = () => {
177
- if (this.messages$.value && this.config.savedChatSettings?.enabled) {
178
- this.chatService.listSavedChat(); // Refresh the list of saved chats
179
- }
180
- this.openChat(this.chat.messages);
181
- };
182
- this.chatService.generateChatId();
183
- if (this.chat) {
184
- this.chatService.generateAuditEvent('ast-chat.new', { 'configuration': JSON.stringify(this.chatService.assistantConfig$.value), 'chat-init': JSON.stringify(this.chat) });
185
- openChat();
186
- }
187
- else {
188
- this.chatService.generateAuditEvent('ast-chat.new', { 'configuration': JSON.stringify(this.chatService.assistantConfig$.value) });
189
- this.loadDefaultChat();
190
- }
191
- }
192
- /**
193
- * If the chat is initialized, the initialization event is "Query", the query changes and the queryChangeShouldTriggerReload function is provided,
194
- * then the chat should be reloaded if the function returns true
195
- * Otherwise, the chat should be reloaded by default
196
- */
197
- if (this.firstChangesHandled && changes?.query && this.config.modeSettings.initialization.event === 'Query') {
198
- if (this.queryChangeShouldTriggerReload ? this.queryChangeShouldTriggerReload(this._previousQuery, this.query) : true) {
199
- if (!!this.chatService.stoppingGeneration$.value) {
200
- if (!this._reloadSubscription) {
201
- // Create a subscription to wait for both streaming$ and stoppingGeneration$ to be false
202
- this._reloadSubscription = combineLatest([
203
- this.chatService.streaming$,
204
- this.chatService.stoppingGeneration$
205
- ])
206
- .pipe(filter(([streaming, stopping]) => !streaming && !stopping), // Wait until both are false
207
- take(1) // Complete after the first match
208
- ).subscribe(() => {
209
- // Execute the reload after the query change
210
- this._triggerReloadAfterQueryChange();
211
- // Update _previousQuery with the current query
212
- this._previousQuery = JSON.parse(JSON.stringify(this.query));
213
- // Clean up subscription and reset its value
214
- this._reloadSubscription.unsubscribe();
215
- this._reloadSubscription = undefined;
216
- });
217
- }
218
- }
219
- else if (!!this.chatService.streaming$.value) {
220
- if (!this._reloadSubscription) {
221
- this._reloadSubscription = this.chatService.stopGeneration()
222
- .subscribe({
223
- next: () => { },
224
- error: () => {
225
- // Clean up subscription and reset its value
226
- this._reloadSubscription?.unsubscribe();
227
- this._reloadSubscription = undefined;
228
- },
229
- complete: () => {
230
- // Wait for the ongoing fetch to complete, then trigger the reload
231
- this.chatService.streaming$.pipe(filter((streaming) => !streaming), take(1)).subscribe(() => {
232
- // Execute the reload after the query change
233
- this._triggerReloadAfterQueryChange();
234
- // Update _previousQuery with the current query
235
- this._previousQuery = JSON.parse(JSON.stringify(this.query));
236
- // Clean up subscription and reset its value
237
- this._reloadSubscription.unsubscribe();
238
- this._reloadSubscription = undefined;
239
- });
240
- }
241
- });
242
- }
243
- }
244
- else {
245
- // Execute the reload after the query change
246
- this._triggerReloadAfterQueryChange();
247
- // Update _previousQuery with the current query
248
- this._previousQuery = JSON.parse(JSON.stringify(this.query));
249
- }
250
- }
251
- else {
252
- // Update _previousQuery with the current query
253
- this._previousQuery = JSON.parse(JSON.stringify(this.query));
254
- }
255
- }
256
- }
257
- /**
258
- * Triggers a reload after the query change.
259
- * This method performs the necessary operations to reload the chat after a query change.
260
- * It sets the system and user messages, resets the savedChatId, generates a new chatId,
261
- * generates a new chat audit event, and handles the query mode.
262
- */
263
- _triggerReloadAfterQueryChange() {
264
- const systemMsg = { role: 'system', content: this.config.defaultValues.systemPrompt, additionalProperties: { display: false, messageId: guid() } };
265
- // backward compatibility with old configuration files
266
- const userPrompt = this.config.defaultValues.userPrompt.replace(/\{\{(.*?)\}\}/g, '[[$1]]');
267
- const userMsg = { role: 'user', content: AssistantUtils.formatPrompt(this.transloco.translate(userPrompt), { principal: this.principalService.principal }), additionalProperties: { display: this.config.modeSettings.displayUserPrompt, messageId: guid() } };
268
- this.chatService.generateChatId(); // Generate a new chatId
269
- this.chatService.generateAuditEvent('ast-chat.new', { 'configuration': JSON.stringify(this.chatService.assistantConfig$.value) }); // Generate a new chat audit event
270
- this._handleQueryMode(systemMsg, userMsg);
271
- }
272
- /**
273
- * Adds a scroll listener to the message list element.
274
- * The listener is triggered when any of the following events occur:
275
- * - Loading state changes
276
- * - Messages change
277
- * - Streaming state changes
278
- * - Scroll event occurs on the message list element
279
- *
280
- * When the listener is triggered, it updates the `isAtBottom` property.
281
- */
282
- _addScrollListener() {
283
- const messageList = document.getElementById(`messageList-${this.instanceId}`);
284
- merge(this.loading$, this.messages$, this.chatService.streaming$, fromEvent(messageList, 'scroll'))
285
- .pipe(takeUntilDestroyed(this.destroyRef))
286
- .subscribe(() => {
287
- setTimeout(() => {
288
- this.isAtBottom = this._toggleScrollButtonVisibility();
289
- this.cdr.detectChanges();
290
- });
291
- });
292
- }
293
- /**
294
- * Get the model description based on the defaultValues service_id and model_id
295
- */
296
- updateModelDescription() {
297
- this.modelDescription = this.chatService.getModel(this.config.defaultValues.service_id, this.config.defaultValues.model_id);
298
- this.cdr.detectChanges();
299
- }
300
- /**
301
- * Submits a question from the user.
302
- * If the user is editing a previous message, removes all subsequent messages from the chat history.
303
- * Triggers the fetch of the answer for the submitted question by calling _fetchAnswer().
304
- * Clears the input value in the UI.
305
- * ⚠️ If the chat is streaming or stopping the generation, the operation is not allowed.
306
- */
307
- submitQuestion() {
308
- if (!!this.chatService.streaming$.value || !!this.chatService.stoppingGeneration$.value) {
309
- return;
310
- }
311
- if (this.question.trim() && this.messages$.value && this.chatService.chatHistory) {
312
- // When the user submits a question, if the user is editing a previous message, remove all subsequent messages from the chat history
313
- if (this.indexMessageToEdit !== undefined && this.rankMessageToEdit !== undefined) {
314
- // Update the messages in the UI
315
- this.messages$.next(this.messages$.value.slice(0, this.indexMessageToEdit));
316
- // Update the raw messages in the chat history which is the clean version used to make the next request
317
- this.chatService.chatHistory = this.chatService.chatHistory.slice(0, this.rankMessageToEdit - 1);
318
- this.indexMessageToEdit = undefined;
319
- this.rankMessageToEdit = undefined;
320
- }
321
- // Remove the search warning message if exists
322
- if (this.chatService.chatHistory.at(-1)?.role === 'search-warning') {
323
- this.chatService.chatHistory.pop();
324
- }
325
- // Fetch the answer
326
- this._fetchAnswer(this.question.trim(), this.chatService.chatHistory);
327
- // Clear the input value in the UI
328
- this.questionInput.nativeElement.value = '';
329
- this.questionInput.nativeElement.style.height = `auto`;
330
- }
331
- }
332
- /**
333
- * Triggers the fetch of the answer for the given question and updates the conversation.
334
- * Generates an audit event for the user input.
335
- *
336
- * @param question - The question asked by the user.
337
- * @param conversation - The current conversation messages.
338
- */
339
- _fetchAnswer(question, conversation) {
340
- // merge additionalWorkflowProperties from the chat component and the customization JSON
341
- const additionalWorkflowProperties = { ...this.config.additionalWorkflowProperties, ...this.additionalWorkflowProperties };
342
- const userMsg = { role: 'user', content: question, additionalProperties: { display: true, messageId: guid(), isUserInput: true, additionalWorkflowProperties } };
343
- const messages = [...conversation, userMsg];
344
- this.messages$.next(messages); // Update the messages in the UI with the new user message
345
- this.chatService.chatHistory = messages; // Update the chat history with the new user message
346
- this.scrollDown(); // Scroll down to the bottom of the chat to see the new user message and the incoming assistant answer
347
- this.fetch(messages);
348
- this.chatService.generateAuditEvent('ast-message.message', { ...this._defineMessageAuditDetails(userMsg), 'query': JSON.stringify(this.query), 'is-user-input': true, 'enabled-functions': this.config.defaultValues.functions?.filter(func => func.enabled).map(func => func.name), 'additional-workflow-properties': JSON.stringify(additionalWorkflowProperties) });
349
- }
350
- /**
351
- * Depending on the connection's state :
352
- * - If connected => given a list of messages, the chat endpoint is invoked for a continuation and updates the list of messages accordingly.
353
- * - If any other state => a connection error message is displayed in the chat.
354
- * ⚠️ If the assistant is streaming or stopping the generation, the operation is not allowed.
355
- * @param messages The list of messages to invoke the chat endpoint with
356
- */
357
- fetch(messages) {
358
- if (!!this.chatService.streaming$.value || !!this.chatService.stoppingGeneration$.value) {
359
- return;
360
- }
361
- this._updateConnectionStatus();
362
- this.cdr.detectChanges();
363
- if (this.isConnected) {
364
- this.loading$.next(true);
365
- this._dataSubscription?.unsubscribe();
366
- this._dataSubscription = this.chatService.fetch(messages, this.query)
367
- .subscribe({
368
- next: res => this.updateData(res.history),
369
- error: () => {
370
- this._updateConnectionStatus();
371
- if (!this.isConnected) {
372
- const message = {
373
- role: 'connection-error',
374
- content: { type: "text", text: this.transloco.translate(this.config.connectionSettings.connectionErrorMessage) },
375
- additionalProperties: { display: true, messageId: guid() }
376
- };
377
- this.messages$.next([...messages, message]);
378
- }
379
- this.terminateFetch();
380
- },
381
- complete: () => {
382
- // Remove the last message if it's an empty message
383
- // This is due to the manner in which the chat service handles consecutive messages
384
- const lastMessage = this.messages$.value?.at(-1);
385
- if (this.isEmptyAssistantMessage(lastMessage)) {
386
- this.messages$.next(this.messages$.value?.slice(0, -1));
387
- }
388
- this.terminateFetch();
389
- }
390
- });
391
- }
392
- else {
393
- const message = { role: 'connection-error', content: this.transloco.translate(this.config.connectionSettings.connectionErrorMessage), additionalProperties: { display: true, messageId: guid() } };
394
- this.messages$.next([...messages, message]);
395
- }
396
- if (this.automaticScrollToLastResponse || this.config.globalSettings.automaticScroll) {
397
- this.scrollDown();
398
- }
399
- }
400
- /**
401
- * Retry to fetch the messages if the connection issues.
402
- * - If reconnecting => keep display the connection error message even when clicking on the "retry" button and increasing the number of retrial attempts, until the connection is re-established
403
- * - If disconnected => On click on the "retry" button, start the connection process while displaying the connection error message :
404
- * * If successful => given a list of messages, the chat endpoint is invoked for a continuation and updates the list of messages accordingly.
405
- * * If failed => increase the number of retrial attempts
406
- */
407
- retryFetch() {
408
- // A one-time listener for reconnected event
409
- const onReconnectedHandler = () => {
410
- // Get the messages without the last one (the connection error message)
411
- const messages = this.messages$.value.slice(0, -1);
412
- // Find the last "user" message in the messages list
413
- let index = messages.length - 1;
414
- while (index >= 0 && messages[index].role !== 'user') {
415
- index--;
416
- }
417
- // If a user message is found (and it should always be the case), remove all subsequent messages from the chat history
418
- // Update the messages in the UI
419
- // and fetch the answer from the assistant
420
- if (index >= 0) {
421
- this.messages$.next(this.messages$.value.slice(0, index + 1));
422
- const remappedIndex = this.assistantUtils.getMessageRankInChatHistory(this.chatService.chatHistory, messages[index].additionalProperties.messageId);
423
- this.chatService.chatHistory = this.chatService.chatHistory.slice(0, remappedIndex + 1);
424
- this.fetch(this.chatService.chatHistory);
425
- }
426
- this.retrialAttempts = undefined; // Reset the number of retrial attempts
427
- /**
428
- * To remove the handler for onreconnected() after it's been registered,cannot directly use off() like you would for normal events registered with connection.on().
429
- * Instead, you need to explicitly remove or reset the handler by assigning it to null or an empty function
430
- */
431
- this.chatService.connection.onreconnected(() => { });
432
- // Reset the flag to ensure the handler is registered again when needed
433
- this._isReconnectedListenerRegistered = false;
434
- };
435
- // Depending on the connection's state, take the appropriate action
436
- switch (this.chatService.connection.state) {
437
- case HubConnectionState.Connected:
438
- // If the connection is re-established in the meantime, fetch the messages
439
- onReconnectedHandler();
440
- break;
441
- case HubConnectionState.Reconnecting:
442
- // Attach the reconnected listener if not already registered
443
- if (!this._isReconnectedListenerRegistered) {
444
- this.chatService.connection.onreconnected(onReconnectedHandler);
445
- this._isReconnectedListenerRegistered = true;
446
- }
447
- // Increase the number of retrial attempts
448
- this.retrialAttempts = this.retrialAttempts ? this.retrialAttempts + 1 : 1;
449
- break;
450
- case HubConnectionState.Disconnected:
451
- // Start the new connection
452
- this.chatService.startConnection()
453
- .then(() => onReconnectedHandler())
454
- .catch(() => {
455
- this.retrialAttempts = this.retrialAttempts ? this.retrialAttempts + 1 : 1;
456
- });
457
- break;
458
- default:
459
- break;
460
- }
461
- }
462
- /**
463
- * Check if the signalR connection is connected.
464
- * For the REST protocol, the connection is always considered connected (for the moment).
465
- */
466
- _updateConnectionStatus() {
467
- this.isConnected = this.chatService.connection.state === HubConnectionState.Connected;
468
- }
469
- /**
470
- * Update the UI with the new messages
471
- * @param messages
472
- */
473
- updateData(messages) {
474
- this.messages$.next(messages);
475
- this.data.emit(messages);
476
- this.loading$.next(false);
477
- this.question = '';
478
- if (this.automaticScrollToLastResponse || this.config.globalSettings.automaticScroll) {
479
- this.scrollDown();
480
- }
481
- }
482
- /**
483
- * @returns true if the chat discussion is scrolled down to the bottom, false otherwise
484
- */
485
- _toggleScrollButtonVisibility() {
486
- const messageList = document.getElementById(`messageList-${this.instanceId}`);
487
- if (messageList) {
488
- return Math.round(messageList.scrollHeight - messageList.scrollTop - 1) <= messageList.clientHeight;
489
- }
490
- return true;
491
- }
492
- /**
493
- * Scroll down to the bottom of the chat discussion
494
- */
495
- scrollDown() {
496
- setTimeout(() => {
497
- const messageList = document.getElementById(`messageList-${this.instanceId}`);
498
- if (messageList) {
499
- messageList.scrollTop = messageList.scrollHeight;
500
- this.cdr.detectChanges();
501
- }
502
- }, 10);
503
- }
504
- /**
505
- * Start a new chat with the defaultValues settings.
506
- * The savedChatId in the chat service will be reset, so that the upcoming saved chat operations will be performed on the fresh new chat.
507
- * If the savedChat feature is enabled, the list of saved chats will be refreshed.
508
- * ⚠️ If the assistant is streaming or stopping the generation, the operation is not allowed.
509
- */
510
- newChat() {
511
- if (!!this.chatService.streaming$.value || !!this.chatService.stoppingGeneration$.value) {
512
- return;
513
- }
514
- this.chatService.generateChatId(); // Generate a new chatId
515
- if (this.config.savedChatSettings?.enabled) {
516
- this.chatService.listSavedChat(); // Refresh the list of saved chats
517
- }
518
- this.chatService.generateAuditEvent('ast-chat.new', { 'configuration': JSON.stringify(this.chatService.assistantConfig$.value) }); // Generate a new chat audit event
519
- this.loadDefaultChat(); // Start a new chat
520
- }
521
- /**
522
- * Attaches the specified document IDs to the assistant.
523
- * If no document IDs are provided, the operation is not allowed.
524
- * If the action for attaching a document is not defined at the application customization level, an error is logged.
525
- * ⚠️ If the assistant is streaming or stopping the generation, the operation is not allowed.
526
- * @param ids - An array of document IDs to attach.
527
- */
528
- attachToChat(ids) {
529
- if (!!this.chatService.streaming$.value || !!this.chatService.stoppingGeneration$.value) {
530
- return;
531
- }
532
- if (!ids || ids?.length < 1) {
533
- return;
534
- }
535
- const attachDocAction = this.config.modeSettings.actions?.["attachDocAction"];
536
- if (!attachDocAction) {
537
- console.error(`No action is defined for attaching a document to the assistant "${this.instanceId}"`);
538
- return;
539
- }
540
- const userMsg = { role: 'user', content: '', additionalProperties: { display: false, messageId: guid(), isUserInput: false, type: "Action", forcedWorkflow: attachDocAction.forcedWorkflow, forcedWorkflowProperties: { ...(attachDocAction.forcedWorkflowProperties || {}), ids }, additionalWorkflowProperties: this.config.additionalWorkflowProperties } };
541
- // Remove the search warning message if exists
542
- if (this.chatService.chatHistory.at(-1)?.role === 'search-warning') {
543
- this.chatService.chatHistory.pop();
544
- }
545
- const messages = [...this.chatService.chatHistory, userMsg];
546
- this.messages$.next(messages);
547
- this.fetch(messages);
548
- this.chatService.generateAuditEvent('ast-action.requested', {
549
- 'detail': 'attachDocAction',
550
- 'forced-workflow': 'SinequaAddSelectedDocumentsWorkflow',
551
- 'forced-workflow-properties': JSON.stringify(ids),
552
- });
553
- }
554
- /**
555
- * Start the default chat with the defaultValues settings
556
- * If the chat is meant to be initialized with event === "Query", the corresponding user query message will be added to the chat history
557
- */
558
- loadDefaultChat() {
559
- const date = (new Date()).toLocaleString('en-US', { weekday: 'long', month: 'long', day: '2-digit', year: 'numeric' });
560
- // Define the default system prompt and user prompt messages
561
- const systemMsg = {
562
- role: 'system',
563
- content: AssistantUtils.formatPrompt(this.transloco.translate(this.config.defaultValues.systemPrompt), { principal: this.principalService.principal, date }),
564
- additionalProperties: { display: false, messageId: guid() }
565
- };
566
- // backward compatibility with old configuration files
567
- const userPrompt = this.config.defaultValues.userPrompt.replace(/\{\{(.*?)\}\}/g, '[[$1]]');
568
- const userMsg = {
569
- role: 'user',
570
- content: AssistantUtils.formatPrompt(this.transloco.translate(userPrompt), { principal: this.principalService.principal, date }),
571
- additionalProperties: { display: this.config.modeSettings.displayUserPrompt, messageId: guid() }
572
- };
573
- if (this.config.modeSettings.initialization.event === 'Query') {
574
- this._handleQueryMode(systemMsg, userMsg);
575
- }
576
- else {
577
- this._handlePromptMode(systemMsg, userMsg);
578
- }
579
- }
580
- /**
581
- * Handles the prompt mode of the chat component.
582
- * If `sendUserPrompt` is true, it opens the chat with both system and user messages,
583
- * and generates audit events for both messages.
584
- * If `sendUserPrompt` is false, it opens the chat with only the system message,
585
- * and generates an audit event for the system message.
586
- *
587
- * @param systemMsg - The system message to be displayed in the chat.
588
- * @param userMsg - The user message to be displayed in the chat (optional).
589
- */
590
- _handlePromptMode(systemMsg, userMsg) {
591
- if (this.config.modeSettings.sendUserPrompt) {
592
- this.openChat([systemMsg, userMsg]);
593
- this.chatService.generateAuditEvent('ast-message.message', this._defineMessageAuditDetails(systemMsg));
594
- this.chatService.generateAuditEvent('ast-message.message', this._defineMessageAuditDetails(userMsg));
595
- }
596
- else {
597
- this.openChat([systemMsg]);
598
- this.chatService.generateAuditEvent('ast-message.message', this._defineMessageAuditDetails(systemMsg));
599
- }
600
- }
601
- /**
602
- * Handles the query mode by displaying the system message, user message, and user query message.
603
- * If the provided query text is not empty, then add the user query message to the chat history and invoke the assistant
604
- * Otherwise, just start a new chat with a warning message inviting the user to perform a full text search to retrieve some results
605
- * @param systemMsg - The system message to be displayed.
606
- * @param userMsg - The user message to be displayed.
607
- */
608
- _handleQueryMode(systemMsg, userMsg) {
609
- if (!!this.query.text) {
610
- const userQueryMsg = { role: 'user', content: this.query.text, additionalProperties: { display: this.config.modeSettings.initialization.displayUserQuery, messageId: guid(), query: this.query, forcedWorkflow: this.config.modeSettings.initialization.forcedWorkflow, forcedFunction: this.config.modeSettings.initialization.forcedFunction, isUserInput: true, additionalWorkflowProperties: this.config.additionalWorkflowProperties } };
611
- if (this.config.modeSettings.sendUserPrompt) {
612
- this.openChat([systemMsg, userMsg, userQueryMsg]);
613
- this.chatService.generateAuditEvent('ast-message.message', this._defineMessageAuditDetails(systemMsg));
614
- this.chatService.generateAuditEvent('ast-message.message', this._defineMessageAuditDetails(userMsg));
615
- this.chatService.generateAuditEvent('ast-message.message', { ...this._defineMessageAuditDetails(userQueryMsg), 'query': JSON.stringify(this.query), 'is-user-input': true, 'forced-workflow': this.config.modeSettings.initialization.forcedWorkflow, 'forced-function': this.config.modeSettings.initialization.forcedFunction, 'enabled-functions': this.config.defaultValues.functions?.filter(func => func.enabled).map(func => func.name), 'additional-workflow-properties': JSON.stringify(this.config.additionalWorkflowProperties) });
616
- }
617
- else {
618
- this.openChat([systemMsg, userQueryMsg]);
619
- this.chatService.generateAuditEvent('ast-message.message', this._defineMessageAuditDetails(systemMsg));
620
- this.chatService.generateAuditEvent('ast-message.message', { ...this._defineMessageAuditDetails(userQueryMsg), 'query': JSON.stringify(this.query), 'is-user-input': true, 'forced-workflow': this.config.modeSettings.initialization.forcedWorkflow, 'forced-function': this.config.modeSettings.initialization.forcedFunction, 'enabled-functions': this.config.defaultValues.functions?.filter(func => func.enabled).map(func => func.name), 'additional-workflow-properties': JSON.stringify(this.config.additionalWorkflowProperties) });
621
- }
622
- }
623
- else {
624
- const warningMsg = { role: 'search-warning', content: this.transloco.translate(this.config.globalSettings.searchWarningMessage), additionalProperties: { display: true, messageId: guid() } };
625
- this.openChat([systemMsg, warningMsg]);
626
- this.chatService.generateAuditEvent('ast-message.message', this._defineMessageAuditDetails(warningMsg));
627
- }
628
- }
629
- _defineMessageAuditDetails(message) {
630
- const rank = this.assistantUtils.getMessageRankInChatHistory(this.chatService.chatHistory, message.additionalProperties.messageId);
631
- const details = {
632
- 'duration': 0,
633
- 'role': message.role,
634
- 'rank': rank,
635
- 'message-id': message.additionalProperties.messageId
636
- };
637
- if (!!this.config.auditSettings?.logContent) {
638
- if (typeof message.content === 'string') {
639
- details.text = message.content;
640
- }
641
- else if (Array.isArray(message.content)) {
642
- details.text = message.content.find((msg) => msg.type === "text").text;
643
- }
644
- }
645
- return details;
646
- }
647
- /**
648
- * Start/open a new chat with the provided messages and chatId
649
- * If the last message is from the user, a request to the assistant is made to get an answer
650
- * If the last message is from the assistant, the conversation is loaded right away
651
- * @param messages The list of messages of the chat
652
- * @param chatId The id of the discussion. If provided (ie. an existing discussion in the saved chat index), update the chatId in the chat service for the upcoming saved chat operations
653
- */
654
- openChat(messages, chatId) {
655
- if (!messages || !Array.isArray(messages)) {
656
- console.error('Error occurs while trying to load the discussion. Invalid messages received :', messages);
657
- return;
658
- }
659
- if (chatId) {
660
- this.chatService.generateChatId(chatId);
661
- }
662
- // Ensure each message has a unique messageId
663
- // This is necessary specially in case the assistant is started with a predefined history Or an old saved chat
664
- const messagesWithIds = messages.map((msg) => {
665
- msg.additionalProperties.messageId ??= guid();
666
- return msg;
667
- });
668
- this.resetChat();
669
- this.messages$.next(messagesWithIds);
670
- this.chatService.chatHistory = messagesWithIds;
671
- const lastMessage = messages.at(-1);
672
- if (lastMessage && lastMessage.role === 'user') {
673
- this.fetch(messagesWithIds); // If the last message if from a user, an answer from the assistant is expected
674
- }
675
- else {
676
- this.updateData(messagesWithIds); // If the last message if from the assistant, we can load the conversation right away
677
- this.terminateFetch();
678
- }
679
- this._addScrollListener();
680
- }
681
- /**
682
- * Reset the chat by clearing the chat history and the UI accordingly
683
- * The user input will be cleared
684
- * The fetch subscription will be terminated
685
- */
686
- resetChat() {
687
- if (this.messages$.value) {
688
- this.messages$.next(undefined); // Reset chat
689
- }
690
- this.chatService.chatHistory = undefined; // Reset chat history
691
- this.question = '';
692
- this.terminateFetch();
693
- }
694
- /**
695
- * Fetch and Load the saved chat from the saved chat index.
696
- * If the saved chat is found, the chat discussion will be loaded with the provided messages and chatId
697
- */
698
- onLoadChat() {
699
- this.loading$.next(true);
700
- this.chatService.loadSavedChat$
701
- .pipe(takeUntilDestroyed(this.destroyRef), filter(savedChat => !!savedChat), switchMap(savedChat => this.chatService.getSavedChat(savedChat.id)), filter(savedChatHistory => !!savedChatHistory), tap(savedChatHistory => this.openChat(savedChatHistory.history, savedChatHistory.id))).subscribe();
702
- }
703
- /**
704
- * Stop the generation of the current assistant's answer.
705
- * The fetch subscription will be terminated.
706
- */
707
- stopGeneration() {
708
- this.chatService.stopGeneration().subscribe(() => {
709
- // Remove the last message if it's an empty message
710
- // This is due to the manner in which the chat service handles consecutive messages
711
- const lastMessage = this.messages$.value?.at(-1);
712
- if (this.isEmptyAssistantMessage(lastMessage)) {
713
- this.messages$.next(this.messages$.value?.slice(0, -1));
714
- }
715
- this.terminateFetch();
716
- });
717
- }
718
- /**
719
- * Terminate the fetch process by unsubscribing from the data subscription and updating the loading status to false.
720
- * Additionally, focus on the chat input if the focusAfterResponse flag is set to true.
721
- */
722
- terminateFetch() {
723
- this._dataSubscription?.unsubscribe();
724
- this._dataSubscription = undefined;
725
- this.loading$.next(false);
726
- this.cdr.detectChanges();
727
- if (this.focusAfterResponse) {
728
- setTimeout(() => {
729
- this.questionInput?.nativeElement.focus();
730
- });
731
- }
732
- }
733
- /**
734
- * Copy a previous user message of the chat history to the chat user input.
735
- * Thus, the user can edit and resubmit the message.
736
- * Once the edited message is submitted, all subsequent messages starting from @param index will be removed from the history and the UI will be updated accordingly.
737
- * The assistant will regenerate a new answer based on the updated chat history.
738
- * ⚠️ If the assistant is streaming or stopping the generation, the operation is not allowed.
739
- * @param message The user's message to edit
740
- * @param index The index of the user's message to edit
741
- * @returns void
742
- */
743
- editMessage(message, index) {
744
- if (!!this.chatService.streaming$.value || !!this.chatService.stoppingGeneration$.value) {
745
- return;
746
- }
747
- this.indexMessageToEdit = index;
748
- this.rankMessageToEdit = this.assistantUtils.getMessageRankInChatHistory(this.chatService.chatHistory, message.additionalProperties.messageId);
749
- // Get user message from both legacy and text message type
750
- this.question = typeof message.content === 'string' ? message.content : message.content[0].text;
751
- this.chatService.generateAuditEvent('ast-edit.click', { 'rank': this.rankMessageToEdit, 'message-id': message.additionalProperties.messageId });
752
- }
753
- /**
754
- * Copy a previous assistant message of the chat history to the clipboard.
755
- * @param message The message to copy
756
- * @param index The index of the message to copy
757
- * @returns void
758
- */
759
- copyMessage(message, index) {
760
- // Remap the index in the chat history
761
- const rank = this.assistantUtils.getMessageRankInChatHistory(this.chatService.chatHistory, message.additionalProperties.messageId);
762
- this.chatService.generateAuditEvent('ast-copy.click', { 'rank': rank, 'message-id': message.additionalProperties.messageId });
763
- }
764
- /**
765
- * Starting from the provided index, remove all subsequent messages from the chat history and the UI accordingly.
766
- * The assistant will regenerate a new answer based on the updated chat history.
767
- * ⚠️ If the assistant is streaming or stopping the generation, the operation is not allowed.
768
- * @param message The assistant's message to regenerate
769
- * @param index The index of the assistant's message to regenerate
770
- */
771
- regenerateMessage(message, index) {
772
- if (!!this.chatService.streaming$.value || !!this.chatService.stoppingGeneration$.value) {
773
- return;
774
- }
775
- // Update the messages in the UI by removing all subsequent 'assistant' messages starting from the provided index until the first previous 'user' message
776
- let i = index;
777
- while (i >= 0 && !((this.messages$.value)[i].role === 'user' && (this.messages$.value)[i].additionalProperties.isUserInput === true)) {
778
- i--;
779
- }
780
- // It should always be the case that i > 0
781
- if (i >= 0) {
782
- this.messages$.next(this.messages$.value.slice(0, i + 1));
783
- // Rank of this found first previous 'user' message in the chat history
784
- const rankFirstPreviousUserMessage = this.assistantUtils.getMessageRankInChatHistory(this.chatService.chatHistory, this.messages$.value[i].additionalProperties.messageId);
785
- // Rank of the assistant's message on which the user clicked to regenerate
786
- const rank = this.assistantUtils.getMessageRankInChatHistory(this.chatService.chatHistory, message.additionalProperties.messageId);
787
- // Define and Update the chat history based on which the assistant will generate a new answer
788
- this.chatService.chatHistory = this.chatService.chatHistory.slice(0, rankFirstPreviousUserMessage);
789
- // Fetch the answer
790
- this.fetch(this.chatService.chatHistory);
791
- this.chatService.generateAuditEvent('ast-regenerate.click', { 'rank': rank, 'message-id': message.additionalProperties.messageId });
792
- }
793
- }
794
- /**
795
- * Handles the key up event for 'Backspace' and 'Enter' keys.
796
- * @param event - The keyboard event.
797
- */
798
- onKeyUp(event) {
799
- switch (event.key) {
800
- case 'Backspace':
801
- this.calculateHeight();
802
- break;
803
- case 'Enter':
804
- if (!event.shiftKey) {
805
- event.preventDefault();
806
- this.submitQuestion();
807
- }
808
- this.calculateHeight();
809
- break;
810
- default:
811
- break;
812
- }
813
- }
814
- /**
815
- * Calculates and adjusts the height of the question input element based on its content.
816
- * If the Enter key is pressed without the Shift key, it prevents the default behavior.
817
- * @param event The keyboard event
818
- */
819
- calculateHeight(event) {
820
- if (event?.key === 'Enter' && !event.shiftKey) {
821
- event?.preventDefault();
822
- }
823
- const maxHeight = 170;
824
- const el = this.questionInput.nativeElement;
825
- el.style.maxHeight = `${maxHeight}px`;
826
- el.style.height = 'auto';
827
- el.style.height = `${el.scrollHeight}px`;
828
- el.style.overflowY = el.scrollHeight >= maxHeight ? 'scroll' : 'hidden';
829
- }
830
- /**
831
- * Send a "like" event on clicking on the thumb-up icon of an assistant's message
832
- * @param message The assistant message to like
833
- * @param index The index of the message to like
834
- */
835
- onLike(message, index) {
836
- // Remap the index in the chat history
837
- const rank = this.assistantUtils.getMessageRankInChatHistory(this.chatService.chatHistory, message.additionalProperties.messageId);
838
- this.chatService.generateAuditEvent('ast-thumb-up.click', { 'rank': rank, 'message-id': message.additionalProperties.messageId });
839
- this.reportType = 'like';
840
- this.messageToReport = message;
841
- this.reportComment = undefined;
842
- this.reportRank = rank;
843
- this.showReport = true;
844
- this.chatService.chatHistory[rank - 1].additionalProperties.$liked = true;
845
- this.chatService.chatHistory[rank - 1].additionalProperties.$disliked = false;
846
- this._updateChatHistory();
847
- }
848
- /**
849
- * Send a "dislike" event on clicking on the thumb-down icon of an assistant's message.
850
- * It also opens the issue reporting dialog.
851
- * @param message The assistant message to dislike
852
- * @param index The rank of the message to dislike
853
- */
854
- onDislike(message, index) {
855
- // Remap the index in the chat history
856
- const rank = this.assistantUtils.getMessageRankInChatHistory(this.chatService.chatHistory, message.additionalProperties.messageId);
857
- this.chatService.generateAuditEvent('ast-thumb-down.click', { 'rank': rank, 'message-id': message.additionalProperties.messageId });
858
- this.reportType = 'dislike';
859
- this.messageToReport = message;
860
- this.issueType = '';
861
- this.reportComment = undefined;
862
- this.reportRank = rank;
863
- this.showReport = true;
864
- this.chatService.chatHistory[rank - 1].additionalProperties.$disliked = true;
865
- this.chatService.chatHistory[rank - 1].additionalProperties.$liked = false;
866
- this._updateChatHistory();
867
- }
868
- _updateChatHistory() {
869
- this.messages$.next(this.chatService.chatHistory);
870
- if (this.config.savedChatSettings.enabled) {
871
- this.chatService.updateSavedChat(this.chatService.chatId, undefined, this.chatService.chatHistory).subscribe();
872
- }
873
- this.cdr.detectChanges();
874
- }
875
- /**
876
- * Report an issue related to the assistant's message.
877
- */
878
- sendReport() {
879
- const details = {
880
- 'comment': this.reportComment,
881
- 'rank': this.reportRank
882
- };
883
- //check if the message to report is defined. It should always be the case
884
- if (this.messageToReport) {
885
- details['message-id'] = this.messageToReport.additionalProperties.messageId;
886
- }
887
- // hide text in case logContent is not enabled
888
- if (this.config.auditSettings.logContent)
889
- details['text'] = this.messageToReport.content;
890
- if (this.reportType === 'dislike') {
891
- details['report-type'] = this.issueType;
892
- this.chatService.generateAuditEvent('ast-negative-report.send', details);
893
- }
894
- else {
895
- this.chatService.generateAuditEvent('ast-positive-report.send', details);
896
- }
897
- this.notificationsService.success(this.transloco.translate('chat.sendReportNotification'));
898
- this.showReport = false;
899
- }
900
- /**
901
- * Close the reporting dialog.
902
- */
903
- ignoreReport() {
904
- this.showReport = false;
905
- }
906
- /**
907
- * Handle the click on a reference's 'open preview'.
908
- * @param data
909
- * @param message the message containing the reference
910
- * @param index index of the message containing the reference
911
- * @returns void
912
- */
913
- openAttachmentPreview(data, message, index) {
914
- this.openPreview.emit(data.reference);
915
- const rank = this.assistantUtils.getMessageRankInChatHistory(this.chatService.chatHistory, message.additionalProperties.messageId);
916
- const details = {
917
- 'doc-id': data.reference.recordId,
918
- 'source': data.reference.record.treepath,
919
- 'collection': data.reference.record.collection,
920
- 'index': data.reference.record.databasealias,
921
- 'rank': rank,
922
- 'message-id': message.additionalProperties.messageId
923
- };
924
- if (!!data.partId)
925
- details['part-id'] = data.partId;
926
- this.chatService.generateAuditEvent('ast-attachment.preview.click', details);
927
- }
928
- /**
929
- * Handle the click on a reference's 'open original document'.
930
- * @param data
931
- * @param message the message containing the reference
932
- * @param index index of the message containing the reference
933
- * @returns void
934
- */
935
- openOriginalAttachment(data, message, index) {
936
- this.openDocument.emit(data.reference.record);
937
- const rank = this.assistantUtils.getMessageRankInChatHistory(this.chatService.chatHistory, message.additionalProperties.messageId);
938
- const details = {
939
- 'doc-id': data.reference.recordId,
940
- 'source': data.reference.record.treepath,
941
- 'collection': data.reference.record.collection,
942
- 'index': data.reference.record.databasealias,
943
- 'rank': rank,
944
- 'message-id': message.additionalProperties.messageId
945
- };
946
- if (!!data.partId)
947
- details['part-id'] = data.partId;
948
- this.chatService.generateAuditEvent('ast-attachment.link.click', details);
949
- }
950
- /**
951
- * Handle the click on a suggested action.
952
- * @param action Suggested action.
953
- * @param index index of the message containing the suggested action.
954
- * @returns void
955
- */
956
- suggestActionClick(action, index) {
957
- this.suggestAction.emit(action);
958
- const details = {
959
- 'text': action.content,
960
- 'suggestedAction-type': action.type
961
- };
962
- this.chatService.generateAuditEvent('ast-suggested-action.click', details);
963
- }
964
- /**
965
- * It looks for the debug messages available in the current group of "assistant" messages.
966
- * By design, the debug messages are only available in the first visible message among the group of "assistant" messages.
967
- * @param message The message containing the debug information
968
- * @param index The index of the message
969
- * @returns The debug messages available in the current group of "assistant" messages
970
- */
971
- getDebugMessages(message, index) {
972
- // If it is not an assistant message, return an empty array
973
- if (message.role !== 'assistant') {
974
- return [];
975
- }
976
- // Get the array of messages up to the indicated index
977
- const array = this.messages$.value.slice(0, index + 1);
978
- // If it is an assistant message, look for the debug messages available in the current group of "assistant" messages
979
- // By design, the debug messages are only available in the first visible message among the group "assistant" messages.
980
- const idx = this.assistantUtils.firstVisibleAssistantMessageIndex(array);
981
- if (idx > -1) {
982
- return (this.messages$.value)[idx].additionalProperties.$debug || [];
983
- }
984
- return [];
985
- }
986
- /**
987
- * Handle the click on the 'show log info' button of a message.
988
- * @param message The message containing the debug information
989
- * @param index The index of the message
990
- */
991
- showDebug(message, index) {
992
- this.debugMessages = this.getDebugMessages(message, index);
993
- this.showDebugMessages = true;
994
- this.cdr.detectChanges();
995
- }
996
- /**
997
- * Verify whether the current message is an assistant message and that all following messages are assistant ones
998
- * Used to keep the "View progress" opened even though the assistant is sending additional messages after the current one
999
- * @param messages the list of current messages
1000
- * @param index the index of the current message
1001
- * @returns if this messages and the following ones (if any) are the last ones
1002
- */
1003
- isAssistantLastMessages(messages, index) {
1004
- for (let i = index; i < messages.length; i++) {
1005
- if (messages[i].role !== 'assistant')
1006
- return false;
1007
- }
1008
- return true;
1009
- }
1010
- /**
1011
- * Checks if the given message is an empty assistant message.
1012
- * An empty assistant message is defined as a message with the role 'assistant',
1013
- * an empty content, and no additional properties such as attachments, progress,
1014
- * debug information, or suggested actions.
1015
- *
1016
- * @param message - The message to check.
1017
- * @returns `true` if the message is an empty assistant message, `false` otherwise.
1018
- */
1019
- isEmptyAssistantMessage(message) {
1020
- if (message?.role === 'assistant'
1021
- && (
1022
- // Legacy message type
1023
- (typeof message?.content === 'string' && message?.content === "")
1024
- // New message type
1025
- // - Text
1026
- || message?.content?.[0]?.text === ""
1027
- // TODO: image and video message types https://sinequa.atlassian.net/browse/ES-25940
1028
- )
1029
- && !message?.additionalProperties?.$attachment
1030
- && !message?.additionalProperties?.$progress
1031
- && !message?.additionalProperties?.$debug
1032
- && !message?.additionalProperties?.$suggestedAction) {
1033
- return true;
1034
- }
1035
- return false;
1036
- }
1037
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1038
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ChatComponent, isStandalone: true, selector: "sq-chat-v3", inputs: { instanceId: "instanceId", query: "query", queryChangeShouldTriggerReload: "queryChangeShouldTriggerReload", messageHandlers: "messageHandlers", automaticScrollToLastResponse: "automaticScrollToLastResponse", focusAfterResponse: "focusAfterResponse", chat: "chat", assistantMessageIcon: "assistantMessageIcon", userMessageIcon: "userMessageIcon", connectionErrorMessageIcon: "connectionErrorMessageIcon", searchWarningMessageIcon: "searchWarningMessageIcon", additionalWorkflowProperties: "additionalWorkflowProperties", appConfig: "appConfig" }, outputs: { connection: "connection", loading$: "loading", _config: "config", data: "data", openDocument: "openDocument", openPreview: "openPreview", suggestAction: "suggestAction" }, providers: [
1039
- ChatService,
1040
- AssistantConfigurationService,
1041
- AssistantTokensTrackingService,
1042
- SavedChatsService,
1043
- DebugMessageService,
1044
- provideTranslocoScope('chat')
1045
- ], queries: [{ propertyName: "loadingTpl", first: true, predicate: ["loadingTpl"], descendants: true }, { propertyName: "reportTpl", first: true, predicate: ["reportTpl"], descendants: true }, { propertyName: "tokenConsumptionTpl", first: true, predicate: ["tokenConsumptionTpl"], descendants: true }, { propertyName: "debugMessagesTpl", first: true, predicate: ["debugMessagesTpl"], descendants: true }], viewQueries: [{ propertyName: "questionInput", first: true, predicate: ["questionInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"!initializationError\">\n <div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n <!-- Token consumption -->\n <div class=\"ms-1\" *ngIf=\"config?.globalSettings?.displayUserQuotaConsumption || config?.globalSettings?.displayChatTokensConsumption\">\n <ng-container *ngTemplateOutlet=\"tokenConsumptionTpl || defaultTokenConsumptionTpl; context: { $implicit: instanceId }\"></ng-container>\n </div>\n\n <!-- Chat Messages -->\n <ul class=\"d-flex flex-column list-unstyled gap-3 overflow-auto flex-grow-1 pe-2 pb-2\" #messageList [id]=\"'messageList-' + instanceId\">\n <ng-container *ngFor=\"let message of messages; let index = index; let last = last\">\n <!-- Regular messages -->\n <li class=\"list-group-item\"\n *ngIf=\"message.additionalProperties.display && !isEmptyAssistantMessage(message)\"\n [style.--bs-list-group-item-padding-y.rem]=\"'0.6'\"\n [class.opacity-50]=\"indexMessageToEdit && (indexMessageToEdit < (index + 1))\">\n <sq-chat-message\n [id]=\"message.additionalProperties.messageId\"\n [class.sq-user-message]=\"message.role === 'user'\"\n [class.last-message]=\"last\"\n [message]=\"message\"\n [conversation]=\"messages\"\n [suggestedActions]=\"last ? message.additionalProperties.$suggestedAction : undefined\"\n [assistantMessageIcon]=\"assistantMessageIcon\"\n [userMessageIcon]=\"userMessageIcon\"\n [connectionErrorMessageIcon]=\"connectionErrorMessageIcon\"\n [searchWarningMessageIcon]=\"searchWarningMessageIcon\"\n [streaming]=\"(chatService.streaming$ | async) && (last || isAssistantLastMessages(messages, index))\"\n [canEdit]=\"(chatService.streaming$ | async) === false && indexMessageToEdit === undefined && message.role === 'user'\"\n [canCopy]=\"((chatService.streaming$ | async) === false || !last) && indexMessageToEdit === undefined && message.role !== 'connection-error' && message.role !== 'search-warning'\"\n [canLike]=\"((chatService.streaming$ | async) === false || !last) && message.role === 'assistant'\"\n [canDislike]=\"((chatService.streaming$ | async) === false || !last) && message.role === 'assistant'\"\n [canDebug]=\"(((chatService.streaming$ | async) === false && last) || (!last && messages[index+1].role !== 'assistant')) && message.role === 'assistant' && (getDebugMessages(message, index).length > 0) && ((isAdminOrDeletedAdmin || (chatService.userOverride$ | async)) && config?.defaultValues.debug)\"\n [canRegenerate]=\"(chatService.streaming$ | async) === false && (last || (!last && messages[index+1].role !== 'assistant')) && message.role === 'assistant' && indexMessageToEdit === undefined\"\n [collapseReferences]=\"!!config?.globalSettings.collapseReferences\"\n (edit)=\"editMessage(message, index)\"\n (copy)=\"copyMessage(message, index)\"\n (regenerate)=\"regenerateMessage(message, index)\"\n (openDocument)=\"openOriginalAttachment($event, message, index)\"\n (openPreview)=\"openAttachmentPreview($event, message, index)\"\n (suggestAction)=\"suggestActionClick($event, index)\"\n (like)=\"onLike(message, index)\"\n (dislike)=\"onDislike(message, index)\"\n (debug)=\"showDebug(message, index)\">\n </sq-chat-message>\n </li>\n </ng-container>\n <!-- Loading spinner -->\n <li *ngIf=\"(loading$ | async) === true\">\n <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n </li>\n </ul>\n\n <!-- Reporting a feedback form -->\n <div class=\"issue-report p-3 rounded-lg\" *ngIf=\"showReport\">\n <ng-container *ngTemplateOutlet=\"reportTpl || reportTplDefault; context: { $implicit: messageToReport, rank: reportRank, type: reportType }\"></ng-container>\n </div>\n\n <!-- User text input -->\n @if (!showReport) {\n <div class=\"user-input mt-auto\">\n <div class=\"py-2\">\n <div [hidden]=\"!isConnected\">\n <ng-container *ngIf=\"enabledUserInput\" [ngTemplateOutlet]=\"inputTpl\"></ng-container>\n </div>\n <!-- Retry button -->\n <!-- hidden attribute is in conflict with a css rule display: flex -->\n @if(!isConnected){\n <button class=\"btn mb-4 ast-error ast-btn sq-retry\" (click)=\"retryFetch()\">\n <span>{{ 'chat.tryAgain' | transloco }}</span>\n <span *ngIf=\"retrialAttempts\" class=\"ms-2 attempts\">{{ retrialAttempts }}</span>\n </button>\n }\n <div class=\"text-end small text-muted px-3\" *ngIf=\"!!config?.globalSettings?.disclaimer\">\n {{ config?.globalSettings?.disclaimer | transloco }}\n </div>\n </div>\n </div>\n }\n\n <!-- Floating scroll button -->\n <div *ngIf=\"!isAtBottom && !showReport\" class=\"sq-floating-scroll\" [ngClass]=\"enabledUserInput ? 'sq-floating-scroll--when-user-input' : 'sq-floating-scroll--without-user-input'\">\n <button class=\"btn shadow\" (click)=\"scrollDown()\" aria-label=\"Scroll down\">\n <i class=\"fas fa-angle-double-down\"></i>\n </button>\n </div>\n </div>\n</ng-container>\n\n<!-- NG TEMPLATES-->\n\n<ng-template #loadingTplDefault>\n <div class=\"spinner-grow text-primary d-block mx-auto my-5\" role=\"status\">\n <span class=\"visually-hidden\">{{ 'chat.loading' | transloco }}</span>\n </div>\n</ng-template>\n\n<ng-template #inputTpl>\n <div class=\"px-3 py-1\">\n <div class=\"ast-input-container\">\n <button disabled class=\"btn btn-light\" aria-label=\"search\">\n <i class=\"fas fa-search\"></i>\n </button>\n <textarea #questionInput rows=\"1\"\n type=\"text\" class=\"form-control\"\n [placeholder]=\"'chat.askSomething' | transloco\" autofocus\n [(ngModel)]=\"question\"\n (keyup)=\"onKeyUp($event)\"\n (keydown)=\"calculateHeight($event)\"\n [disabled]=\"(loading$ | async) || (chatService.streaming$ | async) || (chatService.stoppingGeneration$ | async)\">\n </textarea>\n <div id=\"chat-actions\" class=\"d-flex gap-2\">\n <button\n *ngIf=\"(chatService.streaming$ | async) === false && (loading$ | async) !== true && (chatService.stoppingGeneration$ | async) === false\"\n type=\"button\"\n class=\"btn btn-light\"\n aria-label=\"Send message\"\n [sqTooltip]=\"'chat.sendMessage' | transloco\"\n (click)=\"submitQuestion()\">\n <i class=\"fas fa-paper-plane\"></i>\n </button>\n <button\n *ngIf=\"indexMessageToEdit\"\n aria-label=\"Cancel edition\"\n type=\"button\"\n class=\"btn btn-light\"\n [sqTooltip]=\"'chat.cancelEdition' | transloco\"\n (click)=\"indexMessageToEdit = undefined; question = ''\">\n <i class=\"fas fa-undo-alt\"></i>\n </button>\n <span *ngIf=\"(chatService.streaming$ | async) && (chatService.stoppingGeneration$ | async) === false\" class=\"processing\">\n {{ 'chat.generating' | transloco }}<i class=\"fas fa-spinner fa-pulse\"></i>\n </span>\n <span *ngIf=\"(chatService.stoppingGeneration$ | async)\" class=\"processing\">\n {{ 'chat.stopping' | transloco }}<i class=\"fas fa-spinner fa-pulse\"></i>\n </span>\n <button\n *ngIf=\"(chatService.streaming$ | async) && (chatService.stoppingGeneration$ | async) === false\"\n type=\"button\"\n class=\"btn btn-light\"\n aria-label=\"Stop generating\"\n [sqTooltip]=\"'chat.stopGeneration' | transloco\"\n (click)=\"stopGeneration()\">\n <i class=\"fas fa-stop\"></i>\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #reportTplDefault let-message let-rank=\"rank\" let-type=\"type\">\n <div class=\"px-3\">\n <ng-container *ngIf=\"type === 'dislike'\">\n <h5>{{ 'chat.issueType' | transloco }}</h5>\n <select class=\"form-select mb-4\" [(ngModel)]=\"issueType\">\n <option [value]=\"''\">{{ 'chat.chooseIssueType' | transloco }}</option>\n <option *ngFor=\"let type of (issueTypes ?? defaultIssueTypes)\" [value]=\"type\">{{ type | transloco }}</option>\n </select>\n <h5>{{ 'chat.askUnlikeReasons' | transloco }}</h5>\n </ng-container>\n <ng-container *ngIf=\"type === 'like'\">\n <h5>{{ 'chat.askLikeReasons' | transloco }}</h5>\n </ng-container>\n <textarea class=\"form-control border border-neutral-200\" [(ngModel)]=\"reportComment\" [placeholder]=\"'chat.writeComment' | transloco\"></textarea>\n <div class=\"d-flex flex-row-reverse gap-1 mt-2\">\n <button class=\"btn btn-primary\" [disabled]=\"type === 'dislike' && !issueType\" (click)=\"sendReport()\">{{ 'chat.send' | transloco }}</button>\n <button class=\"btn btn-light\" (click)=\"ignoreReport()\">{{ 'chat.doNotSend' | transloco }}</button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultTokenConsumptionTpl let-instanceId>\n <sq-token-progress-bar\n [instanceId]=\"instanceId\">\n </sq-token-progress-bar>\n</ng-template>\n\n<div class=\"debug-messages\" [class.displayed]=\"showDebugMessages\">\n <button *ngIf=\"showDebugMessages\" class=\"btn btn-light shadow back-btn\" (click)=\"showDebugMessages=false\" aria-label=\"Hide debug messages\">\n <i class=\"fas fa-chevron-right\"></i>\n </button>\n <ng-container *ngTemplateOutlet=\"debugMessagesTpl || defaultDebugMessagesTpl; context: { $implicit: debugMessages }\">\n </ng-container>\n</div>\n\n<ng-template #defaultDebugMessagesTpl let-debugMessages>\n <sq-debug-message [data]=\"debugMessages\"></sq-debug-message>\n</ng-template>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-uploaded-doc-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference,:host ::ng-deep .attachment .reference{position:relative;bottom:var(--ast-reference-bottom, .3em);font-weight:var(--ast-reference-font-weight, bold);padding:var(--ast-reference-padding, 0 .2em);margin:var(--ast-reference-margin, 0 .1em);border-radius:var(--ast-reference-border-radius, .2em);background-color:var(--ast-reference-background-color, lightblue);color:var(--ast-reference-color, black)}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference{font-size:var(--ast-reference-message-font-size, .7em)}:host ::ng-deep .attachment .reference{font-size:var(--ast-reference-attachment-font-size, 13px)}:host{font-size:.875rem}:host>div>.user-input>div:not(.progress),:host>div>.issue-report>div,:host>div>ul>li{width:var(--ast-chat-container-width, 100%);max-width:100%;margin-left:auto;margin-right:auto}:host>div>ul{padding-top:var(--ast-chat-padding-top, 0);padding-bottom:var(--ast-chat-padding-bottom, 0)}li.attachment>p{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;-webkit-line-clamp:3}li.attachment.expanded>p{display:block}.progress{--bs-progress-height: 3px}.progress.disabled{--bs-progress-height: 20px;--bs-progress-bar-bg: var(--bs-danger)}.user-input{z-index:1}.user-input ul.list-group{max-height:30vh}.form-control:disabled{background-color:#ededed}a.disabled{cursor:default;opacity:.5}.no-max-height{max-height:initial!important}.sq-floating-scroll{position:absolute;right:50%;text-align:center}.sq-floating-scroll--when-user-input{bottom:75px}.sq-floating-scroll--without-user-input{bottom:15px}.sq-floating-scroll .btn{background-color:#fff}.sq-floating-scroll .btn:hover{background-color:#fff;opacity:.9}.ast-input-container{display:flex;align-items:center;background-color:var(--ast-input-bg, #F8F8F8);border-radius:var(--ast-size-3, .75rem)}.ast-input-container>i{padding-left:var(--ast-size-3, .75rem);color:var(--ast-muted-color, rgba(33, 37, 41, .75))}.ast-input-container textarea{padding-left:var(--ast-size-3, .75rem);padding-right:var(--ast-size-3, .75rem);resize:none}.ast-input-container textarea,.ast-input-container button,.ast-input-container button:hover{background-color:transparent;border:0}.ast-input-container button:hover{color:var(--ast-primary-color, #005DA7)}.ast-input-container button:not(:hover){color:var(--ast-muted-color, rgba(33, 37, 41, .75))}.ast-input-container .processing{display:flex;align-items:center;color:var(--ast-secondary-color, #FF732E);gap:.5rem}sq-chat-message.sq-user-message{float:var(--ast-user-message-float, none)}sq-token-progress-bar{z-index:10;position:absolute;top:0;right:0}.debug-messages{position:fixed;z-index:999999;right:-60%;top:0;width:60%;height:100%;transition:all .5s ease;background-color:var(--bs-body-bg);overflow:auto}.debug-messages .back-btn{position:fixed;right:0%;transition:all .5s ease}.debug-messages.displayed{right:0}.debug-messages.displayed .back-btn{right:60%}.debug-messages sq-debug-message:first-of-type{display:block;width:100%}.btn.sq-retry{display:flex;margin:auto;background:var(--ast-error-bg, rgba(249, 58, 55, .2));font-weight:var(--font-weight-bold, 500)}.btn.sq-retry .attempts{display:flex;border-radius:100%;background:#fff;height:20px;width:20px;place-content:center;align-items:center}.issue-report{background-color:var(--ast-report-bg, white)}.text-end{text-align:right}.small{font-size:.875em}.text-muted{--bs-text-opacity: 1;color:var(--bs-secondary-color)}.d-flex{display:flex}.flex-row-reverse{flex-direction:row-reverse}.flex-grow-1{flex-grow:1}.spinner-grow,.spinner-border{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))}.d-block{display:block}.btn{--bs-border-radius: .25rem;--bs-btn-padding-x: .75rem;--bs-btn-padding-y: .375rem;--bs-btn-font-family: ;--bs-btn-font-size: 1rem;--bs-btn-font-weight: 400;--bs-btn-line-height: 1.5;--bs-btn-color: var(--bs-body-color);--bs-btn-bg: transparent;--bs-btn-border-width: var(--bs-border-width);--bs-btn-border-color: transparent;--bs-btn-border-radius: var(--bs-border-radius);--bs-btn-hover-border-color: transparent;--bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);--bs-btn-disabled-opacity: .65;--bs-btn-focus-box-shadow: 0 0 0 .25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.btn-primary{--bs-btn-color: #fff;--bs-btn-bg: #0d6efd;--bs-btn-border-color: #0d6efd;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #0b5ed7;--bs-btn-hover-border-color: #0a58ca;--bs-btn-focus-shadow-rgb: 49, 132, 253;--bs-btn-active-color: #fff;--bs-btn-active-bg: #0a58ca;--bs-btn-active-border-color: #0a53be;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #0d6efd;--bs-btn-disabled-border-color: #0d6efd}.btn-light{--bs-btn-color: #000;--bs-btn-bg: #f8f9fa;--bs-btn-border-color: #f8f9fa;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #d3d4d5;--bs-btn-hover-border-color: #c6c7c8;--bs-btn-focus-shadow-rgb: 211, 212, 213;--bs-btn-active-color: #000;--bs-btn-active-bg: #c6c7c8;--bs-btn-active-border-color: #babbbc;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #f8f9fa;--bs-btn-disabled-border-color: #f8f9fa}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control:disabled{background-color:var(--bs-body-bg)}.form-select{--bs-form-select-bg-img: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e\");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon, none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width, 1px) solid var(--bs-border-color, oklch(92.2% 0 0));border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ChatMessageComponent, selector: "sq-chat-message", inputs: ["id", "message", "conversation", "suggestedActions", "assistantMessageIcon", "userMessageIcon", "connectionErrorMessageIcon", "searchWarningMessageIcon", "streaming", "canEdit", "canRegenerate", "canCopy", "canDebug", "canLike", "canDislike", "collapseReferences"], outputs: ["openDocument", "openPreview", "suggestAction", "edit", "copy", "regenerate", "like", "dislike", "debug"] }, { kind: "component", type: TokenProgressBarComponent, selector: "sq-token-progress-bar", inputs: ["instanceId"] }, { kind: "component", type: DebugMessageComponent, selector: "sq-debug-message", inputs: ["data"] }, { kind: "directive", type: TooltipDirective, selector: "[sqTooltip]", inputs: ["sqTooltip", "sqTooltipData", "sqTooltipTemplate", "placement", "fallbackPlacements", "delay", "hoverableTooltip", "tooltipClass"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1046
- }
1047
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChatComponent, decorators: [{
1048
- type: Component,
1049
- args: [{ selector: 'sq-chat-v3', providers: [
1050
- ChatService,
1051
- AssistantConfigurationService,
1052
- AssistantTokensTrackingService,
1053
- SavedChatsService,
1054
- DebugMessageService,
1055
- provideTranslocoScope('chat')
1056
- ], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, FormsModule, ChatMessageComponent, TokenProgressBarComponent, DebugMessageComponent, TooltipDirective, TranslocoPipe], template: "<ng-container *ngIf=\"!initializationError\">\n <div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n <!-- Token consumption -->\n <div class=\"ms-1\" *ngIf=\"config?.globalSettings?.displayUserQuotaConsumption || config?.globalSettings?.displayChatTokensConsumption\">\n <ng-container *ngTemplateOutlet=\"tokenConsumptionTpl || defaultTokenConsumptionTpl; context: { $implicit: instanceId }\"></ng-container>\n </div>\n\n <!-- Chat Messages -->\n <ul class=\"d-flex flex-column list-unstyled gap-3 overflow-auto flex-grow-1 pe-2 pb-2\" #messageList [id]=\"'messageList-' + instanceId\">\n <ng-container *ngFor=\"let message of messages; let index = index; let last = last\">\n <!-- Regular messages -->\n <li class=\"list-group-item\"\n *ngIf=\"message.additionalProperties.display && !isEmptyAssistantMessage(message)\"\n [style.--bs-list-group-item-padding-y.rem]=\"'0.6'\"\n [class.opacity-50]=\"indexMessageToEdit && (indexMessageToEdit < (index + 1))\">\n <sq-chat-message\n [id]=\"message.additionalProperties.messageId\"\n [class.sq-user-message]=\"message.role === 'user'\"\n [class.last-message]=\"last\"\n [message]=\"message\"\n [conversation]=\"messages\"\n [suggestedActions]=\"last ? message.additionalProperties.$suggestedAction : undefined\"\n [assistantMessageIcon]=\"assistantMessageIcon\"\n [userMessageIcon]=\"userMessageIcon\"\n [connectionErrorMessageIcon]=\"connectionErrorMessageIcon\"\n [searchWarningMessageIcon]=\"searchWarningMessageIcon\"\n [streaming]=\"(chatService.streaming$ | async) && (last || isAssistantLastMessages(messages, index))\"\n [canEdit]=\"(chatService.streaming$ | async) === false && indexMessageToEdit === undefined && message.role === 'user'\"\n [canCopy]=\"((chatService.streaming$ | async) === false || !last) && indexMessageToEdit === undefined && message.role !== 'connection-error' && message.role !== 'search-warning'\"\n [canLike]=\"((chatService.streaming$ | async) === false || !last) && message.role === 'assistant'\"\n [canDislike]=\"((chatService.streaming$ | async) === false || !last) && message.role === 'assistant'\"\n [canDebug]=\"(((chatService.streaming$ | async) === false && last) || (!last && messages[index+1].role !== 'assistant')) && message.role === 'assistant' && (getDebugMessages(message, index).length > 0) && ((isAdminOrDeletedAdmin || (chatService.userOverride$ | async)) && config?.defaultValues.debug)\"\n [canRegenerate]=\"(chatService.streaming$ | async) === false && (last || (!last && messages[index+1].role !== 'assistant')) && message.role === 'assistant' && indexMessageToEdit === undefined\"\n [collapseReferences]=\"!!config?.globalSettings.collapseReferences\"\n (edit)=\"editMessage(message, index)\"\n (copy)=\"copyMessage(message, index)\"\n (regenerate)=\"regenerateMessage(message, index)\"\n (openDocument)=\"openOriginalAttachment($event, message, index)\"\n (openPreview)=\"openAttachmentPreview($event, message, index)\"\n (suggestAction)=\"suggestActionClick($event, index)\"\n (like)=\"onLike(message, index)\"\n (dislike)=\"onDislike(message, index)\"\n (debug)=\"showDebug(message, index)\">\n </sq-chat-message>\n </li>\n </ng-container>\n <!-- Loading spinner -->\n <li *ngIf=\"(loading$ | async) === true\">\n <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n </li>\n </ul>\n\n <!-- Reporting a feedback form -->\n <div class=\"issue-report p-3 rounded-lg\" *ngIf=\"showReport\">\n <ng-container *ngTemplateOutlet=\"reportTpl || reportTplDefault; context: { $implicit: messageToReport, rank: reportRank, type: reportType }\"></ng-container>\n </div>\n\n <!-- User text input -->\n @if (!showReport) {\n <div class=\"user-input mt-auto\">\n <div class=\"py-2\">\n <div [hidden]=\"!isConnected\">\n <ng-container *ngIf=\"enabledUserInput\" [ngTemplateOutlet]=\"inputTpl\"></ng-container>\n </div>\n <!-- Retry button -->\n <!-- hidden attribute is in conflict with a css rule display: flex -->\n @if(!isConnected){\n <button class=\"btn mb-4 ast-error ast-btn sq-retry\" (click)=\"retryFetch()\">\n <span>{{ 'chat.tryAgain' | transloco }}</span>\n <span *ngIf=\"retrialAttempts\" class=\"ms-2 attempts\">{{ retrialAttempts }}</span>\n </button>\n }\n <div class=\"text-end small text-muted px-3\" *ngIf=\"!!config?.globalSettings?.disclaimer\">\n {{ config?.globalSettings?.disclaimer | transloco }}\n </div>\n </div>\n </div>\n }\n\n <!-- Floating scroll button -->\n <div *ngIf=\"!isAtBottom && !showReport\" class=\"sq-floating-scroll\" [ngClass]=\"enabledUserInput ? 'sq-floating-scroll--when-user-input' : 'sq-floating-scroll--without-user-input'\">\n <button class=\"btn shadow\" (click)=\"scrollDown()\" aria-label=\"Scroll down\">\n <i class=\"fas fa-angle-double-down\"></i>\n </button>\n </div>\n </div>\n</ng-container>\n\n<!-- NG TEMPLATES-->\n\n<ng-template #loadingTplDefault>\n <div class=\"spinner-grow text-primary d-block mx-auto my-5\" role=\"status\">\n <span class=\"visually-hidden\">{{ 'chat.loading' | transloco }}</span>\n </div>\n</ng-template>\n\n<ng-template #inputTpl>\n <div class=\"px-3 py-1\">\n <div class=\"ast-input-container\">\n <button disabled class=\"btn btn-light\" aria-label=\"search\">\n <i class=\"fas fa-search\"></i>\n </button>\n <textarea #questionInput rows=\"1\"\n type=\"text\" class=\"form-control\"\n [placeholder]=\"'chat.askSomething' | transloco\" autofocus\n [(ngModel)]=\"question\"\n (keyup)=\"onKeyUp($event)\"\n (keydown)=\"calculateHeight($event)\"\n [disabled]=\"(loading$ | async) || (chatService.streaming$ | async) || (chatService.stoppingGeneration$ | async)\">\n </textarea>\n <div id=\"chat-actions\" class=\"d-flex gap-2\">\n <button\n *ngIf=\"(chatService.streaming$ | async) === false && (loading$ | async) !== true && (chatService.stoppingGeneration$ | async) === false\"\n type=\"button\"\n class=\"btn btn-light\"\n aria-label=\"Send message\"\n [sqTooltip]=\"'chat.sendMessage' | transloco\"\n (click)=\"submitQuestion()\">\n <i class=\"fas fa-paper-plane\"></i>\n </button>\n <button\n *ngIf=\"indexMessageToEdit\"\n aria-label=\"Cancel edition\"\n type=\"button\"\n class=\"btn btn-light\"\n [sqTooltip]=\"'chat.cancelEdition' | transloco\"\n (click)=\"indexMessageToEdit = undefined; question = ''\">\n <i class=\"fas fa-undo-alt\"></i>\n </button>\n <span *ngIf=\"(chatService.streaming$ | async) && (chatService.stoppingGeneration$ | async) === false\" class=\"processing\">\n {{ 'chat.generating' | transloco }}<i class=\"fas fa-spinner fa-pulse\"></i>\n </span>\n <span *ngIf=\"(chatService.stoppingGeneration$ | async)\" class=\"processing\">\n {{ 'chat.stopping' | transloco }}<i class=\"fas fa-spinner fa-pulse\"></i>\n </span>\n <button\n *ngIf=\"(chatService.streaming$ | async) && (chatService.stoppingGeneration$ | async) === false\"\n type=\"button\"\n class=\"btn btn-light\"\n aria-label=\"Stop generating\"\n [sqTooltip]=\"'chat.stopGeneration' | transloco\"\n (click)=\"stopGeneration()\">\n <i class=\"fas fa-stop\"></i>\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #reportTplDefault let-message let-rank=\"rank\" let-type=\"type\">\n <div class=\"px-3\">\n <ng-container *ngIf=\"type === 'dislike'\">\n <h5>{{ 'chat.issueType' | transloco }}</h5>\n <select class=\"form-select mb-4\" [(ngModel)]=\"issueType\">\n <option [value]=\"''\">{{ 'chat.chooseIssueType' | transloco }}</option>\n <option *ngFor=\"let type of (issueTypes ?? defaultIssueTypes)\" [value]=\"type\">{{ type | transloco }}</option>\n </select>\n <h5>{{ 'chat.askUnlikeReasons' | transloco }}</h5>\n </ng-container>\n <ng-container *ngIf=\"type === 'like'\">\n <h5>{{ 'chat.askLikeReasons' | transloco }}</h5>\n </ng-container>\n <textarea class=\"form-control border border-neutral-200\" [(ngModel)]=\"reportComment\" [placeholder]=\"'chat.writeComment' | transloco\"></textarea>\n <div class=\"d-flex flex-row-reverse gap-1 mt-2\">\n <button class=\"btn btn-primary\" [disabled]=\"type === 'dislike' && !issueType\" (click)=\"sendReport()\">{{ 'chat.send' | transloco }}</button>\n <button class=\"btn btn-light\" (click)=\"ignoreReport()\">{{ 'chat.doNotSend' | transloco }}</button>\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultTokenConsumptionTpl let-instanceId>\n <sq-token-progress-bar\n [instanceId]=\"instanceId\">\n </sq-token-progress-bar>\n</ng-template>\n\n<div class=\"debug-messages\" [class.displayed]=\"showDebugMessages\">\n <button *ngIf=\"showDebugMessages\" class=\"btn btn-light shadow back-btn\" (click)=\"showDebugMessages=false\" aria-label=\"Hide debug messages\">\n <i class=\"fas fa-chevron-right\"></i>\n </button>\n <ng-container *ngTemplateOutlet=\"debugMessagesTpl || defaultDebugMessagesTpl; context: { $implicit: debugMessages }\">\n </ng-container>\n</div>\n\n<ng-template #defaultDebugMessagesTpl let-debugMessages>\n <sq-debug-message [data]=\"debugMessages\"></sq-debug-message>\n</ng-template>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-uploaded-doc-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference,:host ::ng-deep .attachment .reference{position:relative;bottom:var(--ast-reference-bottom, .3em);font-weight:var(--ast-reference-font-weight, bold);padding:var(--ast-reference-padding, 0 .2em);margin:var(--ast-reference-margin, 0 .1em);border-radius:var(--ast-reference-border-radius, .2em);background-color:var(--ast-reference-background-color, lightblue);color:var(--ast-reference-color, black)}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference{font-size:var(--ast-reference-message-font-size, .7em)}:host ::ng-deep .attachment .reference{font-size:var(--ast-reference-attachment-font-size, 13px)}:host{font-size:.875rem}:host>div>.user-input>div:not(.progress),:host>div>.issue-report>div,:host>div>ul>li{width:var(--ast-chat-container-width, 100%);max-width:100%;margin-left:auto;margin-right:auto}:host>div>ul{padding-top:var(--ast-chat-padding-top, 0);padding-bottom:var(--ast-chat-padding-bottom, 0)}li.attachment>p{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;-webkit-line-clamp:3}li.attachment.expanded>p{display:block}.progress{--bs-progress-height: 3px}.progress.disabled{--bs-progress-height: 20px;--bs-progress-bar-bg: var(--bs-danger)}.user-input{z-index:1}.user-input ul.list-group{max-height:30vh}.form-control:disabled{background-color:#ededed}a.disabled{cursor:default;opacity:.5}.no-max-height{max-height:initial!important}.sq-floating-scroll{position:absolute;right:50%;text-align:center}.sq-floating-scroll--when-user-input{bottom:75px}.sq-floating-scroll--without-user-input{bottom:15px}.sq-floating-scroll .btn{background-color:#fff}.sq-floating-scroll .btn:hover{background-color:#fff;opacity:.9}.ast-input-container{display:flex;align-items:center;background-color:var(--ast-input-bg, #F8F8F8);border-radius:var(--ast-size-3, .75rem)}.ast-input-container>i{padding-left:var(--ast-size-3, .75rem);color:var(--ast-muted-color, rgba(33, 37, 41, .75))}.ast-input-container textarea{padding-left:var(--ast-size-3, .75rem);padding-right:var(--ast-size-3, .75rem);resize:none}.ast-input-container textarea,.ast-input-container button,.ast-input-container button:hover{background-color:transparent;border:0}.ast-input-container button:hover{color:var(--ast-primary-color, #005DA7)}.ast-input-container button:not(:hover){color:var(--ast-muted-color, rgba(33, 37, 41, .75))}.ast-input-container .processing{display:flex;align-items:center;color:var(--ast-secondary-color, #FF732E);gap:.5rem}sq-chat-message.sq-user-message{float:var(--ast-user-message-float, none)}sq-token-progress-bar{z-index:10;position:absolute;top:0;right:0}.debug-messages{position:fixed;z-index:999999;right:-60%;top:0;width:60%;height:100%;transition:all .5s ease;background-color:var(--bs-body-bg);overflow:auto}.debug-messages .back-btn{position:fixed;right:0%;transition:all .5s ease}.debug-messages.displayed{right:0}.debug-messages.displayed .back-btn{right:60%}.debug-messages sq-debug-message:first-of-type{display:block;width:100%}.btn.sq-retry{display:flex;margin:auto;background:var(--ast-error-bg, rgba(249, 58, 55, .2));font-weight:var(--font-weight-bold, 500)}.btn.sq-retry .attempts{display:flex;border-radius:100%;background:#fff;height:20px;width:20px;place-content:center;align-items:center}.issue-report{background-color:var(--ast-report-bg, white)}.text-end{text-align:right}.small{font-size:.875em}.text-muted{--bs-text-opacity: 1;color:var(--bs-secondary-color)}.d-flex{display:flex}.flex-row-reverse{flex-direction:row-reverse}.flex-grow-1{flex-grow:1}.spinner-grow,.spinner-border{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))}.d-block{display:block}.btn{--bs-border-radius: .25rem;--bs-btn-padding-x: .75rem;--bs-btn-padding-y: .375rem;--bs-btn-font-family: ;--bs-btn-font-size: 1rem;--bs-btn-font-weight: 400;--bs-btn-line-height: 1.5;--bs-btn-color: var(--bs-body-color);--bs-btn-bg: transparent;--bs-btn-border-width: var(--bs-border-width);--bs-btn-border-color: transparent;--bs-btn-border-radius: var(--bs-border-radius);--bs-btn-hover-border-color: transparent;--bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);--bs-btn-disabled-opacity: .65;--bs-btn-focus-box-shadow: 0 0 0 .25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.btn-primary{--bs-btn-color: #fff;--bs-btn-bg: #0d6efd;--bs-btn-border-color: #0d6efd;--bs-btn-hover-color: #fff;--bs-btn-hover-bg: #0b5ed7;--bs-btn-hover-border-color: #0a58ca;--bs-btn-focus-shadow-rgb: 49, 132, 253;--bs-btn-active-color: #fff;--bs-btn-active-bg: #0a58ca;--bs-btn-active-border-color: #0a53be;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color: #fff;--bs-btn-disabled-bg: #0d6efd;--bs-btn-disabled-border-color: #0d6efd}.btn-light{--bs-btn-color: #000;--bs-btn-bg: #f8f9fa;--bs-btn-border-color: #f8f9fa;--bs-btn-hover-color: #000;--bs-btn-hover-bg: #d3d4d5;--bs-btn-hover-border-color: #c6c7c8;--bs-btn-focus-shadow-rgb: 211, 212, 213;--bs-btn-active-color: #000;--bs-btn-active-bg: #c6c7c8;--bs-btn-active-border-color: #babbbc;--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);--bs-btn-disabled-color: #000;--bs-btn-disabled-bg: #f8f9fa;--bs-btn-disabled-border-color: #f8f9fa}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control:disabled{background-color:var(--bs-body-bg)}.form-select{--bs-form-select-bg-img: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e\");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon, none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width, 1px) solid var(--bs-border-color, oklch(92.2% 0 0));border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}\n"] }]
1057
- }], ctorParameters: () => [], propDecorators: { instanceId: [{
1058
- type: Input
1059
- }], query: [{
1060
- type: Input
1061
- }], queryChangeShouldTriggerReload: [{
1062
- type: Input
1063
- }], messageHandlers: [{
1064
- type: Input
1065
- }], automaticScrollToLastResponse: [{
1066
- type: Input
1067
- }], focusAfterResponse: [{
1068
- type: Input
1069
- }], chat: [{
1070
- type: Input
1071
- }], assistantMessageIcon: [{
1072
- type: Input
1073
- }], userMessageIcon: [{
1074
- type: Input
1075
- }], connectionErrorMessageIcon: [{
1076
- type: Input
1077
- }], searchWarningMessageIcon: [{
1078
- type: Input
1079
- }], additionalWorkflowProperties: [{
1080
- type: Input
1081
- }], appConfig: [{
1082
- type: Input
1083
- }], connection: [{
1084
- type: Output
1085
- }], loading$: [{
1086
- type: Output,
1087
- args: ["loading"]
1088
- }], _config: [{
1089
- type: Output,
1090
- args: ["config"]
1091
- }], data: [{
1092
- type: Output
1093
- }], openDocument: [{
1094
- type: Output
1095
- }], openPreview: [{
1096
- type: Output
1097
- }], suggestAction: [{
1098
- type: Output
1099
- }], questionInput: [{
1100
- type: ViewChild,
1101
- args: ['questionInput']
1102
- }], loadingTpl: [{
1103
- type: ContentChild,
1104
- args: ['loadingTpl']
1105
- }], reportTpl: [{
1106
- type: ContentChild,
1107
- args: ['reportTpl']
1108
- }], tokenConsumptionTpl: [{
1109
- type: ContentChild,
1110
- args: ['tokenConsumptionTpl']
1111
- }], debugMessagesTpl: [{
1112
- type: ContentChild,
1113
- args: ['debugMessagesTpl']
1114
- }] } });
1115
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hc3Npc3RhbnQvY2hhdC9jaGF0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL3Byb2plY3RzL2Fzc2lzdGFudC9jaGF0L2NoYXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBYyxZQUFZLEVBQUUsS0FBSyxFQUFnQyxNQUFNLEVBQThCLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdE8sT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxhQUFhLEVBQUUsZ0JBQWdCLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM1RixPQUFPLEVBQWlCLGtCQUFrQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDdkUsT0FBTyxFQUFFLGVBQWUsRUFBZ0IsYUFBYSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN4SCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUVoRSxPQUFPLEVBQW1DLElBQUksRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFMUcsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDN0UsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3BFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMxRCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxtREFBbUQsQ0FBQztBQUM5RixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUcvRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDdkQsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDM0YsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDOUYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7Ozs7QUFrQjVFLE1BQU0sT0FBTyxhQUFhO0lBZ0h4QjtRQTlHTyxnQkFBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNsQywyQkFBc0IsR0FBRyxNQUFNLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUN4RCxrQkFBYSxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN0QyxxQkFBZ0IsR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUM1QyxRQUFHLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDaEMseUJBQW9CLEdBQUcsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDMUMsY0FBUyxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3JDLG1CQUFjLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2pELGVBQVUsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7UUFJeEMsK0NBQStDO1FBQ3RDLFVBQUssR0FBVSxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQztRQVFqRCx5REFBeUQ7UUFDaEQsb0JBQWUsR0FBcUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUN2RSwyR0FBMkc7UUFDbEcsa0NBQTZCLEdBQUcsS0FBSyxDQUFDO1FBQy9DLHVGQUF1RjtRQUM5RSx1QkFBa0IsR0FBRyxLQUFLLENBQUM7UUFHcEMsNkNBQTZDO1FBQ3BDLHlCQUFvQixHQUFHLFlBQVksQ0FBQztRQU83QyxvRUFBb0U7UUFDM0QsaUNBQTRCLEdBQXdCLEVBQUUsQ0FBQztRQUdoRSwwRUFBMEU7UUFDaEUsZUFBVSxHQUFHLElBQUksWUFBWSxFQUFpQixDQUFDO1FBQ3pELCtFQUErRTtRQUMvRSxtRUFBbUU7UUFDaEQsYUFBUSxHQUFHLElBQUksWUFBWSxDQUFVLEtBQUssQ0FBQyxDQUFDO1FBQy9ELDhFQUE4RTtRQUM1RCxZQUFPLEdBQUcsSUFBSSxZQUFZLEVBQWMsQ0FBQztRQUNqRCxTQUFJLEdBQUcsSUFBSSxZQUFZLEVBQWlCLENBQUM7UUFDbkQsb0hBQW9IO1FBQzFHLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQztRQUNyRCx5SEFBeUg7UUFDL0csZ0JBQVcsR0FBRyxJQUFJLFlBQVksRUFBeUIsQ0FBQztRQUNsRSx5RUFBeUU7UUFDL0Qsa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBbUIsQ0FBQztRQVU5RCxjQUFTLEdBQUcsSUFBSSxlQUFlLENBQTRCLFNBQVMsQ0FBQyxDQUFDO1FBQ3RFLDBCQUFxQixHQUFHLEtBQUssQ0FBQztRQUM5QixhQUFRLEdBQUcsRUFBRSxDQUFDO1FBU2QsYUFBUSxHQUFHLElBQUksZUFBZSxDQUE0QixTQUFTLENBQUMsQ0FBQztRQUVyRSx3QkFBbUIsR0FBRyxLQUFLLENBQUM7UUFDNUIsZUFBVSxHQUFHLElBQUksQ0FBQztRQUNsQix3QkFBbUIsR0FBRyxLQUFLLENBQUM7UUFDNUIscUJBQWdCLEdBQUcsS0FBSyxDQUFDO1FBQ3pCLGdCQUFXLEdBQUcsSUFBSSxDQUFDLENBQUMsK0NBQStDO1FBRW5FLHlFQUF5RTtRQUNqRSxxQ0FBZ0MsR0FBRyxLQUFLLENBQUM7UUFJakQsc0JBQWlCLEdBQWE7WUFDNUIsdUJBQXVCO1lBQ3ZCLHdCQUF3QjtZQUN4Qix5QkFBeUI7WUFDekIscUJBQXFCO1lBQ3JCLCtCQUErQjtZQUMvQixpQkFBaUI7U0FDbEIsQ0FBQztRQUNGLGNBQVMsR0FBVyxFQUFFLENBQUM7UUFJdkIsZUFBVSxHQUF1QixTQUFTLENBQUM7UUFDM0MsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUluQixzQkFBaUIsR0FBRyxLQUFLLENBQUM7UUFHbEIsd0JBQW1CLEdBQTZCLFNBQVMsQ0FBQztRQUdoRSxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxLQUFLLElBQUksRUFBRTtZQUNuQyxPQUFPLENBQUMsR0FBRyxDQUFDLDZCQUE2QixJQUFJLENBQUMsVUFBVSwrQkFBK0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLGdDQUFnQyxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQ25NLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsS0FBSyxLQUFLLGtCQUFrQixDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEtBQUssa0JBQWtCLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ25MLElBQUksQ0FBQztvQkFDSCxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUE7Z0JBQ3pDLENBQUM7Z0JBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztvQkFDZixPQUFPLENBQUMsS0FBSyxDQUFDLGtEQUFrRCxJQUFJLENBQUMsVUFBVSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQzVGLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ25CLGVBQWUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbEMsQ0FBQztRQUVELEVBQUUsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FDeEIsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUNuQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxFQUN2QyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQ3ZDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUNuRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDTixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ2xELElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNwQixDQUFDLENBQUMsRUFDRixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksRUFBRSxDQUFDLEVBQ3pDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLEVBQzlDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsRUFDakQsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ1gsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFVLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFVLENBQUMsZ0JBQWdCLElBQUksS0FBSyxDQUFDO1lBQzVJLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTyxDQUFDO1lBQ3RCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQztZQUNsRSxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ3BILElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzFCLElBQUksQ0FBQztnQkFDSCxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztnQkFDOUIsSUFBRyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO29CQUM3QixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLGdDQUFnQztvQkFDOUYsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO29CQUN0QixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztvQkFDMUIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQztnQkFDbEMsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUE7Z0JBQy9CLE1BQU0sS0FBSyxDQUFDO1lBQ2QsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUNILENBQUMsU0FBUyxFQUFFLENBQUM7UUFFZCx3R0FBd0c7UUFDeEcsZ0JBQWdCLENBQUMsZUFBZSxFQUFFLENBQUMsS0FBVSxFQUFFLEVBQUU7WUFDL0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNoRCxDQUFDLENBQUMsQ0FBQztRQUNILGdCQUFnQixDQUFDLGdCQUFnQixFQUFFLENBQUMsS0FBVSxFQUFFLEVBQUU7WUFDaEQsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzVCLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2hCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN4QixDQUFDO0lBQ0gsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLENBQUM7UUFDdEMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxDQUFDO0lBQzFDLENBQUM7SUFFRCxJQUFJLE9BQU87UUFDVCxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsZUFBZSxJQUFJLEtBQUssQ0FBQztJQUNuRSxDQUFDO0lBRUQ7O09BRUc7SUFDSCxzQkFBc0I7UUFDcEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLHNCQUFzQixDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUMvRSxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNLLGNBQWM7UUFDcEIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFDcEMsdUdBQXVHO1FBQ3ZHLElBQUksT0FBTyxFQUFFLGVBQWUsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDckQsSUFBSSxDQUFDLFdBQVcsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDakUsQ0FBQztRQUNEOzs7V0FHRztRQUNILElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLElBQUksT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDO1lBQy9DLE1BQU0sUUFBUSxHQUFHLEdBQUcsRUFBRTtnQkFDcEIsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixFQUFFLE9BQU8sRUFBRSxDQUFDO29CQUNuRSxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsa0NBQWtDO2dCQUN0RSxDQUFDO2dCQUNELElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNyQyxDQUFDLENBQUM7WUFDRixJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ2xDLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNkLElBQUksQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMsY0FBYyxFQUFFLEVBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsRUFBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUMsQ0FBQyxDQUFDO2dCQUN2SyxRQUFRLEVBQUUsQ0FBQztZQUNiLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLGNBQWMsRUFBRSxFQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLEVBQUMsQ0FBQyxDQUFDO2dCQUNoSSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDekIsQ0FBQztRQUNILENBQUM7UUFDRDs7OztXQUlHO1FBQ0gsSUFBSSxJQUFJLENBQUMsbUJBQW1CLElBQUksT0FBTyxFQUFFLEtBQUssSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUMsS0FBSyxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQzVHLElBQUksSUFBSSxDQUFDLDhCQUE4QixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN0SCxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLG1CQUFtQixDQUFDLEtBQUssRUFBRSxDQUFDO29CQUNqRCxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7d0JBQzlCLHdGQUF3Rjt3QkFDeEYsSUFBSSxDQUFDLG1CQUFtQixHQUFHLGFBQWEsQ0FBQzs0QkFDdkMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVOzRCQUMzQixJQUFJLENBQUMsV0FBVyxDQUFDLG1CQUFtQjt5QkFDckMsQ0FBQzs2QkFDQyxJQUFJLENBQ0gsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsU0FBUyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsNEJBQTRCO3dCQUN4RixJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsaUNBQWlDO3lCQUMxQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7NEJBQ2YsNENBQTRDOzRCQUM1QyxJQUFJLENBQUMsOEJBQThCLEVBQUUsQ0FBQzs0QkFDdEMsK0NBQStDOzRCQUMvQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQzs0QkFDN0QsNENBQTRDOzRCQUM1QyxJQUFJLENBQUMsbUJBQW9CLENBQUMsV0FBVyxFQUFFLENBQUM7NEJBQ3hDLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxTQUFTLENBQUM7d0JBQ3ZDLENBQUMsQ0FBQyxDQUFDO29CQUNQLENBQUM7Z0JBQ0gsQ0FBQztxQkFBTSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDL0MsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO3dCQUM5QixJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUU7NkJBQ3pELFNBQVMsQ0FBQzs0QkFDVCxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUUsQ0FBQzs0QkFDZCxLQUFLLEVBQUUsR0FBRyxFQUFFO2dDQUNWLDRDQUE0QztnQ0FDNUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLFdBQVcsRUFBRSxDQUFDO2dDQUN4QyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsU0FBUyxDQUFDOzRCQUN2QyxDQUFDOzRCQUNELFFBQVEsRUFBRSxHQUFHLEVBQUU7Z0NBQ2Isa0VBQWtFO2dDQUNsRSxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQzlCLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsRUFDakMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUNSLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtvQ0FDZiw0Q0FBNEM7b0NBQzVDLElBQUksQ0FBQyw4QkFBOEIsRUFBRSxDQUFDO29DQUN0QywrQ0FBK0M7b0NBQy9DLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO29DQUM3RCw0Q0FBNEM7b0NBQzVDLElBQUksQ0FBQyxtQkFBb0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztvQ0FDeEMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLFNBQVMsQ0FBQztnQ0FDdkMsQ0FBQyxDQUFDLENBQUM7NEJBQ0wsQ0FBQzt5QkFDRixDQUFDLENBQUM7b0JBQ1AsQ0FBQztnQkFDSCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sNENBQTRDO29CQUM1QyxJQUFJLENBQUMsOEJBQThCLEVBQUUsQ0FBQztvQkFDdEMsK0NBQStDO29CQUMvQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDL0QsQ0FBQztZQUNILENBQUM7aUJBQU0sQ0FBQztnQkFDTiwrQ0FBK0M7Z0JBQy9DLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQy9ELENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssOEJBQThCO1FBQ3BDLE1BQU0sU0FBUyxHQUFHLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLG9CQUFvQixFQUFFLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQ25KLHNEQUFzRDtRQUN0RCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzVGLE1BQU0sT0FBTyxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsY0FBYyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsRUFBRyxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRSxvQkFBb0IsRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQ2hRLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyx3QkFBd0I7UUFDM0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxjQUFjLEVBQUUsRUFBQyxlQUFlLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxFQUFDLENBQUMsQ0FBQyxDQUFDLGtDQUFrQztRQUNuSyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSyxrQkFBa0I7UUFDeEIsTUFBTSxXQUFXLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxlQUFlLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO1FBQzlFLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLFdBQVksRUFBRSxRQUFRLENBQUMsQ0FBQzthQUNuRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQ3pDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDZCxVQUFVLENBQUMsR0FBRyxFQUFFO2dCQUNkLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLDZCQUE2QixFQUFFLENBQUM7Z0JBQ3ZELElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDM0IsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNILHNCQUFzQjtRQUNwQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzVILElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILGNBQWM7UUFDWixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDeEYsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNqRixvSUFBb0k7WUFDcEksSUFBSSxJQUFJLENBQUMsa0JBQWtCLEtBQUssU0FBUyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDbEYsZ0NBQWdDO2dCQUNoQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7Z0JBQzVFLHVHQUF1RztnQkFDdkcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsaUJBQWlCLEdBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQy9GLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxTQUFTLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxTQUFTLENBQUM7WUFDckMsQ0FBQztZQUNELDhDQUE4QztZQUM5QyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksS0FBSyxnQkFBZ0IsRUFBRSxDQUFDO2dCQUNuRSxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNyQyxDQUFDO1lBQ0QsbUJBQW1CO1lBQ25CLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ3RFLGtDQUFrQztZQUNsQyxJQUFJLENBQUMsYUFBYyxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO1lBQzdDLElBQUksQ0FBQyxhQUFjLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQzFELENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ssWUFBWSxDQUFDLFFBQWdCLEVBQUUsWUFBMkI7UUFDaEUsd0ZBQXdGO1FBQ3hGLE1BQU0sNEJBQTRCLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsNEJBQTRCLEVBQUUsR0FBRyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQztRQUMzSCxNQUFNLE9BQU8sR0FBRyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxvQkFBb0IsRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsNEJBQTRCLEVBQUUsRUFBRSxDQUFDO1FBQ2pLLE1BQU0sUUFBUSxHQUFHLENBQUMsR0FBRyxZQUFZLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQywwREFBMEQ7UUFDekYsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDLENBQUMsb0RBQW9EO1FBQzdGLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLHNHQUFzRztRQUN6SCxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMscUJBQXFCLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxPQUFPLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxtQkFBbUIsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxnQ0FBZ0MsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLDRCQUE0QixDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3pXLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxLQUFLLENBQUMsUUFBdUI7UUFDbEMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLG1CQUFtQixDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3hGLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUV6QixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6QixJQUFJLENBQUMsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDO2lCQUNsRSxTQUFTLENBQUM7Z0JBQ1QsSUFBSSxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDO2dCQUN6QyxLQUFLLEVBQUUsR0FBRyxFQUFFO29CQUNWLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO29CQUMvQixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO3dCQUN0QixNQUFNLE9BQU8sR0FBRzs0QkFDZCxJQUFJLEVBQUUsa0JBQWtCOzRCQUN4QixPQUFPLEVBQUcsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLHNCQUFzQixDQUFDLEVBQXlCOzRCQUN4SSxvQkFBb0IsRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxFQUFFO3lCQUNyQyxDQUFDO3dCQUN4QixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7b0JBQzlDLENBQUM7b0JBQ0QsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN4QixDQUFDO2dCQUNELFFBQVEsRUFBRSxHQUFHLEVBQUU7b0JBQ2IsbURBQW1EO29CQUNuRCxtRkFBbUY7b0JBQ25GLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNqRCxJQUFJLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO3dCQUM5QyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDMUQsQ0FBQztvQkFDRCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ3hCLENBQUM7YUFDRixDQUFDLENBQUM7UUFDUCxDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sT0FBTyxHQUFHLEVBQUUsSUFBSSxFQUFFLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLHNCQUFzQixDQUFDLEVBQUUsb0JBQW9CLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUM7WUFDbk0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQzlDLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyw2QkFBNkIsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNyRixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDcEIsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxVQUFVO1FBQ1IsNENBQTRDO1FBQzVDLE1BQU0sb0JBQW9CLEdBQUcsR0FBRyxFQUFFO1lBQ2hDLHVFQUF1RTtZQUN2RSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEQsb0RBQW9EO1lBQ3BELElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1lBQ2hDLE9BQU8sS0FBSyxJQUFJLENBQUMsSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxLQUFLLE1BQU0sRUFBRSxDQUFDO2dCQUNyRCxLQUFLLEVBQUUsQ0FBQztZQUNWLENBQUM7WUFDRCxzSEFBc0g7WUFDdEgsZ0NBQWdDO1lBQ2hDLDBDQUEwQztZQUMxQyxJQUFJLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDZixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUMvRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDcEosSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxhQUFhLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ3pGLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUMzQyxDQUFDO1lBQ0QsSUFBSSxDQUFDLGVBQWUsR0FBRyxTQUFTLENBQUMsQ0FBQyx1Q0FBdUM7WUFDekU7OztlQUdHO1lBQ0gsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFXLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3JELHVFQUF1RTtZQUN2RSxJQUFJLENBQUMsZ0NBQWdDLEdBQUcsS0FBSyxDQUFDO1FBQ2hELENBQUMsQ0FBQTtRQUNELG1FQUFtRTtRQUNuRSxRQUFRLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzNDLEtBQUssa0JBQWtCLENBQUMsU0FBUztnQkFDL0IsMEVBQTBFO2dCQUMxRSxvQkFBb0IsRUFBRSxDQUFDO2dCQUN2QixNQUFNO1lBQ1IsS0FBSyxrQkFBa0IsQ0FBQyxZQUFZO2dCQUNsQyw0REFBNEQ7Z0JBQzVELElBQUksQ0FBQyxJQUFJLENBQUMsZ0NBQWdDLEVBQUUsQ0FBQztvQkFDM0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFXLENBQUMsYUFBYSxDQUFDLG9CQUFvQixDQUFDLENBQUM7b0JBQ2pFLElBQUksQ0FBQyxnQ0FBZ0MsR0FBRyxJQUFJLENBQUM7Z0JBQy9DLENBQUM7Z0JBQ0QsMENBQTBDO2dCQUMxQyxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNFLE1BQU07WUFDUixLQUFLLGtCQUFrQixDQUFDLFlBQVk7Z0JBQ2xDLDJCQUEyQjtnQkFDM0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUU7cUJBQy9CLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO3FCQUNsQyxLQUFLLENBQUMsR0FBRyxFQUFFO29CQUNWLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDN0UsQ0FBQyxDQUFDLENBQUM7Z0JBQ0wsTUFBTTtZQUNSO2dCQUNFLE1BQU07UUFDVixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNLLHVCQUF1QjtRQUM3QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVyxDQUFDLEtBQUssS0FBSyxrQkFBa0IsQ0FBQyxTQUFTLENBQUM7SUFDekYsQ0FBQztJQUVEOzs7T0FHRztJQUNILFVBQVUsQ0FBQyxRQUF1QjtRQUNoQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM5QixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQztRQUNuQixJQUFJLElBQUksQ0FBQyw2QkFBNkIsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNyRixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDcEIsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNLLDZCQUE2QjtRQUNuQyxNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLGVBQWUsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7UUFDOUUsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNoQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxJQUFJLFdBQVcsQ0FBQyxZQUFZLENBQUM7UUFDdEcsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOztPQUVHO0lBQ0gsVUFBVTtRQUNSLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLGVBQWUsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7WUFDOUUsSUFBSSxXQUFXLEVBQUUsQ0FBQztnQkFDaEIsV0FBVyxDQUFDLFNBQVMsR0FBRyxXQUFXLENBQUMsWUFBWSxDQUFDO2dCQUNqRCxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzNCLENBQUM7UUFDSCxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDVCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxPQUFPO1FBQ0wsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLG1CQUFtQixDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3hGLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLHdCQUF3QjtRQUMzRCxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDM0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLGtDQUFrQztRQUN0RSxDQUFDO1FBQ0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxjQUFjLEVBQUUsRUFBQyxlQUFlLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxFQUFDLENBQUMsQ0FBQyxDQUFDLGtDQUFrQztRQUNuSyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQyxtQkFBbUI7SUFDN0MsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILFlBQVksQ0FBQyxHQUFhO1FBQ3hCLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN4RixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxHQUFHLElBQUksR0FBRyxFQUFFLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM1QixPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDOUUsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3JCLE9BQU8sQ0FBQyxLQUFLLENBQUMsbUVBQW1FLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO1lBQ3JHLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsb0JBQW9CLEVBQUUsRUFBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFFLGVBQWUsQ0FBQyxjQUFjLEVBQUUsd0JBQXdCLEVBQUUsRUFBQyxHQUFHLENBQUMsZUFBZSxDQUFDLHdCQUF3QixJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBQyxFQUFFLDRCQUE0QixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsNEJBQTRCLEVBQUMsRUFBQyxDQUFDO1FBQzFWLDhDQUE4QztRQUM5QyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksS0FBSyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3BFLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBWSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3RDLENBQUM7UUFDRCxNQUFNLFFBQVEsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFZLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDN0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNyQixJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLHNCQUFzQixFQUFFO1lBQzFELFFBQVEsRUFBRSxpQkFBaUI7WUFDM0IsaUJBQWlCLEVBQUUscUNBQXFDO1lBQ3hELDRCQUE0QixFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDO1NBQ2xELENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7O09BR0c7SUFDSCxlQUFlO1FBQ2IsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZILDREQUE0RDtRQUM1RCxNQUFNLFNBQVMsR0FBRztZQUNoQixJQUFJLEVBQUUsUUFBUTtZQUNkLE9BQU8sRUFBRSxjQUFjLENBQUMsWUFBWSxDQUNsQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsRUFDaEUsRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FDckQ7WUFDRCxvQkFBb0IsRUFBRSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxFQUFFO1NBQzVELENBQUM7UUFDRixzREFBc0Q7UUFDdEQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUM1RixNQUFNLE9BQU8sR0FBRztZQUNkLElBQUksRUFBRSxNQUFNO1lBQ1osT0FBTyxFQUFFLGNBQWMsQ0FBQyxZQUFZLENBQ2xDLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxFQUNwQyxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxDQUNyRDtZQUNELG9CQUFvQixFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsRUFBRTtTQUNqRyxDQUFDO1FBRUYsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUMsS0FBSyxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQzlELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDNUMsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzdDLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ssaUJBQWlCLENBQUMsU0FBc0IsRUFBRSxPQUFvQjtRQUNwRSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQzVDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNwQyxJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLHFCQUFxQixFQUFFLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ3ZHLElBQUksQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMscUJBQXFCLEVBQUUsSUFBSSxDQUFDLDBCQUEwQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDdkcsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztZQUMzQixJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLHFCQUFxQixFQUFFLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ3pHLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ssZ0JBQWdCLENBQUMsU0FBc0IsRUFBRSxPQUFvQjtRQUNuRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3RCLE1BQU0sWUFBWSxHQUFHLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsb0JBQW9CLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLGdCQUFnQixFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxjQUFjLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLGNBQWMsRUFBRSxjQUFjLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLGNBQWMsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLDRCQUE0QixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsNEJBQTRCLEVBQUUsRUFBRSxDQUFDO1lBQzlhLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQzVDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7Z0JBQ2xELElBQUksQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMscUJBQXFCLEVBQUUsSUFBSSxDQUFDLDBCQUEwQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZHLElBQUksQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMscUJBQXFCLEVBQUUsSUFBSSxDQUFDLDBCQUEwQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQ3JHLElBQUksQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMscUJBQXFCLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxZQUFZLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxpQkFBaUIsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUMsY0FBYyxFQUFFLGlCQUFpQixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxjQUFjLEVBQUUsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsZ0NBQWdDLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLDRCQUE0QixDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hoQixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO2dCQUN6QyxJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLHFCQUFxQixFQUFFLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO2dCQUN2RyxJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLHFCQUFxQixFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsMEJBQTBCLENBQUMsWUFBWSxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUMsY0FBYyxFQUFFLG1CQUFtQixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLGdDQUFnQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyw0QkFBNEIsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNoaEIsQ0FBQztRQUNILENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxVQUFVLEdBQUcsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLG9CQUFvQixDQUFDLEVBQUUsb0JBQW9CLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUM7WUFDOUwsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMscUJBQXFCLEVBQUUsSUFBSSxDQUFDLDBCQUEwQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDMUcsQ0FBQztJQUNILENBQUM7SUFFTywwQkFBMEIsQ0FBQyxPQUFvQjtRQUNyRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBWSxFQUFFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNwSSxNQUFNLE9BQU8sR0FBd0I7WUFDbkMsVUFBVSxFQUFFLENBQUM7WUFDYixNQUFNLEVBQUUsT0FBTyxDQUFDLElBQUk7WUFDcEIsTUFBTSxFQUFFLElBQUk7WUFDWixZQUFZLEVBQUUsT0FBTyxDQUFDLG9CQUFvQixDQUFDLFNBQVM7U0FDckQsQ0FBQztRQUNGLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLFVBQVUsRUFBRSxDQUFDO1lBQzVDLElBQUksT0FBTyxPQUFPLENBQUMsT0FBTyxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUN4QyxPQUFPLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUM7WUFDakMsQ0FBQztpQkFBTSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQzFDLE9BQU8sQ0FBQyxJQUFJLEdBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUF3QixDQUFDLElBQUksQ0FBQTtZQUNoRyxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxRQUFRLENBQUMsUUFBc0IsRUFBRSxNQUFlO1FBQzlDLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDMUMsT0FBTyxDQUFDLEtBQUssQ0FBQywrRUFBK0UsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUN6RyxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksTUFBTSxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMxQyxDQUFDO1FBQ0QsNkNBQTZDO1FBQzdDLDhHQUE4RztRQUM5RyxNQUFNLGVBQWUsR0FBa0IsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQzFELEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDOUMsT0FBTyxHQUFrQixDQUFDO1FBQzVCLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxHQUFHLGVBQWUsQ0FBQztRQUMvQyxNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEMsSUFBSSxXQUFXLElBQUksV0FBVyxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUMvQyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsK0VBQStFO1FBQzlHLENBQUM7YUFDSSxDQUFDO1lBQ0osSUFBSSxDQUFDLFVBQVUsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLHFGQUFxRjtZQUN2SCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDeEIsQ0FBQztRQUNELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsU0FBUztRQUNQLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLGFBQWE7UUFDL0MsQ0FBQztRQUNELElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxHQUFHLFNBQVMsQ0FBQyxDQUFDLHFCQUFxQjtRQUMvRCxJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUVEOzs7T0FHRztJQUNILFVBQVU7UUFDUixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWM7YUFDNUIsSUFBSSxDQUNILGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFDbkMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxFQUNoQyxTQUFTLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxTQUFVLENBQUMsRUFBRSxDQUFDLENBQUMsRUFDcEUsTUFBTSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsRUFDOUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFpQixDQUFDLE9BQU8sRUFBRSxnQkFBaUIsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUN4RixDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ2xCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxjQUFjO1FBQ1osSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxTQUFTLENBQ3pDLEdBQUcsRUFBRTtZQUNILG1EQUFtRDtZQUNuRCxtRkFBbUY7WUFDbkYsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakQsSUFBSSxJQUFJLENBQUMsdUJBQXVCLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztnQkFDOUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUQsQ0FBQztZQUNELElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN4QixDQUFDLENBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRDs7O09BR0c7SUFDSCxjQUFjO1FBQ1osSUFBSSxDQUFDLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxTQUFTLENBQUM7UUFDbkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUV6QixJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBQzVCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2QsSUFBSSxDQUFDLGFBQWEsRUFBRSxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDNUMsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNILFdBQVcsQ0FBQyxPQUFvQixFQUFFLEtBQWE7UUFDN0MsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLG1CQUFtQixDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3hGLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQztRQUNoQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQywyQkFBMkIsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVksRUFBRSxPQUFPLENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFaEosMERBQTBEO1FBQzFELElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxPQUFPLENBQUMsT0FBTyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQXdCLENBQUMsSUFBSSxDQUFDO1FBRXhILElBQUksQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMsZ0JBQWdCLEVBQUUsRUFBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixFQUFFLFlBQVksRUFBRSxPQUFPLENBQUMsb0JBQW9CLENBQUMsU0FBUyxFQUFDLENBQUMsQ0FBQztJQUNoSixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxXQUFXLENBQUMsT0FBb0IsRUFBRSxLQUFhO1FBQzdDLHNDQUFzQztRQUN0QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBWSxFQUFFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNwSSxJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLGdCQUFnQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsT0FBTyxDQUFDLG9CQUFvQixDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7SUFDaEksQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILGlCQUFpQixDQUFDLE9BQW9CLEVBQUUsS0FBYTtRQUNuRCxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDeEYsT0FBTztRQUNULENBQUM7UUFDRCx5SkFBeUo7UUFDekosSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQ2QsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUMsV0FBVyxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDdkksQ0FBQyxFQUFFLENBQUM7UUFDTixDQUFDO1FBQ0QsMENBQTBDO1FBQzFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMzRCx1RUFBdUU7WUFDdkUsTUFBTSw0QkFBNEIsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBWSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzdLLDBFQUEwRTtZQUMxRSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBWSxFQUFFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNwSSw2RkFBNkY7WUFDN0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSw0QkFBNEIsQ0FBQyxDQUFDO1lBQ3BHLG1CQUFtQjtZQUNuQixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDekMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxzQkFBc0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQ3RJLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsT0FBTyxDQUFDLEtBQW9CO1FBQzFCLFFBQVEsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ2xCLEtBQUssV0FBVztnQkFDZCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3ZCLE1BQU07WUFDUixLQUFLLE9BQU87Z0JBQ1YsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDcEIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO29CQUN2QixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ3hCLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUN2QixNQUFNO1lBQ1I7Z0JBQ0UsTUFBTTtRQUNWLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGVBQWUsQ0FBQyxLQUFxQjtRQUNuQyxJQUFJLEtBQUssRUFBRSxHQUFHLEtBQUssT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzlDLEtBQUssRUFBRSxjQUFjLEVBQUUsQ0FBQztRQUMxQixDQUFDO1FBQ0QsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDO1FBQ3RCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxhQUFjLENBQUMsYUFBYSxDQUFDO1FBQzdDLEVBQUUsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLEdBQUcsU0FBUyxJQUFJLENBQUM7UUFDdEMsRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3pCLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLFlBQVksSUFBSSxDQUFDO1FBQ3pDLEVBQUUsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQyxZQUFZLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztJQUMxRSxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxPQUFvQixFQUFFLEtBQWE7UUFDeEMsc0NBQXNDO1FBQ3RDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsMkJBQTJCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFZLEVBQUUsT0FBTyxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3BJLElBQUksQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMsb0JBQW9CLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxPQUFPLENBQUMsb0JBQW9CLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUNsSSxJQUFJLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQztRQUN6QixJQUFJLENBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQztRQUMvQixJQUFJLENBQUMsYUFBYSxHQUFHLFNBQVMsQ0FBQztRQUMvQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQTtRQUV0QixJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVksQ0FBQyxJQUFJLEdBQUMsQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztRQUN6RSxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVksQ0FBQyxJQUFJLEdBQUMsQ0FBQyxDQUFDLENBQUMsb0JBQW9CLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUM3RSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxTQUFTLENBQUMsT0FBb0IsRUFBRSxLQUFhO1FBQzNDLHNDQUFzQztRQUN0QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBWSxFQUFFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNwSSxJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLHNCQUFzQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsT0FBTyxDQUFDLG9CQUFvQixDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDcEksSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDNUIsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUM7UUFDL0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxTQUFTLENBQUM7UUFDL0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7UUFDdkIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUE7UUFFdEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFZLENBQUMsSUFBSSxHQUFDLENBQUMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDNUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFZLENBQUMsSUFBSSxHQUFDLENBQUMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7UUFDMUUsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUVPLGtCQUFrQjtRQUN4QixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2xELElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUMxQyxJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNqSCxDQUFDO1FBQ0QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxVQUFVO1FBQ1IsTUFBTSxPQUFPLEdBQUc7WUFDZCxTQUFTLEVBQUUsSUFBSSxDQUFDLGFBQWE7WUFDN0IsTUFBTSxFQUFFLElBQUksQ0FBQyxVQUFVO1NBQ3hCLENBQUM7UUFFRix5RUFBeUU7UUFDekUsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDekIsT0FBTyxDQUFDLFlBQVksQ0FBQyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsb0JBQW9CLENBQUMsU0FBUyxDQUFDO1FBQzlFLENBQUM7UUFFRCw4Q0FBOEM7UUFDOUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxVQUFVO1lBQ3RDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsZUFBZ0IsQ0FBQyxPQUFPLENBQUM7UUFFbEQsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxhQUFhLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ3hDLElBQUksQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMsMEJBQTBCLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDM0UsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLDBCQUEwQixFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzNFLENBQUM7UUFDRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLDZCQUE2QixDQUFDLENBQUMsQ0FBQztRQUMzRixJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztJQUMxQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxZQUFZO1FBQ1YsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7SUFDMUIsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILHFCQUFxQixDQUFDLElBQTJELEVBQUUsT0FBb0IsRUFBRSxLQUFhO1FBQ3BILElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN0QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBWSxFQUFFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNwSSxNQUFNLE9BQU8sR0FBRztZQUNkLFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVE7WUFDakMsUUFBUSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVE7WUFDeEMsWUFBWSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFVBQVU7WUFDOUMsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLGFBQWE7WUFDNUMsTUFBTSxFQUFFLElBQUk7WUFDWixZQUFZLEVBQUUsT0FBTyxDQUFDLG9CQUFvQixDQUFDLFNBQVM7U0FDckQsQ0FBQztRQUNGLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDcEQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyw4QkFBOEIsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUMvRSxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsc0JBQXNCLENBQUMsSUFBMkQsRUFBRSxPQUFvQixFQUFFLEtBQWE7UUFDckgsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBWSxFQUFFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNwSSxNQUFNLE9BQU8sR0FBRztZQUNkLFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVE7WUFDakMsUUFBUSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVE7WUFDeEMsWUFBWSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFVBQVU7WUFDOUMsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLGFBQWE7WUFDNUMsTUFBTSxFQUFFLElBQUk7WUFDWixZQUFZLEVBQUUsT0FBTyxDQUFDLG9CQUFvQixDQUFDLFNBQVM7U0FDckQsQ0FBQztRQUNGLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNO1lBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDcEQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQywyQkFBMkIsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUM1RSxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxrQkFBa0IsQ0FBQyxNQUF1QixFQUFFLEtBQWE7UUFDdkQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFaEMsTUFBTSxPQUFPLEdBQUc7WUFDZCxNQUFNLEVBQUUsTUFBTSxDQUFDLE9BQU87WUFDdEIsc0JBQXNCLEVBQUUsTUFBTSxDQUFDLElBQUk7U0FDcEMsQ0FBQztRQUNGLElBQUksQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMsNEJBQTRCLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDN0UsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILGdCQUFnQixDQUFDLE9BQW9CLEVBQUUsS0FBYTtRQUNsRCwyREFBMkQ7UUFDM0QsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2pDLE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUNELHNEQUFzRDtRQUN0RCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN4RCxvSEFBb0g7UUFDcEgsc0hBQXNIO1FBQ3RILE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsaUNBQWlDLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDekUsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNiLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUM7UUFDeEUsQ0FBQztRQUNELE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxTQUFTLENBQUMsT0FBb0IsRUFBRSxLQUFhO1FBQzNDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO1FBQzlCLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILHVCQUF1QixDQUFDLFFBQXVCLEVBQUUsS0FBYTtRQUM1RCxLQUFLLElBQUksQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQzdDLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxXQUFXO2dCQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ3JELENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILHVCQUF1QixDQUFDLE9BQWdDO1FBQ3RELElBQ0UsT0FBTyxFQUFFLElBQUksS0FBSyxXQUFXO2VBQzFCO1lBQ0Qsc0JBQXNCO1lBQ3RCLENBQUMsT0FBTyxPQUFPLEVBQUUsT0FBTyxLQUFLLFFBQVEsSUFBSSxPQUFPLEVBQUUsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDakUsbUJBQW1CO2dCQUNuQixTQUFTO21CQUNKLE9BQU8sRUFBRSxPQUE2QixFQUFFLENBQUMsQ0FBQyxDQUF3QixFQUFFLElBQUksS0FBSyxFQUFFO1lBQ3BGLG9GQUFvRjthQUNyRjtlQUNFLENBQUMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLFdBQVc7ZUFDM0MsQ0FBQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsU0FBUztlQUN6QyxDQUFDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNO2VBQ3RDLENBQUMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLGdCQUFnQixFQUNuRCxDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDOytHQWhuQ1UsYUFBYTttR0FBYixhQUFhLDR4QkFaYjtZQUNULFdBQVc7WUFDWCw2QkFBNkI7WUFDN0IsOEJBQThCO1lBQzlCLGlCQUFpQjtZQUNqQixtQkFBbUI7WUFDbkIscUJBQXFCLENBQUMsTUFBTSxDQUFDO1NBQzlCLGtqQkN0Q0gsOHpUQTJMQSxncVJEbEpZLFlBQVkseWpCQUFFLFdBQVcsMGdDQUFFLG9CQUFvQixvY0FBRSx5QkFBeUIsMEZBQUUscUJBQXFCLCtFQUFFLGdCQUFnQixnTUFBRSxhQUFhOzs0RkFFakksYUFBYTtrQkFoQnpCLFNBQVM7K0JBQ0UsWUFBWSxhQUdYO3dCQUNULFdBQVc7d0JBQ1gsNkJBQTZCO3dCQUM3Qiw4QkFBOEI7d0JBQzlCLGlCQUFpQjt3QkFDakIsbUJBQW1CO3dCQUNuQixxQkFBcUIsQ0FBQyxNQUFNLENBQUM7cUJBQzlCLG1CQUNnQix1QkFBdUIsQ0FBQyxNQUFNLGNBQ25DLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxXQUFXLEVBQUUsb0JBQW9CLEVBQUUseUJBQXlCLEVBQUUscUJBQXFCLEVBQUUsZ0JBQWdCLEVBQUUsYUFBYSxDQUFDO3dEQWVwSSxVQUFVO3NCQUFsQixLQUFLO2dCQUVHLEtBQUs7c0JBQWIsS0FBSztnQkFPRyw4QkFBOEI7c0JBQXRDLEtBQUs7Z0JBRUcsZUFBZTtzQkFBdkIsS0FBSztnQkFFRyw2QkFBNkI7c0JBQXJDLEtBQUs7Z0JBRUcsa0JBQWtCO3NCQUExQixLQUFLO2dCQUVHLElBQUk7c0JBQVosS0FBSztnQkFFRyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBRUcsZUFBZTtzQkFBdkIsS0FBSztnQkFFRywwQkFBMEI7c0JBQWxDLEtBQUs7Z0JBRUcsd0JBQXdCO3NCQUFoQyxLQUFLO2dCQUVHLDRCQUE0QjtzQkFBcEMsS0FBSztnQkFFRyxTQUFTO3NCQUFqQixLQUFLO2dCQUVJLFVBQVU7c0JBQW5CLE1BQU07Z0JBR1ksUUFBUTtzQkFBMUIsTUFBTTt1QkFBQyxTQUFTO2dCQUVDLE9BQU87c0JBQXhCLE1BQU07dUJBQUMsUUFBUTtnQkFDTixJQUFJO3NCQUFiLE1BQU07Z0JBRUcsWUFBWTtzQkFBckIsTUFBTTtnQkFFRyxXQUFXO3NCQUFwQixNQUFNO2dCQUVHLGFBQWE7c0JBQXRCLE1BQU07Z0JBRXFCLGFBQWE7c0JBQXhDLFNBQVM7dUJBQUMsZUFBZTtnQkFFRSxVQUFVO3NCQUFyQyxZQUFZO3VCQUFDLFlBQVk7Z0JBQ0MsU0FBUztzQkFBbkMsWUFBWTt1QkFBQyxXQUFXO2dCQUNZLG1CQUFtQjtzQkFBdkQsWUFBWTt1QkFBQyxxQkFBcUI7Z0JBQ0QsZ0JBQWdCO3NCQUFqRCxZQUFZO3VCQUFDLGtCQUFrQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9jb21tb25cIjtcbmltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBDb250ZW50Q2hpbGQsIERlc3Ryb3lSZWYsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uQ2hhbmdlcywgT25EZXN0cm95LCBPbkluaXQsIE91dHB1dCwgU2ltcGxlQ2hhbmdlcywgVGVtcGxhdGVSZWYsIFZpZXdDaGlsZCwgaW5qZWN0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XG5pbXBvcnQgeyBUcmFuc2xvY29QaXBlLCBUcmFuc2xvY29TZXJ2aWNlLCBwcm92aWRlVHJhbnNsb2NvU2NvcGUgfSBmcm9tICdAanN2ZXJzZS90cmFuc2xvY28nO1xuaW1wb3J0IHsgSHViQ29ubmVjdGlvbiwgSHViQ29ubmVjdGlvblN0YXRlIH0gZnJvbSBcIkBtaWNyb3NvZnQvc2lnbmFsclwiO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBTdWJzY3JpcHRpb24sIGNvbWJpbmVMYXRlc3QsIGZpbHRlciwgZnJvbUV2ZW50LCBtZXJnZSwgb2YsIHN3aXRjaE1hcCwgdGFrZSwgdGFwIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcblxuaW1wb3J0IHsgQXBwR2xvYmFsQ29uZmlnLCBBcnRpY2xlLCBRdWVyeSwgZ3VpZCwgaXNBdXRoZW50aWNhdGVkLCBzZXRHbG9iYWxDb25maWcgfSBmcm9tIFwiQHNpbmVxdWEvYXRvbWljXCI7XG5cbmltcG9ydCB7IENoYXRNZXNzYWdlQ29tcG9uZW50IH0gZnJvbSBcIi4vY2hhdC1tZXNzYWdlL2NoYXQtbWVzc2FnZS5jb21wb25lbnRcIjtcbmltcG9ydCB7IENoYXRTZXJ2aWNlIH0gZnJvbSBcIi4vY2hhdC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBEZWJ1Z01lc3NhZ2VDb21wb25lbnQgfSBmcm9tIFwiLi9kZWJ1Zy1tZXNzYWdlL2RlYnVnLW1lc3NhZ2UuY29tcG9uZW50XCI7XG5pbXBvcnQgeyBJbnN0YW5jZU1hbmFnZXJTZXJ2aWNlIH0gZnJvbSBcIi4vaW5zdGFuY2UtbWFuYWdlci5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBOb3RpZmljYXRpb25zU2VydmljZSB9IGZyb20gXCIuL3NlcnZpY2VzL25vdGlmaWNhdGlvbi5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBQcmluY2lwYWxTZXJ2aWNlIH0gZnJvbSBcIi4vc2VydmljZXMvcHJpbmNpcGFsLnNlcnZpY2VcIjtcbmltcG9ydCB7IFNlYXJjaFNlcnZpY2UgfSBmcm9tIFwiLi9zZXJ2aWNlcy9zZWFyY2guc2VydmljZVwiO1xuaW1wb3J0IHsgVG9rZW5Qcm9ncmVzc0JhckNvbXBvbmVudCB9IGZyb20gXCIuL3Rva2VuLXByb2dyZXNzLWJhci90b2tlbi1wcm9ncmVzcy1iYXIuY29tcG9uZW50XCI7XG5pbXBvcnQgeyBUb29sdGlwRGlyZWN0aXZlIH0gZnJvbSBcIi4vdG9vbHRpcC90b29sdGlwLmRpcmVjdGl2ZVwiO1xuaW1wb3J0IHsgQ2hhdENvbmZpZywgQ2hhdENvbnRleHRBdHRhY2htZW50LCBDaGF0TWVzc2FnZSwgRGVidWdNZXNzYWdlLCBHbGxtTW9kZWxEZXNjcmlwdGlvbiwgSW5pdENoYXQsIE1lc3NhZ2VIYW5kbGVyLCBSYXdNZXNzYWdlLCBTdWdnZXN0ZWRBY3Rpb24gfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgUmF3TWVzc2FnZUNvbnRlbnQsIFRleHRNZXNzYWdlQ29udGVudCB9IGZyb20gXCIuL3R5cGVzL21lc3NhZ2UtY29udGVudC50eXBlc1wiO1xuaW1wb3J0IHsgQXNzaXN0YW50VXRpbHMgfSBmcm9tIFwiLi91dGlscy91dGlscy5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBBc3Npc3RhbnRDb25maWd1cmF0aW9uU2VydmljZSB9IGZyb20gXCIuL3NlcnZpY2VzL2Fzc2lzdGFudC1jb25maWd1cmF0aW9uLnNlcnZpY2VcIjtcbmltcG9ydCB7IEFzc2lzdGFudFRva2Vuc1RyYWNraW5nU2VydmljZSB9IGZyb20gXCIuL3NlcnZpY2VzL2Fzc2lzdGFudC10b2tlbnMtdHJhY2tpbmcuc2VydmljZVwiO1xuaW1wb3J0IHsgU2F2ZWRDaGF0c1NlcnZpY2UgfSBmcm9tIFwiLi9zYXZlZC1jaGF0cy9zYXZlZC1jaGF0cy5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBEZWJ1Z01lc3NhZ2VTZXJ2aWNlIH0gZnJvbSBcIi4vZGVidWctbWVzc2FnZS9kZWJ1Zy1tZXNzYWdlLnNlcnZpY2VcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc3EtY2hhdC12MycsIC8vIG1hbmRhdG9yeSBzaW5jZSBAc2luZXF1YS9jb21wb25lbnRzIGFscmVhZHkgaGFzIHRoZSBzYW1lIHRhZy1uYW1lIFwic3EtY2hhdFwiXG4gIHRlbXBsYXRlVXJsOiAnLi9jaGF0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vY2hhdC5jb21wb25lbnQuc2NzcyddLFxuICBwcm92aWRlcnM6IFtcbiAgICBDaGF0U2VydmljZSxcbiAgICBBc3Npc3RhbnRDb25maWd1cmF0aW9uU2VydmljZSxcbiAgICBBc3Npc3RhbnRUb2tlbnNUcmFja2luZ1NlcnZpY2UsXG4gICAgU2F2ZWRDaGF0c1NlcnZpY2UsXG4gICAgRGVidWdNZXNzYWdlU2VydmljZSxcbiAgICBwcm92aWRlVHJhbnNsb2NvU2NvcGUoJ2NoYXQnKVxuICBdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRm9ybXNNb2R1bGUsIENoYXRNZXNzYWdlQ29tcG9uZW50LCBUb2tlblByb2dyZXNzQmFyQ29tcG9uZW50LCBEZWJ1Z01lc3NhZ2VDb21wb25lbnQsIFRvb2x0aXBEaXJlY3RpdmUsIFRyYW5zbG9jb1BpcGVdXG59KVxuZXhwb3J0IGNsYXNzIENoYXRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcblxuICBwdWJsaWMgY2hhdFNlcnZpY2UgPSBpbmplY3QoQ2hhdFNlcnZpY2UpO1xuICBwdWJsaWMgaW5zdGFuY2VNYW5hZ2VyU2VydmljZSA9IGluamVjdChJbnN0YW5jZU1hbmFnZXJTZXJ2aWNlKTtcbiAgcHVibGljIHNlYXJjaFNlcnZpY2UgPSBpbmplY3QoU2VhcmNoU2VydmljZSk7XG4gIHB1YmxpYyBwcmluY2lwYWxTZXJ2aWNlID0gaW5qZWN0KFByaW5jaXBhbFNlcnZpY2UpO1xuICBwdWJsaWMgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcbiAgcHVibGljIG5vdGlmaWNhdGlvbnNTZXJ2aWNlID0gaW5qZWN0KE5vdGlmaWNhdGlvbnNTZXJ2aWNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSB0cmFuc2xvY28gPSBpbmplY3QoVHJhbnNsb2NvU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXNzaXN0YW50VXRpbHMgPSBpbmplY3QoQXNzaXN0YW50VXRpbHMpO1xuICBwcml2YXRlIGRlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG5cbiAgLyoqIERlZmluZSB0aGUga2V5IGJhc2VkIG9uIGl0LCB0aGUgY2hhdCBzZXJ2aWNlIGluc3RhbmNlIHdpbGwgYmUgc3RvcmVkICovXG4gIEBJbnB1dCgpIGluc3RhbmNlSWQ6IHN0cmluZztcbiAgLyoqIERlZmluZSB0aGUgcXVlcnkgdG8gdXNlIHRvIGZldGNoIGFuc3dlcnMgKi9cbiAgQElucHV0KCkgcXVlcnk6IFF1ZXJ5ID0gdGhpcy5zZWFyY2hTZXJ2aWNlLnF1ZXJ5O1xuICAvKiogRnVuY3Rpb24gdGhhdCBkZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGNoYXQgc2hvdWxkIGJlIHJlbG9hZGVkIGFmdGVyIHRoZSBxdWVyeSBjaGFuZ2VzXG4gICAqIElmIG5vdCBwcm92aWRlZCwgdGhlIGNoYXQgd2lsbCBiZSByZWxvYWRlZCBieSBkZWZhdWx0XG4gICAqIEBwYXJhbSBwcmV2UXVlcnkgVGhlIHByZXZpb3VzIHF1ZXJ5XG4gICAqIEBwYXJhbSBuZXdRdWVyeSBUaGUgbmV3IHF1ZXJ5XG4gICAqIEByZXR1cm5zIHRydWUgaWYgdGhlIGNoYXQgc2hvdWxkIGJlIHJlbG9hZGVkLCBmYWxzZSBvdGhlcndpc2VcbiAgICovXG4gIEBJbnB1dCgpIHF1ZXJ5Q2hhbmdlU2hvdWxkVHJpZ2dlclJlbG9hZDogKHByZXZRdWVyeTogUXVlcnksIG5ld1F1ZXJ5OiBRdWVyeSkgPT4gYm9vbGVhbjtcbiAgLyoqIE1hcCBvZiBsaXN0ZW5lcnMgb3ZlcnJpZGluZyBkZWZhdWx0IHJlZ2lzdGVyZWQgb25lcyovXG4gIEBJbnB1dCgpIG1lc3NhZ2VIYW5kbGVyczogTWFwPHN0cmluZywgTWVzc2FnZUhhbmRsZXI8YW55Pj4gPSBuZXcgTWFwKCk7XG4gIC8qKiBXaGVuIHRoZSBhc3Npc3RhbnQgYW5zd2VyIGEgdXNlciBxdWVzdGlvbiwgYXV0b21hdGljYWxseSBzY3JvbGwgZG93biB0byB0aGUgYm90dG9tIG9mIHRoZSBkaXNjdXNzaW9uICovXG4gIEBJbnB1dCgpIGF1dG9tYXRpY1Njcm9sbFRvTGFzdFJlc3BvbnNlID0gZmFsc2U7XG4gIC8qKiBXaGVuIHRoZSBhc3Npc3RhbnQgYW5zd2VyIGEgdXNlciBxdWVzdGlvbiwgYXV0b21hdGljYWxseSBmb2N1cyB0byB0aGUgY2hhdCBpbnB1dCAqL1xuICBASW5wdXQoKSBmb2N1c0FmdGVyUmVzcG9uc2UgPSBmYWxzZTtcbiAgLyoqIEEgY2hhdCBkaXNjdXNzaW9uIHRoYXQgdGhlIGNvbXBvbmVudCBzaG91bGQgZ2V0IGluaXRpYWxpemVkIHdpdGggaXQgKi9cbiAgQElucHV0KCkgY2hhdD86IEluaXRDaGF0O1xuICAvKiogSWNvbiB0byB1c2UgZm9yIHRoZSBhc3Npc3RhbnQgbWVzc2FnZXMgKi9cbiAgQElucHV0KCkgYXNzaXN0YW50TWVzc2FnZUljb24gPSAnc3Etc2luZXF1YSc7XG4gIC8qKiBJY29uIHRvIHVzZSBmb3IgdGhlIHVzZXIgbWVzc2FnZXMgKi9cbiAgQElucHV0KCkgdXNlck1lc3NhZ2VJY29uOiBzdHJpbmc7XG4gIC8qKiBJY29uIHRvIHVzZSBmb3IgdGhlIGNvbm5lY3Rpb24gZXJyb3IgbWVzc2FnZXMgKi9cbiAgQElucHV0KCkgY29ubmVjdGlvbkVycm9yTWVzc2FnZUljb246IHN0cmluZztcbiAgLyoqIEljb24gdG8gdXNlIGZvciB0aGUgc2VhcmNoIHdhcm5pbmcgbWVzc2FnZXMgKi9cbiAgQElucHV0KCkgc2VhcmNoV2FybmluZ01lc3NhZ2VJY29uOiBzdHJpbmc7XG4gIC8vIEFkZCBjdXN0b20gYWRkaXRpb25hbFdvcmtmbG93UHJvcGVydGllcyB0byB0aGUgdXNlciBxdWVyeSBtZXNzYWdlXG4gIEBJbnB1dCgpIGFkZGl0aW9uYWxXb3JrZmxvd1Byb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgLyoqIFVzZWQgYnkgYXNzaXN0YW50IHdlYiBjb21wb25lbnQgdG8gcGFzcyBwcm9wZXJseSBpbml0IHRoZSBnbG9iYWwgY29uZmlnICovXG4gIEBJbnB1dCgpIGFwcENvbmZpZzogQXBwR2xvYmFsQ29uZmlnO1xuICAvKiogRXZlbnQgZW1pdHRlciB0cmlnZ2VyZWQgb25jZSB0aGUgc2lnbmFsUiBjb25uZWN0aW9uIGlzIGVzdGFibGlzaGVkICAqL1xuICBAT3V0cHV0KCkgY29ubmVjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8SHViQ29ubmVjdGlvbj4oKTtcbiAgLyoqIEV2ZW50IGVtaXR0ZXIgdHJpZ2dlcmVkIGVhY2ggdGltZSB0aGUgYXNzaXN0YW50IHVwZGF0ZXMgdGhlIGN1cnJlbnQgY2hhdCAqL1xuICAvKiogRXZlbnQgZW1pdHRlciB0cmlnZ2VyZWQgd2hlbiB0aGUgY2hhdCBpcyBsb2FkaW5nIG5ldyBjb250ZW50ICovXG4gIEBPdXRwdXQoXCJsb2FkaW5nXCIpIGxvYWRpbmckID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPihmYWxzZSk7XG4gIC8qKiBFbWl0cyB0aGUgYXNzaXN0YW50IGNvbmZpZ3VyYXRpb24gdXNlZCB3aGVuIGluc3RhbnRpYXRpbmcgdGhlIGNvbXBvbmVudCAqL1xuICBAT3V0cHV0KFwiY29uZmlnXCIpIF9jb25maWcgPSBuZXcgRXZlbnRFbWl0dGVyPENoYXRDb25maWc+KCk7XG4gIEBPdXRwdXQoKSBkYXRhID0gbmV3IEV2ZW50RW1pdHRlcjxDaGF0TWVzc2FnZVtdPigpO1xuICAvKiogRXZlbnQgZW1pdHRlciB0cmlnZ2VyZWQgd2hlbiB0aGUgdXNlciBjbGlja3MgdG8gb3BlbiB0aGUgb3JpZ2luYWwgZG9jdW1lbnQgcmVwcmVzZW50aW5nIHRoZSBjb250ZXh0IGF0dGFjaG1lbnQqL1xuICBAT3V0cHV0KCkgb3BlbkRvY3VtZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxBcnRpY2xlPigpO1xuICAvKiogRXZlbnQgZW1pdHRlciB0cmlnZ2VyZWQgd2hlbiB0aGUgdXNlciBjbGlja3MgdG8gb3BlbiB0aGUgcHJldmlldyBvZiBhIGRvY3VtZW50IHJlcHJlc2VudGluZyB0aGUgY29udGV4dCBhdHRhY2htZW50ICovXG4gIEBPdXRwdXQoKSBvcGVuUHJldmlldyA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhdENvbnRleHRBdHRhY2htZW50PigpO1xuICAvKiogRXZlbnQgZW1pdHRlciB0cmlnZ2VyZWQgd2hlbiB0aGUgdXNlciBjbGlja3Mgb24gYSBzdWdnZXN0ZWQgYWN0aW9uICovXG4gIEBPdXRwdXQoKSBzdWdnZXN0QWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjxTdWdnZXN0ZWRBY3Rpb24+KCk7XG4gIC8qKiBWaWV3Q2hpbGQgZGVjb3JhdG9ycyB0byBhY2Nlc3MgdGhlIHRlbXBsYXRlIGVsZW1lbnRzICovXG4gIEBWaWV3Q2hpbGQoJ3F1ZXN0aW9uSW5wdXQnKSBxdWVzdGlvbklucHV0PzogRWxlbWVudFJlZjxIVE1MVGV4dEFyZWFFbGVtZW50PjtcbiAgLyoqIENvbnRlbnRDaGlsZCBkZWNvcmF0b3JzIGFsbG93aW5nIHRoZSBvdmVycmlkZSBvZiB0aGUgZGVmYXVsdCB0ZW1wbGF0ZXMgZnJvbSB0aGUgcGFyZW50IGNvbXBvbmVudCAqL1xuICBAQ29udGVudENoaWxkKCdsb2FkaW5nVHBsJykgbG9hZGluZ1RwbD86IFRlbXBsYXRlUmVmPGFueT47XG4gIEBDb250ZW50Q2hpbGQoJ3JlcG9ydFRwbCcpIHJlcG9ydFRwbD86IFRlbXBsYXRlUmVmPGFueT47XG4gIEBDb250ZW50Q2hpbGQoJ3Rva2VuQ29uc3VtcHRpb25UcGwnKSB0b2tlbkNvbnN1bXB0aW9uVHBsPzogVGVtcGxhdGVSZWY8YW55PjtcbiAgQENvbnRlbnRDaGlsZCgnZGVidWdNZXNzYWdlc1RwbCcpIGRlYnVnTWVzc2FnZXNUcGw/OiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIGNvbmZpZzogQ2hhdENvbmZpZztcbiAgbWVzc2FnZXMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxDaGF0TWVzc2FnZVtdIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBpc0FkbWluT3JEZWxldGVkQWRtaW4gPSBmYWxzZTtcbiAgcXVlc3Rpb24gPSAnJztcblxuICBwcml2YXRlIF9kYXRhU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gfCB1bmRlZmluZWQ7XG5cbiAgLyoqIFZhcmlhYmxlcyB0aGF0IGRlcGVuZCBvbiB0aGUgdHlwZSBvZiBtb2RlbCBpbiB1c2UgKi9cbiAgbW9kZWxEZXNjcmlwdGlvbj86IEdsbG1Nb2RlbERlc2NyaXB0aW9uO1xuXG4gIGluZGV4TWVzc2FnZVRvRWRpdD86IG51bWJlcjtcbiAgcmFua01lc3NhZ2VUb0VkaXQ/OiBudW1iZXI7XG4gIGNoYW5nZXMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxTaW1wbGVDaGFuZ2VzIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBjdXJyZW50TWVzc2FnZUluZGV4OiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gIGZpcnN0Q2hhbmdlc0hhbmRsZWQgPSBmYWxzZTtcbiAgaXNBdEJvdHRvbSA9IHRydWU7XG4gIGluaXRpYWxpemF0aW9uRXJyb3IgPSBmYWxzZTtcbiAgZW5hYmxlZFVzZXJJbnB1dCA9IGZhbHNlO1xuICBpc0Nvbm5lY3RlZCA9IHRydWU7IC8vIEJ5IGRlZmF1bHQsIHRoZSBjaGF0IGlzIGNvbnNpZGVyZWQgY29ubmVjdGVkXG4gIHJldHJpYWxBdHRlbXB0czogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAvLyBGbGFnIHRvIHRyYWNrIHdoZXRoZXIgdGhlICdyZWNvbm5lY3RlZCcgbGlzdGVuZXIgaXMgYWxyZWFkeSByZWdpc3RlcmVkXG4gIHByaXZhdGUgX2lzUmVjb25uZWN0ZWRMaXN0ZW5lclJlZ2lzdGVyZWQgPSBmYWxzZTtcblxuICAvLyBJc3N1ZSByZXBvcnRpbmdcbiAgaXNzdWVUeXBlcz86IHN0cmluZ1tdO1xuICBkZWZhdWx0SXNzdWVUeXBlczogc3RyaW5nW10gPSBbXG4gICAgJ2NoYXQudXNlckludGVyZmFjZUJ1ZycsXG4gICAgJ2NoYXQuaW5jb3JyZWN0UmVzcG9uc2UnLFxuICAgICdjaGF0LmluY29tcGxldGVSZXNwb25zZScsXG4gICAgJ2NoYXQudGVjaG5pY2FsSXNzdWUnLFxuICAgICdjaGF0LnByaXZhY3lEYXRhU2VjdXJpdHlJc3N1ZScsXG4gICAgJ2NoYXQub3RoZXJJc3N1ZSdcbiAgXTtcbiAgaXNzdWVUeXBlOiBzdHJpbmcgPSAnJztcbiAgcmVwb3J0Q29tbWVudD86IHN0cmluZztcbiAgbWVzc2FnZVRvUmVwb3J0PzogQ2hhdE1lc3NhZ2U7XG4gIHJlcG9ydFJhbms/OiBudW1iZXI7XG4gIHJlcG9ydFR5cGU6ICdsaWtlJyB8ICdkaXNsaWtlJyA9ICdkaXNsaWtlJztcbiAgc2hvd1JlcG9ydCA9IGZhbHNlO1xuXG4gIC8vIERlYnVnIG1lc3NhZ2VzXG4gIGRlYnVnTWVzc2FnZXM6IERlYnVnTWVzc2FnZVtdIHwgdW5kZWZpbmVkO1xuICBzaG93RGVidWdNZXNzYWdlcyA9IGZhbHNlO1xuXG4gIHByaXZhdGUgX3ByZXZpb3VzUXVlcnk6IFF1ZXJ5O1xuICBwcml2YXRlIF9yZWxvYWRTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmRlc3Ryb3lSZWYub25EZXN0cm95KGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKGBEZXN0cm95aW5nIENoYXRDb21wb25lbnQ6ICR7dGhpcy5pbnN0YW5jZUlkfSBcXG4gYWxvbmcgd2l0aCBDaGF0U2VydmljZTogJHt0aGlzLmNoYXRTZXJ2aWNlLmNoYXRJbnN0YW5jZUlkfSBcXG4gYW5kIHN0b3BwaW5nIGNvbm5lY3Rpb246ICR7dGhpcy5jaGF0U2VydmljZS5jb25uZWN0aW9uPy5jb25uZWN0aW9uSWR9YCk7XG4gICAgICBpZiAodGhpcy5jaGF0U2VydmljZS5jb25uZWN0aW9uICYmIHRoaXMuY2hhdFNlcnZpY2UuY29ubmVjdGlvbi5zdGF0ZSAhPT0gSHViQ29ubmVjdGlvblN0YXRlLkRpc2Nvbm5lY3RlZCAmJiB0aGlzLmNoYXRTZXJ2aWNlLmNvbm5lY3Rpb24uc3RhdGUgIT09IEh1YkNvbm5lY3Rpb25TdGF0ZS5EaXNjb25uZWN0aW5nKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5jaGF0U2VydmljZS5zdG9wQ29ubmVjdGlvbigpXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgZHVyaW5nIHRoZSBkZXN0cnVjdGlvbiBvZiBDaGF0Q29tcG9uZW50OiAke3RoaXMuaW5zdGFuY2VJZH1gLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmFwcENvbmZpZykge1xuICAgICAgc2V0R2xvYmFsQ29uZmlnKHRoaXMuYXBwQ29uZmlnKTtcbiAgICB9XG5cbiAgICBvZihpc0F1dGhlbnRpY2F0ZWQoKSkucGlwZShcbiAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpLFxuICAgICAgdGFwKF8gPT4gdGhpcy5pbnN0YW50aWF0ZUNoYXRTZXJ2aWNlKCkpLFxuICAgICAgc3dpdGNoTWFwKF8gPT4gdGhpcy5jaGF0U2VydmljZS5pbml0KCkpLFxuICAgICAgc3dpdGNoTWFwKF8gPT4gdGhpcy5jaGF0U2VydmljZS5pbml0UHJvY2VzcyQucGlwZShmaWx0ZXIoQm9vbGVhbikpKSxcbiAgICAgIHRhcChfID0+IHtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uLmVtaXQodGhpcy5jaGF0U2VydmljZS5jb25uZWN0aW9uKTtcbiAgICAgICAgdGhpcy5vbkxvYWRDaGF0KCk7XG4gICAgICB9KSxcbiAgICAgIHRhcChfID0+IHRoaXMuY2hhdFNlcnZpY2Uub3ZlcnJpZGVVc2VyKCkpLFxuICAgICAgc3dpdGNoTWFwKF8gPT4gdGhpcy5jaGF0U2VydmljZS51c2VyT3ZlcnJpZGUkKSxcbiAgICAgIHN3aXRjaE1hcChfID0+IHRoaXMuY2hhdFNlcnZpY2UuYXNzaXN0YW50Q29uZmlnJCksXG4gICAgICB0YXAoY29uZmlnID0+IHtcbiAgICAgICAgdGhpcy5pc0FkbWluT3JEZWxldGVkQWRtaW4gPSB0aGlzLnByaW5jaXBhbFNlcnZpY2UucHJpbmNpcGFsIS5pc0FkbWluaXN0cmF0b3IgfHwgdGhpcy5wcmluY2lwYWxTZXJ2aWNlLnByaW5jaXBhbCEuaXNEZWxlZ2F0ZWRBZG1pbiB8fCBmYWxzZTtcbiAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWchO1xuICAgICAgICB0aGlzLmVuYWJsZWRVc2VySW5wdXQgPSB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuZW5hYmxlZFVzZXJJbnB1dDtcbiAgICAgICAgdGhpcy5pc3N1ZVR5cGVzID0gdGhpcy5jb25maWcuYXVkaXRTZXR0aW5ncz8uaXNzdWVUeXBlcz8ubGVuZ3RoID8gdGhpcy5jb25maWcuYXVkaXRTZXR0aW5ncyEuaXNzdWVUeXBlcyA6IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5fY29uZmlnLmVtaXQoY29uZmlnKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZU1vZGVsRGVzY3JpcHRpb24oKTtcbiAgICAgICAgICBpZighdGhpcy5maXJzdENoYW5nZXNIYW5kbGVkKSB7XG4gICAgICAgICAgICB0aGlzLl9wcmV2aW91c1F1ZXJ5ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLnF1ZXJ5KSk7IC8vIEluaXRpYWxpemUgdGhlIHByZXZpb3VzIHF1ZXJ5XG4gICAgICAgICAgICB0aGlzLl9oYW5kbGVDaGFuZ2VzKCk7XG4gICAgICAgICAgICB0aGlzLl9hZGRTY3JvbGxMaXN0ZW5lcigpO1xuICAgICAgICAgICAgdGhpcy5maXJzdENoYW5nZXNIYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgdGhpcy5pbml0aWFsaXphdGlvbkVycm9yID0gdHJ1ZVxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICkuc3Vic2NyaWJlKCk7XG5cbiAgICAvLyBFeGFtcGxlIG9mIGxpc3RlbmluZyB0byBjdXN0b20gZXZlbnRzIGZyb20gdGhlIHdlYiBlbGVtZW50IGFuZCBoYW5kbGluZyB0aGVtIGluIHRoZSBBbmd1bGFyIGNvbXBvbmVudFxuICAgIGFkZEV2ZW50TGlzdGVuZXIoJ29uT3BlblByZXZpZXcnLCAoZXZlbnQ6IGFueSkgPT4ge1xuICAgICAgdGhpcy5vcGVuUHJldmlldy5lbWl0KGV2ZW50LmRldGFpbC5yZWZlcmVuY2UpO1xuICAgIH0pO1xuICAgIGFkZEV2ZW50TGlzdGVuZXIoJ29uT3BlbkRvY3VtZW50JywgKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgIHRoaXMub3BlbkRvY3VtZW50LmVtaXQoZXZlbnQuZGV0YWlsLnJlZmVyZW5jZS5yZWNvcmQpO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIHRoaXMuY2hhbmdlcyQubmV4dChjaGFuZ2VzKTtcbiAgICBpZiAodGhpcy5jb25maWcpIHtcbiAgICAgIHRoaXMuX2hhbmRsZUNoYW5nZXMoKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLl9kYXRhU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuX3JlbG9hZFN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIGdldCBpc0FkbWluKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnByaW5jaXBhbFNlcnZpY2UucHJpbmNpcGFsPy5pc0FkbWluaXN0cmF0b3IgfHwgZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBjaGF0IHNlcnZpY2UgaW5zdGFuY2UgaXMgc3RvcmVkIGluIHRoZSBpbnN0YW5jZU1hbmFnZXJTZXJ2aWNlIHdpdGggcHJvdmlkZWQgQGlucHV0IGluc3RhbmNlSWQgYXMgYSBrZXlcbiAgICovXG4gIGluc3RhbnRpYXRlQ2hhdFNlcnZpY2UoKTogdm9pZCB7XG4gICAgdGhpcy5jaGF0U2VydmljZS5zZXRDaGF0SW5zdGFuY2VJZCh0aGlzLmluc3RhbmNlSWQpO1xuICAgIHRoaXMuaW5zdGFuY2VNYW5hZ2VyU2VydmljZS5zdG9yZUluc3RhbmNlKHRoaXMuaW5zdGFuY2VJZCwgdGhpcy5jaGF0U2VydmljZSk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyB0aGUgY2hhbmdlcyBpbiB0aGUgY2hhdCBjb21wb25lbnQuXG4gICAqIElmIHRoZSBjaGF0IHNlcnZpY2UgaXMgYSBXZWJTb2NrZXRDaGF0U2VydmljZSwgaXQgaGFuZGxlcyB0aGUgb3ZlcnJpZGUgb2YgdGhlIG1lc3NhZ2UgaGFuZGxlcnMgaWYgdGhleSBleGlzdC5cbiAgICogSW5pdGlhbGl6ZXMgdGhlIGNoYXQgd2l0aCB0aGUgcHJvdmlkZWQgY2hhdCBtZXNzYWdlcyBpZiB0aGV5IGV4aXN0LCBvdGhlcndpc2UgbG9hZHMgdGhlIGRlZmF1bHQgY2hhdC5cbiAgICogSWYgdGhlIGNoYXQgaXMgaW5pdGlhbGl6ZWQsIHRoZSBpbml0aWFsaXphdGlvbiBldmVudCBpcyBcIlF1ZXJ5XCIsIHRoZSBxdWVyeSBjaGFuZ2VzLCBhbmQgdGhlIHF1ZXJ5Q2hhbmdlU2hvdWxkVHJpZ2dlclJlbG9hZCBmdW5jdGlvbiBpcyBwcm92aWRlZCxcbiAgICogdGhlbiB0aGUgY2hhdCBzaG91bGQgYmUgcmVsb2FkZWQgaWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZS4gT3RoZXJ3aXNlLCB0aGUgY2hhdCBzaG91bGQgYmUgcmVsb2FkZWQgYnkgZGVmYXVsdC5cbiAgICogSXQgdGFrZXMgaW50byBhY2NvdW50IHRoZSBvbmdvaW5nIHN0cmVhbWluZyBwcm9jZXNzIGFuZCB0aGUgb25nb2luZyBzdG9wcGluZyBwcm9jZXNzIHRvIHRyaWdnZXIgdGhhdCBjb25kaXRpb25hbGx5IGRlZmluZSB0aGUgbG9naWNcbiAgICogb2YgdGhlIHJlbG9hZCA6XG4gICAqIC0gSWYgdGhlIGNoYXQgaXMgc3RyZWFtaW5nLCB0aGVuIHN0b3AgdGhlIGdlbmVyYXRpb24gYW5kIHdhaXQgZm9yIHRoZSBmZXRjaCB0byBjb21wbGV0ZSBiZWZvcmUgcmVsb2FkaW5nIHRoZSBjaGF0LlxuICAgKiAtIElmIHRoZSBjaGF0IGlzIHN0b3BwaW5nIHRoZSBnZW5lcmF0aW9uLCB0aGVuIHdhaXQgZm9yIHRoZSBmZXRjaCB0byBjb21wbGV0ZSBiZWZvcmUgcmVsb2FkaW5nIHRoZSBjaGF0LlxuICAgKi9cbiAgcHJpdmF0ZSBfaGFuZGxlQ2hhbmdlcygpIHtcbiAgICBjb25zdCBjaGFuZ2VzID0gdGhpcy5jaGFuZ2VzJC52YWx1ZTtcbiAgICAvLyBJZiB0aGUgY2hhdCBzZXJ2aWNlIGlzIGEgV2ViU29ja2V0Q2hhdFNlcnZpY2UsIGhhbmRsZSB0aGUgb3ZlcnJpZGUgb2YgdGhlIG1lc3NhZ2UgaGFuZGxlcnMgaWYgZXhpc3RzXG4gICAgaWYgKGNoYW5nZXM/Lm1lc3NhZ2VIYW5kbGVycyAmJiB0aGlzLm1lc3NhZ2VIYW5kbGVycykge1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5vdmVycmlkZU1lc3NhZ2VIYW5kbGVycyh0aGlzLm1lc3NhZ2VIYW5kbGVycyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgdGhlIGNoYXQgd2l0aCB0aGUgcHJvdmlkZWQgY2hhdCBtZXNzYWdlcyBpZiBleGlzdHMsIG90aGVyd2lzZSBsb2FkIHRoZSBkZWZhdWx0IGNoYXRcbiAgICAgKiBPbmNlIHRoZSBjaGF0IGlzIGluaXRpYWxpemVkIChmaXJzdENoYW5nZXNIYW5kbGVkIGlzIHRydWUpLCBhbGxvdyBvcGVuaW5nIHRoZSBjaGF0IHdpdGggdGhlIG5ldyBwcm92aWRlZCBtZXNzYWdlcyAoaWYgZXhpc3RzKVxuICAgICAqL1xuICAgIGlmICghdGhpcy5maXJzdENoYW5nZXNIYW5kbGVkIHx8IGNoYW5nZXM/LmNoYXQpIHtcbiAgICAgIGNvbnN0IG9wZW5DaGF0ID0gKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tZXNzYWdlcyQudmFsdWUgJiYgdGhpcy5jb25maWcuc2F2ZWRDaGF0U2V0dGluZ3M/LmVuYWJsZWQpIHtcbiAgICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmxpc3RTYXZlZENoYXQoKTsgLy8gUmVmcmVzaCB0aGUgbGlzdCBvZiBzYXZlZCBjaGF0c1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3BlbkNoYXQodGhpcy5jaGF0IS5tZXNzYWdlcyk7XG4gICAgICB9O1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUNoYXRJZCgpO1xuICAgICAgaWYgKHRoaXMuY2hhdCkge1xuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LWNoYXQubmV3Jywgeydjb25maWd1cmF0aW9uJzogSlNPTi5zdHJpbmdpZnkodGhpcy5jaGF0U2VydmljZS5hc3Npc3RhbnRDb25maWckLnZhbHVlKSwnY2hhdC1pbml0JzogSlNPTi5zdHJpbmdpZnkodGhpcy5jaGF0KX0pO1xuICAgICAgICBvcGVuQ2hhdCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1jaGF0Lm5ldycsIHsnY29uZmlndXJhdGlvbic6IEpTT04uc3RyaW5naWZ5KHRoaXMuY2hhdFNlcnZpY2UuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSl9KTtcbiAgICAgICAgdGhpcy5sb2FkRGVmYXVsdENoYXQoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGNoYXQgaXMgaW5pdGlhbGl6ZWQsIHRoZSBpbml0aWFsaXphdGlvbiBldmVudCBpcyBcIlF1ZXJ5XCIsIHRoZSBxdWVyeSBjaGFuZ2VzIGFuZCB0aGUgcXVlcnlDaGFuZ2VTaG91bGRUcmlnZ2VyUmVsb2FkIGZ1bmN0aW9uIGlzIHByb3ZpZGVkLFxuICAgICAqIHRoZW4gdGhlIGNoYXQgc2hvdWxkIGJlIHJlbG9hZGVkIGlmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWVcbiAgICAgKiBPdGhlcndpc2UsIHRoZSBjaGF0IHNob3VsZCBiZSByZWxvYWRlZCBieSBkZWZhdWx0XG4gICAgICovXG4gICAgaWYgKHRoaXMuZmlyc3RDaGFuZ2VzSGFuZGxlZCAmJiBjaGFuZ2VzPy5xdWVyeSAmJiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZXZlbnQgPT09ICdRdWVyeScpIHtcbiAgICAgIGlmICh0aGlzLnF1ZXJ5Q2hhbmdlU2hvdWxkVHJpZ2dlclJlbG9hZCA/IHRoaXMucXVlcnlDaGFuZ2VTaG91bGRUcmlnZ2VyUmVsb2FkKHRoaXMuX3ByZXZpb3VzUXVlcnksIHRoaXMucXVlcnkpIDogdHJ1ZSkge1xuICAgICAgICBpZiAoISF0aGlzLmNoYXRTZXJ2aWNlLnN0b3BwaW5nR2VuZXJhdGlvbiQudmFsdWUpIHtcbiAgICAgICAgICBpZiAoIXRoaXMuX3JlbG9hZFN1YnNjcmlwdGlvbikge1xuICAgICAgICAgICAgLy8gQ3JlYXRlIGEgc3Vic2NyaXB0aW9uIHRvIHdhaXQgZm9yIGJvdGggc3RyZWFtaW5nJCBhbmQgc3RvcHBpbmdHZW5lcmF0aW9uJCB0byBiZSBmYWxzZVxuICAgICAgICAgICAgdGhpcy5fcmVsb2FkU3Vic2NyaXB0aW9uID0gY29tYmluZUxhdGVzdChbXG4gICAgICAgICAgICAgIHRoaXMuY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCxcbiAgICAgICAgICAgICAgdGhpcy5jaGF0U2VydmljZS5zdG9wcGluZ0dlbmVyYXRpb24kXG4gICAgICAgICAgICBdKVxuICAgICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBmaWx0ZXIoKFtzdHJlYW1pbmcsIHN0b3BwaW5nXSkgPT4gIXN0cmVhbWluZyAmJiAhc3RvcHBpbmcpLCAvLyBXYWl0IHVudGlsIGJvdGggYXJlIGZhbHNlXG4gICAgICAgICAgICAgICAgdGFrZSgxKSAvLyBDb21wbGV0ZSBhZnRlciB0aGUgZmlyc3QgbWF0Y2hcbiAgICAgICAgICAgICAgKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEV4ZWN1dGUgdGhlIHJlbG9hZCBhZnRlciB0aGUgcXVlcnkgY2hhbmdlXG4gICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlclJlbG9hZEFmdGVyUXVlcnlDaGFuZ2UoKTtcbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgX3ByZXZpb3VzUXVlcnkgd2l0aCB0aGUgY3VycmVudCBxdWVyeVxuICAgICAgICAgICAgICAgIHRoaXMuX3ByZXZpb3VzUXVlcnkgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMucXVlcnkpKTtcbiAgICAgICAgICAgICAgICAvLyBDbGVhbiB1cCBzdWJzY3JpcHRpb24gYW5kIHJlc2V0IGl0cyB2YWx1ZVxuICAgICAgICAgICAgICAgIHRoaXMuX3JlbG9hZFN1YnNjcmlwdGlvbiEudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZWxvYWRTdWJzY3JpcHRpb24gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghIXRoaXMuY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJC52YWx1ZSkge1xuICAgICAgICAgIGlmICghdGhpcy5fcmVsb2FkU3Vic2NyaXB0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLl9yZWxvYWRTdWJzY3JpcHRpb24gPSB0aGlzLmNoYXRTZXJ2aWNlLnN0b3BHZW5lcmF0aW9uKClcbiAgICAgICAgICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgICAgICAgICAgbmV4dDogKCkgPT4ge30sXG4gICAgICAgICAgICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgIC8vIENsZWFuIHVwIHN1YnNjcmlwdGlvbiBhbmQgcmVzZXQgaXRzIHZhbHVlXG4gICAgICAgICAgICAgICAgICB0aGlzLl9yZWxvYWRTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICAgICAgICB0aGlzLl9yZWxvYWRTdWJzY3JpcHRpb24gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgLy8gV2FpdCBmb3IgdGhlIG9uZ29pbmcgZmV0Y2ggdG8gY29tcGxldGUsIHRoZW4gdHJpZ2dlciB0aGUgcmVsb2FkXG4gICAgICAgICAgICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLnN0cmVhbWluZyQucGlwZShcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyKChzdHJlYW1pbmcpID0+ICFzdHJlYW1pbmcpLFxuICAgICAgICAgICAgICAgICAgICB0YWtlKDEpXG4gICAgICAgICAgICAgICAgICApLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEV4ZWN1dGUgdGhlIHJlbG9hZCBhZnRlciB0aGUgcXVlcnkgY2hhbmdlXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3RyaWdnZXJSZWxvYWRBZnRlclF1ZXJ5Q2hhbmdlKCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBfcHJldmlvdXNRdWVyeSB3aXRoIHRoZSBjdXJyZW50IHF1ZXJ5XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3ByZXZpb3VzUXVlcnkgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMucXVlcnkpKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ2xlYW4gdXAgc3Vic2NyaXB0aW9uIGFuZCByZXNldCBpdHMgdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVsb2FkU3Vic2NyaXB0aW9uIS51bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZWxvYWRTdWJzY3JpcHRpb24gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBFeGVjdXRlIHRoZSByZWxvYWQgYWZ0ZXIgdGhlIHF1ZXJ5IGNoYW5nZVxuICAgICAgICAgIHRoaXMuX3RyaWdnZXJSZWxvYWRBZnRlclF1ZXJ5Q2hhbmdlKCk7XG4gICAgICAgICAgLy8gVXBkYXRlIF9wcmV2aW91c1F1ZXJ5IHdpdGggdGhlIGN1cnJlbnQgcXVlcnlcbiAgICAgICAgICB0aGlzLl9wcmV2aW91c1F1ZXJ5ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLnF1ZXJ5KSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFVwZGF0ZSBfcHJldmlvdXNRdWVyeSB3aXRoIHRoZSBjdXJyZW50IHF1ZXJ5XG4gICAgICAgIHRoaXMuX3ByZXZpb3VzUXVlcnkgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMucXVlcnkpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVHJpZ2dlcnMgYSByZWxvYWQgYWZ0ZXIgdGhlIHF1ZXJ5IGNoYW5nZS5cbiAgICogVGhpcyBtZXRob2QgcGVyZm9ybXMgdGhlIG5lY2Vzc2FyeSBvcGVyYXRpb25zIHRvIHJlbG9hZCB0aGUgY2hhdCBhZnRlciBhIHF1ZXJ5IGNoYW5nZS5cbiAgICogSXQgc2V0cyB0aGUgc3lzdGVtIGFuZCB1c2VyIG1lc3NhZ2VzLCByZXNldHMgdGhlIHNhdmVkQ2hhdElkLCBnZW5lcmF0ZXMgYSBuZXcgY2hhdElkLFxuICAgKiBnZW5lcmF0ZXMgYSBuZXcgY2hhdCBhdWRpdCBldmVudCwgYW5kIGhhbmRsZXMgdGhlIHF1ZXJ5IG1vZGUuXG4gICAqL1xuICBwcml2YXRlIF90cmlnZ2VyUmVsb2FkQWZ0ZXJRdWVyeUNoYW5nZSgpIHtcbiAgICBjb25zdCBzeXN0ZW1Nc2cgPSB7IHJvbGU6ICdzeXN0ZW0nLCBjb250ZW50OiB0aGlzLmNvbmZpZy5kZWZhdWx0VmFsdWVzLnN5c3RlbVByb21wdCwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHsgZGlzcGxheTogZmFsc2UsIG1lc3NhZ2VJZDogZ3VpZCgpIH0gfTtcbiAgICAvLyBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdpdGggb2xkIGNvbmZpZ3VyYXRpb24gZmlsZXNcbiAgICBjb25zdCB1c2VyUHJvbXB0ID0gdGhpcy5jb25maWcuZGVmYXVsdFZhbHVlcy51c2VyUHJvbXB0LnJlcGxhY2UoL1xce1xceyguKj8pXFx9XFx9L2csICdbWyQxXV0nKTtcbiAgICBjb25zdCB1c2VyTXNnID0geyByb2xlOiAndXNlcicsIGNvbnRlbnQ6IEFzc2lzdGFudFV0aWxzLmZvcm1hdFByb21wdCh0aGlzLnRyYW5zbG9jby50cmFuc2xhdGUodXNlclByb21wdCkgLCB7IHByaW5jaXBhbDogdGhpcy5wcmluY2lwYWxTZXJ2aWNlLnByaW5jaXBhbCB9KSwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHsgZGlzcGxheTogdGhpcy5jb25maWcubW9kZVNldHRpbmdzLmRpc3BsYXlVc2VyUHJvbXB0LCBtZXNzYWdlSWQ6IGd1aWQoKSB9IH07XG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUNoYXRJZCgpOyAvLyBHZW5lcmF0ZSBhIG5ldyBjaGF0SWRcbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LWNoYXQubmV3Jywgeydjb25maWd1cmF0aW9uJzogSlNPTi5zdHJpbmdpZnkodGhpcy5jaGF0U2VydmljZS5hc3Npc3RhbnRDb25maWckLnZhbHVlKX0pOyAvLyBHZW5lcmF0ZSBhIG5ldyBjaGF0IGF1ZGl0IGV2ZW50XG4gICAgdGhpcy5faGFuZGxlUXVlcnlNb2RlKHN5c3RlbU1zZywgdXNlck1zZyk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHNjcm9sbCBsaXN0ZW5lciB0byB0aGUgbWVzc2FnZSBsaXN0IGVsZW1lbnQuXG4gICAqIFRoZSBsaXN0ZW5lciBpcyB0cmlnZ2VyZWQgd2hlbiBhbnkgb2YgdGhlIGZvbGxvd2luZyBldmVudHMgb2NjdXI6XG4gICAqIC0gTG9hZGluZyBzdGF0ZSBjaGFuZ2VzXG4gICAqIC0gTWVzc2FnZXMgY2hhbmdlXG4gICAqIC0gU3RyZWFtaW5nIHN0YXRlIGNoYW5nZXNcbiAgICogLSBTY3JvbGwgZXZlbnQgb2NjdXJzIG9uIHRoZSBtZXNzYWdlIGxpc3QgZWxlbWVudFxuICAgKlxuICAgKiBXaGVuIHRoZSBsaXN0ZW5lciBpcyB0cmlnZ2VyZWQsIGl0IHVwZGF0ZXMgdGhlIGBpc0F0Qm90dG9tYCBwcm9wZXJ0eS5cbiAgICovXG4gIHByaXZhdGUgX2FkZFNjcm9sbExpc3RlbmVyKCkge1xuICAgIGNvbnN0IG1lc3NhZ2VMaXN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYG1lc3NhZ2VMaXN0LSR7dGhpcy5pbnN0YW5jZUlkfWApO1xuICAgIG1lcmdlKHRoaXMubG9hZGluZyQsIHRoaXMubWVzc2FnZXMkLCB0aGlzLmNoYXRTZXJ2aWNlLnN0cmVhbWluZyQsIGZyb21FdmVudChtZXNzYWdlTGlzdCEsICdzY3JvbGwnKSlcbiAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmlzQXRCb3R0b20gPSB0aGlzLl90b2dnbGVTY3JvbGxCdXR0b25WaXNpYmlsaXR5KCk7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbW9kZWwgZGVzY3JpcHRpb24gYmFzZWQgb24gdGhlIGRlZmF1bHRWYWx1ZXMgc2VydmljZV9pZCBhbmQgbW9kZWxfaWRcbiAgICovXG4gIHVwZGF0ZU1vZGVsRGVzY3JpcHRpb24oKSB7XG4gICAgdGhpcy5tb2RlbERlc2NyaXB0aW9uID0gdGhpcy5jaGF0U2VydmljZS5nZXRNb2RlbCh0aGlzLmNvbmZpZy5kZWZhdWx0VmFsdWVzLnNlcnZpY2VfaWQsIHRoaXMuY29uZmlnLmRlZmF1bHRWYWx1ZXMubW9kZWxfaWQpO1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJtaXRzIGEgcXVlc3Rpb24gZnJvbSB0aGUgdXNlci5cbiAgICogSWYgdGhlIHVzZXIgaXMgZWRpdGluZyBhIHByZXZpb3VzIG1lc3NhZ2UsIHJlbW92ZXMgYWxsIHN1YnNlcXVlbnQgbWVzc2FnZXMgZnJvbSB0aGUgY2hhdCBoaXN0b3J5LlxuICAgKiBUcmlnZ2VycyB0aGUgZmV0Y2ggb2YgdGhlIGFuc3dlciBmb3IgdGhlIHN1Ym1pdHRlZCBxdWVzdGlvbiBieSBjYWxsaW5nIF9mZXRjaEFuc3dlcigpLlxuICAgKiBDbGVhcnMgdGhlIGlucHV0IHZhbHVlIGluIHRoZSBVSS5cbiAgICog4pqg77iPIElmIHRoZSBjaGF0IGlzIHN0cmVhbWluZyBvciBzdG9wcGluZyB0aGUgZ2VuZXJhdGlvbiwgdGhlIG9wZXJhdGlvbiBpcyBub3QgYWxsb3dlZC5cbiAgICovXG4gIHN1Ym1pdFF1ZXN0aW9uKCkge1xuICAgIGlmICghIXRoaXMuY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJC52YWx1ZSB8fCAhIXRoaXMuY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJC52YWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5xdWVzdGlvbi50cmltKCkgJiYgdGhpcy5tZXNzYWdlcyQudmFsdWUgJiYgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSkge1xuICAgICAgLy8gV2hlbiB0aGUgdXNlciBzdWJtaXRzIGEgcXVlc3Rpb24sIGlmIHRoZSB1c2VyIGlzIGVkaXRpbmcgYSBwcmV2aW91cyBtZXNzYWdlLCByZW1vdmUgYWxsIHN1YnNlcXVlbnQgbWVzc2FnZXMgZnJvbSB0aGUgY2hhdCBoaXN0b3J5XG4gICAgICBpZiAodGhpcy5pbmRleE1lc3NhZ2VUb0VkaXQgIT09IHVuZGVmaW5lZCAmJiB0aGlzLnJhbmtNZXNzYWdlVG9FZGl0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gVXBkYXRlIHRoZSBtZXNzYWdlcyBpbiB0aGUgVUlcbiAgICAgICAgdGhpcy5tZXNzYWdlcyQubmV4dCh0aGlzLm1lc3NhZ2VzJC52YWx1ZS5zbGljZSgwLCB0aGlzLmluZGV4TWVzc2FnZVRvRWRpdCkpO1xuICAgICAgICAvLyBVcGRhdGUgdGhlIHJhdyBtZXNzYWdlcyBpbiB0aGUgY2hhdCBoaXN0b3J5IHdoaWNoIGlzIHRoZSBjbGVhbiB2ZXJzaW9uIHVzZWQgdG8gbWFrZSB0aGUgbmV4dCByZXF1ZXN0XG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkgPSB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5LnNsaWNlKDAsIHRoaXMucmFua01lc3NhZ2VUb0VkaXQtMSk7XG4gICAgICAgIHRoaXMuaW5kZXhNZXNzYWdlVG9FZGl0ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLnJhbmtNZXNzYWdlVG9FZGl0ID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgLy8gUmVtb3ZlIHRoZSBzZWFyY2ggd2FybmluZyBtZXNzYWdlIGlmIGV4aXN0c1xuICAgICAgaWYgKHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkuYXQoLTEpPy5yb2xlID09PSAnc2VhcmNoLXdhcm5pbmcnKSB7XG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkucG9wKCk7XG4gICAgICB9XG4gICAgICAvLyBGZXRjaCB0aGUgYW5zd2VyXG4gICAgICB0aGlzLl9mZXRjaEFuc3dlcih0aGlzLnF1ZXN0aW9uLnRyaW0oKSwgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSk7XG4gICAgICAvLyBDbGVhciB0aGUgaW5wdXQgdmFsdWUgaW4gdGhlIFVJXG4gICAgICB0aGlzLnF1ZXN0aW9uSW5wdXQhLm5hdGl2ZUVsZW1lbnQudmFsdWUgPSAnJztcbiAgICAgIHRoaXMucXVlc3Rpb25JbnB1dCEubmF0aXZlRWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgYXV0b2A7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaWdnZXJzIHRoZSBmZXRjaCBvZiB0aGUgYW5zd2VyIGZvciB0aGUgZ2l2ZW4gcXVlc3Rpb24gYW5kIHVwZGF0ZXMgdGhlIGNvbnZlcnNhdGlvbi5cbiAgICogR2VuZXJhdGVzIGFuIGF1ZGl0IGV2ZW50IGZvciB0aGUgdXNlciBpbnB1dC5cbiAgICpcbiAgICogQHBhcmFtIHF1ZXN0aW9uIC0gVGhlIHF1ZXN0aW9uIGFza2VkIGJ5IHRoZSB1c2VyLlxuICAgKiBAcGFyYW0gY29udmVyc2F0aW9uIC0gVGhlIGN1cnJlbnQgY29udmVyc2F0aW9uIG1lc3NhZ2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBfZmV0Y2hBbnN3ZXIocXVlc3Rpb246IHN0cmluZywgY29udmVyc2F0aW9uOiBDaGF0TWVzc2FnZVtdKSB7XG4gICAgLy8gbWVyZ2UgYWRkaXRpb25hbFdvcmtmbG93UHJvcGVydGllcyBmcm9tIHRoZSBjaGF0IGNvbXBvbmVudCBhbmQgdGhlIGN1c3RvbWl6YXRpb24gSlNPTlxuICAgIGNvbnN0IGFkZGl0aW9uYWxXb3JrZmxvd1Byb3BlcnRpZXMgPSB7IC4uLnRoaXMuY29uZmlnLmFkZGl0aW9uYWxXb3JrZmxvd1Byb3BlcnRpZXMsIC4uLnRoaXMuYWRkaXRpb25hbFdvcmtmbG93UHJvcGVydGllcyB9O1xuICAgIGNvbnN0IHVzZXJNc2cgPSB7IHJvbGU6ICd1c2VyJywgY29udGVudDogcXVlc3Rpb24sIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7IGRpc3BsYXk6IHRydWUsIG1lc3NhZ2VJZDogZ3VpZCgpLCBpc1VzZXJJbnB1dDogdHJ1ZSwgYWRkaXRpb25hbFdvcmtmbG93UHJvcGVydGllcyB9IH07XG4gICAgY29uc3QgbWVzc2FnZXMgPSBbLi4uY29udmVyc2F0aW9uLCB1c2VyTXNnXTtcbiAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KG1lc3NhZ2VzKTsgLy8gVXBkYXRlIHRoZSBtZXNzYWdlcyBpbiB0aGUgVUkgd2l0aCB0aGUgbmV3IHVzZXIgbWVzc2FnZVxuICAgIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkgPSBtZXNzYWdlczsgLy8gVXBkYXRlIHRoZSBjaGF0IGhpc3Rvcnkgd2l0aCB0aGUgbmV3IHVzZXIgbWVzc2FnZVxuICAgIHRoaXMuc2Nyb2xsRG93bigpOyAvLyBTY3JvbGwgZG93biB0byB0aGUgYm90dG9tIG9mIHRoZSBjaGF0IHRvIHNlZSB0aGUgbmV3IHVzZXIgbWVzc2FnZSBhbmQgdGhlIGluY29taW5nIGFzc2lzdGFudCBhbnN3ZXJcbiAgICB0aGlzLmZldGNoKG1lc3NhZ2VzKTtcbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LW1lc3NhZ2UubWVzc2FnZScsIHsgLi4udGhpcy5fZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyh1c2VyTXNnKSwgJ3F1ZXJ5JzogSlNPTi5zdHJpbmdpZnkodGhpcy5xdWVyeSksICdpcy11c2VyLWlucHV0JzogdHJ1ZSwgJ2VuYWJsZWQtZnVuY3Rpb25zJzogdGhpcy5jb25maWcuZGVmYXVsdFZhbHVlcy5mdW5jdGlvbnM/LmZpbHRlcihmdW5jID0+IGZ1bmMuZW5hYmxlZCkubWFwKGZ1bmMgPT4gZnVuYy5uYW1lKSwgJ2FkZGl0aW9uYWwtd29ya2Zsb3ctcHJvcGVydGllcyc6IEpTT04uc3RyaW5naWZ5KGFkZGl0aW9uYWxXb3JrZmxvd1Byb3BlcnRpZXMpIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIERlcGVuZGluZyBvbiB0aGUgY29ubmVjdGlvbidzIHN0YXRlIDpcbiAgICogIC0gSWYgY29ubmVjdGVkID0+IGdpdmVuIGEgbGlzdCBvZiBtZXNzYWdlcywgdGhlIGNoYXQgZW5kcG9pbnQgaXMgaW52b2tlZCBmb3IgYSBjb250aW51YXRpb24gYW5kIHVwZGF0ZXMgdGhlIGxpc3Qgb2YgbWVzc2FnZXMgYWNjb3JkaW5nbHkuXG4gICAqICAtIElmIGFueSBvdGhlciBzdGF0ZSA9PiBhIGNvbm5lY3Rpb24gZXJyb3IgbWVzc2FnZSBpcyBkaXNwbGF5ZWQgaW4gdGhlIGNoYXQuXG4gICAqIOKaoO+4jyBJZiB0aGUgYXNzaXN0YW50IGlzIHN0cmVhbWluZyBvciBzdG9wcGluZyB0aGUgZ2VuZXJhdGlvbiwgdGhlIG9wZXJhdGlvbiBpcyBub3QgYWxsb3dlZC5cbiAgICogQHBhcmFtIG1lc3NhZ2VzIFRoZSBsaXN0IG9mIG1lc3NhZ2VzIHRvIGludm9rZSB0aGUgY2hhdCBlbmRwb2ludCB3aXRoXG4gICAqL1xuICBwdWJsaWMgZmV0Y2gobWVzc2FnZXM6IENoYXRNZXNzYWdlW10pIHtcbiAgICBpZiAoISF0aGlzLmNoYXRTZXJ2aWNlLnN0cmVhbWluZyQudmFsdWUgfHwgISF0aGlzLmNoYXRTZXJ2aWNlLnN0b3BwaW5nR2VuZXJhdGlvbiQudmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fdXBkYXRlQ29ubmVjdGlvblN0YXR1cygpO1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcblxuICAgIGlmICh0aGlzLmlzQ29ubmVjdGVkKSB7XG4gICAgICB0aGlzLmxvYWRpbmckLm5leHQodHJ1ZSk7XG4gICAgICB0aGlzLl9kYXRhU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgICAgdGhpcy5fZGF0YVN1YnNjcmlwdGlvbiA9IHRoaXMuY2hhdFNlcnZpY2UuZmV0Y2gobWVzc2FnZXMsIHRoaXMucXVlcnkpXG4gICAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICAgIG5leHQ6IHJlcyA9PiB0aGlzLnVwZGF0ZURhdGEocmVzLmhpc3RvcnkpLFxuICAgICAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVDb25uZWN0aW9uU3RhdHVzKCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNDb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IHtcbiAgICAgICAgICAgICAgICByb2xlOiAnY29ubmVjdGlvbi1lcnJvcicsXG4gICAgICAgICAgICAgICAgY29udGVudDogKHsgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IHRoaXMudHJhbnNsb2NvLnRyYW5zbGF0ZSh0aGlzLmNvbmZpZy5jb25uZWN0aW9uU2V0dGluZ3MuY29ubmVjdGlvbkVycm9yTWVzc2FnZSkgfSBhcyBUZXh0TWVzc2FnZUNvbnRlbnQpLFxuICAgICAgICAgICAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7IGRpc3BsYXk6IHRydWUsIG1lc3NhZ2VJZDogZ3VpZCgpIH1cbiAgICAgICAgICAgICAgfSBhcyBhbnkgYXMgQ2hhdE1lc3NhZ2U7XG4gICAgICAgICAgICAgIHRoaXMubWVzc2FnZXMkLm5leHQoWy4uLm1lc3NhZ2VzLCBtZXNzYWdlXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnRlcm1pbmF0ZUZldGNoKCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBsYXN0IG1lc3NhZ2UgaWYgaXQncyBhbiBlbXB0eSBtZXNzYWdlXG4gICAgICAgICAgICAvLyBUaGlzIGlzIGR1ZSB0byB0aGUgbWFubmVyIGluIHdoaWNoIHRoZSBjaGF0IHNlcnZpY2UgaGFuZGxlcyBjb25zZWN1dGl2ZSBtZXNzYWdlc1xuICAgICAgICAgICAgY29uc3QgbGFzdE1lc3NhZ2UgPSB0aGlzLm1lc3NhZ2VzJC52YWx1ZT8uYXQoLTEpO1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNFbXB0eUFzc2lzdGFudE1lc3NhZ2UobGFzdE1lc3NhZ2UpKSB7XG4gICAgICAgICAgICAgIHRoaXMubWVzc2FnZXMkLm5leHQodGhpcy5tZXNzYWdlcyQudmFsdWU/LnNsaWNlKDAsIC0xKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnRlcm1pbmF0ZUZldGNoKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IHsgcm9sZTogJ2Nvbm5lY3Rpb24tZXJyb3InLCBjb250ZW50OiB0aGlzLnRyYW5zbG9jby50cmFuc2xhdGUodGhpcy5jb25maWcuY29ubmVjdGlvblNldHRpbmdzLmNvbm5lY3Rpb25FcnJvck1lc3NhZ2UpLCBhZGRpdGlvbmFsUHJvcGVydGllczogeyBkaXNwbGF5OiB0cnVlLCBtZXNzYWdlSWQ6IGd1aWQoKSB9IH07XG4gICAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KFsuLi5tZXNzYWdlcywgbWVzc2FnZV0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmF1dG9tYXRpY1Njcm9sbFRvTGFzdFJlc3BvbnNlIHx8IHRoaXMuY29uZmlnLmdsb2JhbFNldHRpbmdzLmF1dG9tYXRpY1Njcm9sbCkge1xuICAgICAgdGhpcy5zY3JvbGxEb3duKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHJ5IHRvIGZldGNoIHRoZSBtZXNzYWdlcyBpZiB0aGUgY29ubmVjdGlvbiBpc3N1ZXMuXG4gICAqICAtIElmIHJlY29ubmVjdGluZyA9PiBrZWVwIGRpc3BsYXkgdGhlIGNvbm5lY3Rpb24gZXJyb3IgbWVzc2FnZSBldmVuIHdoZW4gY2xpY2tpbmcgb24gdGhlIFwicmV0cnlcIiBidXR0b24gYW5kIGluY3JlYXNpbmcgdGhlIG51bWJlciBvZiByZXRyaWFsIGF0dGVtcHRzLCB1bnRpbCB0aGUgY29ubmVjdGlvbiBpcyByZS1lc3RhYmxpc2hlZFxuICAgKiAgLSBJZiBkaXNjb25uZWN0ZWQgPT4gT24gY2xpY2sgb24gdGhlIFwicmV0cnlcIiBidXR0b24sIHN0YXJ0IHRoZSBjb25uZWN0aW9uIHByb2Nlc3Mgd2hpbGUgZGlzcGxheWluZyB0aGUgY29ubmVjdGlvbiBlcnJvciBtZXNzYWdlIDpcbiAgICogICAgICAqIElmIHN1Y2Nlc3NmdWwgPT4gZ2l2ZW4gYSBsaXN0IG9mIG1lc3NhZ2VzLCB0aGUgY2hhdCBlbmRwb2ludCBpcyBpbnZva2VkIGZvciBhIGNvbnRpbnVhdGlvbiBhbmQgdXBkYXRlcyB0aGUgbGlzdCBvZiBtZXNzYWdlcyBhY2NvcmRpbmdseS5cbiAgICogICAgICAqIElmIGZhaWxlZCA9PiBpbmNyZWFzZSB0aGUgbnVtYmVyIG9mIHJldHJpYWwgYXR0ZW1wdHNcbiAgICovXG4gIHJldHJ5RmV0Y2goKSB7XG4gICAgLy8gQSBvbmUtdGltZSBsaXN0ZW5lciBmb3IgcmVjb25uZWN0ZWQgZXZlbnRcbiAgICBjb25zdCBvblJlY29ubmVjdGVkSGFuZGxlciA9ICgpID0+IHtcbiAgICAgIC8vIEdldCB0aGUgbWVzc2FnZXMgd2l0aG91dCB0aGUgbGFzdCBvbmUgKHRoZSBjb25uZWN0aW9uIGVycm9yIG1lc3NhZ2UpXG4gICAgICBjb25zdCBtZXNzYWdlcyA9IHRoaXMubWVzc2FnZXMkLnZhbHVlIS5zbGljZSgwLCAtMSk7XG4gICAgICAvLyBGaW5kIHRoZSBsYXN0IFwidXNlclwiIG1lc3NhZ2UgaW4gdGhlIG1lc3NhZ2VzIGxpc3RcbiAgICAgIGxldCBpbmRleCA9IG1lc3NhZ2VzLmxlbmd0aCAtIDE7XG4gICAgICB3aGlsZSAoaW5kZXggPj0gMCAmJiBtZXNzYWdlc1tpbmRleF0ucm9sZSAhPT0gJ3VzZXInKSB7XG4gICAgICAgIGluZGV4LS07XG4gICAgICB9XG4gICAgICAvLyBJZiBhIHVzZXIgbWVzc2FnZSBpcyBmb3VuZCAoYW5kIGl0IHNob3VsZCBhbHdheXMgYmUgdGhlIGNhc2UpLCByZW1vdmUgYWxsIHN1YnNlcXVlbnQgbWVzc2FnZXMgZnJvbSB0aGUgY2hhdCBoaXN0b3J5XG4gICAgICAvLyBVcGRhdGUgdGhlIG1lc3NhZ2VzIGluIHRoZSBVSVxuICAgICAgLy8gYW5kIGZldGNoIHRoZSBhbnN3ZXIgZnJvbSB0aGUgYXNzaXN0YW50XG4gICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KHRoaXMubWVzc2FnZXMkLnZhbHVlIS5zbGljZSgwLCBpbmRleCArIDEpKTtcbiAgICAgICAgY29uc3QgcmVtYXBwZWRJbmRleCA9IHRoaXMuYXNzaXN0YW50VXRpbHMuZ2V0TWVzc2FnZVJhbmtJbkNoYXRIaXN0b3J5KHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnksIG1lc3NhZ2VzW2luZGV4XS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQpO1xuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ID0gdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSEuc2xpY2UoMCwgcmVtYXBwZWRJbmRleCArIDEpO1xuICAgICAgICB0aGlzLmZldGNoKHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkpO1xuICAgICAgfVxuICAgICAgdGhpcy5yZXRyaWFsQXR0ZW1wdHMgPSB1bmRlZmluZWQ7IC8vIFJlc2V0IHRoZSBudW1iZXIgb2YgcmV0cmlhbCBhdHRlbXB0c1xuICAgICAgLyoqXG4gICAgICAgKiBUbyByZW1vdmUgdGhlIGhhbmRsZXIgZm9yIG9ucmVjb25uZWN0ZWQoKSBhZnRlciBpdCdzIGJlZW4gcmVnaXN0ZXJlZCxjYW5ub3QgZGlyZWN0bHkgdXNlIG9mZigpIGxpa2UgeW91IHdvdWxkIGZvciBub3JtYWwgZXZlbnRzIHJlZ2lzdGVyZWQgd2l0aCBjb25uZWN0aW9uLm9uKCkuXG4gICAgICAgKiBJbnN0ZWFkLCB5b3UgbmVlZCB0byBleHBsaWNpdGx5IHJlbW92ZSBvciByZXNldCB0aGUgaGFuZGxlciBieSBhc3NpZ25pbmcgaXQgdG8gbnVsbCBvciBhbiBlbXB0eSBmdW5jdGlvblxuICAgICAgICovXG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLmNvbm5lY3Rpb24hLm9ucmVjb25uZWN0ZWQoKCkgPT4ge30pO1xuICAgICAgLy8gUmVzZXQgdGhlIGZsYWcgdG8gZW5zdXJlIHRoZSBoYW5kbGVyIGlzIHJlZ2lzdGVyZWQgYWdhaW4gd2hlbiBuZWVkZWRcbiAgICAgIHRoaXMuX2lzUmVjb25uZWN0ZWRMaXN0ZW5lclJlZ2lzdGVyZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgLy8gRGVwZW5kaW5nIG9uIHRoZSBjb25uZWN0aW9uJ3Mgc3RhdGUsIHRha2UgdGhlIGFwcHJvcHJpYXRlIGFjdGlvblxuICAgIHN3aXRjaCAodGhpcy5jaGF0U2VydmljZS5jb25uZWN0aW9uIS5zdGF0ZSkge1xuICAgICAgY2FzZSBIdWJDb25uZWN0aW9uU3RhdGUuQ29ubmVjdGVkOlxuICAgICAgICAvLyBJZiB0aGUgY29ubmVjdGlvbiBpcyByZS1lc3RhYmxpc2hlZCBpbiB0aGUgbWVhbnRpbWUsIGZldGNoIHRoZSBtZXNzYWdlc1xuICAgICAgICBvblJlY29ubmVjdGVkSGFuZGxlcigpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgSHViQ29ubmVjdGlvblN0YXRlLlJlY29ubmVjdGluZzpcbiAgICAgICAgLy8gQXR0YWNoIHRoZSByZWNvbm5lY3RlZCBsaXN0ZW5lciBpZiBub3QgYWxyZWFkeSByZWdpc3RlcmVkXG4gICAgICAgIGlmICghdGhpcy5faXNSZWNvbm5lY3RlZExpc3RlbmVyUmVnaXN0ZXJlZCkge1xuICAgICAgICAgIHRoaXMuY2hhdFNlcnZpY2UuY29ubmVjdGlvbiEub25yZWNvbm5lY3RlZChvblJlY29ubmVjdGVkSGFuZGxlcik7XG4gICAgICAgICAgdGhpcy5faXNSZWNvbm5lY3RlZExpc3RlbmVyUmVnaXN0ZXJlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSW5jcmVhc2UgdGhlIG51bWJlciBvZiByZXRyaWFsIGF0dGVtcHRzXG4gICAgICAgIHRoaXMucmV0cmlhbEF0dGVtcHRzID0gdGhpcy5yZXRyaWFsQXR0ZW1wdHMgPyB0aGlzLnJldHJpYWxBdHRlbXB0cyArIDEgOiAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgSHViQ29ubmVjdGlvblN0YXRlLkRpc2Nvbm5lY3RlZDpcbiAgICAgICAgLy8gU3RhcnQgdGhlIG5ldyBjb25uZWN0aW9uXG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2Uuc3RhcnRDb25uZWN0aW9uKClcbiAgICAgICAgICAudGhlbigoKSA9PiBvblJlY29ubmVjdGVkSGFuZGxlcigpKVxuICAgICAgICAgIC5jYXRjaCgoKSA9PiB7IC8vIElmIHRoZSBjb25uZWN0aW9uIGZhaWxzLCBpbmNyZWFzZSB0aGUgbnVtYmVyIG9mIHJldHJpYWwgYXR0ZW1wdHNcbiAgICAgICAgICAgIHRoaXMucmV0cmlhbEF0dGVtcHRzID0gdGhpcy5yZXRyaWFsQXR0ZW1wdHMgPyB0aGlzLnJldHJpYWxBdHRlbXB0cyArIDEgOiAxO1xuICAgICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0aGUgc2lnbmFsUiBjb25uZWN0aW9uIGlzIGNvbm5lY3RlZC5cbiAgICogRm9yIHRoZSBSRVNUIHByb3RvY29sLCB0aGUgY29ubmVjdGlvbiBpcyBhbHdheXMgY29uc2lkZXJlZCBjb25uZWN0ZWQgKGZvciB0aGUgbW9tZW50KS5cbiAgICovXG4gIHByaXZhdGUgX3VwZGF0ZUNvbm5lY3Rpb25TdGF0dXMoKSB7XG4gICAgdGhpcy5pc0Nvbm5lY3RlZCA9IHRoaXMuY2hhdFNlcnZpY2UuY29ubmVjdGlvbiEuc3RhdGUgPT09IEh1YkNvbm5lY3Rpb25TdGF0ZS5Db25uZWN0ZWQ7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIHRoZSBVSSB3aXRoIHRoZSBuZXcgbWVzc2FnZXNcbiAgICogQHBhcmFtIG1lc3NhZ2VzXG4gICAqL1xuICB1cGRhdGVEYXRhKG1lc3NhZ2VzOiBDaGF0TWVzc2FnZVtdKSB7XG4gICAgdGhpcy5tZXNzYWdlcyQubmV4dChtZXNzYWdlcyk7XG4gICAgdGhpcy5kYXRhLmVtaXQobWVzc2FnZXMpO1xuICAgIHRoaXMubG9hZGluZyQubmV4dChmYWxzZSk7XG4gICAgdGhpcy5xdWVzdGlvbiA9ICcnO1xuICAgIGlmICh0aGlzLmF1dG9tYXRpY1Njcm9sbFRvTGFzdFJlc3BvbnNlIHx8IHRoaXMuY29uZmlnLmdsb2JhbFNldHRpbmdzLmF1dG9tYXRpY1Njcm9sbCkge1xuICAgICAgdGhpcy5zY3JvbGxEb3duKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHRydWUgaWYgdGhlIGNoYXQgZGlzY3Vzc2lvbiBpcyBzY3JvbGxlZCBkb3duIHRvIHRoZSBib3R0b20sIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgcHJpdmF0ZSBfdG9nZ2xlU2Nyb2xsQnV0dG9uVmlzaWJpbGl0eSgpOiBib29sZWFuIHtcbiAgICBjb25zdCBtZXNzYWdlTGlzdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGBtZXNzYWdlTGlzdC0ke3RoaXMuaW5zdGFuY2VJZH1gKTtcbiAgICBpZiAobWVzc2FnZUxpc3QpIHtcbiAgICAgIHJldHVybiBNYXRoLnJvdW5kKG1lc3NhZ2VMaXN0LnNjcm9sbEhlaWdodCAtIG1lc3NhZ2VMaXN0LnNjcm9sbFRvcCAtIDEpIDw9IG1lc3NhZ2VMaXN0LmNsaWVudEhlaWdodDtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogU2Nyb2xsIGRvd24gdG8gdGhlIGJvdHRvbSBvZiB0aGUgY2hhdCBkaXNjdXNzaW9uXG4gICAqL1xuICBzY3JvbGxEb3duKCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgY29uc3QgbWVzc2FnZUxpc3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgbWVzc2FnZUxpc3QtJHt0aGlzLmluc3RhbmNlSWR9YCk7XG4gICAgICBpZiAobWVzc2FnZUxpc3QpIHtcbiAgICAgICAgbWVzc2FnZUxpc3Quc2Nyb2xsVG9wID0gbWVzc2FnZUxpc3Quc2Nyb2xsSGVpZ2h0O1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9XG4gICAgfSwgMTApO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IGEgbmV3IGNoYXQgd2l0aCB0aGUgZGVmYXVsdFZhbHVlcyBzZXR0aW5ncy5cbiAgICogVGhlIHNhdmVkQ2hhdElkIGluIHRoZSBjaGF0IHNlcnZpY2Ugd2lsbCBiZSByZXNldCwgc28gdGhhdCB0aGUgdXBjb21pbmcgc2F2ZWQgY2hhdCBvcGVyYXRpb25zIHdpbGwgYmUgcGVyZm9ybWVkIG9uIHRoZSBmcmVzaCBuZXcgY2hhdC5cbiAgICogSWYgdGhlIHNhdmVkQ2hhdCBmZWF0dXJlIGlzIGVuYWJsZWQsIHRoZSBsaXN0IG9mIHNhdmVkIGNoYXRzIHdpbGwgYmUgcmVmcmVzaGVkLlxuICAgKiDimqDvuI8gSWYgdGhlIGFzc2lzdGFudCBpcyBzdHJlYW1pbmcgb3Igc3RvcHBpbmcgdGhlIGdlbmVyYXRpb24sIHRoZSBvcGVyYXRpb24gaXMgbm90IGFsbG93ZWQuXG4gICAqL1xuICBuZXdDaGF0KCkge1xuICAgIGlmICghIXRoaXMuY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJC52YWx1ZSB8fCAhIXRoaXMuY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJC52YWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQ2hhdElkKCk7IC8vIEdlbmVyYXRlIGEgbmV3IGNoYXRJZFxuICAgIGlmICh0aGlzLmNvbmZpZy5zYXZlZENoYXRTZXR0aW5ncz8uZW5hYmxlZCkge1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5saXN0U2F2ZWRDaGF0KCk7IC8vIFJlZnJlc2ggdGhlIGxpc3Qgb2Ygc2F2ZWQgY2hhdHNcbiAgICB9XG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1jaGF0Lm5ldycsIHsnY29uZmlndXJhdGlvbic6IEpTT04uc3RyaW5naWZ5KHRoaXMuY2hhdFNlcnZpY2UuYXNzaXN0YW50Q29uZmlnJC52YWx1ZSl9KTsgLy8gR2VuZXJhdGUgYSBuZXcgY2hhdCBhdWRpdCBldmVudFxuICAgIHRoaXMubG9hZERlZmF1bHRDaGF0KCk7IC8vIFN0YXJ0IGEgbmV3IGNoYXRcbiAgfVxuXG4gIC8qKlxuICAgKiBBdHRhY2hlcyB0aGUgc3BlY2lmaWVkIGRvY3VtZW50IElEcyB0byB0aGUgYXNzaXN0YW50LlxuICAgKiBJZiBubyBkb2N1bWVudCBJRHMgYXJlIHByb3ZpZGVkLCB0aGUgb3BlcmF0aW9uIGlzIG5vdCBhbGxvd2VkLlxuICAgKiBJZiB0aGUgYWN0aW9uIGZvciBhdHRhY2hpbmcgYSBkb2N1bWVudCBpcyBub3QgZGVmaW5lZCBhdCB0aGUgYXBwbGljYXRpb24gY3VzdG9taXphdGlvbiBsZXZlbCwgYW4gZXJyb3IgaXMgbG9nZ2VkLlxuICAgKiDimqDvuI8gSWYgdGhlIGFzc2lzdGFudCBpcyBzdHJlYW1pbmcgb3Igc3RvcHBpbmcgdGhlIGdlbmVyYXRpb24sIHRoZSBvcGVyYXRpb24gaXMgbm90IGFsbG93ZWQuXG4gICAqIEBwYXJhbSBpZHMgLSBBbiBhcnJheSBvZiBkb2N1bWVudCBJRHMgdG8gYXR0YWNoLlxuICAgKi9cbiAgYXR0YWNoVG9DaGF0KGlkczogc3RyaW5nW10pIHtcbiAgICBpZiAoISF0aGlzLmNoYXRTZXJ2aWNlLnN0cmVhbWluZyQudmFsdWUgfHwgISF0aGlzLmNoYXRTZXJ2aWNlLnN0b3BwaW5nR2VuZXJhdGlvbiQudmFsdWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFpZHMgfHwgaWRzPy5sZW5ndGggPCAxKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGF0dGFjaERvY0FjdGlvbiA9IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5hY3Rpb25zPy5bXCJhdHRhY2hEb2NBY3Rpb25cIl07XG4gICAgaWYgKCFhdHRhY2hEb2NBY3Rpb24pIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYE5vIGFjdGlvbiBpcyBkZWZpbmVkIGZvciBhdHRhY2hpbmcgYSBkb2N1bWVudCB0byB0aGUgYXNzaXN0YW50IFwiJHt0aGlzLmluc3RhbmNlSWR9XCJgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdXNlck1zZyA9IHsgcm9sZTogJ3VzZXInLCBjb250ZW50OiAnJywgYWRkaXRpb25hbFByb3BlcnRpZXM6IHtkaXNwbGF5OiBmYWxzZSwgbWVzc2FnZUlkOiBndWlkKCksIGlzVXNlcklucHV0OiBmYWxzZSwgdHlwZTogXCJBY3Rpb25cIiwgZm9yY2VkV29ya2Zsb3c6IGF0dGFjaERvY0FjdGlvbi5mb3JjZWRXb3JrZmxvdywgZm9yY2VkV29ya2Zsb3dQcm9wZXJ0aWVzOiB7Li4uKGF0dGFjaERvY0FjdGlvbi5mb3JjZWRXb3JrZmxvd1Byb3BlcnRpZXMgfHwge30pLCBpZHN9LCBhZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzOiB0aGlzLmNvbmZpZy5hZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzfX07XG4gICAgLy8gUmVtb3ZlIHRoZSBzZWFyY2ggd2FybmluZyBtZXNzYWdlIGlmIGV4aXN0c1xuICAgIGlmICh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5IS5hdCgtMSk/LnJvbGUgPT09ICdzZWFyY2gtd2FybmluZycpIHtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhLnBvcCgpO1xuICAgIH1cbiAgICBjb25zdCBtZXNzYWdlcyA9IFsuLi50aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ISwgdXNlck1zZ107XG4gICAgdGhpcy5tZXNzYWdlcyQubmV4dChtZXNzYWdlcyk7XG4gICAgdGhpcy5mZXRjaChtZXNzYWdlcyk7XG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1hY3Rpb24ucmVxdWVzdGVkJywge1xuICAgICAgJ2RldGFpbCc6ICdhdHRhY2hEb2NBY3Rpb24nLFxuICAgICAgJ2ZvcmNlZC13b3JrZmxvdyc6ICdTaW5lcXVhQWRkU2VsZWN0ZWREb2N1bWVudHNXb3JrZmxvdycsXG4gICAgICAnZm9yY2VkLXdvcmtmbG93LXByb3BlcnRpZXMnOiBKU09OLnN0cmluZ2lmeShpZHMpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHRoZSBkZWZhdWx0IGNoYXQgd2l0aCB0aGUgZGVmYXVsdFZhbHVlcyBzZXR0aW5nc1xuICAgKiBJZiB0aGUgY2hhdCBpcyBtZWFudCB0byBiZSBpbml0aWFsaXplZCB3aXRoIGV2ZW50ID09PSBcIlF1ZXJ5XCIsIHRoZSBjb3JyZXNwb25kaW5nIHVzZXIgcXVlcnkgbWVzc2FnZSB3aWxsIGJlIGFkZGVkIHRvIHRoZSBjaGF0IGhpc3RvcnlcbiAgICovXG4gIGxvYWREZWZhdWx0Q2hhdCgpIHtcbiAgICBjb25zdCBkYXRlID0gKG5ldyBEYXRlKCkpLnRvTG9jYWxlU3RyaW5nKCdlbi1VUycsIHsgd2Vla2RheTogJ2xvbmcnLCBtb250aDogJ2xvbmcnLCBkYXk6ICcyLWRpZ2l0JywgeWVhcjogJ251bWVyaWMnIH0pO1xuICAgIC8vIERlZmluZSB0aGUgZGVmYXVsdCBzeXN0ZW0gcHJvbXB0IGFuZCB1c2VyIHByb21wdCBtZXNzYWdlc1xuICAgIGNvbnN0IHN5c3RlbU1zZyA9IHtcbiAgICAgIHJvbGU6ICdzeXN0ZW0nLFxuICAgICAgY29udGVudDogQXNzaXN0YW50VXRpbHMuZm9ybWF0UHJvbXB0KFxuICAgICAgICB0aGlzLnRyYW5zbG9jby50cmFuc2xhdGUodGhpcy5jb25maWcuZGVmYXVsdFZhbHVlcy5zeXN0ZW1Qcm9tcHQpLFxuICAgICAgICB7IHByaW5jaXBhbDogdGhpcy5wcmluY2lwYWxTZXJ2aWNlLnByaW5jaXBhbCwgZGF0ZSB9XG4gICAgICApLFxuICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IHsgZGlzcGxheTogZmFsc2UsIG1lc3NhZ2VJZDogZ3VpZCgpIH1cbiAgICB9O1xuICAgIC8vIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgd2l0aCBvbGQgY29uZmlndXJhdGlvbiBmaWxlc1xuICAgIGNvbnN0IHVzZXJQcm9tcHQgPSB0aGlzLmNvbmZpZy5kZWZhdWx0VmFsdWVzLnVzZXJQcm9tcHQucmVwbGFjZSgvXFx7XFx7KC4qPylcXH1cXH0vZywgJ1tbJDFdXScpO1xuICAgIGNvbnN0IHVzZXJNc2cgPSB7XG4gICAgICByb2xlOiAndXNlcicsXG4gICAgICBjb250ZW50OiBBc3Npc3RhbnRVdGlscy5mb3JtYXRQcm9tcHQoXG4gICAgICAgIHRoaXMudHJhbnNsb2NvLnRyYW5zbGF0ZSh1c2VyUHJvbXB0KSxcbiAgICAgICAgeyBwcmluY2lwYWw6IHRoaXMucHJpbmNpcGFsU2VydmljZS5wcmluY2lwYWwsIGRhdGUgfVxuICAgICAgKSxcbiAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiB7IGRpc3BsYXk6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5kaXNwbGF5VXNlclByb21wdCwgbWVzc2FnZUlkOiBndWlkKCkgfVxuICAgIH07XG5cbiAgICBpZiAodGhpcy5jb25maWcubW9kZVNldHRpbmdzLmluaXRpYWxpemF0aW9uLmV2ZW50ID09PSAnUXVlcnknKSB7XG4gICAgICB0aGlzLl9oYW5kbGVRdWVyeU1vZGUoc3lzdGVtTXNnLCB1c2VyTXNnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5faGFuZGxlUHJvbXB0TW9kZShzeXN0ZW1Nc2csIHVzZXJNc2cpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGVzIHRoZSBwcm9tcHQgbW9kZSBvZiB0aGUgY2hhdCBjb21wb25lbnQuXG4gICAqIElmIGBzZW5kVXNlclByb21wdGAgaXMgdHJ1ZSwgaXQgb3BlbnMgdGhlIGNoYXQgd2l0aCBib3RoIHN5c3RlbSBhbmQgdXNlciBtZXNzYWdlcyxcbiAgICogYW5kIGdlbmVyYXRlcyBhdWRpdCBldmVudHMgZm9yIGJvdGggbWVzc2FnZXMuXG4gICAqIElmIGBzZW5kVXNlclByb21wdGAgaXMgZmFsc2UsIGl0IG9wZW5zIHRoZSBjaGF0IHdpdGggb25seSB0aGUgc3lzdGVtIG1lc3NhZ2UsXG4gICAqIGFuZCBnZW5lcmF0ZXMgYW4gYXVkaXQgZXZlbnQgZm9yIHRoZSBzeXN0ZW0gbWVzc2FnZS5cbiAgICpcbiAgICogQHBhcmFtIHN5c3RlbU1zZyAtIFRoZSBzeXN0ZW0gbWVzc2FnZSB0byBiZSBkaXNwbGF5ZWQgaW4gdGhlIGNoYXQuXG4gICAqIEBwYXJhbSB1c2VyTXNnIC0gVGhlIHVzZXIgbWVzc2FnZSB0byBiZSBkaXNwbGF5ZWQgaW4gdGhlIGNoYXQgKG9wdGlvbmFsKS5cbiAgICovXG4gIHByaXZhdGUgX2hhbmRsZVByb21wdE1vZGUoc3lzdGVtTXNnOiBDaGF0TWVzc2FnZSwgdXNlck1zZzogQ2hhdE1lc3NhZ2UpIHtcbiAgICBpZiAodGhpcy5jb25maWcubW9kZVNldHRpbmdzLnNlbmRVc2VyUHJvbXB0KSB7XG4gICAgICB0aGlzLm9wZW5DaGF0KFtzeXN0ZW1Nc2csIHVzZXJNc2ddKTtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgdGhpcy5fZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyhzeXN0ZW1Nc2cpKTtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgdGhpcy5fZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyh1c2VyTXNnKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMub3BlbkNoYXQoW3N5c3RlbU1zZ10pO1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1tZXNzYWdlLm1lc3NhZ2UnLCB0aGlzLl9kZWZpbmVNZXNzYWdlQXVkaXREZXRhaWxzKHN5c3RlbU1zZykpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGVzIHRoZSBxdWVyeSBtb2RlIGJ5IGRpc3BsYXlpbmcgdGhlIHN5c3RlbSBtZXNzYWdlLCB1c2VyIG1lc3NhZ2UsIGFuZCB1c2VyIHF1ZXJ5IG1lc3NhZ2UuXG4gICAqIElmIHRoZSBwcm92aWRlZCBxdWVyeSB0ZXh0IGlzIG5vdCBlbXB0eSwgdGhlbiBhZGQgdGhlIHVzZXIgcXVlcnkgbWVzc2FnZSB0byB0aGUgY2hhdCBoaXN0b3J5IGFuZCBpbnZva2UgdGhlIGFzc2lzdGFudFxuICAgKiBPdGhlcndpc2UsIGp1c3Qgc3RhcnQgYSBuZXcgY2hhdCB3aXRoIGEgd2FybmluZyBtZXNzYWdlIGludml0aW5nIHRoZSB1c2VyIHRvIHBlcmZvcm0gYSBmdWxsIHRleHQgc2VhcmNoIHRvIHJldHJpZXZlIHNvbWUgcmVzdWx0c1xuICAgKiBAcGFyYW0gc3lzdGVtTXNnIC0gVGhlIHN5c3RlbSBtZXNzYWdlIHRvIGJlIGRpc3BsYXllZC5cbiAgICogQHBhcmFtIHVzZXJNc2cgLSBUaGUgdXNlciBtZXNzYWdlIHRvIGJlIGRpc3BsYXllZC5cbiAgICovXG4gIHByaXZhdGUgX2hhbmRsZVF1ZXJ5TW9kZShzeXN0ZW1Nc2c6IENoYXRNZXNzYWdlLCB1c2VyTXNnOiBDaGF0TWVzc2FnZSkge1xuICAgIGlmICghIXRoaXMucXVlcnkudGV4dCkge1xuICAgICAgY29uc3QgdXNlclF1ZXJ5TXNnID0geyByb2xlOiAndXNlcicsIGNvbnRlbnQ6IHRoaXMucXVlcnkudGV4dCwgYWRkaXRpb25hbFByb3BlcnRpZXM6IHsgZGlzcGxheTogdGhpcy5jb25maWcubW9kZVNldHRpbmdzLmluaXRpYWxpemF0aW9uLmRpc3BsYXlVc2VyUXVlcnksIG1lc3NhZ2VJZDogZ3VpZCgpLCBxdWVyeTogdGhpcy5xdWVyeSwgZm9yY2VkV29ya2Zsb3c6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5mb3JjZWRXb3JrZmxvdywgZm9yY2VkRnVuY3Rpb246IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5mb3JjZWRGdW5jdGlvbiwgaXNVc2VySW5wdXQ6IHRydWUsIGFkZGl0aW9uYWxXb3JrZmxvd1Byb3BlcnRpZXM6IHRoaXMuY29uZmlnLmFkZGl0aW9uYWxXb3JrZmxvd1Byb3BlcnRpZXMgfSB9O1xuICAgICAgaWYgKHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5zZW5kVXNlclByb21wdCkge1xuICAgICAgICB0aGlzLm9wZW5DaGF0KFtzeXN0ZW1Nc2csIHVzZXJNc2csIHVzZXJRdWVyeU1zZ10pO1xuICAgICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LW1lc3NhZ2UubWVzc2FnZScsIHRoaXMuX2RlZmluZU1lc3NhZ2VBdWRpdERldGFpbHMoc3lzdGVtTXNnKSk7XG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgdGhpcy5fZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyh1c2VyTXNnKSk7XG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgeyAuLi50aGlzLl9kZWZpbmVNZXNzYWdlQXVkaXREZXRhaWxzKHVzZXJRdWVyeU1zZyksICdxdWVyeSc6IEpTT04uc3RyaW5naWZ5KHRoaXMucXVlcnkpLCAnaXMtdXNlci1pbnB1dCc6IHRydWUsICdmb3JjZWQtd29ya2Zsb3cnOiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZm9yY2VkV29ya2Zsb3csICdmb3JjZWQtZnVuY3Rpb24nOiB0aGlzLmNvbmZpZy5tb2RlU2V0dGluZ3MuaW5pdGlhbGl6YXRpb24uZm9yY2VkRnVuY3Rpb24sICdlbmFibGVkLWZ1bmN0aW9ucyc6IHRoaXMuY29uZmlnLmRlZmF1bHRWYWx1ZXMuZnVuY3Rpb25zPy5maWx0ZXIoZnVuYyA9PiBmdW5jLmVuYWJsZWQpLm1hcChmdW5jID0+IGZ1bmMubmFtZSksICdhZGRpdGlvbmFsLXdvcmtmbG93LXByb3BlcnRpZXMnOiBKU09OLnN0cmluZ2lmeSh0aGlzLmNvbmZpZy5hZGRpdGlvbmFsV29ya2Zsb3dQcm9wZXJ0aWVzKSB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMub3BlbkNoYXQoW3N5c3RlbU1zZywgdXNlclF1ZXJ5TXNnXSk7XG4gICAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgdGhpcy5fZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyhzeXN0ZW1Nc2cpKTtcbiAgICAgICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1tZXNzYWdlLm1lc3NhZ2UnLCB7IC4uLnRoaXMuX2RlZmluZU1lc3NhZ2VBdWRpdERldGFpbHModXNlclF1ZXJ5TXNnKSwgJ3F1ZXJ5JzogSlNPTi5zdHJpbmdpZnkodGhpcy5xdWVyeSksICdpcy11c2VyLWlucHV0JzogdHJ1ZSwgJ2ZvcmNlZC13b3JrZmxvdyc6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5mb3JjZWRXb3JrZmxvdywgJ2ZvcmNlZC1mdW5jdGlvbic6IHRoaXMuY29uZmlnLm1vZGVTZXR0aW5ncy5pbml0aWFsaXphdGlvbi5mb3JjZWRGdW5jdGlvbiwgJ2VuYWJsZWQtZnVuY3Rpb25zJzogdGhpcy5jb25maWcuZGVmYXVsdFZhbHVlcy5mdW5jdGlvbnM/LmZpbHRlcihmdW5jID0+IGZ1bmMuZW5hYmxlZCkubWFwKGZ1bmMgPT4gZnVuYy5uYW1lKSwgJ2FkZGl0aW9uYWwtd29ya2Zsb3ctcHJvcGVydGllcyc6IEpTT04uc3RyaW5naWZ5KHRoaXMuY29uZmlnLmFkZGl0aW9uYWxXb3JrZmxvd1Byb3BlcnRpZXMpIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB3YXJuaW5nTXNnID0geyByb2xlOiAnc2VhcmNoLXdhcm5pbmcnLCBjb250ZW50OiB0aGlzLnRyYW5zbG9jby50cmFuc2xhdGUodGhpcy5jb25maWcuZ2xvYmFsU2V0dGluZ3Muc2VhcmNoV2FybmluZ01lc3NhZ2UpLCBhZGRpdGlvbmFsUHJvcGVydGllczogeyBkaXNwbGF5OiB0cnVlLCBtZXNzYWdlSWQ6IGd1aWQoKSB9IH07XG4gICAgICB0aGlzLm9wZW5DaGF0KFtzeXN0ZW1Nc2csIHdhcm5pbmdNc2ddKTtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtbWVzc2FnZS5tZXNzYWdlJywgdGhpcy5fZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyh3YXJuaW5nTXNnKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfZGVmaW5lTWVzc2FnZUF1ZGl0RGV0YWlscyhtZXNzYWdlOiBDaGF0TWVzc2FnZSk6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICAgIGNvbnN0IHJhbmsgPSB0aGlzLmFzc2lzdGFudFV0aWxzLmdldE1lc3NhZ2VSYW5rSW5DaGF0SGlzdG9yeSh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ISwgbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQpO1xuICAgIGNvbnN0IGRldGFpbHM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7XG4gICAgICAnZHVyYXRpb24nOiAwLFxuICAgICAgJ3JvbGUnOiBtZXNzYWdlLnJvbGUsXG4gICAgICAncmFuayc6IHJhbmssXG4gICAgICAnbWVzc2FnZS1pZCc6IG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkXG4gICAgfTtcbiAgICBpZiAoISF0aGlzLmNvbmZpZy5hdWRpdFNldHRpbmdzPy5sb2dDb250ZW50KSB7XG4gICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuY29udGVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZGV0YWlscy50ZXh0ID0gbWVzc2FnZS5jb250ZW50O1xuICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KG1lc3NhZ2UuY29udGVudCkpIHtcbiAgICAgICAgZGV0YWlscy50ZXh0ID0gKG1lc3NhZ2UuY29udGVudC5maW5kKChtc2cpID0+IG1zZy50eXBlID09PSBcInRleHRcIikgYXMgVGV4dE1lc3NhZ2VDb250ZW50KS50ZXh0XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkZXRhaWxzO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0L29wZW4gYSBuZXcgY2hhdCB3aXRoIHRoZSBwcm92aWRlZCBtZXNzYWdlcyBhbmQgY2hhdElkXG4gICAqIElmIHRoZSBsYXN0IG1lc3NhZ2UgaXMgZnJvbSB0aGUgdXNlciwgYSByZXF1ZXN0IHRvIHRoZSBhc3Npc3RhbnQgaXMgbWFkZSB0byBnZXQgYW4gYW5zd2VyXG4gICAqIElmIHRoZSBsYXN0IG1lc3NhZ2UgaXMgZnJvbSB0aGUgYXNzaXN0YW50LCB0aGUgY29udmVyc2F0aW9uIGlzIGxvYWRlZCByaWdodCBhd2F5XG4gICAqIEBwYXJhbSBtZXNzYWdlcyBUaGUgbGlzdCBvZiBtZXNzYWdlcyBvZiB0aGUgY2hhdFxuICAgKiBAcGFyYW0gY2hhdElkICBUaGUgaWQgb2YgdGhlIGRpc2N1c3Npb24uIElmIHByb3ZpZGVkIChpZS4gYW4gZXhpc3RpbmcgZGlzY3Vzc2lvbiBpbiB0aGUgc2F2ZWQgY2hhdCBpbmRleCksIHVwZGF0ZSB0aGUgY2hhdElkIGluIHRoZSBjaGF0IHNlcnZpY2UgZm9yIHRoZSB1cGNvbWluZyBzYXZlZCBjaGF0IG9wZXJhdGlvbnNcbiAgICovXG4gIG9wZW5DaGF0KG1lc3NhZ2VzOiBSYXdNZXNzYWdlW10sIGNoYXRJZD86IHN0cmluZykge1xuICAgIGlmICghbWVzc2FnZXMgfHwgIUFycmF5LmlzQXJyYXkobWVzc2FnZXMpKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBvY2N1cnMgd2hpbGUgdHJ5aW5nIHRvIGxvYWQgdGhlIGRpc2N1c3Npb24uIEludmFsaWQgbWVzc2FnZXMgcmVjZWl2ZWQgOicsIG1lc3NhZ2VzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGNoYXRJZCkge1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUNoYXRJZChjaGF0SWQpO1xuICAgIH1cbiAgICAvLyBFbnN1cmUgZWFjaCBtZXNzYWdlIGhhcyBhIHVuaXF1ZSBtZXNzYWdlSWRcbiAgICAvLyBUaGlzIGlzIG5lY2Vzc2FyeSBzcGVjaWFsbHkgaW4gY2FzZSB0aGUgYXNzaXN0YW50IGlzIHN0YXJ0ZWQgd2l0aCBhIHByZWRlZmluZWQgaGlzdG9yeSBPciBhbiBvbGQgc2F2ZWQgY2hhdFxuICAgIGNvbnN0IG1lc3NhZ2VzV2l0aElkczogQ2hhdE1lc3NhZ2VbXSA9IG1lc3NhZ2VzLm1hcCgobXNnKSA9PiB7XG4gICAgICBtc2cuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkID8/PSBndWlkKCk7XG4gICAgICByZXR1cm4gbXNnIGFzIENoYXRNZXNzYWdlO1xuICAgIH0pO1xuXG4gICAgdGhpcy5yZXNldENoYXQoKTtcbiAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KG1lc3NhZ2VzV2l0aElkcyk7XG4gICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSA9IG1lc3NhZ2VzV2l0aElkcztcbiAgICBjb25zdCBsYXN0TWVzc2FnZSA9IG1lc3NhZ2VzLmF0KC0xKTtcbiAgICBpZiAobGFzdE1lc3NhZ2UgJiYgbGFzdE1lc3NhZ2Uucm9sZSA9PT0gJ3VzZXInKSB7XG4gICAgICB0aGlzLmZldGNoKG1lc3NhZ2VzV2l0aElkcyk7IC8vIElmIHRoZSBsYXN0IG1lc3NhZ2UgaWYgZnJvbSBhIHVzZXIsIGFuIGFuc3dlciBmcm9tIHRoZSBhc3Npc3RhbnQgaXMgZXhwZWN0ZWRcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLnVwZGF0ZURhdGEobWVzc2FnZXNXaXRoSWRzKTsgLy8gSWYgdGhlIGxhc3QgbWVzc2FnZSBpZiBmcm9tIHRoZSBhc3Npc3RhbnQsIHdlIGNhbiBsb2FkIHRoZSBjb252ZXJzYXRpb24gcmlnaHQgYXdheVxuICAgICAgdGhpcy50ZXJtaW5hdGVGZXRjaCgpO1xuICAgIH1cbiAgICB0aGlzLl9hZGRTY3JvbGxMaXN0ZW5lcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IHRoZSBjaGF0IGJ5IGNsZWFyaW5nIHRoZSBjaGF0IGhpc3RvcnkgYW5kIHRoZSBVSSBhY2NvcmRpbmdseVxuICAgKiBUaGUgdXNlciBpbnB1dCB3aWxsIGJlIGNsZWFyZWRcbiAgICogVGhlIGZldGNoIHN1YnNjcmlwdGlvbiB3aWxsIGJlIHRlcm1pbmF0ZWRcbiAgICovXG4gIHJlc2V0Q2hhdCgpIHtcbiAgICBpZiAodGhpcy5tZXNzYWdlcyQudmFsdWUpIHtcbiAgICAgIHRoaXMubWVzc2FnZXMkLm5leHQodW5kZWZpbmVkKTsgLy8gUmVzZXQgY2hhdFxuICAgIH1cbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ID0gdW5kZWZpbmVkOyAvLyBSZXNldCBjaGF0IGhpc3RvcnlcbiAgICB0aGlzLnF1ZXN0aW9uID0gJyc7XG4gICAgdGhpcy50ZXJtaW5hdGVGZXRjaCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoIGFuZCBMb2FkIHRoZSBzYXZlZCBjaGF0IGZyb20gdGhlIHNhdmVkIGNoYXQgaW5kZXguXG4gICAqIElmIHRoZSBzYXZlZCBjaGF0IGlzIGZvdW5kLCB0aGUgY2hhdCBkaXNjdXNzaW9uIHdpbGwgYmUgbG9hZGVkIHdpdGggdGhlIHByb3ZpZGVkIG1lc3NhZ2VzIGFuZCBjaGF0SWRcbiAgICovXG4gIG9uTG9hZENoYXQoKSB7XG4gICAgdGhpcy5sb2FkaW5nJC5uZXh0KHRydWUpO1xuICAgIHRoaXMuY2hhdFNlcnZpY2UubG9hZFNhdmVkQ2hhdCRcbiAgICAgIC5waXBlKFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSxcbiAgICAgICAgZmlsdGVyKHNhdmVkQ2hhdCA9PiAhIXNhdmVkQ2hhdCksXG4gICAgICAgIHN3aXRjaE1hcChzYXZlZENoYXQgPT4gdGhpcy5jaGF0U2VydmljZS5nZXRTYXZlZENoYXQoc2F2ZWRDaGF0IS5pZCkpLFxuICAgICAgICBmaWx0ZXIoc2F2ZWRDaGF0SGlzdG9yeSA9PiAhIXNhdmVkQ2hhdEhpc3RvcnkpLFxuICAgICAgICB0YXAoc2F2ZWRDaGF0SGlzdG9yeSA9PiB0aGlzLm9wZW5DaGF0KHNhdmVkQ2hhdEhpc3RvcnkhLmhpc3RvcnksIHNhdmVkQ2hhdEhpc3RvcnkhLmlkKSlcbiAgICAgICkuc3Vic2NyaWJlKCk7XG4gIH1cblxuICAvKipcbiAgICogU3RvcCB0aGUgZ2VuZXJhdGlvbiBvZiB0aGUgY3VycmVudCBhc3Npc3RhbnQncyBhbnN3ZXIuXG4gICAqIFRoZSBmZXRjaCBzdWJzY3JpcHRpb24gd2lsbCBiZSB0ZXJtaW5hdGVkLlxuICAgKi9cbiAgc3RvcEdlbmVyYXRpb24oKSB7XG4gICAgdGhpcy5jaGF0U2VydmljZS5zdG9wR2VuZXJhdGlvbigpLnN1YnNjcmliZShcbiAgICAgICgpID0+IHtcbiAgICAgICAgLy8gUmVtb3ZlIHRoZSBsYXN0IG1lc3NhZ2UgaWYgaXQncyBhbiBlbXB0eSBtZXNzYWdlXG4gICAgICAgIC8vIFRoaXMgaXMgZHVlIHRvIHRoZSBtYW5uZXIgaW4gd2hpY2ggdGhlIGNoYXQgc2VydmljZSBoYW5kbGVzIGNvbnNlY3V0aXZlIG1lc3NhZ2VzXG4gICAgICAgIGNvbnN0IGxhc3RNZXNzYWdlID0gdGhpcy5tZXNzYWdlcyQudmFsdWU/LmF0KC0xKTtcbiAgICAgICAgaWYgKHRoaXMuaXNFbXB0eUFzc2lzdGFudE1lc3NhZ2UobGFzdE1lc3NhZ2UpKSB7XG4gICAgICAgICAgdGhpcy5tZXNzYWdlcyQubmV4dCh0aGlzLm1lc3NhZ2VzJC52YWx1ZT8uc2xpY2UoMCwgLTEpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRlcm1pbmF0ZUZldGNoKCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUZXJtaW5hdGUgdGhlIGZldGNoIHByb2Nlc3MgYnkgdW5zdWJzY3JpYmluZyBmcm9tIHRoZSBkYXRhIHN1YnNjcmlwdGlvbiBhbmQgdXBkYXRpbmcgdGhlIGxvYWRpbmcgc3RhdHVzIHRvIGZhbHNlLlxuICAgKiBBZGRpdGlvbmFsbHksIGZvY3VzIG9uIHRoZSBjaGF0IGlucHV0IGlmIHRoZSBmb2N1c0FmdGVyUmVzcG9uc2UgZmxhZyBpcyBzZXQgdG8gdHJ1ZS5cbiAgICovXG4gIHRlcm1pbmF0ZUZldGNoKCkge1xuICAgIHRoaXMuX2RhdGFTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5fZGF0YVN1YnNjcmlwdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmxvYWRpbmckLm5leHQoZmFsc2UpO1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcblxuICAgIGlmICh0aGlzLmZvY3VzQWZ0ZXJSZXNwb25zZSkge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMucXVlc3Rpb25JbnB1dD8ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvcHkgYSBwcmV2aW91cyB1c2VyIG1lc3NhZ2Ugb2YgdGhlIGNoYXQgaGlzdG9yeSB0byB0aGUgY2hhdCB1c2VyIGlucHV0LlxuICAgKiBUaHVzLCB0aGUgdXNlciBjYW4gZWRpdCBhbmQgcmVzdWJtaXQgdGhlIG1lc3NhZ2UuXG4gICAqIE9uY2UgdGhlIGVkaXRlZCBtZXNzYWdlIGlzIHN1Ym1pdHRlZCwgYWxsIHN1YnNlcXVlbnQgbWVzc2FnZXMgc3RhcnRpbmcgZnJvbSBAcGFyYW0gaW5kZXggd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlIGhpc3RvcnkgYW5kIHRoZSBVSSB3aWxsIGJlIHVwZGF0ZWQgYWNjb3JkaW5nbHkuXG4gICAqIFRoZSBhc3Npc3RhbnQgd2lsbCByZWdlbmVyYXRlIGEgbmV3IGFuc3dlciBiYXNlZCBvbiB0aGUgdXBkYXRlZCBjaGF0IGhpc3RvcnkuXG4gICAqIOKaoO+4jyBJZiB0aGUgYXNzaXN0YW50IGlzIHN0cmVhbWluZyBvciBzdG9wcGluZyB0aGUgZ2VuZXJhdGlvbiwgdGhlIG9wZXJhdGlvbiBpcyBub3QgYWxsb3dlZC5cbiAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIHVzZXIncyBtZXNzYWdlIHRvIGVkaXRcbiAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdXNlcidzIG1lc3NhZ2UgdG8gZWRpdFxuICAgKiBAcmV0dXJucyB2b2lkXG4gICAqL1xuICBlZGl0TWVzc2FnZShtZXNzYWdlOiBDaGF0TWVzc2FnZSwgaW5kZXg6IG51bWJlcikge1xuICAgIGlmICghIXRoaXMuY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJC52YWx1ZSB8fCAhIXRoaXMuY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJC52YWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmluZGV4TWVzc2FnZVRvRWRpdCA9IGluZGV4O1xuICAgIHRoaXMucmFua01lc3NhZ2VUb0VkaXQgPSB0aGlzLmFzc2lzdGFudFV0aWxzLmdldE1lc3NhZ2VSYW5rSW5DaGF0SGlzdG9yeSh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ISwgbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQpO1xuXG4gICAgLy8gR2V0IHVzZXIgbWVzc2FnZSBmcm9tIGJvdGggbGVnYWN5IGFuZCB0ZXh0IG1lc3NhZ2UgdHlwZVxuICAgIHRoaXMucXVlc3Rpb24gPSB0eXBlb2YgbWVzc2FnZS5jb250ZW50ID09PSAnc3RyaW5nJyA/IG1lc3NhZ2UuY29udGVudCA6IChtZXNzYWdlLmNvbnRlbnRbMF0gYXMgVGV4dE1lc3NhZ2VDb250ZW50KS50ZXh0O1xuXG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1lZGl0LmNsaWNrJywgeydyYW5rJzogdGhpcy5yYW5rTWVzc2FnZVRvRWRpdCwgJ21lc3NhZ2UtaWQnOiBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvcHkgYSBwcmV2aW91cyBhc3Npc3RhbnQgbWVzc2FnZSBvZiB0aGUgY2hhdCBoaXN0b3J5IHRvIHRoZSBjbGlwYm9hcmQuXG4gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGNvcHlcbiAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgbWVzc2FnZSB0byBjb3B5XG4gICAqIEByZXR1cm5zIHZvaWRcbiAgICovXG4gIGNvcHlNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlLCBpbmRleDogbnVtYmVyKSB7XG4gICAgLy8gUmVtYXAgdGhlIGluZGV4IGluIHRoZSBjaGF0IGhpc3RvcnlcbiAgICBjb25zdCByYW5rID0gdGhpcy5hc3Npc3RhbnRVdGlscy5nZXRNZXNzYWdlUmFua0luQ2hhdEhpc3RvcnkodGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSEsIG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkKTtcbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LWNvcHkuY2xpY2snLCB7ICdyYW5rJzogcmFuaywgJ21lc3NhZ2UtaWQnOiBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydGluZyBmcm9tIHRoZSBwcm92aWRlZCBpbmRleCwgcmVtb3ZlIGFsbCBzdWJzZXF1ZW50IG1lc3NhZ2VzIGZyb20gdGhlIGNoYXQgaGlzdG9yeSBhbmQgdGhlIFVJIGFjY29yZGluZ2x5LlxuICAgKiBUaGUgYXNzaXN0YW50IHdpbGwgcmVnZW5lcmF0ZSBhIG5ldyBhbnN3ZXIgYmFzZWQgb24gdGhlIHVwZGF0ZWQgY2hhdCBoaXN0b3J5LlxuICAgKiDimqDvuI8gSWYgdGhlIGFzc2lzdGFudCBpcyBzdHJlYW1pbmcgb3Igc3RvcHBpbmcgdGhlIGdlbmVyYXRpb24sIHRoZSBvcGVyYXRpb24gaXMgbm90IGFsbG93ZWQuXG4gICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBhc3Npc3RhbnQncyBtZXNzYWdlIHRvIHJlZ2VuZXJhdGVcbiAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgYXNzaXN0YW50J3MgbWVzc2FnZSB0byByZWdlbmVyYXRlXG4gICAqL1xuICByZWdlbmVyYXRlTWVzc2FnZShtZXNzYWdlOiBDaGF0TWVzc2FnZSwgaW5kZXg6IG51bWJlcikge1xuICAgIGlmICghIXRoaXMuY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJC52YWx1ZSB8fCAhIXRoaXMuY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJC52YWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBVcGRhdGUgdGhlIG1lc3NhZ2VzIGluIHRoZSBVSSBieSByZW1vdmluZyBhbGwgc3Vic2VxdWVudCAnYXNzaXN0YW50JyBtZXNzYWdlcyBzdGFydGluZyBmcm9tIHRoZSBwcm92aWRlZCBpbmRleCB1bnRpbCB0aGUgZmlyc3QgcHJldmlvdXMgJ3VzZXInIG1lc3NhZ2VcbiAgICBsZXQgaSA9IGluZGV4O1xuICAgIHdoaWxlIChpID49IDAgJiYgISgodGhpcy5tZXNzYWdlcyQudmFsdWUhKVtpXS5yb2xlID09PSAndXNlcicgJiYgKHRoaXMubWVzc2FnZXMkLnZhbHVlISlbaV0uYWRkaXRpb25hbFByb3BlcnRpZXMuaXNVc2VySW5wdXQgPT09IHRydWUpKSB7XG4gICAgICBpLS07XG4gICAgfVxuICAgIC8vIEl0IHNob3VsZCBhbHdheXMgYmUgdGhlIGNhc2UgdGhhdCBpID4gMFxuICAgIGlmIChpID49IDApIHtcbiAgICAgIHRoaXMubWVzc2FnZXMkLm5leHQodGhpcy5tZXNzYWdlcyQudmFsdWUhLnNsaWNlKDAsIGkgKyAxKSk7XG4gICAgICAvLyBSYW5rIG9mIHRoaXMgZm91bmQgZmlyc3QgcHJldmlvdXMgJ3VzZXInIG1lc3NhZ2UgaW4gdGhlIGNoYXQgaGlzdG9yeVxuICAgICAgY29uc3QgcmFua0ZpcnN0UHJldmlvdXNVc2VyTWVzc2FnZSA9IHRoaXMuYXNzaXN0YW50VXRpbHMuZ2V0TWVzc2FnZVJhbmtJbkNoYXRIaXN0b3J5KHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhLCB0aGlzLm1lc3NhZ2VzJC52YWx1ZSFbaV0uYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkKTtcbiAgICAgIC8vIFJhbmsgb2YgdGhlIGFzc2lzdGFudCdzIG1lc3NhZ2Ugb24gd2hpY2ggdGhlIHVzZXIgY2xpY2tlZCB0byByZWdlbmVyYXRlXG4gICAgICBjb25zdCByYW5rID0gdGhpcy5hc3Npc3RhbnRVdGlscy5nZXRNZXNzYWdlUmFua0luQ2hhdEhpc3RvcnkodGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSEsIG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkKTtcbiAgICAgIC8vIERlZmluZSBhbmQgVXBkYXRlIHRoZSBjaGF0IGhpc3RvcnkgYmFzZWQgb24gd2hpY2ggdGhlIGFzc2lzdGFudCB3aWxsIGdlbmVyYXRlIGEgbmV3IGFuc3dlclxuICAgICAgdGhpcy5jaGF0U2VydmljZS5jaGF0SGlzdG9yeSA9IHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhLnNsaWNlKDAsIHJhbmtGaXJzdFByZXZpb3VzVXNlck1lc3NhZ2UpO1xuICAgICAgLy8gRmV0Y2ggdGhlIGFuc3dlclxuICAgICAgdGhpcy5mZXRjaCh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5KTtcbiAgICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtcmVnZW5lcmF0ZS5jbGljaycsIHsgJ3JhbmsnOiByYW5rLCAnbWVzc2FnZS1pZCc6IG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGVzIHRoZSBrZXkgdXAgZXZlbnQgZm9yICdCYWNrc3BhY2UnIGFuZCAnRW50ZXInIGtleXMuXG4gICAqIEBwYXJhbSBldmVudCAtIFRoZSBrZXlib2FyZCBldmVudC5cbiAgICovXG4gIG9uS2V5VXAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBzd2l0Y2ggKGV2ZW50LmtleSkge1xuICAgICAgY2FzZSAnQmFja3NwYWNlJzpcbiAgICAgICAgdGhpcy5jYWxjdWxhdGVIZWlnaHQoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdFbnRlcic6XG4gICAgICAgIGlmICghZXZlbnQuc2hpZnRLZXkpIHtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIHRoaXMuc3VibWl0UXVlc3Rpb24oKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNhbGN1bGF0ZUhlaWdodCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIGFuZCBhZGp1c3RzIHRoZSBoZWlnaHQgb2YgdGhlIHF1ZXN0aW9uIGlucHV0IGVsZW1lbnQgYmFzZWQgb24gaXRzIGNvbnRlbnQuXG4gICAqIElmIHRoZSBFbnRlciBrZXkgaXMgcHJlc3NlZCB3aXRob3V0IHRoZSBTaGlmdCBrZXksIGl0IHByZXZlbnRzIHRoZSBkZWZhdWx0IGJlaGF2aW9yLlxuICAgKiBAcGFyYW0gZXZlbnQgVGhlIGtleWJvYXJkIGV2ZW50XG4gICAqL1xuICBjYWxjdWxhdGVIZWlnaHQoZXZlbnQ/OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50Py5rZXkgPT09ICdFbnRlcicgJiYgIWV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICBldmVudD8ucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgY29uc3QgbWF4SGVpZ2h0ID0gMTcwO1xuICAgIGNvbnN0IGVsID0gdGhpcy5xdWVzdGlvbklucHV0IS5uYXRpdmVFbGVtZW50O1xuICAgIGVsLnN0eWxlLm1heEhlaWdodCA9IGAke21heEhlaWdodH1weGA7XG4gICAgZWwuc3R5bGUuaGVpZ2h0ID0gJ2F1dG8nO1xuICAgIGVsLnN0eWxlLmhlaWdodCA9IGAke2VsLnNjcm9sbEhlaWdodH1weGA7XG4gICAgZWwuc3R5bGUub3ZlcmZsb3dZID0gZWwuc2Nyb2xsSGVpZ2h0ID49IG1heEhlaWdodCA/ICdzY3JvbGwnIDogJ2hpZGRlbic7XG4gIH1cblxuICAvKipcbiAgICogU2VuZCBhIFwibGlrZVwiIGV2ZW50IG9uIGNsaWNraW5nIG9uIHRoZSB0aHVtYi11cCBpY29uIG9mIGFuIGFzc2lzdGFudCdzIG1lc3NhZ2VcbiAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGFzc2lzdGFudCBtZXNzYWdlIHRvIGxpa2VcbiAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgbWVzc2FnZSB0byBsaWtlXG4gICAqL1xuICBvbkxpa2UobWVzc2FnZTogQ2hhdE1lc3NhZ2UsIGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAvLyBSZW1hcCB0aGUgaW5kZXggaW4gdGhlIGNoYXQgaGlzdG9yeVxuICAgIGNvbnN0IHJhbmsgPSB0aGlzLmFzc2lzdGFudFV0aWxzLmdldE1lc3NhZ2VSYW5rSW5DaGF0SGlzdG9yeSh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ISwgbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQpO1xuICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtdGh1bWItdXAuY2xpY2snLCB7ICdyYW5rJzogcmFuaywgJ21lc3NhZ2UtaWQnOiBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCB9KTtcbiAgICB0aGlzLnJlcG9ydFR5cGUgPSAnbGlrZSc7XG4gICAgdGhpcy5tZXNzYWdlVG9SZXBvcnQgPSBtZXNzYWdlO1xuICAgIHRoaXMucmVwb3J0Q29tbWVudCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnJlcG9ydFJhbmsgPSByYW5rO1xuICAgIHRoaXMuc2hvd1JlcG9ydCA9IHRydWVcblxuICAgIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhW3JhbmstMV0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGxpa2VkID0gdHJ1ZTtcbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5IVtyYW5rLTFdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRkaXNsaWtlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3VwZGF0ZUNoYXRIaXN0b3J5KCk7XG4gIH1cblxuICAvKipcbiAgICogU2VuZCBhIFwiZGlzbGlrZVwiIGV2ZW50IG9uIGNsaWNraW5nIG9uIHRoZSB0aHVtYi1kb3duIGljb24gb2YgYW4gYXNzaXN0YW50J3MgbWVzc2FnZS5cbiAgICogSXQgYWxzbyBvcGVucyB0aGUgaXNzdWUgcmVwb3J0aW5nIGRpYWxvZy5cbiAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIGFzc2lzdGFudCBtZXNzYWdlIHRvIGRpc2xpa2VcbiAgICogQHBhcmFtIGluZGV4IFRoZSByYW5rIG9mIHRoZSBtZXNzYWdlIHRvIGRpc2xpa2VcbiAgICovXG4gIG9uRGlzbGlrZShtZXNzYWdlOiBDaGF0TWVzc2FnZSwgaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIC8vIFJlbWFwIHRoZSBpbmRleCBpbiB0aGUgY2hhdCBoaXN0b3J5XG4gICAgY29uc3QgcmFuayA9IHRoaXMuYXNzaXN0YW50VXRpbHMuZ2V0TWVzc2FnZVJhbmtJbkNoYXRIaXN0b3J5KHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhLCBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCk7XG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC10aHVtYi1kb3duLmNsaWNrJywgeyAncmFuayc6IHJhbmssICdtZXNzYWdlLWlkJzogbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQgfSk7XG4gICAgdGhpcy5yZXBvcnRUeXBlID0gJ2Rpc2xpa2UnO1xuICAgIHRoaXMubWVzc2FnZVRvUmVwb3J0ID0gbWVzc2FnZTtcbiAgICB0aGlzLmlzc3VlVHlwZSA9ICcnO1xuICAgIHRoaXMucmVwb3J0Q29tbWVudCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnJlcG9ydFJhbmsgPSByYW5rO1xuICAgIHRoaXMuc2hvd1JlcG9ydCA9IHRydWVcblxuICAgIHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhW3JhbmstMV0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGRpc2xpa2VkID0gdHJ1ZTtcbiAgICB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5IVtyYW5rLTFdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRsaWtlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3VwZGF0ZUNoYXRIaXN0b3J5KCk7XG4gIH1cblxuICBwcml2YXRlIF91cGRhdGVDaGF0SGlzdG9yeSgpOiB2b2lkIHtcbiAgICB0aGlzLm1lc3NhZ2VzJC5uZXh0KHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkpO1xuICAgIGlmICh0aGlzLmNvbmZpZy5zYXZlZENoYXRTZXR0aW5ncy5lbmFibGVkKSB7XG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLnVwZGF0ZVNhdmVkQ2hhdCh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRJZCwgdW5kZWZpbmVkLCB0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5KS5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcG9ydCBhbiBpc3N1ZSByZWxhdGVkIHRvIHRoZSBhc3Npc3RhbnQncyBtZXNzYWdlLlxuICAgKi9cbiAgc2VuZFJlcG9ydCgpOiB2b2lkIHtcbiAgICBjb25zdCBkZXRhaWxzID0ge1xuICAgICAgJ2NvbW1lbnQnOiB0aGlzLnJlcG9ydENvbW1lbnQsXG4gICAgICAncmFuayc6IHRoaXMucmVwb3J0UmFua1xuICAgIH07XG5cbiAgICAvL2NoZWNrIGlmIHRoZSBtZXNzYWdlIHRvIHJlcG9ydCBpcyBkZWZpbmVkLiBJdCBzaG91bGQgYWx3YXlzIGJlIHRoZSBjYXNlXG4gICAgaWYgKHRoaXMubWVzc2FnZVRvUmVwb3J0KSB7XG4gICAgICBkZXRhaWxzWydtZXNzYWdlLWlkJ10gPSB0aGlzLm1lc3NhZ2VUb1JlcG9ydC5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQ7XG4gICAgfVxuXG4gICAgLy8gaGlkZSB0ZXh0IGluIGNhc2UgbG9nQ29udGVudCBpcyBub3QgZW5hYmxlZFxuICAgIGlmICh0aGlzLmNvbmZpZy5hdWRpdFNldHRpbmdzLmxvZ0NvbnRlbnQpXG4gICAgICBkZXRhaWxzWyd0ZXh0J10gPSB0aGlzLm1lc3NhZ2VUb1JlcG9ydCEuY29udGVudDtcblxuICAgIGlmICh0aGlzLnJlcG9ydFR5cGUgPT09ICdkaXNsaWtlJykge1xuICAgICAgZGV0YWlsc1sncmVwb3J0LXR5cGUnXSA9IHRoaXMuaXNzdWVUeXBlO1xuICAgICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1uZWdhdGl2ZS1yZXBvcnQuc2VuZCcsIGRldGFpbHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNoYXRTZXJ2aWNlLmdlbmVyYXRlQXVkaXRFdmVudCgnYXN0LXBvc2l0aXZlLXJlcG9ydC5zZW5kJywgZGV0YWlscyk7XG4gICAgfVxuICAgIHRoaXMubm90aWZpY2F0aW9uc1NlcnZpY2Uuc3VjY2Vzcyh0aGlzLnRyYW5zbG9jby50cmFuc2xhdGUoJ2NoYXQuc2VuZFJlcG9ydE5vdGlmaWNhdGlvbicpKTtcbiAgICB0aGlzLnNob3dSZXBvcnQgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSB0aGUgcmVwb3J0aW5nIGRpYWxvZy5cbiAgICovXG4gIGlnbm9yZVJlcG9ydCgpOiB2b2lkIHtcbiAgICB0aGlzLnNob3dSZXBvcnQgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgdGhlIGNsaWNrIG9uIGEgcmVmZXJlbmNlJ3MgJ29wZW4gcHJldmlldycuXG4gICAqIEBwYXJhbSBkYXRhXG4gICAqIEBwYXJhbSBtZXNzYWdlIHRoZSBtZXNzYWdlIGNvbnRhaW5pbmcgdGhlIHJlZmVyZW5jZVxuICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgdGhlIG1lc3NhZ2UgY29udGFpbmluZyB0aGUgcmVmZXJlbmNlXG4gICAqIEByZXR1cm5zIHZvaWRcbiAgICovXG4gIG9wZW5BdHRhY2htZW50UHJldmlldyhkYXRhOiB7IHJlZmVyZW5jZTogQ2hhdENvbnRleHRBdHRhY2htZW50LCBwYXJ0SWQ/OiBudW1iZXIgfSwgbWVzc2FnZTogQ2hhdE1lc3NhZ2UsIGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLm9wZW5QcmV2aWV3LmVtaXQoZGF0YS5yZWZlcmVuY2UpO1xuICAgIGNvbnN0IHJhbmsgPSB0aGlzLmFzc2lzdGFudFV0aWxzLmdldE1lc3NhZ2VSYW5rSW5DaGF0SGlzdG9yeSh0aGlzLmNoYXRTZXJ2aWNlLmNoYXRIaXN0b3J5ISwgbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5tZXNzYWdlSWQpO1xuICAgIGNvbnN0IGRldGFpbHMgPSB7XG4gICAgICAnZG9jLWlkJzogZGF0YS5yZWZlcmVuY2UucmVjb3JkSWQsXG4gICAgICAnc291cmNlJzogZGF0YS5yZWZlcmVuY2UucmVjb3JkLnRyZWVwYXRoLFxuICAgICAgJ2NvbGxlY3Rpb24nOiBkYXRhLnJlZmVyZW5jZS5yZWNvcmQuY29sbGVjdGlvbixcbiAgICAgICdpbmRleCc6IGRhdGEucmVmZXJlbmNlLnJlY29yZC5kYXRhYmFzZWFsaWFzLFxuICAgICAgJ3JhbmsnOiByYW5rLFxuICAgICAgJ21lc3NhZ2UtaWQnOiBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZFxuICAgIH07XG4gICAgaWYgKCEhZGF0YS5wYXJ0SWQpIGRldGFpbHNbJ3BhcnQtaWQnXSA9IGRhdGEucGFydElkO1xuICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3QtYXR0YWNobWVudC5wcmV2aWV3LmNsaWNrJywgZGV0YWlscyk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIHRoZSBjbGljayBvbiBhIHJlZmVyZW5jZSdzICdvcGVuIG9yaWdpbmFsIGRvY3VtZW50Jy5cbiAgICogQHBhcmFtIGRhdGFcbiAgICogQHBhcmFtIG1lc3NhZ2UgdGhlIG1lc3NhZ2UgY29udGFpbmluZyB0aGUgcmVmZXJlbmNlXG4gICAqIEBwYXJhbSBpbmRleCBpbmRleCBvZiB0aGUgbWVzc2FnZSBjb250YWluaW5nIHRoZSByZWZlcmVuY2VcbiAgICogQHJldHVybnMgdm9pZFxuICAgKi9cbiAgb3Blbk9yaWdpbmFsQXR0YWNobWVudChkYXRhOiB7IHJlZmVyZW5jZTogQ2hhdENvbnRleHRBdHRhY2htZW50LCBwYXJ0SWQ/OiBudW1iZXIgfSwgbWVzc2FnZTogQ2hhdE1lc3NhZ2UsIGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLm9wZW5Eb2N1bWVudC5lbWl0KGRhdGEucmVmZXJlbmNlLnJlY29yZCk7XG4gICAgY29uc3QgcmFuayA9IHRoaXMuYXNzaXN0YW50VXRpbHMuZ2V0TWVzc2FnZVJhbmtJbkNoYXRIaXN0b3J5KHRoaXMuY2hhdFNlcnZpY2UuY2hhdEhpc3RvcnkhLCBtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLm1lc3NhZ2VJZCk7XG4gICAgY29uc3QgZGV0YWlscyA9IHtcbiAgICAgICdkb2MtaWQnOiBkYXRhLnJlZmVyZW5jZS5yZWNvcmRJZCxcbiAgICAgICdzb3VyY2UnOiBkYXRhLnJlZmVyZW5jZS5yZWNvcmQudHJlZXBhdGgsXG4gICAgICAnY29sbGVjdGlvbic6IGRhdGEucmVmZXJlbmNlLnJlY29yZC5jb2xsZWN0aW9uLFxuICAgICAgJ2luZGV4JzogZGF0YS5yZWZlcmVuY2UucmVjb3JkLmRhdGFiYXNlYWxpYXMsXG4gICAgICAncmFuayc6IHJhbmssXG4gICAgICAnbWVzc2FnZS1pZCc6IG1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkXG4gICAgfTtcbiAgICBpZiAoISFkYXRhLnBhcnRJZCkgZGV0YWlsc1sncGFydC1pZCddID0gZGF0YS5wYXJ0SWQ7XG4gICAgdGhpcy5jaGF0U2VydmljZS5nZW5lcmF0ZUF1ZGl0RXZlbnQoJ2FzdC1hdHRhY2htZW50LmxpbmsuY2xpY2snLCBkZXRhaWxzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgdGhlIGNsaWNrIG9uIGEgc3VnZ2VzdGVkIGFjdGlvbi5cbiAgICogQHBhcmFtIGFjdGlvbiBTdWdnZXN0ZWQgYWN0aW9uLlxuICAgKiBAcGFyYW0gaW5kZXggaW5kZXggb2YgdGhlIG1lc3NhZ2UgY29udGFpbmluZyB0aGUgc3VnZ2VzdGVkIGFjdGlvbi5cbiAgICogQHJldHVybnMgdm9pZFxuICAgKi9cbiAgc3VnZ2VzdEFjdGlvbkNsaWNrKGFjdGlvbjogU3VnZ2VzdGVkQWN0aW9uLCBpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5zdWdnZXN0QWN0aW9uLmVtaXQoYWN0aW9uKTtcblxuICAgIGNvbnN0IGRldGFpbHMgPSB7XG4gICAgICAndGV4dCc6IGFjdGlvbi5jb250ZW50LFxuICAgICAgJ3N1Z2dlc3RlZEFjdGlvbi10eXBlJzogYWN0aW9uLnR5cGVcbiAgICB9O1xuICAgIHRoaXMuY2hhdFNlcnZpY2UuZ2VuZXJhdGVBdWRpdEV2ZW50KCdhc3Qtc3VnZ2VzdGVkLWFjdGlvbi5jbGljaycsIGRldGFpbHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEl0IGxvb2tzIGZvciB0aGUgZGVidWcgbWVzc2FnZXMgYXZhaWxhYmxlIGluIHRoZSBjdXJyZW50IGdyb3VwIG9mIFwiYXNzaXN0YW50XCIgbWVzc2FnZXMuXG4gICAqIEJ5IGRlc2lnbiwgdGhlIGRlYnVnIG1lc3NhZ2VzIGFyZSBvbmx5IGF2YWlsYWJsZSBpbiB0aGUgZmlyc3QgdmlzaWJsZSBtZXNzYWdlIGFtb25nIHRoZSBncm91cCBvZiBcImFzc2lzdGFudFwiIG1lc3NhZ2VzLlxuICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgbWVzc2FnZSBjb250YWluaW5nIHRoZSBkZWJ1ZyBpbmZvcm1hdGlvblxuICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBtZXNzYWdlXG4gICAqIEByZXR1cm5zIFRoZSBkZWJ1ZyBtZXNzYWdlcyBhdmFpbGFibGUgaW4gdGhlIGN1cnJlbnQgZ3JvdXAgb2YgXCJhc3Npc3RhbnRcIiBtZXNzYWdlc1xuICAgKi9cbiAgZ2V0RGVidWdNZXNzYWdlcyhtZXNzYWdlOiBDaGF0TWVzc2FnZSwgaW5kZXg6IG51bWJlcik6IERlYnVnTWVzc2FnZVtdIHtcbiAgICAvLyBJZiBpdCBpcyBub3QgYW4gYXNzaXN0YW50IG1lc3NhZ2UsIHJldHVybiBhbiBlbXB0eSBhcnJheVxuICAgIGlmIChtZXNzYWdlLnJvbGUgIT09ICdhc3Npc3RhbnQnKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIC8vIEdldCB0aGUgYXJyYXkgb2YgbWVzc2FnZXMgdXAgdG8gdGhlIGluZGljYXRlZCBpbmRleFxuICAgIGNvbnN0IGFycmF5ID0gdGhpcy5tZXNzYWdlcyQudmFsdWUhLnNsaWNlKDAsIGluZGV4ICsgMSk7XG4gICAgLy8gSWYgaXQgaXMgYW4gYXNzaXN0YW50IG1lc3NhZ2UsIGxvb2sgZm9yIHRoZSBkZWJ1ZyBtZXNzYWdlcyBhdmFpbGFibGUgaW4gdGhlIGN1cnJlbnQgZ3JvdXAgb2YgXCJhc3Npc3RhbnRcIiBtZXNzYWdlc1xuICAgIC8vIEJ5IGRlc2lnbiwgdGhlIGRlYnVnIG1lc3NhZ2VzIGFyZSBvbmx5IGF2YWlsYWJsZSBpbiB0aGUgZmlyc3QgdmlzaWJsZSBtZXNzYWdlIGFtb25nIHRoZSBncm91cCBcImFzc2lzdGFudFwiIG1lc3NhZ2VzLlxuICAgIGNvbnN0IGlkeCA9IHRoaXMuYXNzaXN0YW50VXRpbHMuZmlyc3RWaXNpYmxlQXNzaXN0YW50TWVzc2FnZUluZGV4KGFycmF5KTtcbiAgICBpZiAoaWR4ID4gLTEpIHtcbiAgICAgIHJldHVybiAodGhpcy5tZXNzYWdlcyQudmFsdWUhKVtpZHhdLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRkZWJ1ZyB8fCBbXTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSB0aGUgY2xpY2sgb24gdGhlICdzaG93IGxvZyBpbmZvJyBidXR0b24gb2YgYSBtZXNzYWdlLlxuICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgbWVzc2FnZSBjb250YWluaW5nIHRoZSBkZWJ1ZyBpbmZvcm1hdGlvblxuICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBtZXNzYWdlXG4gICAqL1xuICBzaG93RGVidWcobWVzc2FnZTogQ2hhdE1lc3NhZ2UsIGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmRlYnVnTWVzc2FnZXMgPSB0aGlzLmdldERlYnVnTWVzc2FnZXMobWVzc2FnZSwgaW5kZXgpO1xuICAgIHRoaXMuc2hvd0RlYnVnTWVzc2FnZXMgPSB0cnVlO1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZnkgd2hldGhlciB0aGUgY3VycmVudCBtZXNzYWdlIGlzIGFuIGFzc2lzdGFudCBtZXNzYWdlIGFuZCB0aGF0IGFsbCBmb2xsb3dpbmcgbWVzc2FnZXMgYXJlIGFzc2lzdGFudCBvbmVzXG4gICAqIFVzZWQgdG8ga2VlcCB0aGUgXCJWaWV3IHByb2dyZXNzXCIgb3BlbmVkIGV2ZW4gdGhvdWdoIHRoZSBhc3Npc3RhbnQgaXMgc2VuZGluZyBhZGRpdGlvbmFsIG1lc3NhZ2VzIGFmdGVyIHRoZSBjdXJyZW50IG9uZVxuICAgKiBAcGFyYW0gbWVzc2FnZXMgdGhlIGxpc3Qgb2YgY3VycmVudCBtZXNzYWdlc1xuICAgKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBjdXJyZW50IG1lc3NhZ2VcbiAgICogQHJldHVybnMgaWYgdGhpcyBtZXNzYWdlcyBhbmQgdGhlIGZvbGxvd2luZyBvbmVzIChpZiBhbnkpIGFyZSB0aGUgbGFzdCBvbmVzXG4gICAqL1xuICBpc0Fzc2lzdGFudExhc3RNZXNzYWdlcyhtZXNzYWdlczogQ2hhdE1lc3NhZ2VbXSwgaW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGZvciAobGV0IGkgPSBpbmRleDsgaSA8IG1lc3NhZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAobWVzc2FnZXNbaV0ucm9sZSAhPT0gJ2Fzc2lzdGFudCcpIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBtZXNzYWdlIGlzIGFuIGVtcHR5IGFzc2lzdGFudCBtZXNzYWdlLlxuICAgKiBBbiBlbXB0eSBhc3Npc3RhbnQgbWVzc2FnZSBpcyBkZWZpbmVkIGFzIGEgbWVzc2FnZSB3aXRoIHRoZSByb2xlICdhc3Npc3RhbnQnLFxuICAgKiBhbiBlbXB0eSBjb250ZW50LCBhbmQgbm8gYWRkaXRpb25hbCBwcm9wZXJ0aWVzIHN1Y2ggYXMgYXR0YWNobWVudHMsIHByb2dyZXNzLFxuICAgKiBkZWJ1ZyBpbmZvcm1hdGlvbiwgb3Igc3VnZ2VzdGVkIGFjdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbWVzc2FnZSBpcyBhbiBlbXB0eSBhc3Npc3RhbnQgbWVzc2FnZSwgYGZhbHNlYCBvdGhlcndpc2UuXG4gICAqL1xuICBpc0VtcHR5QXNzaXN0YW50TWVzc2FnZShtZXNzYWdlOiBDaGF0TWVzc2FnZSB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICAgIGlmIChcbiAgICAgIG1lc3NhZ2U/LnJvbGUgPT09ICdhc3Npc3RhbnQnXG4gICAgICAmJiAoXG4gICAgICAgIC8vIExlZ2FjeSBtZXNzYWdlIHR5cGVcbiAgICAgICAgKHR5cGVvZiBtZXNzYWdlPy5jb250ZW50ID09PSAnc3RyaW5nJyAmJiBtZXNzYWdlPy5jb250ZW50ID09PSBcIlwiKVxuICAgICAgICAvLyBOZXcgbWVzc2FnZSB0eXBlXG4gICAgICAgIC8vIC0gVGV4dFxuICAgICAgICB8fCAoKG1lc3NhZ2U/LmNvbnRlbnQgYXMgUmF3TWVzc2FnZUNvbnRlbnQpPy5bMF0gYXMgVGV4dE1lc3NhZ2VDb250ZW50KT8udGV4dCA9PT0gXCJcIlxuICAgICAgICAvLyBUT0RPOiBpbWFnZSBhbmQgdmlkZW8gbWVzc2FnZSB0eXBlcyBodHRwczovL3NpbmVxdWEuYXRsYXNzaWFuLm5ldC9icm93c2UvRVMtMjU5NDBcbiAgICAgIClcbiAgICAgICYmICFtZXNzYWdlPy5hZGRpdGlvbmFsUHJvcGVydGllcz8uJGF0dGFjaG1lbnRcbiAgICAgICYmICFtZXNzYWdlPy5hZGRpdGlvbmFsUHJvcGVydGllcz8uJHByb2dyZXNzXG4gICAgICAmJiAhbWVzc2FnZT8uYWRkaXRpb25hbFByb3BlcnRpZXM/LiRkZWJ1Z1xuICAgICAgJiYgIW1lc3NhZ2U/LmFkZGl0aW9uYWxQcm9wZXJ0aWVzPy4kc3VnZ2VzdGVkQWN0aW9uXG4gICAgKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG4iLCI8bmctY29udGFpbmVyICpuZ0lmPVwiIWluaXRpYWxpemF0aW9uRXJyb3JcIj5cbiAgPGRpdiAqbmdJZj1cIm1lc3NhZ2VzJCB8IGFzeW5jIGFzIG1lc3NhZ2VzOyBlbHNlIGxvYWRpbmdUcGwgfHwgbG9hZGluZ1RwbERlZmF1bHRcIiBjbGFzcz1cImgtMTAwIGQtZmxleCBmbGV4LWNvbHVtblwiPlxuICAgIDwhLS0gVG9rZW4gY29uc3VtcHRpb24gLS0+XG4gICAgPGRpdiBjbGFzcz1cIm1zLTFcIiAqbmdJZj1cImNvbmZpZz8uZ2xvYmFsU2V0dGluZ3M/LmRpc3BsYXlVc2VyUXVvdGFDb25zdW1wdGlvbiB8fCBjb25maWc/Lmdsb2JhbFNldHRpbmdzPy5kaXNwbGF5Q2hhdFRva2Vuc0NvbnN1bXB0aW9uXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidG9rZW5Db25zdW1wdGlvblRwbCB8fCBkZWZhdWx0VG9rZW5Db25zdW1wdGlvblRwbDsgY29udGV4dDogeyAkaW1wbGljaXQ6IGluc3RhbmNlSWQgfVwiPjwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBDaGF0IE1lc3NhZ2VzIC0tPlxuICAgIDx1bCBjbGFzcz1cImQtZmxleCBmbGV4LWNvbHVtbiBsaXN0LXVuc3R5bGVkIGdhcC0zIG92ZXJmbG93LWF1dG8gZmxleC1ncm93LTEgcGUtMiBwYi0yXCIgI21lc3NhZ2VMaXN0IFtpZF09XCInbWVzc2FnZUxpc3QtJyArIGluc3RhbmNlSWRcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IG1lc3NhZ2Ugb2YgbWVzc2FnZXM7IGxldCBpbmRleCA9IGluZGV4OyBsZXQgbGFzdCA9IGxhc3RcIj5cbiAgICAgICAgPCEtLSBSZWd1bGFyIG1lc3NhZ2VzIC0tPlxuICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW1cIlxuICAgICAgICAgICpuZ0lmPVwibWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy5kaXNwbGF5ICYmICFpc0VtcHR5QXNzaXN0YW50TWVzc2FnZShtZXNzYWdlKVwiXG4gICAgICAgICAgW3N0eWxlLi0tYnMtbGlzdC1ncm91cC1pdGVtLXBhZGRpbmcteS5yZW1dPVwiJzAuNidcIlxuICAgICAgICAgIFtjbGFzcy5vcGFjaXR5LTUwXT1cImluZGV4TWVzc2FnZVRvRWRpdCAmJiAoaW5kZXhNZXNzYWdlVG9FZGl0IDwgKGluZGV4ICsgMSkpXCI+XG4gICAgICAgICAgPHNxLWNoYXQtbWVzc2FnZVxuICAgICAgICAgICAgW2lkXT1cIm1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMubWVzc2FnZUlkXCJcbiAgICAgICAgICAgIFtjbGFzcy5zcS11c2VyLW1lc3NhZ2VdPVwibWVzc2FnZS5yb2xlID09PSAndXNlcidcIlxuICAgICAgICAgICAgW2NsYXNzLmxhc3QtbWVzc2FnZV09XCJsYXN0XCJcbiAgICAgICAgICAgIFttZXNzYWdlXT1cIm1lc3NhZ2VcIlxuICAgICAgICAgICAgW2NvbnZlcnNhdGlvbl09XCJtZXNzYWdlc1wiXG4gICAgICAgICAgICBbc3VnZ2VzdGVkQWN0aW9uc109XCJsYXN0ID8gbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy4kc3VnZ2VzdGVkQWN0aW9uIDogdW5kZWZpbmVkXCJcbiAgICAgICAgICAgIFthc3Npc3RhbnRNZXNzYWdlSWNvbl09XCJhc3Npc3RhbnRNZXNzYWdlSWNvblwiXG4gICAgICAgICAgICBbdXNlck1lc3NhZ2VJY29uXT1cInVzZXJNZXNzYWdlSWNvblwiXG4gICAgICAgICAgICBbY29ubmVjdGlvbkVycm9yTWVzc2FnZUljb25dPVwiY29ubmVjdGlvbkVycm9yTWVzc2FnZUljb25cIlxuICAgICAgICAgICAgW3NlYXJjaFdhcm5pbmdNZXNzYWdlSWNvbl09XCJzZWFyY2hXYXJuaW5nTWVzc2FnZUljb25cIlxuICAgICAgICAgICAgW3N0cmVhbWluZ109XCIoY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCB8IGFzeW5jKSAmJiAobGFzdCB8fCBpc0Fzc2lzdGFudExhc3RNZXNzYWdlcyhtZXNzYWdlcywgaW5kZXgpKVwiXG4gICAgICAgICAgICBbY2FuRWRpdF09XCIoY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCB8IGFzeW5jKSA9PT0gZmFsc2UgJiYgaW5kZXhNZXNzYWdlVG9FZGl0ID09PSB1bmRlZmluZWQgJiYgbWVzc2FnZS5yb2xlID09PSAndXNlcidcIlxuICAgICAgICAgICAgW2NhbkNvcHldPVwiKChjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpID09PSBmYWxzZSB8fCAhbGFzdCkgJiYgaW5kZXhNZXNzYWdlVG9FZGl0ID09PSB1bmRlZmluZWQgJiYgbWVzc2FnZS5yb2xlICE9PSAnY29ubmVjdGlvbi1lcnJvcicgJiYgbWVzc2FnZS5yb2xlICE9PSAnc2VhcmNoLXdhcm5pbmcnXCJcbiAgICAgICAgICAgIFtjYW5MaWtlXT1cIigoY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCB8IGFzeW5jKSA9PT0gZmFsc2UgfHwgIWxhc3QpICYmIG1lc3NhZ2Uucm9sZSA9PT0gJ2Fzc2lzdGFudCdcIlxuICAgICAgICAgICAgW2NhbkRpc2xpa2VdPVwiKChjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpID09PSBmYWxzZSB8fCAhbGFzdCkgJiYgbWVzc2FnZS5yb2xlID09PSAnYXNzaXN0YW50J1wiXG4gICAgICAgICAgICBbY2FuRGVidWddPVwiKCgoY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCB8IGFzeW5jKSA9PT0gZmFsc2UgJiYgbGFzdCkgfHwgKCFsYXN0ICYmIG1lc3NhZ2VzW2luZGV4KzFdLnJvbGUgIT09ICdhc3Npc3RhbnQnKSkgJiYgbWVzc2FnZS5yb2xlID09PSAnYXNzaXN0YW50JyAmJiAoZ2V0RGVidWdNZXNzYWdlcyhtZXNzYWdlLCBpbmRleCkubGVuZ3RoID4gMCkgJiYgKChpc0FkbWluT3JEZWxldGVkQWRtaW4gfHwgKGNoYXRTZXJ2aWNlLnVzZXJPdmVycmlkZSQgfCBhc3luYykpICYmIGNvbmZpZz8uZGVmYXVsdFZhbHVlcy5kZWJ1ZylcIlxuICAgICAgICAgICAgW2NhblJlZ2VuZXJhdGVdPVwiKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYykgPT09IGZhbHNlICAmJiAobGFzdCB8fCAoIWxhc3QgJiYgbWVzc2FnZXNbaW5kZXgrMV0ucm9sZSAhPT0gJ2Fzc2lzdGFudCcpKSAgJiYgbWVzc2FnZS5yb2xlID09PSAnYXNzaXN0YW50JyAmJiBpbmRleE1lc3NhZ2VUb0VkaXQgPT09IHVuZGVmaW5lZFwiXG4gICAgICAgICAgICBbY29sbGFwc2VSZWZlcmVuY2VzXT1cIiEhY29uZmlnPy5nbG9iYWxTZXR0aW5ncy5jb2xsYXBzZVJlZmVyZW5jZXNcIlxuICAgICAgICAgICAgKGVkaXQpPVwiZWRpdE1lc3NhZ2UobWVzc2FnZSwgaW5kZXgpXCJcbiAgICAgICAgICAgIChjb3B5KT1cImNvcHlNZXNzYWdlKG1lc3NhZ2UsIGluZGV4KVwiXG4gICAgICAgICAgICAocmVnZW5lcmF0ZSk9XCJyZWdlbmVyYXRlTWVzc2FnZShtZXNzYWdlLCBpbmRleClcIlxuICAgICAgICAgICAgKG9wZW5Eb2N1bWVudCk9XCJvcGVuT3JpZ2luYWxBdHRhY2htZW50KCRldmVudCwgbWVzc2FnZSwgaW5kZXgpXCJcbiAgICAgICAgICAgIChvcGVuUHJldmlldyk9XCJvcGVuQXR0YWNobWVudFByZXZpZXcoJGV2ZW50LCBtZXNzYWdlLCBpbmRleClcIlxuICAgICAgICAgICAgKHN1Z2dlc3RBY3Rpb24pPVwic3VnZ2VzdEFjdGlvbkNsaWNrKCRldmVudCwgaW5kZXgpXCJcbiAgICAgICAgICAgIChsaWtlKT1cIm9uTGlrZShtZXNzYWdlLCBpbmRleClcIlxuICAgICAgICAgICAgKGRpc2xpa2UpPVwib25EaXNsaWtlKG1lc3NhZ2UsIGluZGV4KVwiXG4gICAgICAgICAgICAoZGVidWcpPVwic2hvd0RlYnVnKG1lc3NhZ2UsIGluZGV4KVwiPlxuICAgICAgICAgIDwvc3EtY2hhdC1tZXNzYWdlPlxuICAgICAgICA8L2xpPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8IS0tIExvYWRpbmcgc3Bpbm5lciAtLT5cbiAgICAgIDxsaSAqbmdJZj1cIihsb2FkaW5nJCB8IGFzeW5jKSA9PT0gdHJ1ZVwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibG9hZGluZ1RwbCB8fCBsb2FkaW5nVHBsRGVmYXVsdFwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9saT5cbiAgICA8L3VsPlxuXG4gICAgPCEtLSBSZXBvcnRpbmcgYSBmZWVkYmFjayBmb3JtIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJpc3N1ZS1yZXBvcnQgcC0zIHJvdW5kZWQtbGdcIiAqbmdJZj1cInNob3dSZXBvcnRcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJyZXBvcnRUcGwgfHwgcmVwb3J0VHBsRGVmYXVsdDsgY29udGV4dDogeyAkaW1wbGljaXQ6IG1lc3NhZ2VUb1JlcG9ydCwgcmFuazogcmVwb3J0UmFuaywgdHlwZTogcmVwb3J0VHlwZSB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIFVzZXIgdGV4dCBpbnB1dCAtLT5cbiAgICBAaWYgKCFzaG93UmVwb3J0KSB7XG4gICAgICA8ZGl2IGNsYXNzPVwidXNlci1pbnB1dCBtdC1hdXRvXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJweS0yXCI+XG4gICAgICAgICAgPGRpdiBbaGlkZGVuXT1cIiFpc0Nvbm5lY3RlZFwiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImVuYWJsZWRVc2VySW5wdXRcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJpbnB1dFRwbFwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwhLS0gUmV0cnkgYnV0dG9uIC0tPlxuICAgICAgICAgIDwhLS0gaGlkZGVuIGF0dHJpYnV0ZSBpcyBpbiBjb25mbGljdCB3aXRoIGEgY3NzIHJ1bGUgZGlzcGxheTogZmxleCAtLT5cbiAgICAgICAgICBAaWYoIWlzQ29ubmVjdGVkKXtcbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gbWItNCBhc3QtZXJyb3IgYXN0LWJ0biBzcS1yZXRyeVwiIChjbGljayk9XCJyZXRyeUZldGNoKClcIj5cbiAgICAgICAgICAgICAgPHNwYW4+e3sgJ2NoYXQudHJ5QWdhaW4nIHwgdHJhbnNsb2NvIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInJldHJpYWxBdHRlbXB0c1wiIGNsYXNzPVwibXMtMiBhdHRlbXB0c1wiPnt7IHJldHJpYWxBdHRlbXB0cyB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIH1cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1lbmQgc21hbGwgdGV4dC1tdXRlZCBweC0zXCIgKm5nSWY9XCIhIWNvbmZpZz8uZ2xvYmFsU2V0dGluZ3M/LmRpc2NsYWltZXJcIj5cbiAgICAgICAgICAgIHt7IGNvbmZpZz8uZ2xvYmFsU2V0dGluZ3M/LmRpc2NsYWltZXIgfCB0cmFuc2xvY28gfX1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICB9XG5cbiAgICA8IS0tIEZsb2F0aW5nIHNjcm9sbCBidXR0b24gLS0+XG4gICAgPGRpdiAqbmdJZj1cIiFpc0F0Qm90dG9tICYmICFzaG93UmVwb3J0XCIgY2xhc3M9XCJzcS1mbG9hdGluZy1zY3JvbGxcIiBbbmdDbGFzc109XCJlbmFibGVkVXNlcklucHV0ID8gJ3NxLWZsb2F0aW5nLXNjcm9sbC0td2hlbi11c2VyLWlucHV0JyA6ICdzcS1mbG9hdGluZy1zY3JvbGwtLXdpdGhvdXQtdXNlci1pbnB1dCdcIj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gc2hhZG93XCIgKGNsaWNrKT1cInNjcm9sbERvd24oKVwiIGFyaWEtbGFiZWw9XCJTY3JvbGwgZG93blwiPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1hbmdsZS1kb3VibGUtZG93blwiPjwvaT5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvbmctY29udGFpbmVyPlxuXG48IS0tIE5HIFRFTVBMQVRFUy0tPlxuXG48bmctdGVtcGxhdGUgI2xvYWRpbmdUcGxEZWZhdWx0PlxuICA8ZGl2IGNsYXNzPVwic3Bpbm5lci1ncm93IHRleHQtcHJpbWFyeSBkLWJsb2NrIG14LWF1dG8gbXktNVwiIHJvbGU9XCJzdGF0dXNcIj5cbiAgICA8c3BhbiBjbGFzcz1cInZpc3VhbGx5LWhpZGRlblwiPnt7ICdjaGF0LmxvYWRpbmcnIHwgdHJhbnNsb2NvIH19PC9zcGFuPlxuICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjaW5wdXRUcGw+XG4gIDxkaXYgY2xhc3M9XCJweC0zIHB5LTFcIj5cbiAgICA8ZGl2IGNsYXNzPVwiYXN0LWlucHV0LWNvbnRhaW5lclwiPlxuICAgICAgPGJ1dHRvbiBkaXNhYmxlZCBjbGFzcz1cImJ0biBidG4tbGlnaHRcIiBhcmlhLWxhYmVsPVwic2VhcmNoXCI+XG4gICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXNlYXJjaFwiPjwvaT5cbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPHRleHRhcmVhICNxdWVzdGlvbklucHV0IHJvd3M9XCIxXCJcbiAgICAgICAgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgIFtwbGFjZWhvbGRlcl09XCInY2hhdC5hc2tTb21ldGhpbmcnIHwgdHJhbnNsb2NvXCIgYXV0b2ZvY3VzXG4gICAgICAgIFsobmdNb2RlbCldPVwicXVlc3Rpb25cIlxuICAgICAgICAoa2V5dXApPVwib25LZXlVcCgkZXZlbnQpXCJcbiAgICAgICAgKGtleWRvd24pPVwiY2FsY3VsYXRlSGVpZ2h0KCRldmVudClcIlxuICAgICAgICBbZGlzYWJsZWRdPVwiKGxvYWRpbmckIHwgYXN5bmMpIHx8IChjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpIHx8IChjaGF0U2VydmljZS5zdG9wcGluZ0dlbmVyYXRpb24kIHwgYXN5bmMpXCI+XG4gICAgICA8L3RleHRhcmVhPlxuICAgICAgPGRpdiBpZD1cImNoYXQtYWN0aW9uc1wiIGNsYXNzPVwiZC1mbGV4IGdhcC0yXCI+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAqbmdJZj1cIihjaGF0U2VydmljZS5zdHJlYW1pbmckIHwgYXN5bmMpID09PSBmYWxzZSAmJiAobG9hZGluZyQgfCBhc3luYykgIT09IHRydWUgJiYgKGNoYXRTZXJ2aWNlLnN0b3BwaW5nR2VuZXJhdGlvbiQgfCBhc3luYykgPT09IGZhbHNlXCJcbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBjbGFzcz1cImJ0biBidG4tbGlnaHRcIlxuICAgICAgICAgIGFyaWEtbGFiZWw9XCJTZW5kIG1lc3NhZ2VcIlxuICAgICAgICAgIFtzcVRvb2x0aXBdPVwiJ2NoYXQuc2VuZE1lc3NhZ2UnIHwgdHJhbnNsb2NvXCJcbiAgICAgICAgICAoY2xpY2spPVwic3VibWl0UXVlc3Rpb24oKVwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXBhcGVyLXBsYW5lXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICpuZ0lmPVwiaW5kZXhNZXNzYWdlVG9FZGl0XCJcbiAgICAgICAgICBhcmlhLWxhYmVsPVwiQ2FuY2VsIGVkaXRpb25cIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1saWdodFwiXG4gICAgICAgICAgW3NxVG9vbHRpcF09XCInY2hhdC5jYW5jZWxFZGl0aW9uJyB8IHRyYW5zbG9jb1wiXG4gICAgICAgICAgKGNsaWNrKT1cImluZGV4TWVzc2FnZVRvRWRpdCA9IHVuZGVmaW5lZDsgcXVlc3Rpb24gPSAnJ1wiPlxuICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXVuZG8tYWx0XCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPHNwYW4gKm5nSWY9XCIoY2hhdFNlcnZpY2Uuc3RyZWFtaW5nJCB8IGFzeW5jKSAmJiAoY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJCB8IGFzeW5jKSA9PT0gZmFsc2VcIiBjbGFzcz1cInByb2Nlc3NpbmdcIj5cbiAgICAgICAgICB7eyAnY2hhdC5nZW5lcmF0aW5nJyB8IHRyYW5zbG9jbyB9fTxpIGNsYXNzPVwiZmFzIGZhLXNwaW5uZXIgZmEtcHVsc2VcIj48L2k+XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPHNwYW4gKm5nSWY9XCIoY2hhdFNlcnZpY2Uuc3RvcHBpbmdHZW5lcmF0aW9uJCB8IGFzeW5jKVwiIGNsYXNzPVwicHJvY2Vzc2luZ1wiPlxuICAgICAgICAgIHt7ICdjaGF0LnN0b3BwaW5nJyB8IHRyYW5zbG9jbyB9fTxpIGNsYXNzPVwiZmFzIGZhLXNwaW5uZXIgZmEtcHVsc2VcIj48L2k+XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICpuZ0lmPVwiKGNoYXRTZXJ2aWNlLnN0cmVhbWluZyQgfCBhc3luYykgJiYgKGNoYXRTZXJ2aWNlLnN0b3BwaW5nR2VuZXJhdGlvbiQgfCBhc3luYykgPT09IGZhbHNlXCJcbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBjbGFzcz1cImJ0biBidG4tbGlnaHRcIlxuICAgICAgICAgIGFyaWEtbGFiZWw9XCJTdG9wIGdlbmVyYXRpbmdcIlxuICAgICAgICAgIFtzcVRvb2x0aXBdPVwiJ2NoYXQuc3RvcEdlbmVyYXRpb24nIHwgdHJhbnNsb2NvXCJcbiAgICAgICAgICAoY2xpY2spPVwic3RvcEdlbmVyYXRpb24oKVwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXN0b3BcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNyZXBvcnRUcGxEZWZhdWx0IGxldC1tZXNzYWdlIGxldC1yYW5rPVwicmFua1wiIGxldC10eXBlPVwidHlwZVwiPlxuICA8ZGl2IGNsYXNzPVwicHgtM1wiPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ0eXBlID09PSAnZGlzbGlrZSdcIj5cbiAgICAgIDxoNT57eyAnY2hhdC5pc3N1ZVR5cGUnIHwgdHJhbnNsb2NvIH19PC9oNT5cbiAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdCBtYi00XCIgWyhuZ01vZGVsKV09XCJpc3N1ZVR5cGVcIj5cbiAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiJydcIj57eyAnY2hhdC5jaG9vc2VJc3N1ZVR5cGUnIHwgdHJhbnNsb2NvIH19PC9vcHRpb24+XG4gICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IHR5cGUgb2YgKGlzc3VlVHlwZXMgPz8gZGVmYXVsdElzc3VlVHlwZXMpXCIgW3ZhbHVlXT1cInR5cGVcIj57eyB0eXBlIHwgdHJhbnNsb2NvIH19PC9vcHRpb24+XG4gICAgICA8L3NlbGVjdD5cbiAgICAgIDxoNT57eyAnY2hhdC5hc2tVbmxpa2VSZWFzb25zJyB8IHRyYW5zbG9jbyB9fTwvaDU+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInR5cGUgPT09ICdsaWtlJ1wiPlxuICAgICAgPGg1Pnt7ICdjaGF0LmFza0xpa2VSZWFzb25zJyB8IHRyYW5zbG9jbyB9fTwvaDU+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPHRleHRhcmVhIGNsYXNzPVwiZm9ybS1jb250cm9sIGJvcmRlciBib3JkZXItbmV1dHJhbC0yMDBcIiBbKG5nTW9kZWwpXT1cInJlcG9ydENvbW1lbnRcIiBbcGxhY2Vob2xkZXJdPVwiJ2NoYXQud3JpdGVDb21tZW50JyB8IHRyYW5zbG9jb1wiPjwvdGV4dGFyZWE+XG4gICAgPGRpdiBjbGFzcz1cImQtZmxleCBmbGV4LXJvdy1yZXZlcnNlIGdhcC0xIG10LTJcIj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiBbZGlzYWJsZWRdPVwidHlwZSA9PT0gJ2Rpc2xpa2UnICYmICFpc3N1ZVR5cGVcIiAoY2xpY2spPVwic2VuZFJlcG9ydCgpXCI+e3sgJ2NoYXQuc2VuZCcgfCB0cmFuc2xvY28gfX08L2J1dHRvbj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWxpZ2h0XCIgKGNsaWNrKT1cImlnbm9yZVJlcG9ydCgpXCI+e3sgJ2NoYXQuZG9Ob3RTZW5kJyB8IHRyYW5zbG9jbyB9fTwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjZGVmYXVsdFRva2VuQ29uc3VtcHRpb25UcGwgbGV0LWluc3RhbmNlSWQ+XG4gIDxzcS10b2tlbi1wcm9ncmVzcy1iYXJcbiAgICBbaW5zdGFuY2VJZF09XCJpbnN0YW5jZUlkXCI+XG4gIDwvc3EtdG9rZW4tcHJvZ3Jlc3MtYmFyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPGRpdiBjbGFzcz1cImRlYnVnLW1lc3NhZ2VzXCIgW2NsYXNzLmRpc3BsYXllZF09XCJzaG93RGVidWdNZXNzYWdlc1wiPlxuICA8YnV0dG9uICpuZ0lmPVwic2hvd0RlYnVnTWVzc2FnZXNcIiBjbGFzcz1cImJ0biBidG4tbGlnaHQgc2hhZG93IGJhY2stYnRuXCIgKGNsaWNrKT1cInNob3dEZWJ1Z01lc3NhZ2VzPWZhbHNlXCIgYXJpYS1sYWJlbD1cIkhpZGUgZGVidWcgbWVzc2FnZXNcIj5cbiAgICA8aSBjbGFzcz1cImZhcyBmYS1jaGV2cm9uLXJpZ2h0XCI+PC9pPlxuICA8L2J1dHRvbj5cbiAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImRlYnVnTWVzc2FnZXNUcGwgfHwgZGVmYXVsdERlYnVnTWVzc2FnZXNUcGw7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBkZWJ1Z01lc3NhZ2VzIH1cIj5cbiAgPC9uZy1jb250YWluZXI+XG48L2Rpdj5cblxuPG5nLXRlbXBsYXRlICNkZWZhdWx0RGVidWdNZXNzYWdlc1RwbCBsZXQtZGVidWdNZXNzYWdlcz5cbiAgPHNxLWRlYnVnLW1lc3NhZ2UgW2RhdGFdPVwiZGVidWdNZXNzYWdlc1wiPjwvc3EtZGVidWctbWVzc2FnZT5cbjwvbmctdGVtcGxhdGU+XG4iXX0=