@snabcentr/client-ui 4.6.6 → 5.1.0

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 (469) hide show
  1. package/fesm2022/snabcentr-client-ui.mjs +3362 -4046
  2. package/fesm2022/snabcentr-client-ui.mjs.map +1 -1
  3. package/package.json +35 -36
  4. package/release_notes.tmp +2 -14
  5. package/styles/taiga/variables.less +16 -17
  6. package/styles/tailwind/tailwind.scss +0 -8
  7. package/types/snabcentr-client-ui.d.ts +5704 -0
  8. package/accordion/index.d.ts +0 -3
  9. package/accordion/sc-accordion-content.directive.d.ts +0 -9
  10. package/accordion/sc-accordion.component.d.ts +0 -56
  11. package/accordion/sc-accordion.module.d.ts +0 -15
  12. package/auth/enums/auth-method.d.ts +0 -13
  13. package/auth/index.d.ts +0 -8
  14. package/auth/interfaces/index.d.ts +0 -2
  15. package/auth/interfaces/sc-bank-account-form-group.d.ts +0 -11
  16. package/auth/interfaces/sc-contact-form-group.d.ts +0 -10
  17. package/auth/sc-auth.module.d.ts +0 -27
  18. package/auth/sc-sign-in-form/sc-sign-in-form-by-email/sc-sign-in-form-by-email.component.d.ts +0 -55
  19. package/auth/sc-sign-in-form/sc-sign-in-form-by-phone/sc-sign-in-form-by-phone.component.d.ts +0 -45
  20. package/auth/sc-sign-in-form/sc-sign-in-form.component.d.ts +0 -53
  21. package/auth/sc-simple-sign-up-form/sc-simple-sign-up-form.component.d.ts +0 -113
  22. package/auth/sign-up-form/sc-sign-up-form.component.d.ts +0 -166
  23. package/banner/index.d.ts +0 -2
  24. package/banner/sc-banner.component.d.ts +0 -79
  25. package/banner/sc-banner.module.d.ts +0 -17
  26. package/brands-list/index.d.ts +0 -2
  27. package/brands-list/sc-brands-list.component.d.ts +0 -15
  28. package/brands-list/sc-brands-list.module.d.ts +0 -12
  29. package/cart/add-or-editing-cart-item-dialog/add-or-editing-cart-item-form/sc-add-or-editing-cart-item-form.component.d.ts +0 -98
  30. package/cart/add-or-editing-cart-item-dialog/index.d.ts +0 -2
  31. package/cart/add-or-editing-cart-item-dialog/sc-add-or-editing-cart-item-dialog.component.d.ts +0 -49
  32. package/cart/index.d.ts +0 -2
  33. package/cart/sc-cart-add-products-from-csv-dialog/sc-cart-add-products-from-csv-dialog.component.d.ts +0 -62
  34. package/catalog/catalog-filters/collapsible/sc-catalog-filter-collapsible.component.d.ts +0 -47
  35. package/catalog/catalog-filters/index.d.ts +0 -4
  36. package/catalog/catalog-filters/sc-catalog-filters.component.d.ts +0 -180
  37. package/catalog/catalog-filters/tokens/sc-catalog-products-filters.d.ts +0 -7
  38. package/catalog/catalog-filters/tokens/sc-catalog-show-products-recursively.d.ts +0 -5
  39. package/catalog/category-card/sc-category-card.component.d.ts +0 -76
  40. package/catalog/cost-with-discount/cost-with-discount.component.d.ts +0 -23
  41. package/catalog/download-price-list/sc-download-price-list.component.d.ts +0 -38
  42. package/catalog/hover-image-carousel/sc-hover-image-carousel.component.d.ts +0 -48
  43. package/catalog/index.d.ts +0 -15
  44. package/catalog/input-quantity/sc-input-quantity.component.d.ts +0 -82
  45. package/catalog/notify-when-in-stock-dialog/index.d.ts +0 -2
  46. package/catalog/notify-when-in-stock-dialog/sc-notify-when-in-stock-dialog.component.d.ts +0 -90
  47. package/catalog/notify-when-in-stock-dialog/sc-product-in-all-warehouses.pipe.d.ts +0 -22
  48. package/catalog/price-card/sc-price-card.component.d.ts +0 -18
  49. package/catalog/price-card-inline/sc-price-card-inline.component.d.ts +0 -10
  50. package/catalog/price-history/sc-price-history.component.d.ts +0 -88
  51. package/catalog/price-list-pagination/sc-price-list-pagination.component.d.ts +0 -40
  52. package/catalog/price-warehouse-stock/sc-price-warehouse-stock.component.d.ts +0 -47
  53. package/catalog/sc-catalog.module.d.ts +0 -29
  54. package/catalog/sc-favorite-button/sc-favorite-button.component.d.ts +0 -25
  55. package/catalog/seo-tags/sc-seo-tags.component.d.ts +0 -20
  56. package/configurators/index.d.ts +0 -3
  57. package/configurators/models/index.d.ts +0 -3
  58. package/configurators/models/sandwich/sc-i-configurator-search-product-sandwich.d.ts +0 -22
  59. package/configurators/models/sandwich/sc-i-sandwich-settings.d.ts +0 -18
  60. package/configurators/models/sandwich_m2/sc-i-sandwich-m2-settings.d.ts +0 -18
  61. package/configurators/sandwich/index.d.ts +0 -3
  62. package/configurators/sandwich/sandwich-skeleton/sc-sandwich-skeleton.component.d.ts +0 -8
  63. package/configurators/sandwich/sc-i-new-cart-item-sandwich.d.ts +0 -14
  64. package/configurators/sandwich/sc-sandwich.component.d.ts +0 -182
  65. package/configurators/sandwich_m2/index.d.ts +0 -4
  66. package/configurators/sandwich_m2/sandwich-m2-skeleton/sc-sandwich-m2-skeleton.component.d.ts +0 -8
  67. package/configurators/sandwich_m2/sc-i-new-cart-item-sandwich-m2.d.ts +0 -23
  68. package/configurators/sandwich_m2/sc-sandwich-m2-item-submit-state.d.ts +0 -13
  69. package/configurators/sandwich_m2/sc-sandwich-m2.component.d.ts +0 -267
  70. package/contacts/add-contact-dialog/sc-add-contact-dialog.component.d.ts +0 -49
  71. package/contacts/contacts-accordion/sc-contacts-accordion.component.d.ts +0 -23
  72. package/contacts/index.d.ts +0 -7
  73. package/contacts/manager-card/sc-manager-card.component.d.ts +0 -22
  74. package/contacts/manager-card-push/sc-manager-card-push.component.d.ts +0 -18
  75. package/contacts/new-contact-form/sc-new-contact-form.component.d.ts +0 -28
  76. package/contacts/sc-contacts.module.d.ts +0 -27
  77. package/contacts/tokens/index.d.ts +0 -2
  78. package/contacts/tokens/sc-manager-qr-handler.token.d.ts +0 -6
  79. package/contacts/tokens/sc-show-help-notification-in-phone-input.token.d.ts +0 -5
  80. package/contragents/add-contragent-bank-account-dialog/sc-add-contragent-bank-account-dialog.component.d.ts +0 -49
  81. package/contragents/add-contragent-dialog/sc-add-contragent-dialog.component.d.ts +0 -158
  82. package/contragents/contragents-accordion/contragents-accordion-item/sc-contragents-accordion-item.component.d.ts +0 -62
  83. package/contragents/contragents-accordion/sc-contragents-accordion.component.d.ts +0 -49
  84. package/contragents/index.d.ts +0 -7
  85. package/contragents/new-contragent-bank-account-form/sc-new-contragent-bank-account-form.component.d.ts +0 -64
  86. package/contragents/new-contragent-form/sc-new-contragent-form.component.d.ts +0 -119
  87. package/contragents/sc-contragents.module.d.ts +0 -26
  88. package/delivery-address/add-delivery-address-dialog/sc-add-delivery-address-dialog.component.d.ts +0 -141
  89. package/delivery-address/delivery-address-accordion/delivery-address-accordion-item/sc-delivery-address-accordion-item.component.d.ts +0 -50
  90. package/delivery-address/delivery-address-accordion/sc-delivery-address-accordion.component.d.ts +0 -49
  91. package/delivery-address/index.d.ts +0 -4
  92. package/delivery-address/sc-delivery-address.module.d.ts +0 -25
  93. package/dialogs/index.d.ts +0 -1
  94. package/dialogs/sc-resource-preview/sc-resource-preview.component.d.ts +0 -42
  95. package/directives/abstract-price-card/abstract-sc-price-card.directive.d.ts +0 -136
  96. package/directives/index.d.ts +0 -9
  97. package/directives/links/index.d.ts +0 -4
  98. package/directives/links/sc-email-link.directive.d.ts +0 -25
  99. package/directives/links/sc-link-location.d.ts +0 -5
  100. package/directives/links/sc-links.d.ts +0 -7
  101. package/directives/links/sc-tel-link.directive.d.ts +0 -40
  102. package/directives/next-input-focus/sc-next-input-focus.directive.d.ts +0 -27
  103. package/directives/next-input-focus/sc-next-input-focus.module.d.ts +0 -10
  104. package/directives/print/sc-print.directive.d.ts +0 -21
  105. package/directives/sc-date-value-transformer.directive.d.ts +0 -8
  106. package/directives/sc-focus-first-invalid-field.directive.d.ts +0 -30
  107. package/directives/select-on-focusin/sc-select-on-focusin.directive.d.ts +0 -14
  108. package/directives/terminal-link/sc-terminal-link.directive.d.ts +0 -34
  109. package/error-handler/consts/error-change-handler.providers.d.ts +0 -6
  110. package/error-handler/error-block-status/error-block-status.component.d.ts +0 -45
  111. package/error-handler/index.d.ts +0 -4
  112. package/error-handler/interfaces/i-block-error.d.ts +0 -17
  113. package/error-handler/sc-error-handler.component.d.ts +0 -40
  114. package/esm2022/accordion/index.mjs +0 -4
  115. package/esm2022/accordion/sc-accordion-content.directive.mjs +0 -17
  116. package/esm2022/accordion/sc-accordion.component.mjs +0 -92
  117. package/esm2022/accordion/sc-accordion.module.mjs +0 -26
  118. package/esm2022/auth/enums/auth-method.mjs +0 -15
  119. package/esm2022/auth/index.mjs +0 -9
  120. package/esm2022/auth/interfaces/index.mjs +0 -3
  121. package/esm2022/auth/interfaces/sc-bank-account-form-group.mjs +0 -2
  122. package/esm2022/auth/interfaces/sc-contact-form-group.mjs +0 -2
  123. package/esm2022/auth/sc-auth.module.mjs +0 -103
  124. package/esm2022/auth/sc-sign-in-form/sc-sign-in-form-by-email/sc-sign-in-form-by-email.component.mjs +0 -100
  125. package/esm2022/auth/sc-sign-in-form/sc-sign-in-form-by-phone/sc-sign-in-form-by-phone.component.mjs +0 -81
  126. package/esm2022/auth/sc-sign-in-form/sc-sign-in-form.component.mjs +0 -89
  127. package/esm2022/auth/sc-simple-sign-up-form/sc-simple-sign-up-form.component.mjs +0 -203
  128. package/esm2022/auth/sign-up-form/sc-sign-up-form.component.mjs +0 -334
  129. package/esm2022/banner/index.mjs +0 -3
  130. package/esm2022/banner/sc-banner.component.mjs +0 -131
  131. package/esm2022/banner/sc-banner.module.mjs +0 -29
  132. package/esm2022/brands-list/index.mjs +0 -3
  133. package/esm2022/brands-list/sc-brands-list.component.mjs +0 -24
  134. package/esm2022/brands-list/sc-brands-list.module.mjs +0 -22
  135. package/esm2022/cart/add-or-editing-cart-item-dialog/add-or-editing-cart-item-form/sc-add-or-editing-cart-item-form.component.mjs +0 -229
  136. package/esm2022/cart/add-or-editing-cart-item-dialog/index.mjs +0 -3
  137. package/esm2022/cart/add-or-editing-cart-item-dialog/sc-add-or-editing-cart-item-dialog.component.mjs +0 -75
  138. package/esm2022/cart/index.mjs +0 -3
  139. package/esm2022/cart/sc-cart-add-products-from-csv-dialog/sc-cart-add-products-from-csv-dialog.component.mjs +0 -110
  140. package/esm2022/catalog/catalog-filters/collapsible/sc-catalog-filter-collapsible.component.mjs +0 -59
  141. package/esm2022/catalog/catalog-filters/index.mjs +0 -5
  142. package/esm2022/catalog/catalog-filters/sc-catalog-filters.component.mjs +0 -402
  143. package/esm2022/catalog/catalog-filters/tokens/sc-catalog-products-filters.mjs +0 -10
  144. package/esm2022/catalog/catalog-filters/tokens/sc-catalog-show-products-recursively.mjs +0 -6
  145. package/esm2022/catalog/category-card/sc-category-card.component.mjs +0 -102
  146. package/esm2022/catalog/cost-with-discount/cost-with-discount.component.mjs +0 -39
  147. package/esm2022/catalog/download-price-list/sc-download-price-list.component.mjs +0 -56
  148. package/esm2022/catalog/hover-image-carousel/sc-hover-image-carousel.component.mjs +0 -76
  149. package/esm2022/catalog/index.mjs +0 -16
  150. package/esm2022/catalog/input-quantity/sc-input-quantity.component.mjs +0 -189
  151. package/esm2022/catalog/notify-when-in-stock-dialog/index.mjs +0 -3
  152. package/esm2022/catalog/notify-when-in-stock-dialog/sc-notify-when-in-stock-dialog.component.mjs +0 -173
  153. package/esm2022/catalog/notify-when-in-stock-dialog/sc-product-in-all-warehouses.pipe.mjs +0 -35
  154. package/esm2022/catalog/price-card/sc-price-card.component.mjs +0 -73
  155. package/esm2022/catalog/price-card-inline/sc-price-card-inline.component.mjs +0 -56
  156. package/esm2022/catalog/price-history/sc-price-history.component.mjs +0 -140
  157. package/esm2022/catalog/price-list-pagination/sc-price-list-pagination.component.mjs +0 -65
  158. package/esm2022/catalog/price-warehouse-stock/sc-price-warehouse-stock.component.mjs +0 -61
  159. package/esm2022/catalog/sc-catalog.module.mjs +0 -126
  160. package/esm2022/catalog/sc-favorite-button/sc-favorite-button.component.mjs +0 -42
  161. package/esm2022/catalog/seo-tags/sc-seo-tags.component.mjs +0 -25
  162. package/esm2022/configurators/index.mjs +0 -4
  163. package/esm2022/configurators/models/index.mjs +0 -4
  164. package/esm2022/configurators/models/sandwich/sc-i-configurator-search-product-sandwich.mjs +0 -2
  165. package/esm2022/configurators/models/sandwich/sc-i-sandwich-settings.mjs +0 -2
  166. package/esm2022/configurators/models/sandwich_m2/sc-i-sandwich-m2-settings.mjs +0 -2
  167. package/esm2022/configurators/sandwich/index.mjs +0 -4
  168. package/esm2022/configurators/sandwich/sandwich-skeleton/sc-sandwich-skeleton.component.mjs +0 -14
  169. package/esm2022/configurators/sandwich/sc-i-new-cart-item-sandwich.mjs +0 -2
  170. package/esm2022/configurators/sandwich/sc-sandwich.component.mjs +0 -382
  171. package/esm2022/configurators/sandwich_m2/index.mjs +0 -5
  172. package/esm2022/configurators/sandwich_m2/sandwich-m2-skeleton/sc-sandwich-m2-skeleton.component.mjs +0 -14
  173. package/esm2022/configurators/sandwich_m2/sc-i-new-cart-item-sandwich-m2.mjs +0 -2
  174. package/esm2022/configurators/sandwich_m2/sc-sandwich-m2-item-submit-state.mjs +0 -5
  175. package/esm2022/configurators/sandwich_m2/sc-sandwich-m2.component.mjs +0 -561
  176. package/esm2022/contacts/add-contact-dialog/sc-add-contact-dialog.component.mjs +0 -91
  177. package/esm2022/contacts/contacts-accordion/sc-contacts-accordion.component.mjs +0 -37
  178. package/esm2022/contacts/index.mjs +0 -8
  179. package/esm2022/contacts/manager-card/sc-manager-card.component.mjs +0 -58
  180. package/esm2022/contacts/manager-card-push/sc-manager-card-push.component.mjs +0 -28
  181. package/esm2022/contacts/new-contact-form/sc-new-contact-form.component.mjs +0 -37
  182. package/esm2022/contacts/sc-contacts.module.mjs +0 -89
  183. package/esm2022/contacts/tokens/index.mjs +0 -3
  184. package/esm2022/contacts/tokens/sc-manager-qr-handler.token.mjs +0 -25
  185. package/esm2022/contacts/tokens/sc-show-help-notification-in-phone-input.token.mjs +0 -9
  186. package/esm2022/contragents/add-contragent-bank-account-dialog/sc-add-contragent-bank-account-dialog.component.mjs +0 -81
  187. package/esm2022/contragents/add-contragent-dialog/sc-add-contragent-dialog.component.mjs +0 -266
  188. package/esm2022/contragents/contragents-accordion/contragents-accordion-item/sc-contragents-accordion-item.component.mjs +0 -74
  189. package/esm2022/contragents/contragents-accordion/sc-contragents-accordion.component.mjs +0 -68
  190. package/esm2022/contragents/index.mjs +0 -8
  191. package/esm2022/contragents/new-contragent-bank-account-form/sc-new-contragent-bank-account-form.component.mjs +0 -72
  192. package/esm2022/contragents/new-contragent-form/sc-new-contragent-form.component.mjs +0 -224
  193. package/esm2022/contragents/sc-contragents.module.mjs +0 -115
  194. package/esm2022/delivery-address/add-delivery-address-dialog/sc-add-delivery-address-dialog.component.mjs +0 -248
  195. package/esm2022/delivery-address/delivery-address-accordion/delivery-address-accordion-item/sc-delivery-address-accordion-item.component.mjs +0 -60
  196. package/esm2022/delivery-address/delivery-address-accordion/sc-delivery-address-accordion.component.mjs +0 -68
  197. package/esm2022/delivery-address/index.mjs +0 -5
  198. package/esm2022/delivery-address/sc-delivery-address.module.mjs +0 -96
  199. package/esm2022/dialogs/index.mjs +0 -2
  200. package/esm2022/dialogs/sc-resource-preview/sc-resource-preview.component.mjs +0 -73
  201. package/esm2022/directives/abstract-price-card/abstract-sc-price-card.directive.mjs +0 -170
  202. package/esm2022/directives/index.mjs +0 -10
  203. package/esm2022/directives/links/index.mjs +0 -5
  204. package/esm2022/directives/links/sc-email-link.directive.mjs +0 -49
  205. package/esm2022/directives/links/sc-link-location.mjs +0 -2
  206. package/esm2022/directives/links/sc-links.mjs +0 -8
  207. package/esm2022/directives/links/sc-tel-link.directive.mjs +0 -79
  208. package/esm2022/directives/next-input-focus/sc-next-input-focus.directive.mjs +0 -70
  209. package/esm2022/directives/next-input-focus/sc-next-input-focus.module.mjs +0 -19
  210. package/esm2022/directives/print/sc-print.directive.mjs +0 -36
  211. package/esm2022/directives/sc-date-value-transformer.directive.mjs +0 -30
  212. package/esm2022/directives/sc-focus-first-invalid-field.directive.mjs +0 -85
  213. package/esm2022/directives/select-on-focusin/sc-select-on-focusin.directive.mjs +0 -31
  214. package/esm2022/directives/terminal-link/sc-terminal-link.directive.mjs +0 -69
  215. package/esm2022/error-handler/consts/error-change-handler.providers.mjs +0 -10
  216. package/esm2022/error-handler/error-block-status/error-block-status.component.mjs +0 -88
  217. package/esm2022/error-handler/index.mjs +0 -5
  218. package/esm2022/error-handler/interfaces/i-block-error.mjs +0 -2
  219. package/esm2022/error-handler/sc-error-handler.component.mjs +0 -58
  220. package/esm2022/feedback/feedback-form/sc-feedback-form.component.mjs +0 -344
  221. package/esm2022/feedback/gratitude/sc-gratitude.component.mjs +0 -32
  222. package/esm2022/feedback/index.mjs +0 -4
  223. package/esm2022/feedback/interfaces/index.mjs +0 -2
  224. package/esm2022/feedback/interfaces/sc-feedback-form-config.mjs +0 -2
  225. package/esm2022/files/directives/index.mjs +0 -3
  226. package/esm2022/files/directives/tree-top.directive.mjs +0 -63
  227. package/esm2022/files/directives/tree.directive.mjs +0 -47
  228. package/esm2022/files/file-tree-item/file-tree-item.component.mjs +0 -18
  229. package/esm2022/files/files-and-documents/files-and-documents.component.mjs +0 -61
  230. package/esm2022/files/files-and-documents.module.mjs +0 -28
  231. package/esm2022/files/index.mjs +0 -6
  232. package/esm2022/files/interfaces/tree-node.mjs +0 -2
  233. package/esm2022/files/services/index.mjs +0 -3
  234. package/esm2022/files/services/tree-icon.service.mjs +0 -49
  235. package/esm2022/files/services/tree-loader.service.mjs +0 -62
  236. package/esm2022/form-fields/addresses-selection-field/sc-addresses-selection-field.component.mjs +0 -156
  237. package/esm2022/form-fields/form-fields.module.mjs +0 -66
  238. package/esm2022/form-fields/index.mjs +0 -4
  239. package/esm2022/form-fields/suggestion-field/sc-suggestion-field.component.mjs +0 -174
  240. package/esm2022/icons/index.mjs +0 -2
  241. package/esm2022/icons/sc-client-ui-icons-name.mjs +0 -99
  242. package/esm2022/loader/index.mjs +0 -2
  243. package/esm2022/loader/sc-i-loader.mjs +0 -2
  244. package/esm2022/masks/index.mjs +0 -8
  245. package/esm2022/masks/sc-account-number-mask.mjs +0 -7
  246. package/esm2022/masks/sc-bic-mask.mjs +0 -7
  247. package/esm2022/masks/sc-correspondent-account-mask.mjs +0 -7
  248. package/esm2022/masks/sc-inn-mask.mjs +0 -13
  249. package/esm2022/masks/sc-kpp-mask.mjs +0 -7
  250. package/esm2022/masks/sc-okpo-mask.mjs +0 -13
  251. package/esm2022/masks/sc-phone-verification-code-mask.mjs +0 -7
  252. package/esm2022/methods/index.mjs +0 -2
  253. package/esm2022/methods/sc-get-current-route.mjs +0 -14
  254. package/esm2022/models/i-sc-image.mjs +0 -2
  255. package/esm2022/models/index.mjs +0 -2
  256. package/esm2022/news/index.mjs +0 -4
  257. package/esm2022/news/news-card/sc-news-card.component.mjs +0 -34
  258. package/esm2022/news/news-card-skeleton/sc-news-card-skeleton.component.mjs +0 -31
  259. package/esm2022/news/sc-news.module.mjs +0 -26
  260. package/esm2022/noindex-wrapper/directives/index.mjs +0 -2
  261. package/esm2022/noindex-wrapper/directives/sc-noindex.directive.mjs +0 -58
  262. package/esm2022/noindex-wrapper/index.mjs +0 -3
  263. package/esm2022/noindex-wrapper/sc-noindex-wrapper.component.mjs +0 -18
  264. package/esm2022/order/directives/index.mjs +0 -3
  265. package/esm2022/order/directives/sc-order-accessor.directive.mjs +0 -28
  266. package/esm2022/order/directives/sc-order-options.mjs +0 -11
  267. package/esm2022/order/draft/sc-draft.component.mjs +0 -118
  268. package/esm2022/order/index.mjs +0 -10
  269. package/esm2022/order/models/sc-i-cart-items-by-direction.mjs +0 -22
  270. package/esm2022/order/order-item/sc-order-item.component.mjs +0 -108
  271. package/esm2022/order/order-items-list/sc-order-items-list.component.mjs +0 -208
  272. package/esm2022/order/order-items-list-by-directions/sc-order-items-list-by-directions.component.mjs +0 -75
  273. package/esm2022/order/order-items-list-by-stock/sc-order-items-list-by-stock.component.mjs +0 -75
  274. package/esm2022/order/sc-order.module.mjs +0 -52
  275. package/esm2022/order/sc-payment-status/sc-payment-status.component.mjs +0 -35
  276. package/esm2022/pages/frequently-asked-questions/sc-frequently-asked-questions.component.mjs +0 -49
  277. package/esm2022/pages/frequently-asked-questions/sc-page-size-options.mjs +0 -8
  278. package/esm2022/pages/frequently-asked-questions-group-selector/sc-frequently-asked-questions-group-selector.component.mjs +0 -59
  279. package/esm2022/pages/frequently-asked-questions-with-groups/sc-frequently-asked-questions-with-groups.component.mjs +0 -107
  280. package/esm2022/pages/index.mjs +0 -7
  281. package/esm2022/pages/personal-data-processing-policy/sc-personal-data-processing-policy.component.mjs +0 -46
  282. package/esm2022/pages/privacy-policy/sc-privacy-policy.component.mjs +0 -30
  283. package/esm2022/pages/public-offer/sc-public-offer.component.mjs +0 -50
  284. package/esm2022/pipes/index.mjs +0 -3
  285. package/esm2022/pipes/sc-format-date.mjs +0 -33
  286. package/esm2022/pipes/sc-phone-format.mjs +0 -44
  287. package/esm2022/profile/index.mjs +0 -3
  288. package/esm2022/profile/sc-profile-accordions-content/sc-profile-accordions-content.component.mjs +0 -174
  289. package/esm2022/profile/sc-profile.module.mjs +0 -73
  290. package/esm2022/providers/cleanup-recaptcha-artifacts.mjs +0 -30
  291. package/esm2022/providers/date-value-transformer/index.mjs +0 -4
  292. package/esm2022/providers/date-value-transformer/sc-date-value-transformer-types.mjs +0 -2
  293. package/esm2022/providers/date-value-transformer/sc-date-value-transformer-with-end-time.mjs +0 -26
  294. package/esm2022/providers/date-value-transformer/sc-date-value-transformer-with-start-time.mjs +0 -37
  295. package/esm2022/providers/index.mjs +0 -17
  296. package/esm2022/providers/sc-allow-select-terminated.mjs +0 -8
  297. package/esm2022/providers/sc-banner-duration.mjs +0 -8
  298. package/esm2022/providers/sc-country-ids.mjs +0 -8
  299. package/esm2022/providers/sc-date-formatter.mjs +0 -15
  300. package/esm2022/providers/sc-date-value-transformer.mjs +0 -12
  301. package/esm2022/providers/sc-debounce-time-default.mjs +0 -9
  302. package/esm2022/providers/sc-dialog-service.providers.mjs +0 -6
  303. package/esm2022/providers/sc-help-notification-close.mjs +0 -9
  304. package/esm2022/providers/sc-help-notification-limit.mjs +0 -8
  305. package/esm2022/providers/sc-hidden-print-elements.token.mjs +0 -10
  306. package/esm2022/providers/sc-max-files-in-form-input.mjs +0 -8
  307. package/esm2022/providers/sc-notify-when-in-stock-required-fields.mjs +0 -8
  308. package/esm2022/providers/sc-page-size-options.mjs +0 -8
  309. package/esm2022/providers/sc-user-providers.mjs +0 -38
  310. package/esm2022/providers/sc-verification-code-timeout.mjs +0 -8
  311. package/esm2022/public-api.mjs +0 -35
  312. package/esm2022/qrcode/index.mjs +0 -3
  313. package/esm2022/qrcode/qrcode-dialog/sc-qrcode-dialog.component.mjs +0 -58
  314. package/esm2022/qrcode/sc-qrcode.module.mjs +0 -25
  315. package/esm2022/samples/index.mjs +0 -5
  316. package/esm2022/samples/interfaces/index.mjs +0 -3
  317. package/esm2022/samples/interfaces/sc-i-preview-sample.mjs +0 -2
  318. package/esm2022/samples/interfaces/sc-preview-mosquito-config.mjs +0 -2
  319. package/esm2022/samples/preview-sample/sc-preview-sample.component.mjs +0 -42
  320. package/esm2022/samples/sc-preview-samples-mosquito/sc-preview-samples-mosquito.component.mjs +0 -63
  321. package/esm2022/samples/sc-sample.module.mjs +0 -66
  322. package/esm2022/services/index.mjs +0 -3
  323. package/esm2022/services/print.service.mjs +0 -49
  324. package/esm2022/services/sc-help-notification.service.mjs +0 -100
  325. package/esm2022/share-button/index.mjs +0 -3
  326. package/esm2022/share-button/sc-share-button.component.mjs +0 -35
  327. package/esm2022/share-button/sc-share-button.module.mjs +0 -22
  328. package/esm2022/snabcentr-client-ui.mjs +0 -5
  329. package/esm2022/user/index.mjs +0 -6
  330. package/esm2022/user/reset-user-password/sc-reset-user-password.component.mjs +0 -74
  331. package/esm2022/user/sc-user.module.mjs +0 -86
  332. package/esm2022/user/update-user-info-dialog/sc-update-user-info-dialog.component.mjs +0 -121
  333. package/esm2022/user/user-managers/sc-user-managers.component.mjs +0 -40
  334. package/esm2022/user/user-phone-approve-dialog/sc-user-phone-approve-dialog.component.mjs +0 -105
  335. package/esm2022/validators/index.mjs +0 -7
  336. package/esm2022/validators/sc-at-least-one-required-validator.mjs +0 -25
  337. package/esm2022/validators/sc-bic-validator.mjs +0 -10
  338. package/esm2022/validators/sc-correspondent-account-validator.mjs +0 -10
  339. package/esm2022/validators/sc-password-confirm-matching-validator.mjs +0 -17
  340. package/esm2022/validators/sc-phone-validator.mjs +0 -14
  341. package/esm2022/validators/step-validator.mjs +0 -18
  342. package/esm2022/verification/index.mjs +0 -3
  343. package/esm2022/verification/sc-verification.module.mjs +0 -86
  344. package/esm2022/verification/verification-phone-check-form/sc-verification-phone-check-form.component.mjs +0 -259
  345. package/feedback/feedback-form/sc-feedback-form.component.d.ts +0 -163
  346. package/feedback/gratitude/sc-gratitude.component.d.ts +0 -20
  347. package/feedback/index.d.ts +0 -3
  348. package/feedback/interfaces/index.d.ts +0 -1
  349. package/feedback/interfaces/sc-feedback-form-config.d.ts +0 -23
  350. package/files/directives/index.d.ts +0 -2
  351. package/files/directives/tree-top.directive.d.ts +0 -33
  352. package/files/directives/tree.directive.d.ts +0 -35
  353. package/files/file-tree-item/file-tree-item.component.d.ts +0 -9
  354. package/files/files-and-documents/files-and-documents.component.d.ts +0 -27
  355. package/files/files-and-documents.module.d.ts +0 -17
  356. package/files/index.d.ts +0 -5
  357. package/files/interfaces/tree-node.d.ts +0 -29
  358. package/files/services/index.d.ts +0 -2
  359. package/files/services/tree-icon.service.d.ts +0 -23
  360. package/files/services/tree-loader.service.d.ts +0 -43
  361. package/form-fields/addresses-selection-field/sc-addresses-selection-field.component.d.ts +0 -78
  362. package/form-fields/form-fields.module.d.ts +0 -18
  363. package/form-fields/index.d.ts +0 -3
  364. package/form-fields/suggestion-field/sc-suggestion-field.component.d.ts +0 -73
  365. package/icons/index.d.ts +0 -1
  366. package/icons/sc-client-ui-icons-name.d.ts +0 -4
  367. package/index.d.ts +0 -5
  368. package/loader/index.d.ts +0 -1
  369. package/loader/sc-i-loader.d.ts +0 -9
  370. package/masks/index.d.ts +0 -7
  371. package/masks/sc-account-number-mask.d.ts +0 -5
  372. package/masks/sc-bic-mask.d.ts +0 -5
  373. package/masks/sc-correspondent-account-mask.d.ts +0 -5
  374. package/masks/sc-inn-mask.d.ts +0 -9
  375. package/masks/sc-kpp-mask.d.ts +0 -5
  376. package/masks/sc-okpo-mask.d.ts +0 -9
  377. package/masks/sc-phone-verification-code-mask.d.ts +0 -5
  378. package/methods/index.d.ts +0 -1
  379. package/methods/sc-get-current-route.d.ts +0 -8
  380. package/models/i-sc-image.d.ts +0 -17
  381. package/models/index.d.ts +0 -1
  382. package/news/index.d.ts +0 -3
  383. package/news/news-card/sc-news-card.component.d.ts +0 -22
  384. package/news/news-card-skeleton/sc-news-card-skeleton.component.d.ts +0 -16
  385. package/news/sc-news.module.d.ts +0 -16
  386. package/noindex-wrapper/directives/index.d.ts +0 -1
  387. package/noindex-wrapper/directives/sc-noindex.directive.d.ts +0 -29
  388. package/noindex-wrapper/index.d.ts +0 -2
  389. package/noindex-wrapper/sc-noindex-wrapper.component.d.ts +0 -9
  390. package/order/directives/index.d.ts +0 -2
  391. package/order/directives/sc-order-accessor.directive.d.ts +0 -13
  392. package/order/directives/sc-order-options.d.ts +0 -14
  393. package/order/draft/sc-draft.component.d.ts +0 -63
  394. package/order/index.d.ts +0 -9
  395. package/order/models/sc-i-cart-items-by-direction.d.ts +0 -25
  396. package/order/order-item/sc-order-item.component.d.ts +0 -39
  397. package/order/order-items-list/sc-order-items-list.component.d.ts +0 -109
  398. package/order/order-items-list-by-directions/sc-order-items-list-by-directions.component.d.ts +0 -58
  399. package/order/order-items-list-by-stock/sc-order-items-list-by-stock.component.d.ts +0 -55
  400. package/order/sc-order.module.d.ts +0 -18
  401. package/order/sc-payment-status/sc-payment-status.component.d.ts +0 -25
  402. package/pages/frequently-asked-questions/sc-frequently-asked-questions.component.d.ts +0 -22
  403. package/pages/frequently-asked-questions/sc-page-size-options.d.ts +0 -5
  404. package/pages/frequently-asked-questions-group-selector/sc-frequently-asked-questions-group-selector.component.d.ts +0 -28
  405. package/pages/frequently-asked-questions-with-groups/sc-frequently-asked-questions-with-groups.component.d.ts +0 -79
  406. package/pages/index.d.ts +0 -6
  407. package/pages/personal-data-processing-policy/sc-personal-data-processing-policy.component.d.ts +0 -17
  408. package/pages/privacy-policy/sc-privacy-policy.component.d.ts +0 -17
  409. package/pages/public-offer/sc-public-offer.component.d.ts +0 -22
  410. package/pipes/index.d.ts +0 -2
  411. package/pipes/sc-format-date.d.ts +0 -20
  412. package/pipes/sc-phone-format.d.ts +0 -21
  413. package/profile/index.d.ts +0 -2
  414. package/profile/sc-profile-accordions-content/sc-profile-accordions-content.component.d.ts +0 -126
  415. package/profile/sc-profile.module.d.ts +0 -23
  416. package/providers/cleanup-recaptcha-artifacts.d.ts +0 -7
  417. package/providers/date-value-transformer/index.d.ts +0 -3
  418. package/providers/date-value-transformer/sc-date-value-transformer-types.d.ts +0 -9
  419. package/providers/date-value-transformer/sc-date-value-transformer-with-end-time.d.ts +0 -16
  420. package/providers/date-value-transformer/sc-date-value-transformer-with-start-time.d.ts +0 -22
  421. package/providers/index.d.ts +0 -16
  422. package/providers/sc-allow-select-terminated.d.ts +0 -5
  423. package/providers/sc-banner-duration.d.ts +0 -5
  424. package/providers/sc-country-ids.d.ts +0 -5
  425. package/providers/sc-date-formatter.d.ts +0 -6
  426. package/providers/sc-date-value-transformer.d.ts +0 -5
  427. package/providers/sc-debounce-time-default.d.ts +0 -5
  428. package/providers/sc-dialog-service.providers.d.ts +0 -45
  429. package/providers/sc-help-notification-close.d.ts +0 -6
  430. package/providers/sc-help-notification-limit.d.ts +0 -5
  431. package/providers/sc-hidden-print-elements.token.d.ts +0 -6
  432. package/providers/sc-max-files-in-form-input.d.ts +0 -5
  433. package/providers/sc-notify-when-in-stock-required-fields.d.ts +0 -5
  434. package/providers/sc-page-size-options.d.ts +0 -5
  435. package/providers/sc-user-providers.d.ts +0 -21
  436. package/providers/sc-verification-code-timeout.d.ts +0 -5
  437. package/public-api.d.ts +0 -34
  438. package/qrcode/index.d.ts +0 -2
  439. package/qrcode/qrcode-dialog/sc-qrcode-dialog.component.d.ts +0 -37
  440. package/qrcode/sc-qrcode.module.d.ts +0 -14
  441. package/samples/index.d.ts +0 -4
  442. package/samples/interfaces/index.d.ts +0 -2
  443. package/samples/interfaces/sc-i-preview-sample.d.ts +0 -56
  444. package/samples/interfaces/sc-preview-mosquito-config.d.ts +0 -62
  445. package/samples/preview-sample/sc-preview-sample.component.d.ts +0 -30
  446. package/samples/sc-preview-samples-mosquito/sc-preview-samples-mosquito.component.d.ts +0 -50
  447. package/samples/sc-sample.module.d.ts +0 -19
  448. package/services/index.d.ts +0 -2
  449. package/services/print.service.d.ts +0 -31
  450. package/services/sc-help-notification.service.d.ts +0 -70
  451. package/share-button/index.d.ts +0 -2
  452. package/share-button/sc-share-button.component.d.ts +0 -22
  453. package/share-button/sc-share-button.module.d.ts +0 -12
  454. package/user/index.d.ts +0 -5
  455. package/user/reset-user-password/sc-reset-user-password.component.d.ts +0 -46
  456. package/user/sc-user.module.d.ts +0 -24
  457. package/user/update-user-info-dialog/sc-update-user-info-dialog.component.d.ts +0 -63
  458. package/user/user-managers/sc-user-managers.component.d.ts +0 -23
  459. package/user/user-phone-approve-dialog/sc-user-phone-approve-dialog.component.d.ts +0 -53
  460. package/validators/index.d.ts +0 -6
  461. package/validators/sc-at-least-one-required-validator.d.ts +0 -10
  462. package/validators/sc-bic-validator.d.ts +0 -8
  463. package/validators/sc-correspondent-account-validator.d.ts +0 -8
  464. package/validators/sc-password-confirm-matching-validator.d.ts +0 -8
  465. package/validators/sc-phone-validator.d.ts +0 -5
  466. package/validators/step-validator.d.ts +0 -8
  467. package/verification/index.d.ts +0 -2
  468. package/verification/sc-verification.module.d.ts +0 -21
  469. package/verification/verification-phone-check-form/sc-verification-phone-check-form.component.d.ts +0 -145
@@ -1,561 +0,0 @@
1
- /* eslint-disable security/detect-object-injection,@typescript-eslint/unbound-method */
2
- import { AsyncPipe, DecimalPipe } from '@angular/common';
3
- import { HttpErrorResponse } from '@angular/common/http';
4
- import { ChangeDetectionStrategy, Component, computed, DestroyRef, inject, Input, input, output, signal } from '@angular/core';
5
- import { takeUntilDestroyed, toObservable, toSignal } from '@angular/core/rxjs-interop';
6
- import { FormArray, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
7
- import { SC_ORDER_LOADER, ScCatalogService, ScConvertersService, } from '@snabcentr/client-core';
8
- import { TuiAutoFocus, tuiControlValue } from '@taiga-ui/cdk';
9
- import { TuiButton, TuiError, TuiIcon, tuiItemsHandlersProvider, TuiLabel, TuiLoader, TuiNumberFormat, tuiNumberFormatProvider, TuiTextfield, } from '@taiga-ui/core';
10
- import { TuiButtonLoading, TuiChevron, TuiDataListWrapperComponent, TuiFieldErrorPipe, TuiInputNumber, tuiInputNumberOptionsProvider, TuiInputSlider, TuiSelect, } from '@taiga-ui/kit';
11
- import { POLYMORPHEUS_CONTEXT } from '@taiga-ui/polymorpheus';
12
- import { catchError, concatMap, from, map, of, switchMap, tap, throwError } from 'rxjs';
13
- import { ScNextInputFocusModule } from '../../directives/next-input-focus/sc-next-input-focus.module';
14
- import { ScSelectOnFocusinDirective } from '../../directives/select-on-focusin/sc-select-on-focusin.directive';
15
- import { stepValidator } from '../../validators/step-validator';
16
- import { IDLE_ITEM_STATE } from './sc-sandwich-m2-item-submit-state';
17
- import * as i0 from "@angular/core";
18
- import * as i1 from "@angular/forms";
19
- import * as i2 from "../../directives/next-input-focus/sc-next-input-focus.directive";
20
- import * as i3 from "@taiga-ui/core";
21
- import * as i4 from "@taiga-ui/kit";
22
- import * as i5 from "@taiga-ui/kit/components/slider";
23
- /**
24
- * Конфигуратор распила сэндвич-панелей по площади.
25
- */
26
- export class ScSandwichM2Component {
27
- constructor() {
28
- /**
29
- * Настройки для конфигуратора распила сэндвич-панелей по площади.
30
- */
31
- this.settings = input();
32
- /**
33
- * Идентификатор категории.
34
- */
35
- this.categoryId = input.required();
36
- /**
37
- * Название конфигуратора.
38
- */
39
- this.editor = input.required();
40
- /**
41
- * Позиция товара/услуги в корзине.
42
- */
43
- this.orderItem = input.required();
44
- /**
45
- * Событие переключения отображения товаров.
46
- */
47
- this.toggleShowEvent = output();
48
- /**
49
- * Форма добавления/редактирования продукта в корзине.
50
- */
51
- this.form = new FormGroup({
52
- productCategoryId: new FormControl(null, { validators: Validators.required }),
53
- configurator: new FormControl(null, { validators: Validators.required }),
54
- items: new FormArray([]),
55
- });
56
- /**
57
- * Сервис получения и редактирования списка товаров заказа (корзина / заказ / черновик = заказ).
58
- */
59
- this.orderService = inject(SC_ORDER_LOADER);
60
- /**
61
- * Сервис конвертации данных.
62
- */
63
- this.convertersService = inject(ScConvertersService);
64
- /**
65
- * Контекст диалогового окна, в котором открыт компонент.
66
- */
67
- this.context = inject(POLYMORPHEUS_CONTEXT, { optional: true });
68
- /**
69
- * Сервис для работы с каталогом.
70
- */
71
- this.catalogService = inject(ScCatalogService);
72
- /**
73
- * {@link Observable} списка товаров категории.
74
- */
75
- this.products$ = toObservable(this.categoryId).pipe(switchMap((categoryId) => {
76
- if (!categoryId) {
77
- return of([]);
78
- }
79
- return this.catalogService.getProductsCategoryCached$({ categoryId: Number(categoryId) }).pipe(map((products) => products ?? []));
80
- }));
81
- /**
82
- * Выбранный продукт.
83
- */
84
- this.product = new FormControl(null, { validators: Validators.required });
85
- /**
86
- * Сигнал текущего выбранного продукта — обновляется при `valueChanges` контрола `product`.
87
- */
88
- this.productSignal = toSignal(tuiControlValue(this.product), { initialValue: null });
89
- /**
90
- * Сигнал содержимого FormArray позиций — пересчитывается при любом изменении значений.
91
- */
92
- this.itemsValue = toSignal(tuiControlValue(this.items).pipe(map(() => this.items.controls.map((c) => c.getRawValue()))), {
93
- initialValue: [],
94
- });
95
- /**
96
- * Признак того, что выполняется запрос на отправку данных.
97
- */
98
- this.isSubmitLoading = computed(() => this.itemStates().includes('loading'));
99
- /**
100
- * Состояние отправки каждой позиции — параллельный массив к контролу `items` формы.
101
- */
102
- this.itemStates = signal([]);
103
- /**
104
- * Признак режима редактирования существующей позиции — `orderItem` задан.
105
- */
106
- this.isEditingExistingItem = computed(() => this.orderItem() != null);
107
- /**
108
- * Признак того, что отправлять больше нечего — все позиции либо успешно
109
- * отправлены, либо находятся в процессе отправки.
110
- */
111
- this.hasNoPendingItems = computed(() => {
112
- const states = this.itemStates();
113
- if (this.items.length === 0) {
114
- return true;
115
- }
116
- return this.items.controls.every((_, index) => {
117
- const state = states[index] ?? IDLE_ITEM_STATE;
118
- return state === 'success' || state === 'loading';
119
- });
120
- });
121
- /**
122
- * Суммарная площадь всех позиций (м²), рассчитанная локально.
123
- */
124
- this.totalAreaM2 = computed(() => {
125
- let total = 0;
126
- this.itemsValue().forEach((value) => {
127
- total += this.rowTotalPartsAreaM2(value);
128
- });
129
- return total;
130
- });
131
- /**
132
- * Итоговая стоимость по всем позициям (локальный расчёт).
133
- */
134
- this.totalCost = computed(() => {
135
- const cost = this.productSignal()?.costRub ?? 0;
136
- const area = this.totalAreaM2();
137
- return Math.round(area * cost * 100) / 100;
138
- });
139
- /**
140
- * Текст ограничения по ширине («от … до …»), пока есть выбранный товар.
141
- */
142
- this.widthRangeText = computed(() => this.formatRange(this.settings()?.minWidth ?? null, this.productSignal()?.properties?.width ?? null, 'мм'));
143
- /**
144
- * Текст ограничения по длине («от … до …»), пока есть выбранный товар.
145
- */
146
- this.lengthRangeText = computed(() => this.formatRange(this.settings()?.minLength ?? null, this.productSignal()?.properties?.length ?? null, 'мм'));
147
- /**
148
- * Ссылка для автоматического управления уничтожением зависимостей.
149
- */
150
- this.destroyRef = inject(DestroyRef);
151
- }
152
- /**
153
- * Валидаторы ширины/длины: пока товар не выбран — не накладываем min/max каталога (поля read-only без товара).
154
- *
155
- * @param min Нижняя граница размера из настроек конфигуратора.
156
- * @param maxUpper Верхняя граница из свойств выбранного товара.
157
- */
158
- dimensionValidators(min, maxUpper) {
159
- const chosenProduct = this.product.value;
160
- if (!chosenProduct) {
161
- return [];
162
- }
163
- return [Validators.required, Validators.min(min), ...(maxUpper != null && maxUpper > 0 ? [Validators.max(maxUpper)] : []), stepValidator(1)];
164
- }
165
- /**
166
- * Обновляет валидаторы размерных полей после смены товара или настроек.
167
- */
168
- updateItemsValidators() {
169
- const settings = this.settings();
170
- const minWidth = settings?.minWidth ?? 0.01;
171
- const minLength = settings?.minLength ?? 0.01;
172
- const chosenProduct = this.product.value;
173
- this.items.controls.forEach((group) => {
174
- group.get('width')?.setValidators(this.dimensionValidators(minWidth, chosenProduct?.properties?.width));
175
- group.get('length')?.setValidators(this.dimensionValidators(minLength, chosenProduct?.properties?.length));
176
- group.get('width')?.updateValueAndValidity({ emitEvent: false });
177
- group.get('length')?.updateValueAndValidity({ emitEvent: false });
178
- });
179
- }
180
- /**
181
- * Форматирование диапазона «от … до …» с учётом отсутствующих границ.
182
- *
183
- * @param min Нижняя граница диапазона.
184
- * @param max Верхняя граница диапазона.
185
- * @param unit Единица измерения для подписи.
186
- */
187
- // eslint-disable-next-line class-methods-use-this
188
- formatRange(min, max, unit) {
189
- const hasMin = min != null && min > 0;
190
- const hasMax = max != null && max > 0;
191
- if (!hasMin && !hasMax) {
192
- return null;
193
- }
194
- if (hasMin && hasMax) {
195
- return `от ${min} ${unit} до ${max} ${unit}`;
196
- }
197
- if (hasMin) {
198
- return `от ${min} ${unit}`;
199
- }
200
- return `до ${max} ${unit}`;
201
- }
202
- /**
203
- * Массив изделий.
204
- */
205
- get items() {
206
- return this.form.controls.items;
207
- }
208
- /**
209
- * {@inheritDoc}
210
- */
211
- ngOnInit() {
212
- this.setDefaultFormValue();
213
- this.products$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((products) => {
214
- if (this.product.value != null || products.length === 0) {
215
- return;
216
- }
217
- /* При загрузке списка автоматически выбираем первый материал. */
218
- this.product.setValue(products[0], { emitEvent: true });
219
- });
220
- this.product.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((chosenProduct) => {
221
- this.updateItemsValidators();
222
- if (chosenProduct) {
223
- this.items.controls.forEach((item) => {
224
- const value = item.getRawValue();
225
- const maxW = chosenProduct.properties?.width;
226
- const maxL = chosenProduct.properties?.length;
227
- item.patchValue({
228
- width: maxW ? Math.min(value.width, maxW) : value.width,
229
- length: maxL ? Math.min(value.length, maxL) : value.length,
230
- });
231
- });
232
- /*
233
- * Смена продукта — сбрасываем состояние позиций: границы каталога изменились,
234
- * успешная отправка больше не отражает текущее состояние.
235
- */
236
- this.resetAllItemStates();
237
- }
238
- });
239
- }
240
- /**
241
- * Создает группу для изделия.
242
- *
243
- * @param item Параметры изделия.
244
- * @param item.width Ширина изделия.
245
- * @param item.length Длина изделия.
246
- * @param item.count Количество изделий.
247
- * @param item.marker Маркер позиции.
248
- */
249
- createItemGroup(item) {
250
- const group = new FormGroup({
251
- width: new FormControl(item?.width ?? 0, { nonNullable: true }),
252
- length: new FormControl(item?.length ?? 0, { nonNullable: true }),
253
- count: new FormControl(item?.count ?? 1, {
254
- validators: [Validators.required, Validators.min(1), stepValidator(1)],
255
- nonNullable: true,
256
- }),
257
- marker: new FormControl(item?.marker ?? null),
258
- });
259
- // Любое изменение значений позиции сбрасывает её состояние отправки —
260
- // ранее успешный submit становится неактуальным при правке полей,
261
- // ошибку валидации сервера тоже сбрасываем.
262
- group.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
263
- const index = this.items.controls.indexOf(group);
264
- if (index !== -1) {
265
- this.resetItemState(index);
266
- ['width', 'length', 'count', 'marker'].forEach((field) => {
267
- const control = group.get(field);
268
- if (control?.hasError('serverResponse')) {
269
- const errors = { ...control.errors };
270
- delete errors['serverResponse'];
271
- control.setErrors(Object.keys(errors).length > 0 ? errors : null);
272
- }
273
- });
274
- }
275
- });
276
- return group;
277
- }
278
- /**
279
- * Сбрасывает состояние одной позиции на `idle`, если оно было `success`/`error`.
280
- *
281
- * @param index Индекс позиции.
282
- */
283
- resetItemState(index) {
284
- const states = this.itemStates();
285
- const current = states[index];
286
- if (current === 'success' || current === 'error') {
287
- const updated = [...states];
288
- updated[index] = 'idle';
289
- this.itemStates.set(updated);
290
- }
291
- }
292
- /**
293
- * Сбрасывает состояния всех позиций на `idle`.
294
- */
295
- resetAllItemStates() {
296
- this.itemStates.set(this.items.controls.map(() => IDLE_ITEM_STATE));
297
- }
298
- /**
299
- * Возвращает состояние позиции по индексу (по умолчанию `idle`).
300
- *
301
- * @param index Индекс позиции.
302
- */
303
- getItemState(index) {
304
- return this.itemStates()[index] ?? IDLE_ITEM_STATE;
305
- }
306
- /**
307
- * Признак того, что позиция отправляется (поля должны быть заблокированы).
308
- *
309
- * @param index Индекс позиции.
310
- */
311
- isItemLoading(index) {
312
- return this.getItemState(index) === 'loading';
313
- }
314
- /**
315
- * Признак того, что позиция успешно отправлена и её поля нужно заблокировать.
316
- *
317
- * @param index Индекс позиции.
318
- */
319
- isItemLocked(index) {
320
- return this.getItemState(index) === 'success';
321
- }
322
- /**
323
- * Добавляет новое изделие в форму.
324
- */
325
- addItem() {
326
- this.items.push(this.createItemGroup());
327
- this.itemStates.update((states) => [...states, 'idle']);
328
- this.updateItemsValidators();
329
- }
330
- /**
331
- * Удаляет изделие из формы.
332
- *
333
- * @param index Индекс изделия.
334
- */
335
- removeItem(index) {
336
- this.items.removeAt(index);
337
- this.itemStates.update((states) => {
338
- const updated = [...states];
339
- updated.splice(index, 1);
340
- return updated;
341
- });
342
- this.updateItemsValidators();
343
- }
344
- /**
345
- * Площадь одной единицы изделия без учёта количества, м².
346
- *
347
- * @param value Значения размеров изделия.
348
- * @param value.width Ширина изделия.
349
- * @param value.length Длина изделия.
350
- */
351
- // eslint-disable-next-line class-methods-use-this
352
- pieceAreaM2(value) {
353
- const { width, length } = value;
354
- if (!width || !length) {
355
- return 0;
356
- }
357
- return (width * length) / 1_000_000;
358
- }
359
- /**
360
- * Суммарная площадь по строке позиции: площадь единицы × количество, м².
361
- *
362
- * @param value Значения позиции.
363
- * @param value.width Ширина изделия.
364
- * @param value.length Длина изделия.
365
- * @param value.count Количество изделий.
366
- */
367
- rowTotalPartsAreaM2(value) {
368
- const qty = value.count;
369
- if (!qty || !value.width || value.length === 0) {
370
- return 0;
371
- }
372
- return this.pieceAreaM2(value) * qty;
373
- }
374
- /**
375
- * Возвращает приблизительную стоимость строки (локальный расчёт — на всю строку позиции).
376
- *
377
- * @param value Значения изделия.
378
- * @param value.width Ширина изделия.
379
- * @param value.length Длина изделия.
380
- * @param value.count Количество изделий.
381
- */
382
- rowCost(value) {
383
- const area = this.rowTotalPartsAreaM2(value);
384
- const cost = this.product.value?.costRub ?? 0;
385
- return Math.round(area * cost * 100) / 100;
386
- }
387
- /**
388
- * Обновляет состояние позиции на указанное значение.
389
- *
390
- * @param index Индекс позиции.
391
- * @param state Новое состояние.
392
- */
393
- setItemState(index, state) {
394
- this.itemStates.update((states) => {
395
- const updated = [...states];
396
- updated[index] = state;
397
- return updated;
398
- });
399
- }
400
- /**
401
- * Применяет ошибки серверной валидации к контролам формы.
402
- * Сервер возвращает ключи вида `items.0.<field>` — переводим в фактический индекс позиции.
403
- *
404
- * @param error Ответ сервера.
405
- * @param index Индекс позиции в форме.
406
- */
407
- applyServerValidationErrors(error, index) {
408
- if (!(error instanceof HttpErrorResponse)) {
409
- return;
410
- }
411
- const { errors, message } = error.error;
412
- if (errors) {
413
- Object.keys(errors).forEach((key) => {
414
- this.form.get(['items', index, key])?.setErrors({ serverResponse: errors[key] });
415
- });
416
- }
417
- else if (message) {
418
- this.form.setErrors({ serverResponse: [message] });
419
- }
420
- }
421
- /**
422
- * Обработчик добавления/редактирования продукта в корзине.
423
- */
424
- onSubmit() {
425
- if (this.form.invalid || !this.product.value) {
426
- return;
427
- }
428
- const productId = this.product.value.id;
429
- const productCategoryId = Number(this.categoryId());
430
- const configurator = this.editor();
431
- const orderData = this.orderItem();
432
- const indexesToSubmit = this.items.controls
433
- .map((_, index) => index)
434
- .filter((index) => {
435
- const state = this.getItemState(index);
436
- return state !== 'success' && state !== 'loading';
437
- });
438
- if (indexesToSubmit.length === 0) {
439
- return;
440
- }
441
- // Позиции отправляются последовательно: каждая следующая — только после ответа предыдущей.
442
- // При ошибке цепочка прерывается; диалог не закрывается.
443
- from(indexesToSubmit)
444
- .pipe(concatMap((index, position) => {
445
- // Editing-режим: первая позиция (index 0) обновляется, остальные добавляются.
446
- const isEdit = orderData != null && index === 0 && position === 0;
447
- this.setItemState(index, 'loading');
448
- return this.buildItemRequest$(index, productId, productCategoryId, configurator, isEdit, orderData).pipe(tap(() => {
449
- this.setItemState(index, 'success');
450
- }), catchError((error) => {
451
- this.applyServerValidationErrors(error, index);
452
- this.setItemState(index, 'error');
453
- return throwError(() => error);
454
- }));
455
- }), takeUntilDestroyed(this.destroyRef))
456
- .subscribe({
457
- complete: () => {
458
- if (this.context) {
459
- this.context.$implicit.complete();
460
- }
461
- else {
462
- this.setDefaultFormValue();
463
- }
464
- },
465
- });
466
- }
467
- /**
468
- * Формирует HTTP-запрос для одной позиции формы.
469
- *
470
- * @param index Индекс позиции в форме.
471
- * @param productId Идентификатор выбранного продукта.
472
- * @param productCategoryId Идентификатор категории.
473
- * @param configurator Название конфигуратора.
474
- * @param isEdit Режим обновления существующей позиции.
475
- * @param orderData Текущая позиция заказа (только в режиме редактирования).
476
- */
477
- buildItemRequest$(index, productId, productCategoryId, configurator, isEdit, orderData) {
478
- const itemValue = this.items.at(index).getRawValue();
479
- const payload = this.convertersService.removeNull({
480
- productCategoryId,
481
- configurator,
482
- productId,
483
- width: itemValue.width,
484
- length: itemValue.length,
485
- quantity: itemValue.count,
486
- marker: itemValue.marker,
487
- });
488
- return isEdit && orderData != null
489
- ? this.orderService.updateProduct$(orderData.id, payload, this.orderId)
490
- : this.orderService.addProduct$(payload, this.orderId);
491
- }
492
- /**
493
- * Устанавливает начальные значения для полей формы.
494
- */
495
- setDefaultFormValue() {
496
- this.form.reset({
497
- productCategoryId: Number(this.categoryId()),
498
- configurator: this.editor(),
499
- });
500
- this.items.clear();
501
- const orderItem = this.orderItem();
502
- this.items.push(this.createItemGroup({
503
- width: (orderItem?.width ?? 0) * 1000,
504
- length: (orderItem?.length ?? 0) * 1000,
505
- count: orderItem?.quantity ?? 1,
506
- marker: orderItem?.marker ?? null,
507
- }));
508
- this.itemStates.set(this.items.controls.map(() => IDLE_ITEM_STATE));
509
- this.updateItemsValidators();
510
- this.form.markAsUntouched();
511
- }
512
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScSandwichM2Component, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
513
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScSandwichM2Component, isStandalone: true, selector: "sc-sandwich-m2", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: false, transformFunction: null }, categoryId: { classPropertyName: "categoryId", publicName: "categoryId", isSignal: true, isRequired: true, transformFunction: null }, editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null }, orderItem: { classPropertyName: "orderItem", publicName: "orderItem", isSignal: true, isRequired: true, transformFunction: null }, orderId: { classPropertyName: "orderId", publicName: "orderId", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { toggleShowEvent: "toggleShowEvent" }, providers: [
514
- tuiNumberFormatProvider({ precision: 0 }),
515
- tuiInputNumberOptionsProvider({
516
- min: 0,
517
- }),
518
- tuiItemsHandlersProvider({
519
- stringify: signal((x) => x.name),
520
- identityMatcher: signal((a, b) => a.id === b.id),
521
- }),
522
- ], ngImport: i0, template: "@if (!orderItem() && settings()?.allowShowTable) {\n <div class=\"mb-5 flex justify-center\">\n <button\n tuiButton\n appearance=\"secondary\"\n (click)=\"toggleShowEvent.emit()\"\n type=\"button\"\n iconStart=\"@tui.layout-list\"\n >\n \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432 \u0432\u0438\u0434\u0435 \u0441\u043F\u0438\u0441\u043A\u0430\n </button>\n </div>\n}\n<div class=\"\">\n @let products = products$ | async;\n @let productValue = product.value;\n\n <form\n [formGroup]=\"form\"\n (ngSubmit)=\"onSubmit()\"\n ScNextInputFocus\n class=\"flex flex-col gap-2\"\n >\n <label\n tuiLabel\n class=\"grow\"\n >\n \u0422\u043E\u0432\u0430\u0440\n <tui-textfield\n tuiChevron\n [tuiTextfieldCleaner]=\"false\"\n >\n <input\n tuiChevron\n tuiSelect\n [formControl]=\"product\"\n placeholder=\"\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043C\u0430\u0442\u0435\u0440\u0438\u0430\u043B\"\n />\n\n <tui-data-list-wrapper\n *tuiTextfieldDropdown\n new\n [items]=\"products\"\n />\n </tui-textfield>\n <tui-error\n [formControl]=\"product\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n @if (productValue && productValue.costRub !== undefined) {\n <div class=\"-mt-1 text-sm text-tui-text-secondary\">\n <span class=\"font-bold\">{{ productValue.code }}</span>\n \u2014\n {{ productValue.costRub.toLocaleString() }} {{ productValue.currency.symbol }}/\u043C\u00B2\n </div>\n }\n\n @if (productValue) {\n <div class=\"mt-4 mb-3 flex flex-col gap-1.5\">\n <div class=\"w-full font-bold\">\u0420\u0430\u0437\u043C\u0435\u0440\u044B \u0438\u0437\u0434\u0435\u043B\u0438\u0439</div>\n <div class=\"flex flex-col gap-1 text-sm text-tui-text-secondary\">\n @let wt = widthRangeText();\n @let lt = lengthRangeText();\n @if (wt) {\n <div>\u0428\u0438\u0440\u0438\u043D\u0430 {{ wt }}.</div>\n }\n @if (lt) {\n <div>\u0414\u043B\u0438\u043D\u0430 {{ lt }}.</div>\n }\n </div>\n </div>\n }\n\n <div class=\"flex flex-col gap-3\">\n <div\n formArrayName=\"items\"\n class=\"flex flex-col gap-3\"\n >\n @for (item of items.controls; track item) {\n @if ($index > 0) {\n <hr class=\"border-sc-grey h-px\" />\n }\n @let itemIndex = $index;\n <div\n class=\"relative flex flex-col gap-1\"\n [formGroupName]=\"itemIndex\"\n >\n @if (isItemLocked(itemIndex)) {\n <div class=\"pointer-events-none absolute right-3 bottom-0 z-10 flex size-8 items-center justify-center\">\n <tui-icon\n icon=\"@tui.check\"\n class=\"text-tui-status-positive\"\n />\n </div>\n }\n <tui-loader [showLoader]=\"isItemLoading(itemIndex)\">\n <div\n [class.opacity-70]=\"isItemLocked(itemIndex)\"\n class=\"flex min-w-0 items-start gap-2\"\n >\n <div class=\"flex min-w-0 flex-1 flex-col gap-3\">\n <div class=\"flex flex-col gap-3 lg:!flex-row lg:!items-start lg:!gap-6\">\n <!-- \u0413\u0440\u0443\u043F\u043F\u0430 1: \u0448\u0438\u0440\u0438\u043D\u0430 + \u0434\u043B\u0438\u043D\u0430 -->\n <div class=\"grid grid-cols-1 gap-2 sm:grid-cols-2 lg:!flex-[2]\">\n <label tuiLabel>\n \u0428\u0438\u0440\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"width\"\n [min]=\"settings()?.minWidth ?? 0\"\n [max]=\"product.value?.properties?.width ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n [tuiAutoFocus]=\"!$first\"\n placeholder=\"\u0428\u0438\u0440\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n <tui-error\n formControlName=\"width\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <label tuiLabel>\n \u0414\u043B\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"length\"\n [min]=\"settings()?.minLength ?? 0\"\n [max]=\"product.value?.properties?.length ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n placeholder=\"\u0414\u043B\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n <tui-error\n formControlName=\"length\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n </div>\n\n <!-- \u0413\u0440\u0443\u043F\u043F\u0430 2: \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E + \u043C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430 (\u043D\u0430 lg 1fr | 2fr) -->\n <div class=\"grid grid-cols-1 gap-2 sm:grid-cols-2 lg:!grid-cols-[1fr_2fr] lg:!flex-[3]\">\n <label tuiLabel>\n <span class=\"whitespace-nowrap\">\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E, \u0448\u0442</span>\n <tui-textfield [tuiTextfieldCleaner]=\"false\">\n <input\n tuiInputNumber\n formControlName=\"count\"\n [min]=\"1\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n placeholder=\"\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E\"\n autocomplete=\"off\"\n />\n </tui-textfield>\n <tui-error\n formControlName=\"count\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <label tuiLabel>\n \u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430\n <tui-textfield>\n <input\n tuiTextfield\n formControlName=\"marker\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n placeholder=\"\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430\"\n autocomplete=\"off\"\n />\n </tui-textfield>\n <tui-error\n formControlName=\"marker\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n </div>\n </div>\n\n @let rowVal = item.getRawValue();\n\n @if (rowVal.width > 0 && rowVal.length > 0) {\n <div class=\"mt-1 flex flex-col gap-y-1 text-sm lg:!flex-row lg:!gap-6\">\n @if (pieceAreaM2(rowVal) > 0) {\n <div class=\"lg:!flex-[2]\">\n \u041F\u043B\u043E\u0449\u0430\u0434\u044C (S) =\n <span class=\"font-bold\">{{ pieceAreaM2(rowVal) | number: '1.0-4' }} \u043C\u00B2</span>\n </div>\n }\n @if (productValue && rowCost(rowVal) > 0) {\n <div class=\"lg:!flex-[3]\">\n \u0418\u0442\u043E\u0433\u043E:\n <span class=\"font-bold\">{{ rowCost(rowVal).toLocaleString() }} {{ productValue.currency.symbol }}</span>\n </div>\n }\n </div>\n }\n </div>\n\n @if (!isEditingExistingItem()) {\n <button\n tuiIconButton\n title=\"\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\"\n (click)=\"removeItem(itemIndex)\"\n [disabled]=\"items.length <= 1 || !product.value || isItemLoading(itemIndex)\"\n size=\"m\"\n type=\"button\"\n iconStart=\"@tui.trash-2\"\n appearance=\"secondary\"\n class=\"mt-6 shrink-0 lg:!ml-4\"\n [style.flex]=\"'0 0 auto'\"\n ></button>\n }\n </div>\n </tui-loader>\n </div>\n }\n </div>\n\n @if (productValue) {\n <hr class=\"border-sc-grey h-px\" />\n <div class=\"min-w-0 gap-1 pt-2 text-right\">\n @if (totalAreaM2() > 0) {\n <div>\n \u041E\u0431\u0449\u0430\u044F \u043F\u043B\u043E\u0449\u0430\u0434\u044C:\n <span class=\"font-bold\">{{ totalAreaM2() | number: '1.0-4' }} \u043C\u00B2</span>\n </div>\n }\n @if (productValue.costRub && totalCost() > 0) {\n <div>\n \u0418\u0442\u043E\u0433\u043E:\n <span class=\"whitespace-nowrap text-xl font-bold\"> {{ totalCost().toLocaleString() }} {{ productValue.currency.symbol }} </span>\n </div>\n }\n </div>\n }\n </div>\n\n <tui-error [error]=\"[] | tuiFieldError | async\" />\n\n <div class=\"flex flex-wrap items-center gap-3\">\n @if (productValue && !isEditingExistingItem()) {\n <button\n tuiButton\n appearance=\"secondary\"\n [disabled]=\"!product.value || items.invalid\"\n (click)=\"addItem()\"\n type=\"button\"\n iconStart=\"@tui.plus\"\n >\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\n </button>\n }\n <button\n type=\"submit\"\n [disabled]=\"form.invalid || isSubmitLoading() || hasNoPendingItems()\"\n [loading]=\"isSubmitLoading()\"\n tuiButton\n class=\"ml-auto\"\n iconStart=\"@tui.check\"\n >\n {{ !orderItem() ? '\u0412 \u043A\u043E\u0440\u0437\u0438\u043D\u0443' : '\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C' }}\n </button>\n </div>\n </form>\n</div>\n", styles: [":host{display:block;width:100%;max-width:36rem}.row-summary{color:var(--tui-text-secondary);font-size:.75rem}\n"], dependencies: [{ kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: ScNextInputFocusModule }, { kind: "directive", type: i2.ScNextInputFocusDirective, selector: "form[ScNextInputFocus]" }, { kind: "directive", type: TuiLabel, selector: "label[tuiLabel]" }, { kind: "component", type: TuiDataListWrapperComponent, selector: "tui-data-list-wrapper:not([labels]), tui-data-list-wrapper:not([labels])[new]", inputs: ["items", "disabledItemHandler", "emptyContent", "size", "itemContent"], outputs: ["itemClick"] }, { kind: "component", type: TuiError, selector: "tui-error", inputs: ["error"] }, { kind: "component", type: i3.TuiTextfieldComponent, selector: "tui-textfield:not([multi])" }, { kind: "directive", type: i3.TuiTextfieldDirective, selector: "input[tuiTextfield]:not([tuiInputCard]):not([tuiInputExpire]):not([tuiInputCVC])" }, { kind: "directive", type: i3.TuiTextfieldOptionsDirective, selector: "[tuiTextfieldAppearance],[tuiTextfieldSize],[tuiTextfieldCleaner]", inputs: ["tuiTextfieldAppearance", "tuiTextfieldSize", "tuiTextfieldCleaner"] }, { kind: "directive", type: i3.TuiTextfieldDropdownDirective, selector: "ng-template[tuiTextfieldDropdown]" }, { kind: "directive", type: TuiChevron, selector: "[tuiChevron]", inputs: ["tuiChevron"] }, { kind: "directive", type: i4.TuiSelectDirective, selector: "input[tuiSelect]" }, { kind: "directive", type: i4.TuiInputNumberDirective, selector: "input[tuiInputNumber]", inputs: ["min", "max", "prefix", "postfix"] }, { kind: "directive", type: TuiNumberFormat, selector: "[tuiNumberFormat]", inputs: ["tuiNumberFormat"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "pipe", type: TuiFieldErrorPipe, name: "tuiFieldError" }, { kind: "component", type: i5.TuiSliderComponent, selector: "input[type=range][tuiSlider]", inputs: ["size", "segments"] }, { kind: "directive", type: i4.TuiInputSliderDirective, selector: "input[tuiInputSlider]" }, { kind: "directive", type: ScSelectOnFocusinDirective, selector: "tui-input-number, tui-input, tui-input-phone, tui-input-date, tui-input-password, input[tuiInputNumber], input[tuiTextfield], input[tuiInputSlider]" }, { kind: "component", type: TuiLoader, selector: "tui-loader", inputs: ["size", "inheritColor", "overlay", "textContent", "showLoader"] }, { kind: "component", type: TuiButtonLoading, selector: "[tuiButton][loading],[tuiIconButton][loading]", inputs: ["size", "loading"] }, { kind: "component", type: TuiIcon, selector: "tui-icon", inputs: ["icon", "background"] }, { kind: "directive", type: TuiAutoFocus, selector: "[tuiAutoFocus]", inputs: ["tuiAutoFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
523
- }
524
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScSandwichM2Component, decorators: [{
525
- type: Component,
526
- args: [{ standalone: true, selector: 'sc-sandwich-m2', imports: [
527
- TuiButton,
528
- FormsModule,
529
- ReactiveFormsModule,
530
- ScNextInputFocusModule,
531
- TuiLabel,
532
- TuiDataListWrapperComponent,
533
- TuiError,
534
- TuiTextfield,
535
- TuiChevron,
536
- TuiSelect,
537
- TuiInputNumber,
538
- TuiNumberFormat,
539
- AsyncPipe,
540
- DecimalPipe,
541
- TuiFieldErrorPipe,
542
- TuiInputSlider,
543
- ScSelectOnFocusinDirective,
544
- TuiLoader,
545
- TuiButtonLoading,
546
- TuiIcon,
547
- TuiAutoFocus,
548
- ], providers: [
549
- tuiNumberFormatProvider({ precision: 0 }),
550
- tuiInputNumberOptionsProvider({
551
- min: 0,
552
- }),
553
- tuiItemsHandlersProvider({
554
- stringify: signal((x) => x.name),
555
- identityMatcher: signal((a, b) => a.id === b.id),
556
- }),
557
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (!orderItem() && settings()?.allowShowTable) {\n <div class=\"mb-5 flex justify-center\">\n <button\n tuiButton\n appearance=\"secondary\"\n (click)=\"toggleShowEvent.emit()\"\n type=\"button\"\n iconStart=\"@tui.layout-list\"\n >\n \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432 \u0432\u0438\u0434\u0435 \u0441\u043F\u0438\u0441\u043A\u0430\n </button>\n </div>\n}\n<div class=\"\">\n @let products = products$ | async;\n @let productValue = product.value;\n\n <form\n [formGroup]=\"form\"\n (ngSubmit)=\"onSubmit()\"\n ScNextInputFocus\n class=\"flex flex-col gap-2\"\n >\n <label\n tuiLabel\n class=\"grow\"\n >\n \u0422\u043E\u0432\u0430\u0440\n <tui-textfield\n tuiChevron\n [tuiTextfieldCleaner]=\"false\"\n >\n <input\n tuiChevron\n tuiSelect\n [formControl]=\"product\"\n placeholder=\"\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043C\u0430\u0442\u0435\u0440\u0438\u0430\u043B\"\n />\n\n <tui-data-list-wrapper\n *tuiTextfieldDropdown\n new\n [items]=\"products\"\n />\n </tui-textfield>\n <tui-error\n [formControl]=\"product\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n @if (productValue && productValue.costRub !== undefined) {\n <div class=\"-mt-1 text-sm text-tui-text-secondary\">\n <span class=\"font-bold\">{{ productValue.code }}</span>\n \u2014\n {{ productValue.costRub.toLocaleString() }} {{ productValue.currency.symbol }}/\u043C\u00B2\n </div>\n }\n\n @if (productValue) {\n <div class=\"mt-4 mb-3 flex flex-col gap-1.5\">\n <div class=\"w-full font-bold\">\u0420\u0430\u0437\u043C\u0435\u0440\u044B \u0438\u0437\u0434\u0435\u043B\u0438\u0439</div>\n <div class=\"flex flex-col gap-1 text-sm text-tui-text-secondary\">\n @let wt = widthRangeText();\n @let lt = lengthRangeText();\n @if (wt) {\n <div>\u0428\u0438\u0440\u0438\u043D\u0430 {{ wt }}.</div>\n }\n @if (lt) {\n <div>\u0414\u043B\u0438\u043D\u0430 {{ lt }}.</div>\n }\n </div>\n </div>\n }\n\n <div class=\"flex flex-col gap-3\">\n <div\n formArrayName=\"items\"\n class=\"flex flex-col gap-3\"\n >\n @for (item of items.controls; track item) {\n @if ($index > 0) {\n <hr class=\"border-sc-grey h-px\" />\n }\n @let itemIndex = $index;\n <div\n class=\"relative flex flex-col gap-1\"\n [formGroupName]=\"itemIndex\"\n >\n @if (isItemLocked(itemIndex)) {\n <div class=\"pointer-events-none absolute right-3 bottom-0 z-10 flex size-8 items-center justify-center\">\n <tui-icon\n icon=\"@tui.check\"\n class=\"text-tui-status-positive\"\n />\n </div>\n }\n <tui-loader [showLoader]=\"isItemLoading(itemIndex)\">\n <div\n [class.opacity-70]=\"isItemLocked(itemIndex)\"\n class=\"flex min-w-0 items-start gap-2\"\n >\n <div class=\"flex min-w-0 flex-1 flex-col gap-3\">\n <div class=\"flex flex-col gap-3 lg:!flex-row lg:!items-start lg:!gap-6\">\n <!-- \u0413\u0440\u0443\u043F\u043F\u0430 1: \u0448\u0438\u0440\u0438\u043D\u0430 + \u0434\u043B\u0438\u043D\u0430 -->\n <div class=\"grid grid-cols-1 gap-2 sm:grid-cols-2 lg:!flex-[2]\">\n <label tuiLabel>\n \u0428\u0438\u0440\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"width\"\n [min]=\"settings()?.minWidth ?? 0\"\n [max]=\"product.value?.properties?.width ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n [tuiAutoFocus]=\"!$first\"\n placeholder=\"\u0428\u0438\u0440\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n <tui-error\n formControlName=\"width\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <label tuiLabel>\n \u0414\u043B\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"length\"\n [min]=\"settings()?.minLength ?? 0\"\n [max]=\"product.value?.properties?.length ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n placeholder=\"\u0414\u043B\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n <tui-error\n formControlName=\"length\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n </div>\n\n <!-- \u0413\u0440\u0443\u043F\u043F\u0430 2: \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E + \u043C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430 (\u043D\u0430 lg 1fr | 2fr) -->\n <div class=\"grid grid-cols-1 gap-2 sm:grid-cols-2 lg:!grid-cols-[1fr_2fr] lg:!flex-[3]\">\n <label tuiLabel>\n <span class=\"whitespace-nowrap\">\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E, \u0448\u0442</span>\n <tui-textfield [tuiTextfieldCleaner]=\"false\">\n <input\n tuiInputNumber\n formControlName=\"count\"\n [min]=\"1\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n placeholder=\"\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E\"\n autocomplete=\"off\"\n />\n </tui-textfield>\n <tui-error\n formControlName=\"count\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <label tuiLabel>\n \u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430\n <tui-textfield>\n <input\n tuiTextfield\n formControlName=\"marker\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n placeholder=\"\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430\"\n autocomplete=\"off\"\n />\n </tui-textfield>\n <tui-error\n formControlName=\"marker\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n </div>\n </div>\n\n @let rowVal = item.getRawValue();\n\n @if (rowVal.width > 0 && rowVal.length > 0) {\n <div class=\"mt-1 flex flex-col gap-y-1 text-sm lg:!flex-row lg:!gap-6\">\n @if (pieceAreaM2(rowVal) > 0) {\n <div class=\"lg:!flex-[2]\">\n \u041F\u043B\u043E\u0449\u0430\u0434\u044C (S) =\n <span class=\"font-bold\">{{ pieceAreaM2(rowVal) | number: '1.0-4' }} \u043C\u00B2</span>\n </div>\n }\n @if (productValue && rowCost(rowVal) > 0) {\n <div class=\"lg:!flex-[3]\">\n \u0418\u0442\u043E\u0433\u043E:\n <span class=\"font-bold\">{{ rowCost(rowVal).toLocaleString() }} {{ productValue.currency.symbol }}</span>\n </div>\n }\n </div>\n }\n </div>\n\n @if (!isEditingExistingItem()) {\n <button\n tuiIconButton\n title=\"\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\"\n (click)=\"removeItem(itemIndex)\"\n [disabled]=\"items.length <= 1 || !product.value || isItemLoading(itemIndex)\"\n size=\"m\"\n type=\"button\"\n iconStart=\"@tui.trash-2\"\n appearance=\"secondary\"\n class=\"mt-6 shrink-0 lg:!ml-4\"\n [style.flex]=\"'0 0 auto'\"\n ></button>\n }\n </div>\n </tui-loader>\n </div>\n }\n </div>\n\n @if (productValue) {\n <hr class=\"border-sc-grey h-px\" />\n <div class=\"min-w-0 gap-1 pt-2 text-right\">\n @if (totalAreaM2() > 0) {\n <div>\n \u041E\u0431\u0449\u0430\u044F \u043F\u043B\u043E\u0449\u0430\u0434\u044C:\n <span class=\"font-bold\">{{ totalAreaM2() | number: '1.0-4' }} \u043C\u00B2</span>\n </div>\n }\n @if (productValue.costRub && totalCost() > 0) {\n <div>\n \u0418\u0442\u043E\u0433\u043E:\n <span class=\"whitespace-nowrap text-xl font-bold\"> {{ totalCost().toLocaleString() }} {{ productValue.currency.symbol }} </span>\n </div>\n }\n </div>\n }\n </div>\n\n <tui-error [error]=\"[] | tuiFieldError | async\" />\n\n <div class=\"flex flex-wrap items-center gap-3\">\n @if (productValue && !isEditingExistingItem()) {\n <button\n tuiButton\n appearance=\"secondary\"\n [disabled]=\"!product.value || items.invalid\"\n (click)=\"addItem()\"\n type=\"button\"\n iconStart=\"@tui.plus\"\n >\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\n </button>\n }\n <button\n type=\"submit\"\n [disabled]=\"form.invalid || isSubmitLoading() || hasNoPendingItems()\"\n [loading]=\"isSubmitLoading()\"\n tuiButton\n class=\"ml-auto\"\n iconStart=\"@tui.check\"\n >\n {{ !orderItem() ? '\u0412 \u043A\u043E\u0440\u0437\u0438\u043D\u0443' : '\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C' }}\n </button>\n </div>\n </form>\n</div>\n", styles: [":host{display:block;width:100%;max-width:36rem}.row-summary{color:var(--tui-text-secondary);font-size:.75rem}\n"] }]
558
- }], propDecorators: { orderId: [{
559
- type: Input
560
- }] } });
561
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Mtc2FuZHdpY2gtbTIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2xpZW50LXVpL2NvbmZpZ3VyYXRvcnMvc2FuZHdpY2hfbTIvc2Mtc2FuZHdpY2gtbTIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2xpZW50LXVpL2NvbmZpZ3VyYXRvcnMvc2FuZHdpY2hfbTIvc2Mtc2FuZHdpY2gtbTIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsdUZBQXVGO0FBRXZGLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDekQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDekQsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkksT0FBTyxFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN4RixPQUFPLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixFQUFlLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlILE9BQU8sRUFDSCxlQUFlLEVBRWYsZ0JBQWdCLEVBQ2hCLG1CQUFtQixHQU90QixNQUFNLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzlELE9BQU8sRUFDSCxTQUFTLEVBRVQsUUFBUSxFQUNSLE9BQU8sRUFDUCx3QkFBd0IsRUFDeEIsUUFBUSxFQUNSLFNBQVMsRUFDVCxlQUFlLEVBQ2YsdUJBQXVCLEVBQ3ZCLFlBQVksR0FDZixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFDSCxnQkFBZ0IsRUFDaEIsVUFBVSxFQUNWLDJCQUEyQixFQUMzQixpQkFBaUIsRUFDakIsY0FBYyxFQUNkLDZCQUE2QixFQUM3QixjQUFjLEVBQ2QsU0FBUyxHQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzlELE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQWMsRUFBRSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXBHLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDhEQUE4RCxDQUFDO0FBQ3RHLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLG1FQUFtRSxDQUFDO0FBQy9HLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUdoRSxPQUFPLEVBQUUsZUFBZSxFQUErQixNQUFNLG9DQUFvQyxDQUFDOzs7Ozs7O0FBRWxHOztHQUVHO0FBeUNILE1BQU0sT0FBTyxxQkFBcUI7SUF4Q2xDO1FBeUNJOztXQUVHO1FBQ2EsYUFBUSxHQUFHLEtBQUssRUFBeUIsQ0FBQztRQUUxRDs7V0FFRztRQUNhLGVBQVUsR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFtQixDQUFDO1FBRS9EOztXQUVHO1FBQ2EsV0FBTSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQVUsQ0FBQztRQUVsRDs7V0FFRztRQUNhLGNBQVMsR0FBRyxLQUFLLENBQUMsUUFBUSxFQUEyQixDQUFDO1FBUXRFOztXQUVHO1FBQ2Esb0JBQWUsR0FBRyxNQUFNLEVBQUUsQ0FBQztRQUUzQzs7V0FFRztRQUNnQixTQUFJLEdBQUcsSUFBSSxTQUFTLENBQUM7WUFDcEMsaUJBQWlCLEVBQUUsSUFBSSxXQUFXLENBQWdCLElBQUksRUFBRSxFQUFFLFVBQVUsRUFBRSxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDNUYsWUFBWSxFQUFFLElBQUksV0FBVyxDQUFnQixJQUFJLEVBQUUsRUFBRSxVQUFVLEVBQUUsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3ZGLEtBQUssRUFBRSxJQUFJLFNBQVMsQ0FBdUQsRUFBRSxDQUFDO1NBQ2pGLENBQUMsQ0FBQztRQUVIOztXQUVHO1FBQ2dCLGlCQUFZLEdBQUcsTUFBTSxDQUEyRCxlQUFlLENBQUMsQ0FBQztRQUVwSDs7V0FFRztRQUNjLHNCQUFpQixHQUF3QixNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUV0Rjs7V0FFRztRQUNjLFlBQU8sR0FBaUMsTUFBTSxDQUFDLG9CQUFvQixFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFpQyxDQUFDO1FBRTFJOztXQUVHO1FBQ2MsbUJBQWMsR0FBcUIsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFFN0U7O1dBRUc7UUFDZ0IsY0FBUyxHQUE0QixZQUFZLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FDdEYsU0FBUyxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUU7WUFDckIsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUNkLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2xCLENBQUM7WUFFRCxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsMEJBQTBCLENBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN0SSxDQUFDLENBQUMsQ0FDTCxDQUFDO1FBRUY7O1dBRUc7UUFDZ0IsWUFBTyxHQUFHLElBQUksV0FBVyxDQUFtQixJQUFJLEVBQUUsRUFBRSxVQUFVLEVBQUUsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFFMUc7O1dBRUc7UUFDZ0Isa0JBQWEsR0FBRyxRQUFRLENBQUMsZUFBZSxDQUFtQixJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUVySDs7V0FFRztRQUNnQixlQUFVLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBWSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUM5SSxZQUFZLEVBQUUsRUFBNEY7U0FDN0csQ0FBQyxDQUFDO1FBRUg7O1dBRUc7UUFDZ0Isb0JBQWUsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBRTNGOztXQUVHO1FBQ2dCLGVBQVUsR0FBRyxNQUFNLENBQWdDLEVBQUUsQ0FBQyxDQUFDO1FBRTFFOztXQUVHO1FBQ2dCLDBCQUFxQixHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksSUFBSSxDQUFDLENBQUM7UUFFcEY7OztXQUdHO1FBQ2dCLHNCQUFpQixHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUU7WUFDakQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBRWpDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQzFCLE9BQU8sSUFBSSxDQUFDO1lBQ2hCLENBQUM7WUFFRCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRTtnQkFDMUMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLGVBQWUsQ0FBQztnQkFFL0MsT0FBTyxLQUFLLEtBQUssU0FBUyxJQUFJLEtBQUssS0FBSyxTQUFTLENBQUM7WUFDdEQsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDLENBQUMsQ0FBQztRQUVIOztXQUVHO1FBQ2dCLGdCQUFXLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUMzQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7WUFFZCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQ2hDLEtBQUssSUFBSSxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDN0MsQ0FBQyxDQUFDLENBQUM7WUFFSCxPQUFPLEtBQUssQ0FBQztRQUNqQixDQUFDLENBQUMsQ0FBQztRQUVIOztXQUVHO1FBQ2dCLGNBQVMsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1lBQ3pDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRSxPQUFPLElBQUksQ0FBQyxDQUFDO1lBQ2hELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUVoQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUM7UUFDL0MsQ0FBQyxDQUFDLENBQUM7UUFFSDs7V0FFRztRQUNnQixtQkFBYyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRSxRQUFRLElBQUksSUFBSSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRSxVQUFVLEVBQUUsS0FBSyxJQUFJLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBRS9KOztXQUVHO1FBQ2dCLG9CQUFlLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLFNBQVMsSUFBSSxJQUFJLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxFQUFFLFVBQVUsRUFBRSxNQUFNLElBQUksSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFbEs7O1dBRUc7UUFDYyxlQUFVLEdBQWUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0tBd2JoRTtJQXRiRzs7Ozs7T0FLRztJQUNLLG1CQUFtQixDQUFDLEdBQVcsRUFBRSxRQUFtQztRQUN4RSxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztRQUV6QyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDakIsT0FBTyxFQUFFLENBQUM7UUFDZCxDQUFDO1FBRUQsT0FBTyxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsUUFBUSxJQUFJLElBQUksSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakosQ0FBQztJQUVEOztPQUVHO0lBQ0sscUJBQXFCO1FBQ3pCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNqQyxNQUFNLFFBQVEsR0FBRyxRQUFRLEVBQUUsUUFBUSxJQUFJLElBQUksQ0FBQztRQUM1QyxNQUFNLFNBQVMsR0FBRyxRQUFRLEVBQUUsU0FBUyxJQUFJLElBQUksQ0FBQztRQUM5QyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztRQUV6QyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNsQyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLGFBQWEsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUN4RyxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLGFBQWEsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsU0FBUyxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUMzRyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLHNCQUFzQixDQUFDLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDakUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxzQkFBc0IsQ0FBQyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3RFLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILGtEQUFrRDtJQUMxQyxXQUFXLENBQUMsR0FBOEIsRUFBRSxHQUE4QixFQUFFLElBQVk7UUFDNUYsTUFBTSxNQUFNLEdBQUcsR0FBRyxJQUFJLElBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sTUFBTSxHQUFHLEdBQUcsSUFBSSxJQUFJLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztRQUV0QyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDckIsT0FBTyxJQUFJLENBQUM7UUFDaEIsQ0FBQztRQUVELElBQUksTUFBTSxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ25CLE9BQU8sTUFBTSxHQUFHLElBQUksSUFBSSxPQUFPLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNqRCxDQUFDO1FBRUQsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUNULE9BQU8sTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDL0IsQ0FBQztRQUVELE9BQU8sTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7SUFDL0IsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxLQUFLO1FBQ0wsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7SUFDcEMsQ0FBQztJQUVEOztPQUVHO0lBQ0ksUUFBUTtRQUNYLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBRTNCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQzVFLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQUksSUFBSSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3RELE9BQU87WUFDWCxDQUFDO1lBRUQsaUVBQWlFO1lBQ2pFLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzVELENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLGFBQWEsRUFBRSxFQUFFO1lBQzVGLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBRTdCLElBQUksYUFBYSxFQUFFLENBQUM7Z0JBQ2hCLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO29CQUNqQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7b0JBRWpDLE1BQU0sSUFBSSxHQUFHLGFBQWEsQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDO29CQUM3QyxNQUFNLElBQUksR0FBRyxhQUFhLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQztvQkFFOUMsSUFBSSxDQUFDLFVBQVUsQ0FBQzt3QkFDWixLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLO3dCQUN2RCxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNO3FCQUM3RCxDQUFDLENBQUM7Z0JBQ1AsQ0FBQyxDQUFDLENBQUM7Z0JBRUg7OzttQkFHRztnQkFDSCxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUM5QixDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSyxlQUFlLENBQUMsSUFBOEU7UUFNbEcsTUFBTSxLQUFLLEdBQUcsSUFBSSxTQUFTLENBQUM7WUFDeEIsS0FBSyxFQUFFLElBQUksV0FBVyxDQUFTLElBQUksRUFBRSxLQUFLLElBQUksQ0FBQyxFQUFFLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxDQUFDO1lBQ3ZFLE1BQU0sRUFBRSxJQUFJLFdBQVcsQ0FBUyxJQUFJLEVBQUUsTUFBTSxJQUFJLENBQUMsRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQztZQUN6RSxLQUFLLEVBQUUsSUFBSSxXQUFXLENBQVMsSUFBSSxFQUFFLEtBQUssSUFBSSxDQUFDLEVBQUU7Z0JBQzdDLFVBQVUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RFLFdBQVcsRUFBRSxJQUFJO2FBQ3BCLENBQUM7WUFDRixNQUFNLEVBQUUsSUFBSSxXQUFXLENBQWdCLElBQUksRUFBRSxNQUFNLElBQUksSUFBSSxDQUFDO1NBQy9ELENBQUMsQ0FBQztRQUVILHNFQUFzRTtRQUN0RSxrRUFBa0U7UUFDbEUsNENBQTRDO1FBQzVDLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDeEUsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRWpELElBQUksS0FBSyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ2YsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDMUIsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtvQkFDaEUsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFFakMsSUFBSSxPQUFPLEVBQUUsUUFBUSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQzt3QkFDdEMsTUFBTSxNQUFNLEdBQUcsRUFBRSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQTZCLENBQUM7d0JBQ2hFLE9BQU8sTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7d0JBQ2hDLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUN0RSxDQUFDO2dCQUNMLENBQUMsQ0FBQyxDQUFDO1lBQ1AsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxjQUFjLENBQUMsS0FBYTtRQUNoQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDakMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRTlCLElBQUksT0FBTyxLQUFLLFNBQVMsSUFBSSxPQUFPLEtBQUssT0FBTyxFQUFFLENBQUM7WUFDL0MsTUFBTSxPQUFPLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDO1lBQzVCLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxNQUFNLENBQUM7WUFDeEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDakMsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNLLGtCQUFrQjtRQUN0QixJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNPLFlBQVksQ0FBQyxLQUFhO1FBQ2hDLE9BQU8sSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLGVBQWUsQ0FBQztJQUN2RCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNPLGFBQWEsQ0FBQyxLQUFhO1FBQ2pDLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsS0FBSyxTQUFTLENBQUM7SUFDbEQsQ0FBQztJQUVEOzs7O09BSUc7SUFDTyxZQUFZLENBQUMsS0FBYTtRQUNoQyxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLEtBQUssU0FBUyxDQUFDO0lBQ2xELENBQUM7SUFFRDs7T0FFRztJQUNPLE9BQU87UUFDYixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQztRQUN4QyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7OztPQUlHO0lBQ08sVUFBVSxDQUFDLEtBQWE7UUFDOUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUM5QixNQUFNLE9BQU8sR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUM7WUFDNUIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFekIsT0FBTyxPQUFPLENBQUM7UUFDbkIsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsa0RBQWtEO0lBQ3hDLFdBQVcsQ0FBQyxLQUF3QztRQUMxRCxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQztRQUVoQyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDcEIsT0FBTyxDQUFDLENBQUM7UUFDYixDQUFDO1FBRUQsT0FBTyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsR0FBRyxTQUFTLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSyxtQkFBbUIsQ0FBQyxLQUF1RDtRQUMvRSxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDO1FBRXhCLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDN0MsT0FBTyxDQUFDLENBQUM7UUFDYixDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNPLE9BQU8sQ0FBQyxLQUF1RDtRQUNyRSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsT0FBTyxJQUFJLENBQUMsQ0FBQztRQUU5QyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUM7SUFDL0MsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssWUFBWSxDQUFDLEtBQWEsRUFBRSxLQUFrQztRQUNsRSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQzlCLE1BQU0sT0FBTyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQztZQUM1QixPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsS0FBSyxDQUFDO1lBRXZCLE9BQU8sT0FBTyxDQUFDO1FBQ25CLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNLLDJCQUEyQixDQUFDLEtBQWMsRUFBRSxLQUFhO1FBQzdELElBQUksQ0FBQyxDQUFDLEtBQUssWUFBWSxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7WUFDeEMsT0FBTztRQUNYLENBQUM7UUFFRCxNQUFNLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLEtBQUssQ0FBQyxLQUE0QixDQUFDO1FBRS9ELElBQUksTUFBTSxFQUFFLENBQUM7WUFDVCxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsRUFBRSxjQUFjLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNyRixDQUFDLENBQUMsQ0FBQztRQUNQLENBQUM7YUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ2pCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsY0FBYyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDTyxRQUFRO1FBQ2QsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDM0MsT0FBTztRQUNYLENBQUM7UUFFRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDeEMsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7UUFDcEQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ25DLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUVuQyxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVE7YUFDdEMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDO2FBQ3hCLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ2QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUV2QyxPQUFPLEtBQUssS0FBSyxTQUFTLElBQUksS0FBSyxLQUFLLFNBQVMsQ0FBQztRQUN0RCxDQUFDLENBQUMsQ0FBQztRQUVQLElBQUksZUFBZSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMvQixPQUFPO1FBQ1gsQ0FBQztRQUVELDJGQUEyRjtRQUMzRix5REFBeUQ7UUFDekQsSUFBSSxDQUFDLGVBQWUsQ0FBQzthQUNoQixJQUFJLENBQ0QsU0FBUyxDQUFDLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFFO1lBQzFCLDhFQUE4RTtZQUM5RSxNQUFNLE1BQU0sR0FBRyxTQUFTLElBQUksSUFBSSxJQUFJLEtBQUssS0FBSyxDQUFDLElBQUksUUFBUSxLQUFLLENBQUMsQ0FBQztZQUNsRSxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztZQUVwQyxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLGlCQUFpQixFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUNwRyxHQUFHLENBQUMsR0FBRyxFQUFFO2dCQUNMLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ3hDLENBQUMsQ0FBQyxFQUNGLFVBQVUsQ0FBQyxDQUFDLEtBQWMsRUFBRSxFQUFFO2dCQUMxQixJQUFJLENBQUMsMkJBQTJCLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUMvQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFFbEMsT0FBTyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbkMsQ0FBQyxDQUFDLENBQ0wsQ0FBQztRQUNOLENBQUMsQ0FBQyxFQUNGLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FDdEM7YUFDQSxTQUFTLENBQUM7WUFDUCxRQUFRLEVBQUUsR0FBRyxFQUFFO2dCQUNYLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUNmLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUN0QyxDQUFDO3FCQUFNLENBQUM7b0JBQ0osSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7Z0JBQy9CLENBQUM7WUFDTCxDQUFDO1NBQ0osQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNLLGlCQUFpQixDQUNyQixLQUFhLEVBQ2IsU0FBaUIsRUFDakIsaUJBQXlCLEVBQ3pCLFlBQW9CLEVBQ3BCLE1BQWUsRUFDZixTQUFrQztRQUVsQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNyRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsVUFBVSxDQUFDO1lBQzlDLGlCQUFpQjtZQUNqQixZQUFZO1lBQ1osU0FBUztZQUNULEtBQUssRUFBRSxTQUFTLENBQUMsS0FBSztZQUN0QixNQUFNLEVBQUUsU0FBUyxDQUFDLE1BQU07WUFDeEIsUUFBUSxFQUFFLFNBQVMsQ0FBQyxLQUFLO1lBQ3pCLE1BQU0sRUFBRSxTQUFTLENBQUMsTUFBTTtTQUMzQixDQUFDLENBQUM7UUFFSCxPQUFPLE1BQU0sSUFBSSxTQUFTLElBQUksSUFBSTtZQUM5QixDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSxPQUEwRSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUM7WUFDMUksQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLE9BQW1DLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzNGLENBQUM7SUFFRDs7T0FFRztJQUNLLG1CQUFtQjtRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUNaLGlCQUFpQixFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDNUMsWUFBWSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUU7U0FDOUIsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUVuQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFFbkMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQ1gsSUFBSSxDQUFDLGVBQWUsQ0FBQztZQUNqQixLQUFLLEVBQUUsQ0FBQyxTQUFTLEVBQUUsS0FBSyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUk7WUFDckMsTUFBTSxFQUFFLENBQUMsU0FBUyxFQUFFLE1BQU0sSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJO1lBQ3ZDLEtBQUssRUFBRSxTQUFTLEVBQUUsUUFBUSxJQUFJLENBQUM7WUFDL0IsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLElBQUksSUFBSTtTQUNwQyxDQUFDLENBQ0wsQ0FBQztRQUVGLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDaEMsQ0FBQzsrR0F2bEJRLHFCQUFxQjttR0FBckIscUJBQXFCLDZ2QkFabkI7WUFDUCx1QkFBdUIsQ0FBQyxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUN6Qyw2QkFBNkIsQ0FBQztnQkFDMUIsR0FBRyxFQUFFLENBQUM7YUFDVCxDQUFDO1lBQ0Ysd0JBQXdCLENBQUM7Z0JBQ3JCLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFZLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7Z0JBQzNDLGVBQWUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFZLEVBQUUsQ0FBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7YUFDekUsQ0FBQztTQUNMLDBCQzVGTCxvZ2dCQStSQSx5S0RsT1EsU0FBUyxtSUFDVCxXQUFXLDJwQkFDWCxtQkFBbUIsZ3RCQUNuQixzQkFBc0IsOEhBQ3RCLFFBQVEsNERBQ1IsMkJBQTJCLG1PQUMzQixRQUFRLHVvQkFFUixVQUFVLDRTQUdWLGVBQWUsc0ZBQ2YsU0FBUyx5Q0FDVCxXQUFXLDBDQUNYLGlCQUFpQiw4UUFFakIsMEJBQTBCLGdNQUMxQixTQUFTLGlJQUNULGdCQUFnQix1SEFDaEIsT0FBTyxxRkFDUCxZQUFZOzs0RkFjUCxxQkFBcUI7a0JBeENqQyxTQUFTO2lDQUNNLElBQUksWUFDTixnQkFBZ0IsV0FHakI7d0JBQ0wsU0FBUzt3QkFDVCxXQUFXO3dCQUNYLG1CQUFtQjt3QkFDbkIsc0JBQXNCO3dCQUN0QixRQUFRO3dCQUNSLDJCQUEyQjt3QkFDM0IsUUFBUTt3QkFDUixZQUFZO3dCQUNaLFVBQVU7d0JBQ1YsU0FBUzt3QkFDVCxjQUFjO3dCQUNkLGVBQWU7d0JBQ2YsU0FBUzt3QkFDVCxXQUFXO3dCQUNYLGlCQUFpQjt3QkFDakIsY0FBYzt3QkFDZCwwQkFBMEI7d0JBQzFCLFNBQVM7d0JBQ1QsZ0JBQWdCO3dCQUNoQixPQUFPO3dCQUNQLFlBQVk7cUJBQ2YsYUFDVTt3QkFDUCx1QkFBdUIsQ0FBQyxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQzt3QkFDekMsNkJBQTZCLENBQUM7NEJBQzFCLEdBQUcsRUFBRSxDQUFDO3lCQUNULENBQUM7d0JBQ0Ysd0JBQXdCLENBQUM7NEJBQ3JCLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFZLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7NEJBQzNDLGVBQWUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFZLEVBQUUsQ0FBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7eUJBQ3pFLENBQUM7cUJBQ0wsbUJBQ2dCLHVCQUF1QixDQUFDLE1BQU07OEJBMkJ4QyxPQUFPO3NCQURiLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBzZWN1cml0eS9kZXRlY3Qtb2JqZWN0LWluamVjdGlvbixAdHlwZXNjcmlwdC1lc2xpbnQvdW5ib3VuZC1tZXRob2QgKi9cblxuaW1wb3J0IHsgQXN5bmNQaXBlLCBEZWNpbWFsUGlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBIdHRwRXJyb3JSZXNwb25zZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIGNvbXB1dGVkLCBEZXN0cm95UmVmLCBpbmplY3QsIElucHV0LCBpbnB1dCwgT25Jbml0LCBvdXRwdXQsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkLCB0b09ic2VydmFibGUsIHRvU2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgRm9ybUFycmF5LCBGb3JtQ29udHJvbCwgRm9ybUdyb3VwLCBGb3Jtc01vZHVsZSwgUmVhY3RpdmVGb3Jtc01vZHVsZSwgVmFsaWRhdG9yRm4sIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1xuICAgIFNDX09SREVSX0xPQURFUixcbiAgICBTY0NhcnQsXG4gICAgU2NDYXRhbG9nU2VydmljZSxcbiAgICBTY0NvbnZlcnRlcnNTZXJ2aWNlLFxuICAgIFNjSUFwaUVycm9yUmVzcG9uc2UsXG4gICAgU2NJTmV3T3JkZXJJdGVtQmFzZSxcbiAgICBTY0lPcmRlckVkaXRvckxvYWRlcixcbiAgICBTY09yZGVyRHJhZnQsXG4gICAgU2NPcmRlckl0ZW0sXG4gICAgU2NQcm9kdWN0LFxufSBmcm9tICdAc25hYmNlbnRyL2NsaWVudC1jb3JlJztcbmltcG9ydCB7IFR1aUF1dG9Gb2N1cywgdHVpQ29udHJvbFZhbHVlIH0gZnJvbSAnQHRhaWdhLXVpL2Nkayc7XG5pbXBvcnQge1xuICAgIFR1aUJ1dHRvbixcbiAgICBUdWlEaWFsb2dDb250ZXh0LFxuICAgIFR1aUVycm9yLFxuICAgIFR1aUljb24sXG4gICAgdHVpSXRlbXNIYW5kbGVyc1Byb3ZpZGVyLFxuICAgIFR1aUxhYmVsLFxuICAgIFR1aUxvYWRlcixcbiAgICBUdWlOdW1iZXJGb3JtYXQsXG4gICAgdHVpTnVtYmVyRm9ybWF0UHJvdmlkZXIsXG4gICAgVHVpVGV4dGZpZWxkLFxufSBmcm9tICdAdGFpZ2EtdWkvY29yZSc7XG5pbXBvcnQge1xuICAgIFR1aUJ1dHRvbkxvYWRpbmcsXG4gICAgVHVpQ2hldnJvbixcbiAgICBUdWlEYXRhTGlzdFdyYXBwZXJDb21wb25lbnQsXG4gICAgVHVpRmllbGRFcnJvclBpcGUsXG4gICAgVHVpSW5wdXROdW1iZXIsXG4gICAgdHVpSW5wdXROdW1iZXJPcHRpb25zUHJvdmlkZXIsXG4gICAgVHVpSW5wdXRTbGlkZXIsXG4gICAgVHVpU2VsZWN0LFxufSBmcm9tICdAdGFpZ2EtdWkva2l0JztcbmltcG9ydCB7IFBPTFlNT1JQSEVVU19DT05URVhUIH0gZnJvbSAnQHRhaWdhLXVpL3BvbHltb3JwaGV1cyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBjb25jYXRNYXAsIGZyb20sIG1hcCwgT2JzZXJ2YWJsZSwgb2YsIHN3aXRjaE1hcCwgdGFwLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IFNjTmV4dElucHV0Rm9jdXNNb2R1bGUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL25leHQtaW5wdXQtZm9jdXMvc2MtbmV4dC1pbnB1dC1mb2N1cy5tb2R1bGUnO1xuaW1wb3J0IHsgU2NTZWxlY3RPbkZvY3VzaW5EaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL3NlbGVjdC1vbi1mb2N1c2luL3NjLXNlbGVjdC1vbi1mb2N1c2luLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBzdGVwVmFsaWRhdG9yIH0gZnJvbSAnLi4vLi4vdmFsaWRhdG9ycy9zdGVwLXZhbGlkYXRvcic7XG5pbXBvcnQgeyBTY0lTYW5kd2ljaE0yU2V0dGluZ3MgfSBmcm9tICcuLi9tb2RlbHMvc2FuZHdpY2hfbTIvc2MtaS1zYW5kd2ljaC1tMi1zZXR0aW5ncyc7XG5pbXBvcnQgeyBTY0lOZXdDYXJ0SXRlbVNhbmR3aWNoTTIgfSBmcm9tICcuL3NjLWktbmV3LWNhcnQtaXRlbS1zYW5kd2ljaC1tMic7XG5pbXBvcnQgeyBJRExFX0lURU1fU1RBVEUsIFNjU2FuZHdpY2hNMkl0ZW1TdWJtaXRTdGF0ZSB9IGZyb20gJy4vc2Mtc2FuZHdpY2gtbTItaXRlbS1zdWJtaXQtc3RhdGUnO1xuXG4vKipcbiAqINCa0L7QvdGE0LjQs9GD0YDQsNGC0L7RgCDRgNCw0YHQv9C40LvQsCDRgdGN0L3QtNCy0LjRhy3Qv9Cw0L3QtdC70LXQuSDQv9C+INC/0LvQvtGJ0LDQtNC4LlxuICovXG5AQ29tcG9uZW50KHtcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIHNlbGVjdG9yOiAnc2Mtc2FuZHdpY2gtbTInLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9zYy1zYW5kd2ljaC1tMi5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmw6ICcuL3NjLXNhbmR3aWNoLW0yLmNvbXBvbmVudC5zY3NzJyxcbiAgICBpbXBvcnRzOiBbXG4gICAgICAgIFR1aUJ1dHRvbixcbiAgICAgICAgRm9ybXNNb2R1bGUsXG4gICAgICAgIFJlYWN0aXZlRm9ybXNNb2R1bGUsXG4gICAgICAgIFNjTmV4dElucHV0Rm9jdXNNb2R1bGUsXG4gICAgICAgIFR1aUxhYmVsLFxuICAgICAgICBUdWlEYXRhTGlzdFdyYXBwZXJDb21wb25lbnQsXG4gICAgICAgIFR1aUVycm9yLFxuICAgICAgICBUdWlUZXh0ZmllbGQsXG4gICAgICAgIFR1aUNoZXZyb24sXG4gICAgICAgIFR1aVNlbGVjdCxcbiAgICAgICAgVHVpSW5wdXROdW1iZXIsXG4gICAgICAgIFR1aU51bWJlckZvcm1hdCxcbiAgICAgICAgQXN5bmNQaXBlLFxuICAgICAgICBEZWNpbWFsUGlwZSxcbiAgICAgICAgVHVpRmllbGRFcnJvclBpcGUsXG4gICAgICAgIFR1aUlucHV0U2xpZGVyLFxuICAgICAgICBTY1NlbGVjdE9uRm9jdXNpbkRpcmVjdGl2ZSxcbiAgICAgICAgVHVpTG9hZGVyLFxuICAgICAgICBUdWlCdXR0b25Mb2FkaW5nLFxuICAgICAgICBUdWlJY29uLFxuICAgICAgICBUdWlBdXRvRm9jdXMsXG4gICAgXSxcbiAgICBwcm92aWRlcnM6IFtcbiAgICAgICAgdHVpTnVtYmVyRm9ybWF0UHJvdmlkZXIoeyBwcmVjaXNpb246IDAgfSksXG4gICAgICAgIHR1aUlucHV0TnVtYmVyT3B0aW9uc1Byb3ZpZGVyKHtcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgfSksXG4gICAgICAgIHR1aUl0ZW1zSGFuZGxlcnNQcm92aWRlcih7XG4gICAgICAgICAgICBzdHJpbmdpZnk6IHNpZ25hbCgoeDogU2NQcm9kdWN0KSA9PiB4Lm5hbWUpLFxuICAgICAgICAgICAgaWRlbnRpdHlNYXRjaGVyOiBzaWduYWwoKGE6IFNjUHJvZHVjdCwgYjogU2NQcm9kdWN0KSA9PiBhLmlkID09PSBiLmlkKSxcbiAgICAgICAgfSksXG4gICAgXSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgU2NTYW5kd2ljaE0yQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgICAvKipcbiAgICAgKiDQndCw0YHRgtGA0L7QudC60Lgg0LTQu9GPINC60L7QvdGE0LjQs9GD0YDQsNGC0L7RgNCwINGA0LDRgdC/0LjQu9CwINGB0Y3QvdC00LLQuNGHLdC/0LDQvdC10LvQtdC5INC/0L4g0L/Qu9C+0YnQsNC00LguXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHNldHRpbmdzID0gaW5wdXQ8U2NJU2FuZHdpY2hNMlNldHRpbmdzPigpO1xuXG4gICAgLyoqXG4gICAgICog0JjQtNC10L3RgtC40YTQuNC60LDRgtC+0YAg0LrQsNGC0LXQs9C+0YDQuNC4LlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSBjYXRlZ29yeUlkID0gaW5wdXQucmVxdWlyZWQ8bnVtYmVyIHwgc3RyaW5nPigpO1xuXG4gICAgLyoqXG4gICAgICog0J3QsNC30LLQsNC90LjQtSDQutC+0L3RhNC40LPRg9GA0LDRgtC+0YDQsC5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgZWRpdG9yID0gaW5wdXQucmVxdWlyZWQ8c3RyaW5nPigpO1xuXG4gICAgLyoqXG4gICAgICog0J/QvtC30LjRhtC40Y8g0YLQvtCy0LDRgNCwL9GD0YHQu9GD0LPQuCDQsiDQutC+0YDQt9C40L3QtS5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgb3JkZXJJdGVtID0gaW5wdXQucmVxdWlyZWQ8U2NPcmRlckl0ZW0gfCB1bmRlZmluZWQ+KCk7XG5cbiAgICAvKipcbiAgICAgKiDQmNC00LXQvdGC0LjRhNC40LrQsNGC0L7RgCDQt9Cw0LrQsNC30LAuXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgb3JkZXJJZD86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqINCh0L7QsdGL0YLQuNC1INC/0LXRgNC10LrQu9GO0YfQtdC90LjRjyDQvtGC0L7QsdGA0LDQttC10L3QuNGPINGC0L7QstCw0YDQvtCyLlxuICAgICAqL1xuICAgIHB1YmxpYyByZWFkb25seSB0b2dnbGVTaG93RXZlbnQgPSBvdXRwdXQoKTtcblxuICAgIC8qKlxuICAgICAqINCk0L7RgNC80LAg0LTQvtCx0LDQstC70LXQvdC40Y8v0YDQtdC00LDQutGC0LjRgNC+0LLQsNC90LjRjyDQv9GA0L7QtNGD0LrRgtCwINCyINC60L7RgNC30LjQvdC1LlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBmb3JtID0gbmV3IEZvcm1Hcm91cCh7XG4gICAgICAgIHByb2R1Y3RDYXRlZ29yeUlkOiBuZXcgRm9ybUNvbnRyb2w8bnVtYmVyIHwgbnVsbD4obnVsbCwgeyB2YWxpZGF0b3JzOiBWYWxpZGF0b3JzLnJlcXVpcmVkIH0pLFxuICAgICAgICBjb25maWd1cmF0b3I6IG5ldyBGb3JtQ29udHJvbDxzdHJpbmcgfCBudWxsPihudWxsLCB7IHZhbGlkYXRvcnM6IFZhbGlkYXRvcnMucmVxdWlyZWQgfSksXG4gICAgICAgIGl0ZW1zOiBuZXcgRm9ybUFycmF5PFJldHVyblR5cGU8U2NTYW5kd2ljaE0yQ29tcG9uZW50WydjcmVhdGVJdGVtR3JvdXAnXT4+KFtdKSxcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqINCh0LXRgNCy0LjRgSDQv9C+0LvRg9GH0LXQvdC40Y8g0Lgg0YDQtdC00LDQutGC0LjRgNC+0LLQsNC90LjRjyDRgdC/0LjRgdC60LAg0YLQvtCy0LDRgNC+0LIg0LfQsNC60LDQt9CwICjQutC+0YDQt9C40L3QsCAvINC30LDQutCw0LcgLyDRh9C10YDQvdC+0LLQuNC6ID0g0LfQsNC60LDQtykuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IG9yZGVyU2VydmljZSA9IGluamVjdDxTY0lPcmRlckVkaXRvckxvYWRlcjxTY09yZGVySXRlbSwgU2NDYXJ0IHwgU2NPcmRlckRyYWZ0Pj4oU0NfT1JERVJfTE9BREVSKTtcblxuICAgIC8qKlxuICAgICAqINCh0LXRgNCy0LjRgSDQutC+0L3QstC10YDRgtCw0YbQuNC4INC00LDQvdC90YvRhS5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbnZlcnRlcnNTZXJ2aWNlOiBTY0NvbnZlcnRlcnNTZXJ2aWNlID0gaW5qZWN0KFNjQ29udmVydGVyc1NlcnZpY2UpO1xuXG4gICAgLyoqXG4gICAgICog0JrQvtC90YLQtdC60YHRgiDQtNC40LDQu9C+0LPQvtCy0L7Qs9C+INC+0LrQvdCwLCDQsiDQutC+0YLQvtGA0L7QvCDQvtGC0LrRgNGL0YIg0LrQvtC80L/QvtC90LXQvdGCLlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgY29udGV4dDogVHVpRGlhbG9nQ29udGV4dCB8IHVuZGVmaW5lZCA9IGluamVjdChQT0xZTU9SUEhFVVNfQ09OVEVYVCwgeyBvcHRpb25hbDogdHJ1ZSB9KSBhcyBUdWlEaWFsb2dDb250ZXh0IHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICog0KHQtdGA0LLQuNGBINC00LvRjyDRgNCw0LHQvtGC0Ysg0YEg0LrQsNGC0LDQu9C+0LPQvtC8LlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgY2F0YWxvZ1NlcnZpY2U6IFNjQ2F0YWxvZ1NlcnZpY2UgPSBpbmplY3QoU2NDYXRhbG9nU2VydmljZSk7XG5cbiAgICAvKipcbiAgICAgKiB7QGxpbmsgT2JzZXJ2YWJsZX0g0YHQv9C40YHQutCwINGC0L7QstCw0YDQvtCyINC60LDRgtC10LPQvtGA0LjQuC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgcHJvZHVjdHMkOiBPYnNlcnZhYmxlPFNjUHJvZHVjdFtdPiA9IHRvT2JzZXJ2YWJsZSh0aGlzLmNhdGVnb3J5SWQpLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCgoY2F0ZWdvcnlJZCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFjYXRlZ29yeUlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9mKFtdKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2F0YWxvZ1NlcnZpY2UuZ2V0UHJvZHVjdHNDYXRlZ29yeUNhY2hlZCQoeyBjYXRlZ29yeUlkOiBOdW1iZXIoY2F0ZWdvcnlJZCkgfSkucGlwZShtYXAoKHByb2R1Y3RzKSA9PiBwcm9kdWN0cyA/PyBbXSkpO1xuICAgICAgICB9KVxuICAgICk7XG5cbiAgICAvKipcbiAgICAgKiDQktGL0LHRgNCw0L3QvdGL0Lkg0L/RgNC+0LTRg9C60YIuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IHByb2R1Y3QgPSBuZXcgRm9ybUNvbnRyb2w8U2NQcm9kdWN0IHwgbnVsbD4obnVsbCwgeyB2YWxpZGF0b3JzOiBWYWxpZGF0b3JzLnJlcXVpcmVkIH0pO1xuXG4gICAgLyoqXG4gICAgICog0KHQuNCz0L3QsNC7INGC0LXQutGD0YnQtdCz0L4g0LLRi9Cx0YDQsNC90L3QvtCz0L4g0L/RgNC+0LTRg9C60YLQsCDigJQg0L7QsdC90L7QstC70Y/QtdGC0YHRjyDQv9GA0LggYHZhbHVlQ2hhbmdlc2Ag0LrQvtC90YLRgNC+0LvQsCBgcHJvZHVjdGAuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IHByb2R1Y3RTaWduYWwgPSB0b1NpZ25hbCh0dWlDb250cm9sVmFsdWU8U2NQcm9kdWN0IHwgbnVsbD4odGhpcy5wcm9kdWN0KSwgeyBpbml0aWFsVmFsdWU6IG51bGwgfSk7XG5cbiAgICAvKipcbiAgICAgKiDQodC40LPQvdCw0Lsg0YHQvtC00LXRgNC20LjQvNC+0LPQviBGb3JtQXJyYXkg0L/QvtC30LjRhtC40Lkg4oCUINC/0LXRgNC10YHRh9C40YLRi9Cy0LDQtdGC0YHRjyDQv9GA0Lgg0LvRjtCx0L7QvCDQuNC30LzQtdC90LXQvdC40Lgg0LfQvdCw0YfQtdC90LjQuS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgaXRlbXNWYWx1ZSA9IHRvU2lnbmFsKHR1aUNvbnRyb2xWYWx1ZTx1bmtub3duW10+KHRoaXMuaXRlbXMpLnBpcGUobWFwKCgpID0+IHRoaXMuaXRlbXMuY29udHJvbHMubWFwKChjKSA9PiBjLmdldFJhd1ZhbHVlKCkpKSksIHtcbiAgICAgICAgaW5pdGlhbFZhbHVlOiBbXSBhcyBBcnJheTxSZXR1cm5UeXBlPFJldHVyblR5cGU8U2NTYW5kd2ljaE0yQ29tcG9uZW50WydjcmVhdGVJdGVtR3JvdXAnXT5bJ2dldFJhd1ZhbHVlJ10+PixcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqINCf0YDQuNC30L3QsNC6INGC0L7Qs9C+LCDRh9GC0L4g0LLRi9C/0L7Qu9C90Y/QtdGC0YHRjyDQt9Cw0L/RgNC+0YEg0L3QsCDQvtGC0L/RgNCw0LLQutGDINC00LDQvdC90YvRhS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgaXNTdWJtaXRMb2FkaW5nID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5pdGVtU3RhdGVzKCkuaW5jbHVkZXMoJ2xvYWRpbmcnKSk7XG5cbiAgICAvKipcbiAgICAgKiDQodC+0YHRgtC+0Y/QvdC40LUg0L7RgtC/0YDQsNCy0LrQuCDQutCw0LbQtNC+0Lkg0L/QvtC30LjRhtC40Lgg4oCUINC/0LDRgNCw0LvQu9C10LvRjNC90YvQuSDQvNCw0YHRgdC40LIg0Log0LrQvtC90YLRgNC+0LvRgyBgaXRlbXNgINGE0L7RgNC80YsuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGl0ZW1TdGF0ZXMgPSBzaWduYWw8U2NTYW5kd2ljaE0ySXRlbVN1Ym1pdFN0YXRlW10+KFtdKTtcblxuICAgIC8qKlxuICAgICAqINCf0YDQuNC30L3QsNC6INGA0LXQttC40LzQsCDRgNC10LTQsNC60YLQuNGA0L7QstCw0L3QuNGPINGB0YPRidC10YHRgtCy0YPRjtGJ0LXQuSDQv9C+0LfQuNGG0LjQuCDigJQgYG9yZGVySXRlbWAg0LfQsNC00LDQvS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgaXNFZGl0aW5nRXhpc3RpbmdJdGVtID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5vcmRlckl0ZW0oKSAhPSBudWxsKTtcblxuICAgIC8qKlxuICAgICAqINCf0YDQuNC30L3QsNC6INGC0L7Qs9C+LCDRh9GC0L4g0L7RgtC/0YDQsNCy0LvRj9GC0Ywg0LHQvtC70YzRiNC1INC90LXRh9C10LPQviDigJQg0LLRgdC1INC/0L7Qt9C40YbQuNC4INC70LjQsdC+INGD0YHQv9C10YjQvdC+XG4gICAgICog0L7RgtC/0YDQsNCy0LvQtdC90YssINC70LjQsdC+INC90LDRhdC+0LTRj9GC0YHRjyDQsiDQv9GA0L7RhtC10YHRgdC1INC+0YLQv9GA0LDQstC60LguXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGhhc05vUGVuZGluZ0l0ZW1zID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCBzdGF0ZXMgPSB0aGlzLml0ZW1TdGF0ZXMoKTtcblxuICAgICAgICBpZiAodGhpcy5pdGVtcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuaXRlbXMuY29udHJvbHMuZXZlcnkoKF8sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdGF0ZSA9IHN0YXRlc1tpbmRleF0gPz8gSURMRV9JVEVNX1NUQVRFO1xuXG4gICAgICAgICAgICByZXR1cm4gc3RhdGUgPT09ICdzdWNjZXNzJyB8fCBzdGF0ZSA9PT0gJ2xvYWRpbmcnO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqINCh0YPQvNC80LDRgNC90LDRjyDQv9C70L7RidCw0LTRjCDQstGB0LXRhSDQv9C+0LfQuNGG0LjQuSAo0LzCsiksINGA0LDRgdGB0YfQuNGC0LDQvdC90LDRjyDQu9C+0LrQsNC70YzQvdC+LlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSB0b3RhbEFyZWFNMiA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgICAgbGV0IHRvdGFsID0gMDtcblxuICAgICAgICB0aGlzLml0ZW1zVmFsdWUoKS5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgdG90YWwgKz0gdGhpcy5yb3dUb3RhbFBhcnRzQXJlYU0yKHZhbHVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHRvdGFsO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICog0JjRgtC+0LPQvtCy0LDRjyDRgdGC0L7QuNC80L7RgdGC0Ywg0L/QviDQstGB0LXQvCDQv9C+0LfQuNGG0LjRj9C8ICjQu9C+0LrQsNC70YzQvdGL0Lkg0YDQsNGB0YfRkdGCKS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgdG90YWxDb3N0ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICBjb25zdCBjb3N0ID0gdGhpcy5wcm9kdWN0U2lnbmFsKCk/LmNvc3RSdWIgPz8gMDtcbiAgICAgICAgY29uc3QgYXJlYSA9IHRoaXMudG90YWxBcmVhTTIoKTtcblxuICAgICAgICByZXR1cm4gTWF0aC5yb3VuZChhcmVhICogY29zdCAqIDEwMCkgLyAxMDA7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiDQotC10LrRgdGCINC+0LPRgNCw0L3QuNGH0LXQvdC40Y8g0L/QviDRiNC40YDQuNC90LUgKMKr0L7RgiDigKYg0LTQviDigKbCuyksINC/0L7QutCwINC10YHRgtGMINCy0YvQsdGA0LDQvdC90YvQuSDRgtC+0LLQsNGALlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSB3aWR0aFJhbmdlVGV4dCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZm9ybWF0UmFuZ2UodGhpcy5zZXR0aW5ncygpPy5taW5XaWR0aCA/PyBudWxsLCB0aGlzLnByb2R1Y3RTaWduYWwoKT8ucHJvcGVydGllcz8ud2lkdGggPz8gbnVsbCwgJ9C80LwnKSk7XG5cbiAgICAvKipcbiAgICAgKiDQotC10LrRgdGCINC+0LPRgNCw0L3QuNGH0LXQvdC40Y8g0L/QviDQtNC70LjQvdC1ICjCq9C+0YIg4oCmINC00L4g4oCmwrspLCDQv9C+0LrQsCDQtdGB0YLRjCDQstGL0LHRgNCw0L3QvdGL0Lkg0YLQvtCy0LDRgC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgbGVuZ3RoUmFuZ2VUZXh0ID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5mb3JtYXRSYW5nZSh0aGlzLnNldHRpbmdzKCk/Lm1pbkxlbmd0aCA/PyBudWxsLCB0aGlzLnByb2R1Y3RTaWduYWwoKT8ucHJvcGVydGllcz8ubGVuZ3RoID8/IG51bGwsICfQvNC8JykpO1xuXG4gICAgLyoqXG4gICAgICog0KHRgdGL0LvQutCwINC00LvRjyDQsNCy0YLQvtC80LDRgtC40YfQtdGB0LrQvtCz0L4g0YPQv9GA0LDQstC70LXQvdC40Y8g0YPQvdC40YfRgtC+0LbQtdC90LjQtdC8INC30LDQstC40YHQuNC80L7RgdGC0LXQuS5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IGRlc3Ryb3lSZWY6IERlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG5cbiAgICAvKipcbiAgICAgKiDQktCw0LvQuNC00LDRgtC+0YDRiyDRiNC40YDQuNC90Ysv0LTQu9C40L3Rizog0L/QvtC60LAg0YLQvtCy0LDRgCDQvdC1INCy0YvQsdGA0LDQvSDigJQg0L3QtSDQvdCw0LrQu9Cw0LTRi9Cy0LDQtdC8IG1pbi9tYXgg0LrQsNGC0LDQu9C+0LPQsCAo0L/QvtC70Y8gcmVhZC1vbmx5INCx0LXQtyDRgtC+0LLQsNGA0LApLlxuICAgICAqXG4gICAgICogQHBhcmFtIG1pbiDQndC40LbQvdGP0Y8g0LPRgNCw0L3QuNGG0LAg0YDQsNC30LzQtdGA0LAg0LjQtyDQvdCw0YHRgtGA0L7QtdC6INC60L7QvdGE0LjQs9GD0YDQsNGC0L7RgNCwLlxuICAgICAqIEBwYXJhbSBtYXhVcHBlciDQktC10YDRhdC90Y/RjyDQs9GA0LDQvdC40YbQsCDQuNC3INGB0LLQvtC50YHRgtCyINCy0YvQsdGA0LDQvdC90L7Qs9C+INGC0L7QstCw0YDQsC5cbiAgICAgKi9cbiAgICBwcml2YXRlIGRpbWVuc2lvblZhbGlkYXRvcnMobWluOiBudW1iZXIsIG1heFVwcGVyOiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkKTogVmFsaWRhdG9yRm5bXSB7XG4gICAgICAgIGNvbnN0IGNob3NlblByb2R1Y3QgPSB0aGlzLnByb2R1Y3QudmFsdWU7XG5cbiAgICAgICAgaWYgKCFjaG9zZW5Qcm9kdWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMubWluKG1pbiksIC4uLihtYXhVcHBlciAhPSBudWxsICYmIG1heFVwcGVyID4gMCA/IFtWYWxpZGF0b3JzLm1heChtYXhVcHBlcildIDogW10pLCBzdGVwVmFsaWRhdG9yKDEpXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQntCx0L3QvtCy0LvRj9C10YIg0LLQsNC70LjQtNCw0YLQvtGA0Ysg0YDQsNC30LzQtdGA0L3Ri9GFINC/0L7Qu9C10Lkg0L/QvtGB0LvQtSDRgdC80LXQvdGLINGC0L7QstCw0YDQsCDQuNC70Lgg0L3QsNGB0YLRgNC+0LXQui5cbiAgICAgKi9cbiAgICBwcml2YXRlIHVwZGF0ZUl0ZW1zVmFsaWRhdG9ycygpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSB0aGlzLnNldHRpbmdzKCk7XG4gICAgICAgIGNvbnN0IG1pbldpZHRoID0gc2V0dGluZ3M/Lm1pbldpZHRoID8/IDAuMDE7XG4gICAgICAgIGNvbnN0IG1pbkxlbmd0aCA9IHNldHRpbmdzPy5taW5MZW5ndGggPz8gMC4wMTtcbiAgICAgICAgY29uc3QgY2hvc2VuUHJvZHVjdCA9IHRoaXMucHJvZHVjdC52YWx1ZTtcblxuICAgICAgICB0aGlzLml0ZW1zLmNvbnRyb2xzLmZvckVhY2goKGdyb3VwKSA9PiB7XG4gICAgICAgICAgICBncm91cC5nZXQoJ3dpZHRoJyk/LnNldFZhbGlkYXRvcnModGhpcy5kaW1lbnNpb25WYWxpZGF0b3JzKG1pbldpZHRoLCBjaG9zZW5Qcm9kdWN0Py5wcm9wZXJ0aWVzPy53aWR0aCkpO1xuICAgICAgICAgICAgZ3JvdXAuZ2V0KCdsZW5ndGgnKT8uc2V0VmFsaWRhdG9ycyh0aGlzLmRpbWVuc2lvblZhbGlkYXRvcnMobWluTGVuZ3RoLCBjaG9zZW5Qcm9kdWN0Py5wcm9wZXJ0aWVzPy5sZW5ndGgpKTtcbiAgICAgICAgICAgIGdyb3VwLmdldCgnd2lkdGgnKT8udXBkYXRlVmFsdWVBbmRWYWxpZGl0eSh7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgICAgICBncm91cC5nZXQoJ2xlbmd0aCcpPy51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0KTQvtGA0LzQsNGC0LjRgNC+0LLQsNC90LjQtSDQtNC40LDQv9Cw0LfQvtC90LAgwqvQvtGCIOKApiDQtNC+IOKApsK7INGBINGD0YfRkdGC0L7QvCDQvtGC0YHRg9GC0YHRgtCy0YPRjtGJ0LjRhSDQs9GA0LDQvdC40YYuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbWluINCd0LjQttC90Y/RjyDQs9GA0LDQvdC40YbQsCDQtNC40LDQv9Cw0LfQvtC90LAuXG4gICAgICogQHBhcmFtIG1heCDQktC10YDRhdC90Y/RjyDQs9GA0LDQvdC40YbQsCDQtNC40LDQv9Cw0LfQvtC90LAuXG4gICAgICogQHBhcmFtIHVuaXQg0JXQtNC40L3QuNGG0LAg0LjQt9C80LXRgNC10L3QuNGPINC00LvRjyDQv9C+0LTQv9C40YHQuC5cbiAgICAgKi9cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2xhc3MtbWV0aG9kcy11c2UtdGhpc1xuICAgIHByaXZhdGUgZm9ybWF0UmFuZ2UobWluOiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkLCBtYXg6IG51bWJlciB8IG51bGwgfCB1bmRlZmluZWQsIHVuaXQ6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAgICAgICBjb25zdCBoYXNNaW4gPSBtaW4gIT0gbnVsbCAmJiBtaW4gPiAwO1xuICAgICAgICBjb25zdCBoYXNNYXggPSBtYXggIT0gbnVsbCAmJiBtYXggPiAwO1xuXG4gICAgICAgIGlmICghaGFzTWluICYmICFoYXNNYXgpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhc01pbiAmJiBoYXNNYXgpIHtcbiAgICAgICAgICAgIHJldHVybiBg0L7RgiAke21pbn0gJHt1bml0fSDQtNC+ICR7bWF4fSAke3VuaXR9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChoYXNNaW4pIHtcbiAgICAgICAgICAgIHJldHVybiBg0L7RgiAke21pbn0gJHt1bml0fWA7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYNC00L4gJHttYXh9ICR7dW5pdH1gO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCc0LDRgdGB0LjQsiDQuNC30LTQtdC70LjQuS5cbiAgICAgKi9cbiAgICBnZXQgaXRlbXMoKTogRm9ybUFycmF5PFJldHVyblR5cGU8U2NTYW5kd2ljaE0yQ29tcG9uZW50WydjcmVhdGVJdGVtR3JvdXAnXT4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybS5jb250cm9scy5pdGVtcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB7QGluaGVyaXREb2N9XG4gICAgICovXG4gICAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldERlZmF1bHRGb3JtVmFsdWUoKTtcblxuICAgICAgICB0aGlzLnByb2R1Y3RzJC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKS5zdWJzY3JpYmUoKHByb2R1Y3RzKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9kdWN0LnZhbHVlICE9IG51bGwgfHwgcHJvZHVjdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvKiDQn9GA0Lgg0LfQsNCz0YDRg9C30LrQtSDRgdC/0LjRgdC60LAg0LDQstGC0L7QvNCw0YLQuNGH0LXRgdC60Lgg0LLRi9Cx0LjRgNCw0LXQvCDQv9C10YDQstGL0Lkg0LzQsNGC0LXRgNC40LDQuy4gKi9cbiAgICAgICAgICAgIHRoaXMucHJvZHVjdC5zZXRWYWx1ZShwcm9kdWN0c1swXSwgeyBlbWl0RXZlbnQ6IHRydWUgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucHJvZHVjdC52YWx1ZUNoYW5nZXMucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSkuc3Vic2NyaWJlKChjaG9zZW5Qcm9kdWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUl0ZW1zVmFsaWRhdG9ycygpO1xuXG4gICAgICAgICAgICBpZiAoY2hvc2VuUHJvZHVjdCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaXRlbXMuY29udHJvbHMuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGl0ZW0uZ2V0UmF3VmFsdWUoKTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXhXID0gY2hvc2VuUHJvZHVjdC5wcm9wZXJ0aWVzPy53aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF4TCA9IGNob3NlblByb2R1Y3QucHJvcGVydGllcz8ubGVuZ3RoO1xuXG4gICAgICAgICAgICAgICAgICAgIGl0ZW0ucGF0Y2hWYWx1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogbWF4VyA/IE1hdGgubWluKHZhbHVlLndpZHRoLCBtYXhXKSA6IHZhbHVlLndpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoOiBtYXhMID8gTWF0aC5taW4odmFsdWUubGVuZ3RoLCBtYXhMKSA6IHZhbHVlLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqINCh0LzQtdC90LAg0L/RgNC+0LTRg9C60YLQsCDigJQg0YHQsdGA0LDRgdGL0LLQsNC10Lwg0YHQvtGB0YLQvtGP0L3QuNC1INC/0L7Qt9C40YbQuNC5OiDQs9GA0LDQvdC40YbRiyDQutCw0YLQsNC70L7Qs9CwINC40LfQvNC10L3QuNC70LjRgdGMLFxuICAgICAgICAgICAgICAgICAqINGD0YHQv9C10YjQvdCw0Y8g0L7RgtC/0YDQsNCy0LrQsCDQsdC+0LvRjNGI0LUg0L3QtSDQvtGC0YDQsNC20LDQtdGCINGC0LXQutGD0YnQtdC1INGB0L7RgdGC0L7Rj9C90LjQtS5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICB0aGlzLnJlc2V0QWxsSXRlbVN0YXRlcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQodC+0LfQtNCw0LXRgiDQs9GA0YPQv9C/0YMg0LTQu9GPINC40LfQtNC10LvQuNGPLlxuICAgICAqXG4gICAgICogQHBhcmFtIGl0ZW0g0J/QsNGA0LDQvNC10YLRgNGLINC40LfQtNC10LvQuNGPLlxuICAgICAqIEBwYXJhbSBpdGVtLndpZHRoINCo0LjRgNC40L3QsCDQuNC30LTQtdC70LjRjy5cbiAgICAgKiBAcGFyYW0gaXRlbS5sZW5ndGgg0JTQu9C40L3QsCDQuNC30LTQtdC70LjRjy5cbiAgICAgKiBAcGFyYW0gaXRlbS5jb3VudCDQmtC+0LvQuNGH0LXRgdGC0LLQviDQuNC30LTQtdC70LjQuS5cbiAgICAgKiBAcGFyYW0gaXRlbS5tYXJrZXIg0JzQsNGA0LrQtdGAINC/0L7Qt9C40YbQuNC4LlxuICAgICAqL1xuICAgIHByaXZhdGUgY3JlYXRlSXRlbUdyb3VwKGl0ZW0/OiB7IHdpZHRoOiBudW1iZXI7IGxlbmd0aDogbnVtYmVyOyBjb3VudDogbnVtYmVyOyBtYXJrZXI6IHN0cmluZyB8IG51bGwgfSk6IEZvcm1Hcm91cDx7XG4gICAgICAgIHdpZHRoOiBGb3JtQ29udHJvbDxudW1iZXI+O1xuICAgICAgICBsZW5ndGg6IEZvcm1Db250cm9sPG51bWJlcj47XG4gICAgICAgIGNvdW50OiBGb3JtQ29udHJvbDxudW1iZXI+O1xuICAgICAgICBtYXJrZXI6IEZvcm1Db250cm9sPHN0cmluZyB8IG51bGw+O1xuICAgIH0+IHtcbiAgICAgICAgY29uc3QgZ3JvdXAgPSBuZXcgRm9ybUdyb3VwKHtcbiAgICAgICAgICAgIHdpZHRoOiBuZXcgRm9ybUNvbnRyb2w8bnVtYmVyPihpdGVtPy53aWR0aCA/PyAwLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pLFxuICAgICAgICAgICAgbGVuZ3RoOiBuZXcgRm9ybUNvbnRyb2w8bnVtYmVyPihpdGVtPy5sZW5ndGggPz8gMCwgeyBub25OdWxsYWJsZTogdHJ1ZSB9KSxcbiAgICAgICAgICAgIGNvdW50OiBuZXcgRm9ybUNvbnRyb2w8bnVtYmVyPihpdGVtPy5jb3VudCA/PyAxLCB7XG4gICAgICAgICAgICAgICAgdmFsaWRhdG9yczogW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMubWluKDEpLCBzdGVwVmFsaWRhdG9yKDEpXSxcbiAgICAgICAgICAgICAgICBub25OdWxsYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgbWFya2VyOiBuZXcgRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD4oaXRlbT8ubWFya2VyID8/IG51bGwpLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyDQm9GO0LHQvtC1INC40LfQvNC10L3QtdC90LjQtSDQt9C90LDRh9C10L3QuNC5INC/0L7Qt9C40YbQuNC4INGB0LHRgNCw0YHRi9Cy0LDQtdGCINC10ZEg0YHQvtGB0YLQvtGP0L3QuNC1INC+0YLQv9GA0LDQstC60Lgg4oCUXG4gICAgICAgIC8vINGA0LDQvdC10LUg0YPRgdC/0LXRiNC90YvQuSBzdWJtaXQg0YHRgtCw0L3QvtCy0LjRgtGB0Y8g0L3QtdCw0LrRgtGD0LDQu9GM0L3Ri9C8INC/0YDQuCDQv9GA0LDQstC60LUg0L/QvtC70LXQuSxcbiAgICAgICAgLy8g0L7RiNC40LHQutGDINCy0LDQu9C40LTQsNGG0LjQuCDRgdC10YDQstC10YDQsCDRgtC+0LbQtSDRgdCx0YDQsNGB0YvQstCw0LXQvC5cbiAgICAgICAgZ3JvdXAudmFsdWVDaGFuZ2VzLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuaXRlbXMuY29udHJvbHMuaW5kZXhPZihncm91cCk7XG5cbiAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2V0SXRlbVN0YXRlKGluZGV4KTtcbiAgICAgICAgICAgICAgICAoWyd3aWR0aCcsICdsZW5ndGgnLCAnY291bnQnLCAnbWFya2VyJ10gYXMgY29uc3QpLmZvckVhY2goKGZpZWxkKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRyb2wgPSBncm91cC5nZXQoZmllbGQpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250cm9sPy5oYXNFcnJvcignc2VydmVyUmVzcG9uc2UnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JzID0geyAuLi5jb250cm9sLmVycm9ycyB9IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGVycm9yc1snc2VydmVyUmVzcG9uc2UnXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wuc2V0RXJyb3JzKE9iamVjdC5rZXlzKGVycm9ycykubGVuZ3RoID4gMCA/IGVycm9ycyA6IG51bGwpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBncm91cDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQodCx0YDQsNGB0YvQstCw0LXRgiDRgdC+0YHRgtC+0Y/QvdC40LUg0L7QtNC90L7QuSDQv9C+0LfQuNGG0LjQuCDQvdCwIGBpZGxlYCwg0LXRgdC70Lgg0L7QvdC+INCx0YvQu9C+IGBzdWNjZXNzYC9gZXJyb3JgLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluZGV4INCY0L3QtNC10LrRgSDQv9C+0LfQuNGG0LjQuC5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlc2V0SXRlbVN0YXRlKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgc3RhdGVzID0gdGhpcy5pdGVtU3RhdGVzKCk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSBzdGF0ZXNbaW5kZXhdO1xuXG4gICAgICAgIGlmIChjdXJyZW50ID09PSAnc3VjY2VzcycgfHwgY3VycmVudCA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlZCA9IFsuLi5zdGF0ZXNdO1xuICAgICAgICAgICAgdXBkYXRlZFtpbmRleF0gPSAnaWRsZSc7XG4gICAgICAgICAgICB0aGlzLml0ZW1TdGF0ZXMuc2V0KHVwZGF0ZWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0KHQsdGA0LDRgdGL0LLQsNC10YIg0YHQvtGB0YLQvtGP0L3QuNGPINCy0YHQtdGFINC/0L7Qt9C40YbQuNC5INC90LAgYGlkbGVgLlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVzZXRBbGxJdGVtU3RhdGVzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLml0ZW1TdGF0ZXMuc2V0KHRoaXMuaXRlbXMuY29udHJvbHMubWFwKCgpID0+IElETEVfSVRFTV9TVEFURSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCS0L7Qt9Cy0YDQsNGJ0LDQtdGCINGB0L7RgdGC0L7Rj9C90LjQtSDQv9C+0LfQuNGG0LjQuCDQv9C+INC40L3QtNC10LrRgdGDICjQv9C+INGD0LzQvtC70YfQsNC90LjRjiBgaWRsZWApLlxuICAgICAqXG4gICAgICogQHBhcmFtIGluZGV4INCY0L3QtNC10LrRgSDQv9C+0LfQuNGG0LjQuC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgZ2V0SXRlbVN0YXRlKGluZGV4OiBudW1iZXIpOiBTY1NhbmR3aWNoTTJJdGVtU3VibWl0U3RhdGUge1xuICAgICAgICByZXR1cm4gdGhpcy5pdGVtU3RhdGVzKClbaW5kZXhdID8/IElETEVfSVRFTV9TVEFURTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQn9GA0LjQt9C90LDQuiDRgtC+0LPQviwg0YfRgtC+INC/0L7Qt9C40YbQuNGPINC+0YLQv9GA0LDQstC70Y/QtdGC0YHRjyAo0L/QvtC70Y8g0LTQvtC70LbQvdGLINCx0YvRgtGMINC30LDQsdC70L7QutC40YDQvtCy0LDQvdGLKS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbmRleCDQmNC90LTQtdC60YEg0L/QvtC30LjRhtC40LguXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGlzSXRlbUxvYWRpbmcoaW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRJdGVtU3RhdGUoaW5kZXgpID09PSAnbG9hZGluZyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J/RgNC40LfQvdCw0Log0YLQvtCz0L4sINGH0YLQviDQv9C+0LfQuNGG0LjRjyDRg9GB0L/QtdGI0L3QviDQvtGC0L/RgNCw0LLQu9C10L3QsCDQuCDQtdGRINC/0L7Qu9GPINC90YPQttC90L4g0LfQsNCx0LvQvtC60LjRgNC+0LLQsNGC0YwuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5kZXgg0JjQvdC00LXQutGBINC/0L7Qt9C40YbQuNC4LlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBpc0l0ZW1Mb2NrZWQoaW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRJdGVtU3RhdGUoaW5kZXgpID09PSAnc3VjY2Vzcyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0JTQvtCx0LDQstC70Y/QtdGCINC90L7QstC+0LUg0LjQt9C00LXQu9C40LUg0LIg0YTQvtGA0LzRgy5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgYWRkSXRlbSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5pdGVtcy5wdXNoKHRoaXMuY3JlYXRlSXRlbUdyb3VwKCkpO1xuICAgICAgICB0aGlzLml0ZW1TdGF0ZXMudXBkYXRlKChzdGF0ZXMpID0+IFsuLi5zdGF0ZXMsICdpZGxlJ10pO1xuICAgICAgICB0aGlzLnVwZGF0ZUl0ZW1zVmFsaWRhdG9ycygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCj0LTQsNC70Y/QtdGCINC40LfQtNC10LvQuNC1INC40Lcg0YTQvtGA0LzRiy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbmRleCDQmNC90LTQtdC60YEg0LjQt9C00LXQu9C40Y8uXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlbW92ZUl0ZW0oaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLml0ZW1zLnJlbW92ZUF0KGluZGV4KTtcbiAgICAgICAgdGhpcy5pdGVtU3RhdGVzLnVwZGF0ZSgoc3RhdGVzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB1cGRhdGVkID0gWy4uLnN0YXRlc107XG4gICAgICAgICAgICB1cGRhdGVkLnNwbGljZShpbmRleCwgMSk7XG5cbiAgICAgICAgICAgIHJldHVybiB1cGRhdGVkO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy51cGRhdGVJdGVtc1ZhbGlkYXRvcnMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQn9C70L7RidCw0LTRjCDQvtC00L3QvtC5INC10LTQuNC90LjRhtGLINC40LfQtNC10LvQuNGPINCx0LXQtyDRg9GH0ZHRgtCwINC60L7Qu9C40YfQtdGB0YLQstCwLCDQvMKyLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlINCX0L3QsNGH0LXQvdC40Y8g0YDQsNC30LzQtdGA0L7QsiDQuNC30LTQtdC70LjRjy5cbiAgICAgKiBAcGFyYW0gdmFsdWUud2lkdGgg0KjQuNGA0LjQvdCwINC40LfQtNC10LvQuNGPLlxuICAgICAqIEBwYXJhbSB2YWx1ZS5sZW5ndGgg0JTQu9C40L3QsCDQuNC30LTQtdC70LjRjy5cbiAgICAgKi9cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2xhc3MtbWV0aG9kcy11c2UtdGhpc1xuICAgIHByb3RlY3RlZCBwaWVjZUFyZWFNMih2YWx1ZTogeyB3aWR0aDogbnVtYmVyOyBsZW5ndGg6IG51bWJlciB9KTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgeyB3aWR0aCwgbGVuZ3RoIH0gPSB2YWx1ZTtcblxuICAgICAgICBpZiAoIXdpZHRoIHx8ICFsZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuICh3aWR0aCAqIGxlbmd0aCkgLyAxXzAwMF8wMDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0KHRg9C80LzQsNGA0L3QsNGPINC/0LvQvtGJ0LDQtNGMINC/0L4g0YHRgtGA0L7QutC1INC/0L7Qt9C40YbQuNC4OiDQv9C70L7RidCw0LTRjCDQtdC00LjQvdC40YbRiyDDlyDQutC+0LvQuNGH0LXRgdGC0LLQviwg0LzCsi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZSDQl9C90LDRh9C10L3QuNGPINC/0L7Qt9C40YbQuNC4LlxuICAgICAqIEBwYXJhbSB2YWx1ZS53aWR0aCDQqNC40YDQuNC90LAg0LjQt9C00LXQu9C40Y8uXG4gICAgICogQHBhcmFtIHZhbHVlLmxlbmd0aCDQlNC70LjQvdCwINC40LfQtNC10LvQuNGPLlxuICAgICAqIEBwYXJhbSB2YWx1ZS5jb3VudCDQmtC+0LvQuNGH0LXRgdGC0LLQviDQuNC30LTQtdC70LjQuS5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJvd1RvdGFsUGFydHNBcmVhTTIodmFsdWU6IHsgd2lkdGg6IG51bWJlcjsgbGVuZ3RoOiBudW1iZXI7IGNvdW50OiBudW1iZXIgfSk6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IHF0eSA9IHZhbHVlLmNvdW50O1xuXG4gICAgICAgIGlmICghcXR5IHx8ICF2YWx1ZS53aWR0aCB8fCB2YWx1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMucGllY2VBcmVhTTIodmFsdWUpICogcXR5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCS0L7Qt9Cy0YDQsNGJ0LDQtdGCINC/0YDQuNCx0LvQuNC30LjRgtC10LvRjNC90YPRjiDRgdGC0L7QuNC80L7RgdGC0Ywg0YHRgtGA0L7QutC4ICjQu9C+0LrQsNC70YzQvdGL0Lkg0YDQsNGB0YfRkdGCIOKAlCDQvdCwINCy0YHRjiDRgdGC0YDQvtC60YMg0L/QvtC30LjRhtC40LgpLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlINCX0L3QsNGH0LXQvdC40Y8g0LjQt9C00LXQu9C40Y8uXG4gICAgICogQHBhcmFtIHZhbHVlLndpZHRoINCo0LjRgNC40L3QsCDQuNC30LTQtdC70LjRjy5cbiAgICAgKiBAcGFyYW0gdmFsdWUubGVuZ3RoINCU0LvQuNC90LAg0LjQt9C00LXQu9C40Y8uXG4gICAgICogQHBhcmFtIHZhbHVlLmNvdW50INCa0L7Qu9C40YfQtdGB0YLQstC+INC40LfQtNC10LvQuNC5LlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByb3dDb3N0KHZhbHVlOiB7IHdpZHRoOiBudW1iZXI7IGxlbmd0aDogbnVtYmVyOyBjb3VudDogbnVtYmVyIH0pOiBudW1iZXIge1xuICAgICAgICBjb25zdCBhcmVhID0gdGhpcy5yb3dUb3RhbFBhcnRzQXJlYU0yKHZhbHVlKTtcbiAgICAgICAgY29uc3QgY29zdCA9IHRoaXMucHJvZHVjdC52YWx1ZT8uY29zdFJ1YiA/PyAwO1xuXG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKGFyZWEgKiBjb3N0ICogMTAwKSAvIDEwMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQntCx0L3QvtCy0LvRj9C10YIg0YHQvtGB0YLQvtGP0L3QuNC1INC/0L7Qt9C40YbQuNC4INC90LAg0YPQutCw0LfQsNC90L3QvtC1INC30L3QsNGH0LXQvdC40LUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5kZXgg0JjQvdC00LXQutGBINC/0L7Qt9C40YbQuNC4LlxuICAgICAqIEBwYXJhbSBzdGF0ZSDQndC+0LLQvtC1INGB0L7RgdGC0L7Rj9C90LjQtS5cbiAgICAgKi9cbiAgICBwcml2YXRlIHNldEl0ZW1TdGF0ZShpbmRleDogbnVtYmVyLCBzdGF0ZTogU2NTYW5kd2ljaE0ySXRlbVN1Ym1pdFN0YXRlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaXRlbVN0YXRlcy51cGRhdGUoKHN0YXRlcykgPT4ge1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlZCA9IFsuLi5zdGF0ZXNdO1xuICAgICAgICAgICAgdXBkYXRlZFtpbmRleF0gPSBzdGF0ZTtcblxuICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZWQ7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCf0YDQuNC80LXQvdGP0LXRgiDQvtGI0LjQsdC60Lgg0YHQtdGA0LLQtdGA0L3QvtC5INCy0LDQu9C40LTQsNGG0LjQuCDQuiDQutC+0L3RgtGA0L7Qu9Cw0Lwg0YTQvtGA0LzRiy5cbiAgICAgKiDQodC10YDQstC10YAg0LLQvtC30LLRgNCw0YnQsNC10YIg0LrQu9GO0YfQuCDQstC40LTQsCBgaXRlbXMuMC48ZmllbGQ+YCDigJQg0L/QtdGA0LXQstC+0LTQuNC8INCyINGE0LDQutGC0LjRh9C10YHQutC40Lkg0LjQvdC00LXQutGBINC/0L7Qt9C40YbQuNC4LlxuICAgICAqXG4gICAgICogQHBhcmFtIGVycm9yINCe0YLQstC10YIg0YHQtdGA0LLQtdGA0LAuXG4gICAgICogQHBhcmFtIGluZGV4INCY0L3QtNC10LrRgSDQv9C+0LfQuNGG0LjQuCDQsiDRhNC+0YDQvNC1LlxuICAgICAqL1xuICAgIHByaXZhdGUgYXBwbHlTZXJ2ZXJWYWxpZGF0aW9uRXJyb3JzKGVycm9yOiB1bmtub3duLCBpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGlmICghKGVycm9yIGluc3RhbmNlb2YgSHR0cEVycm9yUmVzcG9uc2UpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7IGVycm9ycywgbWVzc2FnZSB9ID0gZXJyb3IuZXJyb3IgYXMgU2NJQXBpRXJyb3JSZXNwb25zZTtcblxuICAgICAgICBpZiAoZXJyb3JzKSB7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhlcnJvcnMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZm9ybS5nZXQoWydpdGVtcycsIGluZGV4LCBrZXldKT8uc2V0RXJyb3JzKHsgc2VydmVyUmVzcG9uc2U6IGVycm9yc1trZXldIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAobWVzc2FnZSkge1xuICAgICAgICAgICAgdGhpcy5mb3JtLnNldEVycm9ycyh7IHNlcnZlclJlc3BvbnNlOiBbbWVzc2FnZV0gfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQntCx0YDQsNCx0L7RgtGH0LjQuiDQtNC+0LHQsNCy0LvQtdC90LjRjy/RgNC10LTQsNC60YLQuNGA0L7QstCw0L3QuNGPINC/0YDQvtC00YPQutGC0LAg0LIg0LrQvtGA0LfQuNC90LUuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIG9uU3VibWl0KCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5mb3JtLmludmFsaWQgfHwgIXRoaXMucHJvZHVjdC52YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHJvZHVjdElkID0gdGhpcy5wcm9kdWN0LnZhbHVlLmlkO1xuICAgICAgICBjb25zdCBwcm9kdWN0Q2F0ZWdvcnlJZCA9IE51bWJlcih0aGlzLmNhdGVnb3J5SWQoKSk7XG4gICAgICAgIGNvbnN0IGNvbmZpZ3VyYXRvciA9IHRoaXMuZWRpdG9yKCk7XG4gICAgICAgIGNvbnN0IG9yZGVyRGF0YSA9IHRoaXMub3JkZXJJdGVtKCk7XG5cbiAgICAgICAgY29uc3QgaW5kZXhlc1RvU3VibWl0ID0gdGhpcy5pdGVtcy5jb250cm9sc1xuICAgICAgICAgICAgLm1hcCgoXywgaW5kZXgpID0+IGluZGV4KVxuICAgICAgICAgICAgLmZpbHRlcigoaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdGF0ZSA9IHRoaXMuZ2V0SXRlbVN0YXRlKGluZGV4KTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBzdGF0ZSAhPT0gJ3N1Y2Nlc3MnICYmIHN0YXRlICE9PSAnbG9hZGluZyc7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICBpZiAoaW5kZXhlc1RvU3VibWl0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8g0J/QvtC30LjRhtC40Lgg0L7RgtC/0YDQsNCy0LvRj9GO0YLRgdGPINC/0L7RgdC70LXQtNC+0LLQsNGC0LXQu9GM0L3Qvjog0LrQsNC20LTQsNGPINGB0LvQtdC00YPRjtGJ0LDRjyDigJQg0YLQvtC70YzQutC+INC/0L7RgdC70LUg0L7RgtCy0LXRgtCwINC/0YDQtdC00YvQtNGD0YnQtdC5LlxuICAgICAgICAvLyDQn9GA0Lgg0L7RiNC40LHQutC1INGG0LXQv9C+0YfQutCwINC/0YDQtdGA0YvQstCw0LXRgtGB0Y87INC00LjQsNC70L7QsyDQvdC1INC30LDQutGA0YvQstCw0LXRgtGB0Y8uXG4gICAgICAgIGZyb20oaW5kZXhlc1RvU3VibWl0KVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgY29uY2F0TWFwKChpbmRleCwgcG9zaXRpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gRWRpdGluZy3RgNC10LbQuNC8OiDQv9C10YDQstCw0Y8g0L/QvtC30LjRhtC40Y8gKGluZGV4IDApINC+0LHQvdC+0LLQu9GP0LXRgtGB0Y8sINC+0YHRgtCw0LvRjNC90YvQtSDQtNC+0LHQsNCy0LvRj9GO0YLRgdGPLlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpc0VkaXQgPSBvcmRlckRhdGEgIT0gbnVsbCAmJiBpbmRleCA9PT0gMCAmJiBwb3NpdGlvbiA9PT0gMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRJdGVtU3RhdGUoaW5kZXgsICdsb2FkaW5nJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRJdGVtUmVxdWVzdCQoaW5kZXgsIHByb2R1Y3RJZCwgcHJvZHVjdENhdGVnb3J5SWQsIGNvbmZpZ3VyYXRvciwgaXNFZGl0LCBvcmRlckRhdGEpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXAoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0SXRlbVN0YXRlKGluZGV4LCAnc3VjY2VzcycpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXRjaEVycm9yKChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlTZXJ2ZXJWYWxpZGF0aW9uRXJyb3JzKGVycm9yLCBpbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRJdGVtU3RhdGUoaW5kZXgsICdlcnJvcicpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgICAgICAgICAgY29tcGxldGU6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LiRpbXBsaWNpdC5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXREZWZhdWx0Rm9ybVZhbHVlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0KTQvtGA0LzQuNGA0YPQtdGCIEhUVFAt0LfQsNC/0YDQvtGBINC00LvRjyDQvtC00L3QvtC5INC/0L7Qt9C40YbQuNC4INGE0L7RgNC80YsuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW5kZXgg0JjQvdC00LXQutGBINC/0L7Qt9C40YbQuNC4INCyINGE0L7RgNC80LUuXG4gICAgICogQHBhcmFtIHByb2R1Y3RJZCDQmNC00LXQvdGC0LjRhNC40LrQsNGC0L7RgCDQstGL0LHRgNCw0L3QvdC+0LPQviDQv9GA0L7QtNGD0LrRgtCwLlxuICAgICAqIEBwYXJhbSBwcm9kdWN0Q2F0ZWdvcnlJZCDQmNC00LXQvdGC0LjRhNC40LrQsNGC0L7RgCDQutCw0YLQtdCz0L7RgNC40LguXG4gICAgICogQHBhcmFtIGNvbmZpZ3VyYXRvciDQndCw0LfQstCw0L3QuNC1INC60L7QvdGE0LjQs9GD0YDQsNGC0L7RgNCwLlxuICAgICAqIEBwYXJhbSBpc0VkaXQg0KDQtdC20LjQvCDQvtCx0L3QvtCy0LvQtdC90LjRjyDRgdGD0YnQtdGB0YLQstGD0Y7RidC10Lkg0L/QvtC30LjRhtC40LguXG4gICAgICogQHBhcmFtIG9yZGVyRGF0YSDQotC10LrRg9GJ0LDRjyDQv9C+0LfQuNGG0LjRjyDQt9Cw0LrQsNC30LAgKNGC0L7Qu9GM0LrQviDQsiDRgNC10LbQuNC80LUg0YDQtdC00LDQutGC0LjRgNC+0LLQsNC90LjRjykuXG4gICAgICovXG4gICAgcHJpdmF0ZSBidWlsZEl0ZW1SZXF1ZXN0JChcbiAgICAgICAgaW5kZXg6IG51bWJlcixcbiAgICAgICAgcHJvZHVjdElkOiBudW1iZXIsXG4gICAgICAgIHByb2R1Y3RDYXRlZ29yeUlkOiBudW1iZXIsXG4gICAgICAgIGNvbmZpZ3VyYXRvcjogc3RyaW5nLFxuICAgICAgICBpc0VkaXQ6IGJvb2xlYW4sXG4gICAgICAgIG9yZGVyRGF0YTogU2NPcmRlckl0ZW0gfCB1bmRlZmluZWRcbiAgICApOiBPYnNlcnZhYmxlPHVua25vd24+IHtcbiAgICAgICAgY29uc3QgaXRlbVZhbHVlID0gdGhpcy5pdGVtcy5hdChpbmRleCkuZ2V0UmF3VmFsdWUoKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IHRoaXMuY29udmVydGVyc1NlcnZpY2UucmVtb3ZlTnVsbCh7XG4gICAgICAgICAgICBwcm9kdWN0Q2F0ZWdvcnlJZCxcbiAgICAgICAgICAgIGNvbmZpZ3VyYXRvcixcbiAgICAgICAgICAgIHByb2R1Y3RJZCxcbiAgICAgICAgICAgIHdpZHRoOiBpdGVtVmFsdWUud2lkdGgsXG4gICAgICAgICAgICBsZW5ndGg6IGl0ZW1WYWx1ZS5sZW5ndGgsXG4gICAgICAgICAgICBxdWFudGl0eTogaXRlbVZhbHVlLmNvdW50LFxuICAgICAgICAgICAgbWFya2VyOiBpdGVtVmFsdWUubWFya2VyLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gaXNFZGl0ICYmIG9yZGVyRGF0YSAhPSBudWxsXG4gICAgICAgICAgICA/IHRoaXMub3JkZXJTZXJ2aWNlLnVwZGF0ZVByb2R1Y3QkKG9yZGVyRGF0YS5pZCwgcGF5bG9hZCBhcyBPbWl0PFNjSU5ld09yZGVySXRlbUJhc2UsICdwcm9kdWN0SWQnPiAmIHsgcHJvZHVjdElkPzogbnVtYmVyIH0sIHRoaXMub3JkZXJJZClcbiAgICAgICAgICAgIDogdGhpcy5vcmRlclNlcnZpY2UuYWRkUHJvZHVjdCQocGF5bG9hZCBhcyBTY0lOZXdDYXJ0SXRlbVNhbmR3aWNoTTIsIHRoaXMub3JkZXJJZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0KPRgdGC0LDQvdCw0LLQu9C40LLQsNC10YIg0L3QsNGH0LDQu9GM0L3Ri9C1INC30L3QsNGH0LXQvdC40Y8g0LTQu9GPINC/0L7Qu9C10Lkg0YTQvtGA0LzRiy5cbiAgICAgKi9cbiAgICBwcml2YXRlIHNldERlZmF1bHRGb3JtVmFsdWUoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZm9ybS5yZXNldCh7XG4gICAgICAgICAgICBwcm9kdWN0Q2F0ZWdvcnlJZDogTnVtYmVyKHRoaXMuY2F0ZWdvcnlJZCgpKSxcbiAgICAgICAgICAgIGNvbmZpZ3VyYXRvcjogdGhpcy5lZGl0b3IoKSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5pdGVtcy5jbGVhcigpO1xuXG4gICAgICAgIGNvbnN0IG9yZGVySXRlbSA9IHRoaXMub3JkZXJJdGVtKCk7XG5cbiAgICAgICAgdGhpcy5pdGVtcy5wdXNoKFxuICAgICAgICAgICAgdGhpcy5jcmVhdGVJdGVtR3JvdXAoe1xuICAgICAgICAgICAgICAgIHdpZHRoOiAob3JkZXJJdGVtPy53aWR0aCA/PyAwKSAqIDEwMDAsXG4gICAgICAgICAgICAgICAgbGVuZ3RoOiAob3JkZXJJdGVtPy5sZW5ndGggPz8gMCkgKiAxMDAwLFxuICAgICAgICAgICAgICAgIGNvdW50OiBvcmRlckl0ZW0/LnF1YW50aXR5ID8/IDEsXG4gICAgICAgICAgICAgICAgbWFya2VyOiBvcmRlckl0ZW0/Lm1hcmtlciA/PyBudWxsLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcblxuICAgICAgICB0aGlzLml0ZW1TdGF0ZXMuc2V0KHRoaXMuaXRlbXMuY29udHJvbHMubWFwKCgpID0+IElETEVfSVRFTV9TVEFURSkpO1xuICAgICAgICB0aGlzLnVwZGF0ZUl0ZW1zVmFsaWRhdG9ycygpO1xuICAgICAgICB0aGlzLmZvcm0ubWFya0FzVW50b3VjaGVkKCk7XG4gICAgfVxufVxuIiwiQGlmICghb3JkZXJJdGVtKCkgJiYgc2V0dGluZ3MoKT8uYWxsb3dTaG93VGFibGUpIHtcbiAgICA8ZGl2IGNsYXNzPVwibWItNSBmbGV4IGp1c3RpZnktY2VudGVyXCI+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR1aUJ1dHRvblxuICAgICAgICAgICAgYXBwZWFyYW5jZT1cInNlY29uZGFyeVwiXG4gICAgICAgICAgICAoY2xpY2spPVwidG9nZ2xlU2hvd0V2ZW50LmVtaXQoKVwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGljb25TdGFydD1cIkB0dWkubGF5b3V0LWxpc3RcIlxuICAgICAgICA+XG4gICAgICAgICAgICDQn9C+0LrQsNC30LDRgtGMINCyINCy0LjQtNC1INGB0L/QuNGB0LrQsFxuICAgICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbn1cbjxkaXYgY2xhc3M9XCJcIj5cbiAgICBAbGV0IHByb2R1Y3RzID0gcHJvZHVjdHMkIHwgYXN5bmM7XG4gICAgQGxldCBwcm9kdWN0VmFsdWUgPSBwcm9kdWN0LnZhbHVlO1xuXG4gICAgPGZvcm1cbiAgICAgICAgW2Zvcm1Hcm91cF09XCJmb3JtXCJcbiAgICAgICAgKG5nU3VibWl0KT1cIm9uU3VibWl0KClcIlxuICAgICAgICBTY05leHRJbnB1dEZvY3VzXG4gICAgICAgIGNsYXNzPVwiZmxleCBmbGV4LWNvbCBnYXAtMlwiXG4gICAgPlxuICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgIHR1aUxhYmVsXG4gICAgICAgICAgICBjbGFzcz1cImdyb3dcIlxuICAgICAgICA+XG4gICAgICAgICAgICDQotC+0LLQsNGAXG4gICAgICAgICAgICA8dHVpLXRleHRmaWVsZFxuICAgICAgICAgICAgICAgIHR1aUNoZXZyb25cbiAgICAgICAgICAgICAgICBbdHVpVGV4dGZpZWxkQ2xlYW5lcl09XCJmYWxzZVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgIHR1aUNoZXZyb25cbiAgICAgICAgICAgICAgICAgICAgdHVpU2VsZWN0XG4gICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJwcm9kdWN0XCJcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCLQktGL0LHQtdGA0LjRgtC1INC80LDRgtC10YDQuNCw0LtcIlxuICAgICAgICAgICAgICAgIC8+XG5cbiAgICAgICAgICAgICAgICA8dHVpLWRhdGEtbGlzdC13cmFwcGVyXG4gICAgICAgICAgICAgICAgICAgICp0dWlUZXh0ZmllbGREcm9wZG93blxuICAgICAgICAgICAgICAgICAgICBuZXdcbiAgICAgICAgICAgICAgICAgICAgW2l0ZW1zXT1cInByb2R1Y3RzXCJcbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgPC90dWktdGV4dGZpZWxkPlxuICAgICAgICAgICAgPHR1aS1lcnJvclxuICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJwcm9kdWN0XCJcbiAgICAgICAgICAgICAgICBbZXJyb3JdPVwiW10gfCB0dWlGaWVsZEVycm9yIHwgYXN5bmNcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgPC9sYWJlbD5cblxuICAgICAgICBAaWYgKHByb2R1Y3RWYWx1ZSAmJiBwcm9kdWN0VmFsdWUuY29zdFJ1YiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiLW10LTEgdGV4dC1zbSB0ZXh0LXR1aS10ZXh0LXNlY29uZGFyeVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZm9udC1ib2xkXCI+e3sgcHJvZHVjdFZhbHVlLmNvZGUgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAg4oCUXG4gICAgICAgICAgICAgICAge3sgcHJvZHVjdFZhbHVlLmNvc3RSdWIudG9Mb2NhbGVTdHJpbmcoKSB9fSB7eyBwcm9kdWN0VmFsdWUuY3VycmVuY3kuc3ltYm9sIH19L9C8wrJcbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG5cbiAgICAgICAgQGlmIChwcm9kdWN0VmFsdWUpIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC00IG1iLTMgZmxleCBmbGV4LWNvbCBnYXAtMS41XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctZnVsbCBmb250LWJvbGRcIj7QoNCw0LfQvNC10YDRiyDQuNC30LTQtdC70LjQuTwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIGdhcC0xIHRleHQtc20gdGV4dC10dWktdGV4dC1zZWNvbmRhcnlcIj5cbiAgICAgICAgICAgICAgICAgICAgQGxldCB3dCA9IHdpZHRoUmFuZ2VUZXh0KCk7XG4gICAgICAgICAgICAgICAgICAgIEBsZXQgbHQgPSBsZW5ndGhSYW5nZVRleHQoKTtcbiAgICAgICAgICAgICAgICAgICAgQGlmICh3dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj7QqNC40YDQuNC90LAge3sgd3QgfX0uPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGlmIChsdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj7QlNC70LjQvdCwIHt7IGx0IH19LjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIGdhcC0zXCI+XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgZm9ybUFycmF5TmFtZT1cIml0ZW1zXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXggZmxleC1jb2wgZ2FwLTNcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIEBmb3IgKGl0ZW0gb2YgaXRlbXMuY29udHJvbHM7IHRyYWNrIGl0ZW0pIHtcbiAgICAgICAgICAgICAgICAgICAgQGlmICgkaW5kZXggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8aHIgY2xhc3M9XCJib3JkZXItc2MtZ3JleSBoLXB4XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAbGV0IGl0ZW1JbmRleCA9ICRpbmRleDtcbiAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJyZWxhdGl2ZSBmbGV4IGZsZXgtY29sIGdhcC0xXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtR3JvdXBOYW1lXT1cIml0ZW1JbmRleFwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoaXNJdGVtTG9ja2VkKGl0ZW1JbmRleCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9pbnRlci1ldmVudHMtbm9uZSBhYnNvbHV0ZSByaWdodC0zIGJvdHRvbS0wIHotMTAgZmxleCBzaXplLTggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0dWktaWNvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvbj1cIkB0dWkuY2hlY2tcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LXR1aS1zdGF0dXMtcG9zaXRpdmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgPHR1aS1sb2FkZXIgW3Nob3dMb2FkZXJdPVwiaXNJdGVtTG9hZGluZyhpdGVtSW5kZXgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3Mub3BhY2l0eS03MF09XCJpc0l0ZW1Mb2NrZWQoaXRlbUluZGV4KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxleCBtaW4tdy0wIGl0ZW1zLXN0YXJ0IGdhcC0yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IG1pbi13LTAgZmxleC0xIGZsZXgtY29sIGdhcC0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBnYXAtMyBsZzohZmxleC1yb3cgbGc6IWl0ZW1zLXN0YXJ0IGxnOiFnYXAtNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0g0JPRgNGD0L/Qv9CwIDE6INGI0LjRgNC40L3QsCArINC00LvQuNC90LAgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQgZ3JpZC1jb2xzLTEgZ2FwLTIgc206Z3JpZC1jb2xzLTIgbGc6IWZsZXgtWzJdXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCB0dWlMYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgINCo0LjRgNC40L3QsCwg0LzQvFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHR1aS10ZXh0ZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR1aUlucHV0U2xpZGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cIndpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21pbl09XCJzZXR0aW5ncygpPy5taW5XaWR0aCA/PyAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21heF09XCJwcm9kdWN0LnZhbHVlPy5wcm9wZXJ0aWVzPy53aWR0aCA/PyAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3R1aU51bWJlckZvcm1hdF09XCJ7IHByZWNpc2lvbjogMCB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JlYWRPbmx5XT1cIiFwcm9kdWN0LnZhbHVlIHx8IGlzSXRlbUxvY2tlZChpdGVtSW5kZXgpIHx8IGlzSXRlbUxvYWRpbmcoaXRlbUluZGV4KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0dWlBdXRvRm9jdXNdPVwiISRmaXJzdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwi0KjQuNGA0LjQvdCwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAocHJvZHVjdC52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR1aVNsaWRlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInJhbmdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3R1aS10ZXh0ZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHVpLWVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwid2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtlcnJvcl09XCJbXSB8IHR1aUZpZWxkRXJyb3IgfCBhc3luY1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCB0dWlMYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgINCU0LvQuNC90LAsINC80LxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0dWktdGV4dGZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0dWlJbnB1dFNsaWRlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJsZW5ndGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWluXT1cInNldHRpbmdzKCk/Lm1pbkxlbmd0aCA/PyAwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21heF09XCJwcm9kdWN0LnZhbHVlPy5wcm9wZXJ0aWVzPy5sZW5ndGggPz8gMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0dWlOdW1iZXJGb3JtYXRdPVwieyBwcmVjaXNpb246IDAgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZWFkT25seV09XCIhcHJvZHVjdC52YWx1ZSB8fCBpc0l0ZW1Mb2NrZWQoaXRlbUluZGV4KSB8fCBpc0l0ZW1Mb2FkaW5nKGl0ZW1JbmRleClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cItCU0LvQuNC90LBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChwcm9kdWN0LnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHVpU2xpZGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwicmFuZ2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHVpLXRleHRmaWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0dWktZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJsZW5ndGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtlcnJvcl09XCJbXSB8IHR1aUZpZWxkRXJyb3IgfCBhc3luY1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSDQk9GA0YPQv9C/0LAgMjog0LrQvtC70LjRh9C10YHRgtCy0L4gKyDQvNCw0YDQutC40YDQvtCy0LrQsCAo0L3QsCBsZyAxZnIgfCAyZnIpIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncmlkIGdyaWQtY29scy0xIGdhcC0yIHNtOmdyaWQtY29scy0yIGxnOiFncmlkLWNvbHMtWzFmcl8yZnJdIGxnOiFmbGV4LVszXVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgdHVpTGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIndoaXRlc3BhY2Utbm93cmFwXCI+0JrQvtC70LjRh9C10YHRgtCy0L4sINGI0YI8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHVpLXRleHRmaWVsZCBbdHVpVGV4dGZpZWxkQ2xlYW5lcl09XCJmYWxzZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0dWlJbnB1dE51bWJlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJjb3VudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttaW5dPVwiMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0dWlOdW1iZXJGb3JtYXRdPVwieyBwcmVjaXNpb246IDAgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZWFkT25seV09XCIhcHJvZHVjdC52YWx1ZSB8fCBpc0l0ZW1Mb2NrZWQoaXRlbUluZGV4KSB8fCBpc0l0ZW1Mb2FkaW5nKGl0ZW1JbmRleClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cItCa0L7Qu9C40YfQtdGB0YLQstC+XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90dWktdGV4dGZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHR1aS1lcnJvclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cImNvdW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZXJyb3JdPVwiW10gfCB0dWlGaWVsZEVycm9yIHwgYXN5bmNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgdHVpTGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDQnNCw0YDQutC40YDQvtCy0LrQsFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHR1aS10ZXh0ZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR1aVRleHRmaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJtYXJrZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcmVhZE9ubHldPVwiIXByb2R1Y3QudmFsdWUgfHwgaXNJdGVtTG9ja2VkKGl0ZW1JbmRleCkgfHwgaXNJdGVtTG9hZGluZyhpdGVtSW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCLQnNCw0YDQutC40YDQvtCy0LrQsFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9jb21wbGV0ZT1cIm9mZlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHVpLXRleHRmaWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0dWktZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJtYXJrZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtlcnJvcl09XCJbXSB8IHR1aUZpZWxkRXJyb3IgfCBhc3luY1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBsZXQgcm93VmFsID0gaXRlbS5nZXRSYXdWYWx1ZSgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKHJvd1ZhbC53aWR0aCA+IDAgJiYgcm93VmFsLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMSBmbGV4IGZsZXgtY29sIGdhcC15LTEgdGV4dC1zbSBsZzohZmxleC1yb3cgbGc6IWdhcC02XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAocGllY2VBcmVhTTIocm93VmFsKSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsZzohZmxleC1bMl1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDQn9C70L7RidCw0LTRjCAoUykgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZm9udC1ib2xkXCI+e3sgcGllY2VBcmVhTTIocm93VmFsKSB8IG51bWJlcjogJzEuMC00JyB9fSDQvMKyPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChwcm9kdWN0VmFsdWUgJiYgcm93Q29zdChyb3dWYWwpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxnOiFmbGV4LVszXVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgINCY0YLQvtCz0L46XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmb250LWJvbGRcIj57eyByb3dDb3N0KHJvd1ZhbCkudG9Mb2NhbGVTdHJpbmcoKSB9fSB7eyBwcm9kdWN0VmFsdWUuY3VycmVuY3kuc3ltYm9sIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmICghaXNFZGl0aW5nRXhpc3RpbmdJdGVtKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0dWlJY29uQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCLQo9C00LDQu9C40YLRjCDQuNC30LTQtdC70LjQtVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJlbW92ZUl0ZW0oaXRlbUluZGV4KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIml0ZW1zLmxlbmd0aCA8PSAxIHx8ICFwcm9kdWN0LnZhbHVlIHx8IGlzSXRlbUxvYWRpbmcoaXRlbUluZGV4KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT1cIm1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljb25TdGFydD1cIkB0dWkudHJhc2gtMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZWFyYW5jZT1cInNlY29uZGFyeVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtdC02IHNocmluay0wIGxnOiFtbC00XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUuZmxleF09XCInMCAwIGF1dG8nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90dWktbG9hZGVyPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgQGlmIChwcm9kdWN0VmFsdWUpIHtcbiAgICAgICAgICAgICAgICA8aHIgY2xhc3M9XCJib3JkZXItc2MtZ3JleSBoLXB4XCIgLz5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWluLXctMCBnYXAtMSBwdC0yIHRleHQtcmlnaHRcIj5cbiAgICAgICAgICAgICAgICAgICAgQGlmICh0b3RhbEFyZWFNMigpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICDQntCx0YnQsNGPINC/0LvQvtGJ0LDQtNGMOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZm9udC1ib2xkXCI+e3sgdG90YWxBcmVhTTIoKSB8IG51bWJlcjogJzEuMC00JyB9fSDQvMKyPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGlmIChwcm9kdWN0VmFsdWUuY29zdFJ1YiAmJiB0b3RhbENvc3QoKSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAg0JjRgtC+0LPQvjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIndoaXRlc3BhY2Utbm93cmFwIHRleHQteGwgZm9udC1ib2xkXCI+IHt7IHRvdGFsQ29zdCgpLnRvTG9jYWxlU3RyaW5nKCkgfX0ge3sgcHJvZHVjdFZhbHVlLmN1cnJlbmN5LnN5bWJvbCB9fSA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8dHVpLWVycm9yIFtlcnJvcl09XCJbXSB8IHR1aUZpZWxkRXJyb3IgfCBhc3luY1wiIC8+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC13cmFwIGl0ZW1zLWNlbnRlciBnYXAtM1wiPlxuICAgICAgICAgICAgQGlmIChwcm9kdWN0VmFsdWUgJiYgIWlzRWRpdGluZ0V4aXN0aW5nSXRlbSgpKSB7XG4gICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICB0dWlCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgYXBwZWFyYW5jZT1cInNlY29uZGFyeVwiXG4gICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhcHJvZHVjdC52YWx1ZSB8fCBpdGVtcy5pbnZhbGlkXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImFkZEl0ZW0oKVwiXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBpY29uU3RhcnQ9XCJAdHVpLnBsdXNcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAg0JTQvtCx0LDQstC40YLRjCDQuNC30LTQtdC70LjQtVxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIHR5cGU9XCJzdWJtaXRcIlxuICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJmb3JtLmludmFsaWQgfHwgaXNTdWJtaXRMb2FkaW5nKCkgfHwgaGFzTm9QZW5kaW5nSXRlbXMoKVwiXG4gICAgICAgICAgICAgICAgW2xvYWRpbmddPVwiaXNTdWJtaXRMb2FkaW5nKClcIlxuICAgICAgICAgICAgICAgIHR1aUJ1dHRvblxuICAgICAgICAgICAgICAgIGNsYXNzPVwibWwtYXV0b1wiXG4gICAgICAgICAgICAgICAgaWNvblN0YXJ0PVwiQHR1aS5jaGVja1wiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAge3sgIW9yZGVySXRlbSgpID8gJ9CSINC60L7RgNC30LjQvdGDJyA6ICfQmNC30LzQtdC90LjRgtGMJyB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZm9ybT5cbjwvZGl2PlxuIl19