@eqproject/eqp-dynamic-module 2.8.7 → 3.0.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 (293) hide show
  1. package/{esm2020 → esm2022}/eqproject-eqp-dynamic-module.mjs +4 -4
  2. package/esm2022/lib/components/exported/eqp-dynamic-module/eqp-dynamic-module.component.mjs +531 -0
  3. package/esm2022/lib/components/exported/eqp-dynamic-module-configurator/eqp-dynamic-module-configurator.component.mjs +1245 -0
  4. package/esm2022/lib/components/private/add-form-field/add-form-field.component.mjs +1263 -0
  5. package/esm2022/lib/components/private/add-formula-field/add-formula-field.component.mjs +200 -0
  6. package/esm2022/lib/components/private/dbgetter/dbgetter.component.mjs +233 -0
  7. package/esm2022/lib/components/private/dynamic-module-field-fix/dynamic-module-field.component.mjs +280 -0
  8. package/esm2022/lib/components/private/field-templates/attachment-field-template/attachment-field-template.component.mjs +143 -0
  9. package/esm2022/lib/components/private/field-templates/boolean-field-template/boolean-field-template.component.mjs +75 -0
  10. package/esm2022/lib/components/private/field-templates/date-field-template/date-field-template.component.mjs +106 -0
  11. package/esm2022/lib/components/private/field-templates/image-field-selector-template/image-field-selector-template.component.mjs +107 -0
  12. package/esm2022/lib/components/private/field-templates/image-field-template/image-field-template.component.mjs +265 -0
  13. package/esm2022/lib/components/private/field-templates/image-with-markers-field-template/image-with-markers-field-template.component.mjs +261 -0
  14. package/esm2022/lib/components/private/field-templates/label-field-template/label-field-template.component.mjs +82 -0
  15. package/esm2022/lib/components/private/field-templates/list-value-field-template/list-value-field-template.component.mjs +176 -0
  16. package/esm2022/lib/components/private/field-templates/numeric-field-template/numeric-field-template.component.mjs +129 -0
  17. package/esm2022/lib/components/private/field-templates/text-field-template/text-field-template.component.mjs +103 -0
  18. package/esm2022/lib/components/private/field-templates/textarea-field-template/textarea-field-template.component.mjs +78 -0
  19. package/esm2022/lib/components/private/form-records/add-form-record/add-form-record.component.mjs +837 -0
  20. package/esm2022/lib/components/private/form-records/list-form-record/list-form-record.component.mjs +408 -0
  21. package/esm2022/lib/components/private/form-records/list-view-form-record/list-view-form-record.component.mjs +651 -0
  22. package/esm2022/lib/components/private/form-records/list-view-form-record/single-record/single-record.component.mjs +82 -0
  23. package/esm2022/lib/components/private/form-records/repair-form-fields/repair-form-fields.component.mjs +59 -0
  24. package/esm2022/lib/components/private/form-records/view-form-record/view-form-record.component.mjs +131 -0
  25. package/esm2022/lib/components/private/form-statistics/dynamic-module-filter-fix/dynamic-module-filter-fix.component.mjs +89 -0
  26. package/esm2022/lib/components/private/form-statistics/filter-form-statistic/filter-form-statistic.component.mjs +460 -0
  27. package/esm2022/lib/components/private/form-statistics/filter-templates/attachment-filter-template/attachment-filter-template.component.mjs +58 -0
  28. package/esm2022/lib/components/private/form-statistics/filter-templates/boolean-filter-template/boolean-filter-template.component.mjs +110 -0
  29. package/esm2022/lib/components/private/form-statistics/filter-templates/date-filter-template/date-filter-template.component.mjs +108 -0
  30. package/esm2022/lib/components/private/form-statistics/filter-templates/image-filter-template/image-filter-template.component.mjs +58 -0
  31. package/esm2022/lib/components/private/form-statistics/filter-templates/image-selector-filter-template/image-selector-filter-template.component.mjs +135 -0
  32. package/esm2022/lib/components/private/form-statistics/filter-templates/list-form-record-filter-template/list-form-record-filter-template.component.mjs +58 -0
  33. package/esm2022/lib/components/private/form-statistics/filter-templates/list-value-filter-template/list-value-filter-template.component.mjs +141 -0
  34. package/esm2022/lib/components/private/form-statistics/filter-templates/numeric-filter-template/numeric-filter-template.component.mjs +126 -0
  35. package/esm2022/lib/components/private/form-statistics/filter-templates/text-filter-template/text-filter-template.component.mjs +111 -0
  36. package/esm2022/lib/components/private/form-statistics/filter-templates/textarea-filter-template/textarea-filter-template.component.mjs +111 -0
  37. package/esm2022/lib/components/private/graphs/graph/graph.component.mjs +186 -0
  38. package/esm2022/lib/components/private/graphs/graphs.component.mjs +175 -0
  39. package/esm2022/lib/components/private/spinner/spinner.component.mjs +21 -0
  40. package/{esm2020 → esm2022}/lib/components/private/tmw-image-drawer/i18n.mjs +62 -62
  41. package/esm2022/lib/components/private/tmw-image-drawer/tmw-image-drawer.component.mjs +413 -0
  42. package/esm2022/lib/components/private/tmw-image-marker/tmw-image-marker.component.mjs +348 -0
  43. package/esm2022/lib/components/private/trigger-creator/dynamic-module-trigger-fix/dynamic-module-trigger-fix.component.mjs +81 -0
  44. package/esm2022/lib/components/private/trigger-creator/trigger-creator.component.mjs +199 -0
  45. package/esm2022/lib/components/private/trigger-creator/trigger-templates/boolean-trigger-template/boolean-trigger-template.component.mjs +91 -0
  46. package/esm2022/lib/components/private/trigger-creator/trigger-templates/date-trigger-template/date-trigger-template.component.mjs +88 -0
  47. package/esm2022/lib/components/private/trigger-creator/trigger-templates/list-form-record-trigger-template/list-form-record-trigger-template.component.mjs +61 -0
  48. package/esm2022/lib/components/private/trigger-creator/trigger-templates/list-value-trigger-template/list-value-trigger-template.component.mjs +69 -0
  49. package/esm2022/lib/components/private/trigger-creator/trigger-templates/numeric-trigger-template/numeric-trigger-template.component.mjs +107 -0
  50. package/esm2022/lib/components/private/trigger-creator/trigger-templates/text-trigger-template/text-trigger-template.component.mjs +92 -0
  51. package/esm2022/lib/components/private/trigger-creator/trigger-templates/textarea-trigger-template/textarea-trigger-template.component.mjs +92 -0
  52. package/esm2022/lib/directives/dynamic-loader/dynamic-loader.directive.mjs +63 -0
  53. package/esm2022/lib/directives/speech-to-text/speech-to-text.directive.mjs +192 -0
  54. package/esm2022/lib/eqp-dynamic-module.module.mjs +253 -0
  55. package/{esm2020 → esm2022}/lib/interfaces/iBaseFieldComponent.interface.mjs +1 -1
  56. package/{esm2020 → esm2022}/lib/interfaces/iRootObject.interface.mjs +1 -1
  57. package/esm2022/lib/models/baseField.model.mjs +133 -0
  58. package/esm2022/lib/models/baseObj.model.mjs +10 -0
  59. package/{esm2020 → esm2022}/lib/models/context.model.mjs +10 -8
  60. package/esm2022/lib/models/dynAttachment.mjs +52 -0
  61. package/esm2022/lib/models/dynamicModuleCompileConfig.model.mjs +45 -0
  62. package/esm2022/lib/models/dynamicModuleConfig.model.mjs +13 -0
  63. package/esm2022/lib/models/dynamicModuleConfiguratorConfig.model.mjs +11 -0
  64. package/esm2022/lib/models/dynamicModuleConfiguratorSpecificConfig.model.mjs +16 -0
  65. package/{esm2020 → esm2022}/lib/models/dynamicModuleFilterResultViewModeEnum.model.mjs +6 -6
  66. package/esm2022/lib/models/dynamicModuleGeneralConfig.model.mjs +36 -0
  67. package/esm2022/lib/models/dynamicModuleListConfig.model.mjs +48 -0
  68. package/esm2022/lib/models/dynamicModuleListFormRecordActionsDefault.mjs +35 -0
  69. package/{esm2020 → esm2022}/lib/models/dynamicModuleRepairConfig.model.mjs +10 -10
  70. package/{esm2020 → esm2022}/lib/models/dynamicModuleViewModeEnum.mjs +11 -11
  71. package/esm2022/lib/models/endPointConfiguration.model.mjs +211 -0
  72. package/{esm2020 → esm2022}/lib/models/entity.model.mjs +10 -7
  73. package/esm2022/lib/models/fields/attachmentField.model.mjs +28 -0
  74. package/esm2022/lib/models/fields/booleanField.model.mjs +15 -0
  75. package/esm2022/lib/models/fields/dateField.model.mjs +15 -0
  76. package/esm2022/lib/models/fields/imageField.model.mjs +14 -0
  77. package/esm2022/lib/models/fields/imageSelectorField.model.mjs +10 -0
  78. package/esm2022/lib/models/fields/imageWithMarkersField.model.mjs +7 -0
  79. package/{esm2020 → esm2022}/lib/models/fields/labelField.model.mjs +5 -4
  80. package/esm2022/lib/models/fields/listValueField.model.mjs +24 -0
  81. package/esm2022/lib/models/fields/lookupField.model.mjs +11 -0
  82. package/esm2022/lib/models/fields/numericField.model.mjs +13 -0
  83. package/esm2022/lib/models/fields/textField.model.mjs +18 -0
  84. package/esm2022/lib/models/fields/textareaField.model.mjs +9 -0
  85. package/esm2022/lib/models/form.model.mjs +63 -0
  86. package/esm2022/lib/models/getter.model.mjs +6 -0
  87. package/esm2022/lib/models/graph.model.mjs +19 -0
  88. package/{esm2020 → esm2022}/lib/models/logicOperator.model.mjs +55 -55
  89. package/esm2022/lib/models/record.model.mjs +39 -0
  90. package/esm2022/lib/models/statistic.model.mjs +12 -0
  91. package/esm2022/lib/models/trigger.model.mjs +63 -0
  92. package/esm2022/lib/modules/formula.model.mjs +266 -0
  93. package/{esm2020 → esm2022}/lib/modules/material.module.mjs +231 -231
  94. package/{esm2020 → esm2022}/lib/services/custom-form-validators.service.mjs +18 -18
  95. package/esm2022/lib/services/db-date.service.mjs +178 -0
  96. package/esm2022/lib/services/eqp-dynamic-module-dialog.service.mjs +114 -0
  97. package/esm2022/lib/services/global.service.mjs +43 -0
  98. package/esm2022/lib/services/spinner.service.mjs +41 -0
  99. package/esm2022/lib/services/utilityHelper.services.mjs +601 -0
  100. package/{esm2020 → esm2022}/public-api.mjs +56 -56
  101. package/fesm2022/eqproject-eqp-dynamic-module.mjs +13506 -0
  102. package/fesm2022/eqproject-eqp-dynamic-module.mjs.map +1 -0
  103. package/index.d.ts +5 -5
  104. package/lib/components/exported/eqp-dynamic-module/eqp-dynamic-module.component.d.ts +162 -162
  105. package/lib/components/exported/eqp-dynamic-module-configurator/eqp-dynamic-module-configurator.component.d.ts +308 -308
  106. package/lib/components/private/add-form-field/add-form-field.component.d.ts +263 -263
  107. package/lib/components/private/add-formula-field/add-formula-field.component.d.ts +45 -45
  108. package/lib/components/private/dbgetter/dbgetter.component.d.ts +51 -51
  109. package/lib/components/private/dynamic-module-field-fix/dynamic-module-field.component.d.ts +84 -84
  110. package/lib/components/private/field-templates/attachment-field-template/attachment-field-template.component.d.ts +57 -57
  111. package/lib/components/private/field-templates/boolean-field-template/boolean-field-template.component.d.ts +27 -27
  112. package/lib/components/private/field-templates/date-field-template/date-field-template.component.d.ts +36 -36
  113. package/lib/components/private/field-templates/image-field-selector-template/image-field-selector-template.component.d.ts +33 -33
  114. package/lib/components/private/field-templates/image-field-template/image-field-template.component.d.ts +80 -80
  115. package/lib/components/private/field-templates/image-with-markers-field-template/image-with-markers-field-template.component.d.ts +78 -78
  116. package/lib/components/private/field-templates/label-field-template/label-field-template.component.d.ts +33 -33
  117. package/lib/components/private/field-templates/list-value-field-template/list-value-field-template.component.d.ts +59 -59
  118. package/lib/components/private/field-templates/numeric-field-template/numeric-field-template.component.d.ts +40 -40
  119. package/lib/components/private/field-templates/text-field-template/text-field-template.component.d.ts +35 -35
  120. package/lib/components/private/field-templates/textarea-field-template/textarea-field-template.component.d.ts +31 -31
  121. package/lib/components/private/form-records/add-form-record/add-form-record.component.d.ts +104 -104
  122. package/lib/components/private/form-records/list-form-record/list-form-record.component.d.ts +83 -83
  123. package/lib/components/private/form-records/list-view-form-record/list-view-form-record.component.d.ts +151 -151
  124. package/lib/components/private/form-records/list-view-form-record/single-record/single-record.component.d.ts +39 -39
  125. package/lib/components/private/form-records/repair-form-fields/repair-form-fields.component.d.ts +20 -20
  126. package/lib/components/private/form-records/view-form-record/view-form-record.component.d.ts +36 -36
  127. package/lib/components/private/form-statistics/dynamic-module-filter-fix/dynamic-module-filter-fix.component.d.ts +42 -42
  128. package/lib/components/private/form-statistics/filter-form-statistic/filter-form-statistic.component.d.ts +109 -109
  129. package/lib/components/private/form-statistics/filter-templates/attachment-filter-template/attachment-filter-template.component.d.ts +21 -21
  130. package/lib/components/private/form-statistics/filter-templates/boolean-filter-template/boolean-filter-template.component.d.ts +37 -37
  131. package/lib/components/private/form-statistics/filter-templates/date-filter-template/date-filter-template.component.d.ts +37 -37
  132. package/lib/components/private/form-statistics/filter-templates/image-filter-template/image-filter-template.component.d.ts +21 -21
  133. package/lib/components/private/form-statistics/filter-templates/image-selector-filter-template/image-selector-filter-template.component.d.ts +47 -47
  134. package/lib/components/private/form-statistics/filter-templates/list-form-record-filter-template/list-form-record-filter-template.component.d.ts +21 -21
  135. package/lib/components/private/form-statistics/filter-templates/list-value-filter-template/list-value-filter-template.component.d.ts +47 -47
  136. package/lib/components/private/form-statistics/filter-templates/numeric-filter-template/numeric-filter-template.component.d.ts +40 -40
  137. package/lib/components/private/form-statistics/filter-templates/text-filter-template/text-filter-template.component.d.ts +38 -38
  138. package/lib/components/private/form-statistics/filter-templates/textarea-filter-template/textarea-filter-template.component.d.ts +38 -38
  139. package/lib/components/private/graphs/graph/graph.component.d.ts +25 -25
  140. package/lib/components/private/graphs/graphs.component.d.ts +47 -47
  141. package/lib/components/private/spinner/spinner.component.d.ts +12 -12
  142. package/lib/components/private/tmw-image-drawer/i18n.d.ts +27 -27
  143. package/lib/components/private/tmw-image-drawer/tmw-image-drawer.component.d.ts +70 -70
  144. package/lib/components/private/tmw-image-marker/tmw-image-marker.component.d.ts +62 -62
  145. package/lib/components/private/trigger-creator/dynamic-module-trigger-fix/dynamic-module-trigger-fix.component.d.ts +42 -42
  146. package/lib/components/private/trigger-creator/trigger-creator.component.d.ts +42 -42
  147. package/lib/components/private/trigger-creator/trigger-templates/boolean-trigger-template/boolean-trigger-template.component.d.ts +34 -34
  148. package/lib/components/private/trigger-creator/trigger-templates/date-trigger-template/date-trigger-template.component.d.ts +34 -34
  149. package/lib/components/private/trigger-creator/trigger-templates/list-form-record-trigger-template/list-form-record-trigger-template.component.d.ts +24 -24
  150. package/lib/components/private/trigger-creator/trigger-templates/list-value-trigger-template/list-value-trigger-template.component.d.ts +34 -34
  151. package/lib/components/private/trigger-creator/trigger-templates/numeric-trigger-template/numeric-trigger-template.component.d.ts +37 -37
  152. package/lib/components/private/trigger-creator/trigger-templates/text-trigger-template/text-trigger-template.component.d.ts +36 -36
  153. package/lib/components/private/trigger-creator/trigger-templates/textarea-trigger-template/textarea-trigger-template.component.d.ts +36 -36
  154. package/lib/directives/dynamic-loader/dynamic-loader.directive.d.ts +26 -26
  155. package/lib/directives/speech-to-text/speech-to-text.directive.d.ts +31 -31
  156. package/lib/eqp-dynamic-module.module.d.ts +85 -85
  157. package/lib/interfaces/iBaseFieldComponent.interface.d.ts +8 -8
  158. package/lib/interfaces/iRootObject.interface.d.ts +11 -11
  159. package/lib/models/baseField.model.d.ts +126 -126
  160. package/lib/models/baseObj.model.d.ts +9 -9
  161. package/lib/models/context.model.d.ts +9 -9
  162. package/lib/models/dynAttachment.d.ts +49 -49
  163. package/lib/models/dynamicModuleCompileConfig.model.d.ts +35 -35
  164. package/lib/models/dynamicModuleConfig.model.d.ts +11 -11
  165. package/lib/models/dynamicModuleConfiguratorConfig.model.d.ts +7 -7
  166. package/lib/models/dynamicModuleConfiguratorSpecificConfig.model.d.ts +11 -11
  167. package/lib/models/dynamicModuleFilterResultViewModeEnum.model.d.ts +5 -5
  168. package/lib/models/dynamicModuleGeneralConfig.model.d.ts +29 -29
  169. package/lib/models/dynamicModuleListConfig.model.d.ts +39 -39
  170. package/lib/models/dynamicModuleListFormRecordActionsDefault.d.ts +9 -9
  171. package/lib/models/dynamicModuleRepairConfig.model.d.ts +4 -4
  172. package/lib/models/dynamicModuleViewModeEnum.d.ts +10 -10
  173. package/lib/models/endPointConfiguration.model.d.ts +46 -46
  174. package/lib/models/entity.model.d.ts +11 -11
  175. package/lib/models/fields/attachmentField.model.d.ts +17 -17
  176. package/lib/models/fields/booleanField.model.d.ts +11 -11
  177. package/lib/models/fields/dateField.model.d.ts +13 -13
  178. package/lib/models/fields/imageField.model.d.ts +13 -13
  179. package/lib/models/fields/imageSelectorField.model.d.ts +12 -12
  180. package/lib/models/fields/imageWithMarkersField.model.d.ts +7 -7
  181. package/lib/models/fields/labelField.model.d.ts +4 -4
  182. package/lib/models/fields/listValueField.model.d.ts +24 -24
  183. package/lib/models/fields/lookupField.model.d.ts +10 -10
  184. package/lib/models/fields/numericField.model.d.ts +12 -12
  185. package/lib/models/fields/textField.model.d.ts +16 -16
  186. package/lib/models/fields/textareaField.model.d.ts +8 -8
  187. package/lib/models/form.model.d.ts +61 -61
  188. package/lib/models/getter.model.d.ts +5 -5
  189. package/lib/models/graph.model.d.ts +18 -18
  190. package/lib/models/logicOperator.model.d.ts +48 -48
  191. package/lib/models/record.model.d.ts +41 -41
  192. package/lib/models/statistic.model.d.ts +13 -13
  193. package/lib/models/trigger.model.d.ts +51 -51
  194. package/lib/modules/formula.model.d.ts +32 -32
  195. package/lib/modules/material.module.d.ts +37 -37
  196. package/lib/services/custom-form-validators.service.d.ts +5 -5
  197. package/lib/services/db-date.service.d.ts +24 -24
  198. package/lib/services/eqp-dynamic-module-dialog.service.d.ts +44 -44
  199. package/lib/services/global.service.d.ts +16 -16
  200. package/lib/services/spinner.service.d.ts +18 -18
  201. package/lib/services/utilityHelper.services.d.ts +101 -101
  202. package/package.json +20 -25
  203. package/public-api.d.ts +53 -53
  204. package/esm2020/lib/components/exported/eqp-dynamic-module/eqp-dynamic-module.component.mjs +0 -516
  205. package/esm2020/lib/components/exported/eqp-dynamic-module-configurator/eqp-dynamic-module-configurator.component.mjs +0 -1196
  206. package/esm2020/lib/components/private/add-form-field/add-form-field.component.mjs +0 -1202
  207. package/esm2020/lib/components/private/add-formula-field/add-formula-field.component.mjs +0 -196
  208. package/esm2020/lib/components/private/dbgetter/dbgetter.component.mjs +0 -226
  209. package/esm2020/lib/components/private/dynamic-module-field-fix/dynamic-module-field.component.mjs +0 -263
  210. package/esm2020/lib/components/private/field-templates/attachment-field-template/attachment-field-template.component.mjs +0 -138
  211. package/esm2020/lib/components/private/field-templates/boolean-field-template/boolean-field-template.component.mjs +0 -71
  212. package/esm2020/lib/components/private/field-templates/date-field-template/date-field-template.component.mjs +0 -104
  213. package/esm2020/lib/components/private/field-templates/image-field-selector-template/image-field-selector-template.component.mjs +0 -100
  214. package/esm2020/lib/components/private/field-templates/image-field-template/image-field-template.component.mjs +0 -256
  215. package/esm2020/lib/components/private/field-templates/image-with-markers-field-template/image-with-markers-field-template.component.mjs +0 -252
  216. package/esm2020/lib/components/private/field-templates/label-field-template/label-field-template.component.mjs +0 -74
  217. package/esm2020/lib/components/private/field-templates/list-value-field-template/list-value-field-template.component.mjs +0 -172
  218. package/esm2020/lib/components/private/field-templates/numeric-field-template/numeric-field-template.component.mjs +0 -124
  219. package/esm2020/lib/components/private/field-templates/text-field-template/text-field-template.component.mjs +0 -95
  220. package/esm2020/lib/components/private/field-templates/textarea-field-template/textarea-field-template.component.mjs +0 -71
  221. package/esm2020/lib/components/private/form-records/add-form-record/add-form-record.component.mjs +0 -828
  222. package/esm2020/lib/components/private/form-records/list-form-record/list-form-record.component.mjs +0 -400
  223. package/esm2020/lib/components/private/form-records/list-view-form-record/list-view-form-record.component.mjs +0 -628
  224. package/esm2020/lib/components/private/form-records/list-view-form-record/single-record/single-record.component.mjs +0 -75
  225. package/esm2020/lib/components/private/form-records/repair-form-fields/repair-form-fields.component.mjs +0 -54
  226. package/esm2020/lib/components/private/form-records/view-form-record/view-form-record.component.mjs +0 -125
  227. package/esm2020/lib/components/private/form-statistics/dynamic-module-filter-fix/dynamic-module-filter-fix.component.mjs +0 -76
  228. package/esm2020/lib/components/private/form-statistics/filter-form-statistic/filter-form-statistic.component.mjs +0 -453
  229. package/esm2020/lib/components/private/form-statistics/filter-templates/attachment-filter-template/attachment-filter-template.component.mjs +0 -57
  230. package/esm2020/lib/components/private/form-statistics/filter-templates/boolean-filter-template/boolean-filter-template.component.mjs +0 -104
  231. package/esm2020/lib/components/private/form-statistics/filter-templates/date-filter-template/date-filter-template.component.mjs +0 -105
  232. package/esm2020/lib/components/private/form-statistics/filter-templates/image-filter-template/image-filter-template.component.mjs +0 -57
  233. package/esm2020/lib/components/private/form-statistics/filter-templates/image-selector-filter-template/image-selector-filter-template.component.mjs +0 -128
  234. package/esm2020/lib/components/private/form-statistics/filter-templates/list-form-record-filter-template/list-form-record-filter-template.component.mjs +0 -57
  235. package/esm2020/lib/components/private/form-statistics/filter-templates/list-value-filter-template/list-value-filter-template.component.mjs +0 -135
  236. package/esm2020/lib/components/private/form-statistics/filter-templates/numeric-filter-template/numeric-filter-template.component.mjs +0 -120
  237. package/esm2020/lib/components/private/form-statistics/filter-templates/text-filter-template/text-filter-template.component.mjs +0 -102
  238. package/esm2020/lib/components/private/form-statistics/filter-templates/textarea-filter-template/textarea-filter-template.component.mjs +0 -102
  239. package/esm2020/lib/components/private/graphs/graph/graph.component.mjs +0 -180
  240. package/esm2020/lib/components/private/graphs/graphs.component.mjs +0 -164
  241. package/esm2020/lib/components/private/spinner/spinner.component.mjs +0 -19
  242. package/esm2020/lib/components/private/tmw-image-drawer/tmw-image-drawer.component.mjs +0 -403
  243. package/esm2020/lib/components/private/tmw-image-marker/tmw-image-marker.component.mjs +0 -336
  244. package/esm2020/lib/components/private/trigger-creator/dynamic-module-trigger-fix/dynamic-module-trigger-fix.component.mjs +0 -69
  245. package/esm2020/lib/components/private/trigger-creator/trigger-creator.component.mjs +0 -179
  246. package/esm2020/lib/components/private/trigger-creator/trigger-templates/boolean-trigger-template/boolean-trigger-template.component.mjs +0 -86
  247. package/esm2020/lib/components/private/trigger-creator/trigger-templates/date-trigger-template/date-trigger-template.component.mjs +0 -86
  248. package/esm2020/lib/components/private/trigger-creator/trigger-templates/list-form-record-trigger-template/list-form-record-trigger-template.component.mjs +0 -60
  249. package/esm2020/lib/components/private/trigger-creator/trigger-templates/list-value-trigger-template/list-value-trigger-template.component.mjs +0 -66
  250. package/esm2020/lib/components/private/trigger-creator/trigger-templates/numeric-trigger-template/numeric-trigger-template.component.mjs +0 -102
  251. package/esm2020/lib/components/private/trigger-creator/trigger-templates/text-trigger-template/text-trigger-template.component.mjs +0 -84
  252. package/esm2020/lib/components/private/trigger-creator/trigger-templates/textarea-trigger-template/textarea-trigger-template.component.mjs +0 -84
  253. package/esm2020/lib/directives/dynamic-loader/dynamic-loader.directive.mjs +0 -59
  254. package/esm2020/lib/directives/speech-to-text/speech-to-text.directive.mjs +0 -186
  255. package/esm2020/lib/eqp-dynamic-module.module.mjs +0 -253
  256. package/esm2020/lib/models/baseField.model.mjs +0 -101
  257. package/esm2020/lib/models/baseObj.model.mjs +0 -9
  258. package/esm2020/lib/models/dynAttachment.mjs +0 -21
  259. package/esm2020/lib/models/dynamicModuleCompileConfig.model.mjs +0 -13
  260. package/esm2020/lib/models/dynamicModuleConfig.model.mjs +0 -9
  261. package/esm2020/lib/models/dynamicModuleConfiguratorConfig.model.mjs +0 -9
  262. package/esm2020/lib/models/dynamicModuleConfiguratorSpecificConfig.model.mjs +0 -15
  263. package/esm2020/lib/models/dynamicModuleGeneralConfig.model.mjs +0 -36
  264. package/esm2020/lib/models/dynamicModuleListConfig.model.mjs +0 -30
  265. package/esm2020/lib/models/dynamicModuleListFormRecordActionsDefault.mjs +0 -11
  266. package/esm2020/lib/models/endPointConfiguration.model.mjs +0 -205
  267. package/esm2020/lib/models/fields/attachmentField.model.mjs +0 -22
  268. package/esm2020/lib/models/fields/booleanField.model.mjs +0 -12
  269. package/esm2020/lib/models/fields/dateField.model.mjs +0 -15
  270. package/esm2020/lib/models/fields/imageField.model.mjs +0 -15
  271. package/esm2020/lib/models/fields/imageSelectorField.model.mjs +0 -8
  272. package/esm2020/lib/models/fields/imageWithMarkersField.model.mjs +0 -8
  273. package/esm2020/lib/models/fields/listValueField.model.mjs +0 -11
  274. package/esm2020/lib/models/fields/lookupField.model.mjs +0 -5
  275. package/esm2020/lib/models/fields/numericField.model.mjs +0 -5
  276. package/esm2020/lib/models/fields/textField.model.mjs +0 -14
  277. package/esm2020/lib/models/fields/textareaField.model.mjs +0 -4
  278. package/esm2020/lib/models/form.model.mjs +0 -24
  279. package/esm2020/lib/models/getter.model.mjs +0 -3
  280. package/esm2020/lib/models/graph.model.mjs +0 -15
  281. package/esm2020/lib/models/record.model.mjs +0 -10
  282. package/esm2020/lib/models/statistic.model.mjs +0 -8
  283. package/esm2020/lib/models/trigger.model.mjs +0 -41
  284. package/esm2020/lib/modules/formula.model.mjs +0 -265
  285. package/esm2020/lib/services/db-date.service.mjs +0 -178
  286. package/esm2020/lib/services/eqp-dynamic-module-dialog.service.mjs +0 -114
  287. package/esm2020/lib/services/global.service.mjs +0 -41
  288. package/esm2020/lib/services/spinner.service.mjs +0 -43
  289. package/esm2020/lib/services/utilityHelper.services.mjs +0 -598
  290. package/fesm2015/eqproject-eqp-dynamic-module.mjs +0 -12770
  291. package/fesm2015/eqproject-eqp-dynamic-module.mjs.map +0 -1
  292. package/fesm2020/eqproject-eqp-dynamic-module.mjs +0 -12739
  293. package/fesm2020/eqproject-eqp-dynamic-module.mjs.map +0 -1
@@ -1,598 +0,0 @@
1
- import { Injectable } from "@angular/core";
2
- import { UntypedFormControl, Validators, } from "@angular/forms";
3
- import { ColSpanSizesEnum, FieldInvisibilityEnum, FieldTypeEnum, } from "../models/baseField.model";
4
- import { Context } from "../models/context.model";
5
- import { EndPointConfiguration, ParamTypeEnum, RequestMethodEnum, } from "../models/endPointConfiguration.model";
6
- import { TextMaskEnum, TextField, UrlRegex, TelRegex, } from "../models/fields/textField.model";
7
- import { ArrayValidators } from "./custom-form-validators.service";
8
- import { EqpDynamicModuleDialogService } from "./eqp-dynamic-module-dialog.service";
9
- import * as i0 from "@angular/core";
10
- import * as i1 from "@angular/forms";
11
- import * as i2 from "@angular/common/http";
12
- import * as i3 from "./spinner.service";
13
- export class UtilityHelperService {
14
- debugLog(message, item) {
15
- if (this.debugMode) {
16
- if (item) {
17
- console.log(message, item);
18
- }
19
- else {
20
- console.log(message);
21
- }
22
- }
23
- }
24
- constructor(formBuilder, http, spinnerService) {
25
- this.formBuilder = formBuilder;
26
- this.http = http;
27
- this.spinnerService = spinnerService;
28
- this.debugMode = false;
29
- }
30
- static EvaluateFieldFormula(formula, rec, ctx) {
31
- const evaluatedValue = eval(formula);
32
- return evaluatedValue ? evaluatedValue : null;
33
- }
34
- static SetContext(ctx) {
35
- this.context = ctx;
36
- }
37
- static isNumeric(n) {
38
- return !isNaN(n);
39
- }
40
- static initStyles(stylecss) {
41
- return stylecss.split(";").reduce((a, b) => {
42
- const keypar = b.split(":");
43
- if (keypar.length > 1)
44
- a[keypar[0].trim()] = keypar[1].trim();
45
- return a;
46
- }, {});
47
- }
48
- static GetFieldType(field) {
49
- switch (field.FieldType) {
50
- case FieldTypeEnum["Campo di testo"]: {
51
- const t = Object.assign(new TextField(), field);
52
- return t;
53
- break;
54
- }
55
- default: {
56
- break;
57
- }
58
- }
59
- }
60
- /**
61
- * Metodo per impostare i valori da suggerire nell'autocomplete per i campi in cui l'utente deve scrivere comandi javascript.
62
- * In base all'ultimo carattere digitato viene impostato un elenco di oggetti o proprietà che l'utente ha a disposizione in quel momento.
63
- * @param fields Array di BaseField aggiunti alla Form
64
- * @param typedFormula Stringa digitata dall'utente
65
- * @summary Il metodo imposta i suggerimenti basandosi su 3 casi:
66
- * 1) l'utente non ha digitato nulla o la stringa digitata dall'utente finisce con uno spazio vuoto
67
- * 2) la stringa digitata dall'utente finisce con un "."
68
- * 3) la stringa digitata dall'utente non coincide con nessun altro caso sopra (finisce con un carattere qualunque)
69
- */
70
- static GetAutocompleteOptions(fields, typedFormula) {
71
- let autocompleteOptions = [];
72
- // Recupero i nomi di tutti i campi creati fino ad ora nella form.
73
- const availableRecProperties = fields.map((f) => f.Label.split(" ").join("_"));
74
- // Nel casi in cui l'utente non ha inserito nulla oppure la stringa finisce con uno spazio vuoto o un simbolo diverso da "."
75
- // (un carattere non alfanumerico) imposto come suggerimenti solo "rec" e "ctx", ovvero gli unici due oggetti a cui l'utente ha accesso.
76
- if (!typedFormula ||
77
- (!typedFormula.endsWith(".") &&
78
- new RegExp("[^0-9a-zA-Z_]").test(typedFormula.substring(typedFormula.length - 1, typedFormula.length)))) {
79
- autocompleteOptions = [
80
- { label: "rec", value: (typedFormula ? typedFormula : "") + "rec" },
81
- { label: "ctx", value: (typedFormula ? typedFormula : "") + "ctx" },
82
- ];
83
- }
84
- // Se la stringa finisce con un "." vuol dire che l'utente sta cercando di accedere ad una proprietà di un oggetto
85
- // a sua disposizione. Recupero il nome dell'ultimo oggetto digitato dall'utente e se l'oggetto scelto è "rec" o "ctx"
86
- // allora suggerisco le proprietà che esistono all'interno di questi oggetti altrimenti non mostro nulla.
87
- else if (typedFormula.endsWith(".")) {
88
- const formulaPieces = typedFormula
89
- .split(" ")[typedFormula.split(" ").length - 1].split(".");
90
- if (formulaPieces[formulaPieces.length - 2] === "rec") {
91
- autocompleteOptions = availableRecProperties.map((f) => {
92
- return { label: f, value: typedFormula + f };
93
- });
94
- }
95
- else if (formulaPieces[formulaPieces.length - 2] === "ctx") {
96
- autocompleteOptions = Object.keys(UtilityHelperService.context).map((f) => {
97
- return { label: f, value: typedFormula + f };
98
- });
99
- }
100
- else if (formulaPieces.length > 2 &&
101
- formulaPieces[formulaPieces.length - 3] === "ctx" &&
102
- formulaPieces[formulaPieces.length - 2] === "User") {
103
- autocompleteOptions = Object.keys(UtilityHelperService.context.User).map((f) => {
104
- return { label: f, value: typedFormula + f };
105
- });
106
- }
107
- else {
108
- autocompleteOptions = [];
109
- }
110
- }
111
- // In tutti gli altri casi, ovvero quando la stringa digitata finisce con un carattere diverso da quelli
112
- // controllati finora, vuol dire che l'utente sta digitanto il nome di un oggetto, una proprietà o una
113
- // funzione javascript. Controllo la parola che l'utente sta digitando e se fa parte di uno degli oggetti a disposizione
114
- // o una proprietà di essi allora suggerisco i possibili match.
115
- else {
116
- const availableOptions = [];
117
- // Prendo tutti i blocchi di caratteri digitati dall'utente
118
- const allFormulaWords = typedFormula.split(" ");
119
- // Prendo l'ultimo blocco di caratteri digitato dall'utente
120
- const lastTypedString = allFormulaWords[allFormulaWords.length - 1];
121
- // Se la l'ultima stringa digitata non contiene caratteri speciali allora splitto la stringa
122
- // sui "." e imposto i suggerimenti in base al path della prorpietà che si sta digitando.
123
- if (!new RegExp("[^0-9a-zA-Z_.]").test(lastTypedString)) {
124
- const propertyPath = lastTypedString.split(".");
125
- const lastTypedWork = propertyPath[propertyPath.length - 1];
126
- let propertiesToCheck = [];
127
- if (propertyPath.length == 1) {
128
- propertiesToCheck = ["rec", "ctx"];
129
- }
130
- else if (propertyPath.length > 1 &&
131
- propertyPath[propertyPath.length - 2] === "ctx") {
132
- propertiesToCheck = Object.keys(UtilityHelperService.context);
133
- }
134
- else if (propertyPath.length > 2 &&
135
- propertyPath[propertyPath.length - 3] === "ctx" &&
136
- propertyPath[propertyPath.length - 2] === "User") {
137
- propertiesToCheck = Object.keys(UtilityHelperService.context.User);
138
- }
139
- else if (propertyPath.length > 1 &&
140
- propertyPath[propertyPath.length - 2] === "rec") {
141
- propertiesToCheck = availableRecProperties;
142
- }
143
- // Eseguo il controllo sulle proprietà recuperate, aggiungo ai suggerimenti tutti i nomi che iniziano con
144
- // quello che sta digitando l'utente.
145
- propertiesToCheck.forEach((prop) => {
146
- if (prop.startsWith(lastTypedWork)) {
147
- availableOptions.push({
148
- label: prop,
149
- value: typedFormula +
150
- prop.substring(lastTypedWork.length, prop.length),
151
- });
152
- }
153
- });
154
- }
155
- autocompleteOptions = availableOptions;
156
- }
157
- return autocompleteOptions;
158
- }
159
- /**
160
- * Metodo invocato dall'html per impostare le classi css per visualizzare il campo all'interno della form.
161
- * Se per il field sono state specificate delle classi allora vengono applcate quelle, altrimenti vengono usate
162
- * delle classi di default.
163
- * @param field BaseField da visualizzare.
164
- * @returns Restituisce una stringa contenente le classi css da applicare.
165
- */
166
- getFieldSyleClass(field, showAllFields = false) {
167
- var colspanvalues = "";
168
- var visibilityvalues = "";
169
- if (field.ColSpanSizes && field.ColSpanSizes.length > 0) {
170
- colspanvalues = field.ColSpanSizes.map((size) => ColSpanSizesEnum[size].toString()).join(" ");
171
- }
172
- else {
173
- colspanvalues = this.getDefaultStyleClass(field, 'align-self-end');
174
- }
175
- if (!field.InListView && !showAllFields) {
176
- if (field.Invisibility == FieldInvisibilityEnum.NASCOSTO) {
177
- visibilityvalues = "visibility_hidden";
178
- }
179
- if (field.Invisibility == FieldInvisibilityEnum["NASCOSTO CON AREA VISIBILE"]) {
180
- visibilityvalues = "visibility_transparent";
181
- }
182
- }
183
- return colspanvalues + " " + visibilityvalues;
184
- }
185
- /**
186
- * Metodo invocato dall'html per impostare le classi css per visualizzare il campo all'interno della form.
187
- * Se per il field sono state specificate delle classi allora vengono applcate quelle, altrimenti vengono usate
188
- * delle classi di default.
189
- * @param field BaseField da visualizzare.
190
- * @returns Restituisce una stringa contenente le classi css da applicare.
191
- */
192
- getFieldAnswerStyleClass(field) {
193
- var colspanvalues = "";
194
- var visibilityvalues = "";
195
- if (field.AnswerStyle && field.AnswerStyle.ColSpanSizes && field.AnswerStyle.ColSpanSizes.length > 0) {
196
- colspanvalues = field.AnswerStyle.ColSpanSizes.map((size) => ColSpanSizesEnum[size].toString()).join(" ");
197
- }
198
- else {
199
- colspanvalues = this.getDefaultStyleClass(field, 'align-self-start');
200
- }
201
- if (!field.AnswerStyle.InListView) {
202
- if (field.AnswerStyle.Invisibility == FieldInvisibilityEnum.NASCOSTO) {
203
- visibilityvalues = "visibility_hidden";
204
- }
205
- if (field.AnswerStyle.Invisibility == FieldInvisibilityEnum["NASCOSTO CON AREA VISIBILE"]) {
206
- visibilityvalues = "visibility_transparent";
207
- }
208
- }
209
- return colspanvalues + " " + visibilityvalues;
210
- }
211
- getDefaultStyleClass(field, defaultAlign) {
212
- switch (field.FieldType) {
213
- case FieldTypeEnum["Campo di testo"]:
214
- //GlobalService.debugLog('Campo di testo')
215
- return "col-sm-12 col-md-4 col-lg-4 " + defaultAlign;
216
- case FieldTypeEnum["Area di testo"]:
217
- //GlobalService.debugLog('Area di testo')
218
- return "col-sm-12 col-md-12 col-lg-12 " + defaultAlign;
219
- case FieldTypeEnum["Booleano"]:
220
- //GlobalService.debugLog('Booleano')
221
- return "col-sm-12 col-md-4 col-lg-4 " + defaultAlign;
222
- case FieldTypeEnum["Data e/o ora"]:
223
- //GlobalService.debugLog('Data e/o ora')
224
- return "col-sm-12 col-md-4 col-lg-4 " + defaultAlign;
225
- case FieldTypeEnum["Campo numerico"]:
226
- //GlobalService.debugLog('Campo numerico')
227
- return "col-sm-12 col-md-4 col-lg-4 " + defaultAlign;
228
- case FieldTypeEnum["Allegato"]:
229
- //GlobalService.debugLog('Allegato')
230
- if (field.IsMultiAttach ||
231
- (field.MetadataFields &&
232
- field.MetadataFields.length > 0)) {
233
- return "col-sm-12 col-md-12 col-lg-12 " + defaultAlign;
234
- }
235
- else {
236
- return "col-sm-12 col-md-4 col-lg-4 " + defaultAlign;
237
- }
238
- case FieldTypeEnum["Immagine"]:
239
- //GlobalService.debugLog('Immagine')
240
- /*
241
- if (
242
- (field as ImageField).AttachDefinition.IsMultiAttach ||
243
- ((field as ImageField).AttachDefinition.MetadataFields &&
244
- (field as ImageField).AttachDefinition.MetadataFields.length > 0)
245
- ) {
246
- return "col-sm-12 col-md-12 col-lg-12 " + defaultAlign;
247
- } else {
248
- return "col-sm-12 col-md-4 col-lg-4 " + defaultAlign;
249
- }*/
250
- case FieldTypeEnum["Elenco generico"]:
251
- //GlobalService.debugLog('Elenco generico')
252
- return "col-sm-12 col-md-4 col-lg-4 " + defaultAlign;
253
- case FieldTypeEnum["Lookup"]:
254
- //GlobalService.debugLog('Lookup')
255
- return "col-sm-12 col-md-4 col-lg-4 " + defaultAlign;
256
- case FieldTypeEnum["Form di dettaglio"]:
257
- //GlobalService.debugLog('Form di dettaglio')
258
- return "col-sm-12 col-md-12 col-lg-12 " + defaultAlign;
259
- case FieldTypeEnum["Elenco immagini"]:
260
- return "col-sm-12 col-md-4 col-lg-4 " + defaultAlign;
261
- case FieldTypeEnum["Etichetta"]:
262
- return "col-sm-12 col-md-4 col-lg-4 " + defaultAlign;
263
- }
264
- }
265
- /**
266
- * Metodo per creare il FormGroup che rappresenta una Form a partire dai suoi BaseField.
267
- * @param formFields Lista dei BaseField che compongono la form.
268
- * @param record Oggetto di tipo Record che contiene i valori dei campi.
269
- * @param onlyView Se TRUE disabilita la form per renderla in sola lettura.
270
- * @param includeCurrentFormInField Se TRUE popola la proprietà FormFormGroup all'interno di ogni BaseField con il FormGroup corrente.
271
- * @returns Restituisce un FormGroup rappresentate la Form a cui appartengono i BaseField ricevuti in input.
272
- */
273
- CreateFormFormGroup(formFields, record, onlyView = false, includeCurrentFormInField = true) {
274
- // //GlobalService.debugLog("formFields", formFields);
275
- // //GlobalService.debugLog("record", record);
276
- // //GlobalService.debugLog("onlyView", onlyView);
277
- // //GlobalService.debugLog("includeCurrentFormInField", includeCurrentFormInField);
278
- const formForm = this.formBuilder.group([]);
279
- formFields.forEach((field) => {
280
- // //GlobalService.debugLog(field);
281
- formForm.addControl(field.Name, this.createFieldFormControl(field, record));
282
- if (includeCurrentFormInField) {
283
- // //GlobalService.debugLog(field);
284
- field.FormFormGroup = formForm;
285
- }
286
- });
287
- if (onlyView) {
288
- formForm.disable();
289
- }
290
- return formForm;
291
- }
292
- /**
293
- * Funzione per creare e aggiungere al FormGroup rappresentante la form un nuovo FormControl a partire da un Field.
294
- * In nuovo FormControl avrà il nome del campo passato e verranno impostati i Validators in base al tipo del campo stesso.
295
- * @param field BaseField per cui creare il FormControl da inserire nel FormGroup dela form.
296
- */
297
- createFieldFormControl(field, record) {
298
- const validators = [];
299
- if (field.Required)
300
- validators.push(Validators.required);
301
- switch (field.FieldType) {
302
- case FieldTypeEnum["Campo di testo"]:
303
- if (field.MaxLenght) {
304
- validators.push(Validators.maxLength(field.MaxLenght));
305
- }
306
- if (field.MinLenght) {
307
- validators.push(Validators.minLength(field.MinLenght));
308
- }
309
- switch (field.TextMask) {
310
- case TextMaskEnum.Url:
311
- validators.push(Validators.pattern(UrlRegex));
312
- break;
313
- case TextMaskEnum.Email:
314
- validators.push(Validators.email);
315
- break;
316
- case TextMaskEnum.Telefono:
317
- validators.push(Validators.pattern(TelRegex));
318
- break;
319
- }
320
- break;
321
- case FieldTypeEnum["Area di testo"]:
322
- if (field.MaxLenght) {
323
- validators.push(Validators.maxLength(field.MaxLenght));
324
- }
325
- if (field.MinLenght) {
326
- validators.push(Validators.minLength(field.MinLenght));
327
- }
328
- break;
329
- case FieldTypeEnum.Allegato:
330
- case FieldTypeEnum.Immagine:
331
- if (field.Required)
332
- validators.push(ArrayValidators.minLenght(1));
333
- break;
334
- case FieldTypeEnum["Elenco generico"]:
335
- if (field.IsMultiChoiche)
336
- if (field.Required)
337
- validators.push(ArrayValidators.minLenght(1));
338
- break;
339
- case FieldTypeEnum["Elenco immagini"]:
340
- if (field.IsMultiChoiche)
341
- if (field.Required)
342
- validators.push(ArrayValidators.minLenght(1));
343
- break;
344
- }
345
- return new UntypedFormControl(record[field.Name], validators);
346
- }
347
- /**
348
- * Metodo per configurare gli endpoint da usare di default a partire dall'url base del server
349
- * a cui si deve connettere e al token da passare per autenticarsi.
350
- * @param baseServerUrl Stringa dell'url base del server (es: "http://localhost:5000").
351
- * @param userToken Token dell'utente loggato da usare per autenticarsi se necessario.
352
- * @returns Resituisce la configurazione completa degli endPoint da usare di default.
353
- */
354
- ConfigureDefaultEndPoints(baseServerUrl, userToken) {
355
- let endPointConfiguration = new EndPointConfiguration(baseServerUrl, userToken);
356
- // endPointConfiguration.Records = {
357
- // GetByFormIDEndPoint: {
358
- // Url: baseServerUrl + "/api/v1/getall",
359
- // Token: userToken,
360
- // RequestMethod: RequestMethodEnum.GET,
361
- // },
362
- // GetAllByEntAndUserIDEndPoint: {
363
- // Url: baseServerUrl + "/api/v1/GetAllByUserID",
364
- // Token: userToken,
365
- // RequestMethod: RequestMethodEnum.GET,
366
- // },
367
- // GetByIDEndPoint: {
368
- // Url: baseServerUrl + "/api/v1/getByID",
369
- // Token: userToken,
370
- // RequestMethod: RequestMethodEnum.GET,
371
- // },
372
- // SaveEndPoint: {
373
- // Url: baseServerUrl + "/api/v1/save",
374
- // Token: userToken,
375
- // RequestMethod: RequestMethodEnum.POST,
376
- // },
377
- // DuplicateEndPoint: {
378
- // Url: baseServerUrl + "/api/v1/duplicate",
379
- // Token: userToken,
380
- // RequestMethod: RequestMethodEnum.GET,
381
- // },
382
- // DeleteEndPoint: {
383
- // Url: baseServerUrl + "/api/v1/delete",
384
- // Token: userToken,
385
- // RequestMethod: RequestMethodEnum.DELETE,
386
- // },
387
- // };
388
- // endPointConfiguration.Forms = {
389
- // GetByIDEndPoint: {
390
- // Url: baseServerUrl + "/api/conf/form",
391
- // Token: userToken,
392
- // RequestMethod: RequestMethodEnum.GET,
393
- // },
394
- // GetByIDAndVersionEndPoint: {
395
- // Url: baseServerUrl + "/api/conf/GetByIDAndVersion",
396
- // Token: userToken,
397
- // RequestMethod: RequestMethodEnum.GET,
398
- // },
399
- // SaveEndPoint: {
400
- // Url: baseServerUrl + "/api/conf/form",
401
- // Token: userToken,
402
- // RequestMethod: RequestMethodEnum.POST,
403
- // },
404
- // };
405
- return endPointConfiguration;
406
- }
407
- /**
408
- *
409
- * @param expression prende una stringa in input e verifica che ogni parentesi aperta venga anche chiusa
410
- * @returns true se le parentesi sono pari e ogni parentesi chiude se stessa, false se mancano parentesi o non vengono chiuse
411
- */
412
- static stringCheckParentesis(expression, required = false) {
413
- if (expression == undefined || expression == null) {
414
- return required ? false : true;
415
- }
416
- let stack = [];
417
- let current;
418
- const matchLookup = {
419
- "(": ")",
420
- "[": "]",
421
- "{": "}",
422
- };
423
- for (let i = 0; i < expression.length; i++) {
424
- current = expression[i]; //easier than writing it over and over
425
- if (current === "(" || current === "[" || current === "{") {
426
- stack.push(current);
427
- }
428
- else if (current === ")" || current === "]" || current === "}") {
429
- const lastBracket = stack.pop();
430
- if (matchLookup[lastBracket] !== current) {
431
- //if the stack is empty, .pop() returns undefined, so this expression is still correct
432
- return false; //terminate immediately - no need to continue scanning the string
433
- }
434
- }
435
- }
436
- return stack.length === 0; //any elements mean brackets left open
437
- }
438
- /**
439
- * Metodo che data la configurazione di un endpoint costruisce l'url da chiamare, gli eventuali parametri
440
- * da passare (nel body o nella rotta) ed effettua la chiamata. Al termine della chiamata esegue le eventuali
441
- * funzioni di callback (sia in caso di successo che in caso di errore) passate in input.
442
- * @param endPointData Cofigurazione dell'endpoint da chiamare.
443
- * @param dynamicModuleParams Array dei parametri aggiunti dal modulo dinamico a quelli già configurati
444
- * (ad esempio il record o la form da salvare oppure l'ID per recuperare una particolare entità).
445
- * @param callback Metodo da eseguire in caso di successo dopo la chiamata http.
446
- * NOTA: in input viene passata la risposta della chiamata stessa.
447
- * @param errorCallBack Metodo da eseguire in caso di errore dopo la chiamata http.
448
- * NOTA: in input viene passato l'errore generato della chiamata stessa.
449
- */
450
- RunEndPointCall(endPointData, dynamicModuleParams = null, callback = null, errorCallBack = null) {
451
- this.spinnerService.addRequestCounter();
452
- let url = `${endPointData.Url}`;
453
- let queryParams = null;
454
- const bodyParams = {
455
- AdditionalParams: {},
456
- };
457
- //#region mergeParam
458
- // unisco i dati di default definiti nella configurazione della chiamata con i dati che imposto nella chiamata specifica
459
- if (endPointData.Params == undefined || endPointData.Params == null) {
460
- endPointData.Params = [];
461
- }
462
- if (dynamicModuleParams == undefined || dynamicModuleParams == null) {
463
- dynamicModuleParams = [];
464
- }
465
- const mergedParams = [...endPointData.Params];
466
- dynamicModuleParams.forEach((obj) => {
467
- const existingIndex = mergedParams.findIndex((item) => item.ParamName === obj.ParamName);
468
- if (existingIndex !== -1) {
469
- mergedParams[existingIndex].ParamValue = obj.ParamValue;
470
- mergedParams[existingIndex].ParamType = obj.ParamType;
471
- }
472
- else {
473
- mergedParams.push(obj);
474
- }
475
- });
476
- if (mergedParams) {
477
- mergedParams.forEach((param) => {
478
- switch (param.ParamType) {
479
- case ParamTypeEnum["Query param"]: {
480
- const stringParam = param.ParamName + "=" + param.ParamValue;
481
- queryParams =
482
- (queryParams == null ? "" : queryParams + "&") + stringParam;
483
- break;
484
- }
485
- case ParamTypeEnum["In route"]: {
486
- url = url + (url.endsWith("/") ? "" : "/") + param.ParamValue;
487
- break;
488
- }
489
- case ParamTypeEnum["In Body"]: {
490
- bodyParams[param.ParamName] = param.ParamValue;
491
- break;
492
- }
493
- }
494
- });
495
- }
496
- //#endregion mergeParam
497
- //#region addDefaultParams
498
- // Se nella configurazione sono stati definiti parametri da aggiungere alla chiamata questi vengono ciclati
499
- // e aggiunti nel punto in cui devono essere usati.
500
- // if (endPointData.Params) {
501
- // endPointData.Params.forEach(param => {
502
- // switch (param.ParamType) {
503
- // case ParamTypeEnum['Query param']: {
504
- // const stringParam: string = param.ParamName + "=" + param.ParamValue;
505
- // queryParams = (queryParams == null ? "" : queryParams + "&") + stringParam;
506
- // break;
507
- // }
508
- // case ParamTypeEnum['In route']: {
509
- // url = url + (url.endsWith("/") ? "" : "/") + param.ParamValue;
510
- // break;
511
- // }
512
- // case ParamTypeEnum['In Body']: {
513
- // bodyParams.AdditionalParams[param.ParamName] = param.ParamValue;
514
- // break;
515
- // }
516
- // }
517
- // });
518
- // }
519
- //#endregion addDefaultParams
520
- //#region addSpecificParams
521
- // Se sono stati passati parametri da aggiungere alla chiamata definiti all'interno del modulo dinamico
522
- // vengono ciclati e aggiunti nel punto in cui devono essere usati dopo quelli definiti nella configurazione.
523
- // if (dynamicModuleParams) {
524
- // dynamicModuleParams.forEach(param => {
525
- // switch (param.ParamType) {
526
- // case ParamTypeEnum['Query param']: {
527
- // const stringParam: string = param.ParamName + "=" + param.ParamValue;
528
- // queryParams = (queryParams == null ? "" : queryParams + "&") + stringParam;
529
- // break;
530
- // }
531
- // case ParamTypeEnum['In route']: {
532
- // url = url + (url.endsWith("/") ? "" : "/") + param.ParamValue;
533
- // break;
534
- // }
535
- // case ParamTypeEnum['In Body']: {
536
- // bodyParams[param.ParamName] = param.ParamValue;
537
- // break;
538
- // }
539
- // }
540
- // })
541
- // }
542
- //#endregion addSpecificParams
543
- if (queryParams != null) {
544
- url =
545
- (url.endsWith("/") ? url.substring(0, url.length - 1) : url) +
546
- "?" +
547
- queryParams;
548
- }
549
- this.http
550
- .request(endPointData.RequestMethod, url, {
551
- headers: endPointData.Token
552
- ? { Authorization: endPointData.Token }
553
- : null,
554
- body: ![RequestMethodEnum.DELETE, RequestMethodEnum.GET].includes(endPointData.RequestMethod)
555
- ? bodyParams
556
- : null,
557
- })
558
- .subscribe((res) => {
559
- this.spinnerService.removeRequestCounter();
560
- if (callback) {
561
- callback(res);
562
- }
563
- }, (error) => {
564
- this.spinnerService.removeRequestCounter();
565
- if (errorCallBack) {
566
- errorCallBack(error);
567
- }
568
- EqpDynamicModuleDialogService.Error(error.message);
569
- throw new Error(error.message);
570
- //GlobalService.debugLog("RunEndPointCall - subscribe - end");
571
- });
572
- }
573
- static base64ToBlob(b64Data, contentType = '', sliceSize = 512) {
574
- let byteCharacters = atob(b64Data);
575
- let byteArrays = [];
576
- for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
577
- let slice = byteCharacters.slice(offset, offset + sliceSize);
578
- let byteNumbers = new Array(slice.length);
579
- for (let i = 0; i < slice.length; i++) {
580
- byteNumbers[i] = slice.charCodeAt(i);
581
- }
582
- let byteArray = new Uint8Array(byteNumbers);
583
- byteArrays.push(byteArray);
584
- }
585
- let blob = new Blob(byteArrays, { type: contentType });
586
- return blob;
587
- }
588
- }
589
- UtilityHelperService.context = new Context();
590
- UtilityHelperService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UtilityHelperService, deps: [{ token: i1.UntypedFormBuilder }, { token: i2.HttpClient }, { token: i3.SpinnerService }], target: i0.ɵɵFactoryTarget.Injectable });
591
- UtilityHelperService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UtilityHelperService, providedIn: "root" });
592
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UtilityHelperService, decorators: [{
593
- type: Injectable,
594
- args: [{
595
- providedIn: "root",
596
- }]
597
- }], ctorParameters: function () { return [{ type: i1.UntypedFormBuilder }, { type: i2.HttpClient }, { type: i3.SpinnerService }]; } });
598
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbGl0eUhlbHBlci5zZXJ2aWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2VxcC1keW5hbWljLW1vZHVsZS9zcmMvbGliL3NlcnZpY2VzL3V0aWxpdHlIZWxwZXIuc2VydmljZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBR0wsa0JBQWtCLEVBR2xCLFVBQVUsR0FDWCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFFTCxnQkFBZ0IsRUFDaEIscUJBQXFCLEVBQ3JCLGFBQWEsR0FDZCxNQUFNLDJCQUEyQixDQUFDO0FBQ25DLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNsRCxPQUFPLEVBQ0wscUJBQXFCLEVBR3JCLGFBQWEsRUFDYixpQkFBaUIsR0FDbEIsTUFBTSx1Q0FBdUMsQ0FBQztBQUsvQyxPQUFPLEVBQ0wsWUFBWSxFQUNaLFNBQVMsRUFDVCxRQUFRLEVBQ1IsUUFBUSxHQUNULE1BQU0sa0NBQWtDLENBQUM7QUFHMUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDOzs7OztBQVNwRixNQUFNLE9BQU8sb0JBQW9CO0lBSS9CLFFBQVEsQ0FBQyxPQUFlLEVBQUUsSUFBVTtRQUNsQyxJQUFHLElBQUksQ0FBQyxTQUFTLEVBQUM7WUFDaEIsSUFBRyxJQUFJLEVBQUM7Z0JBQ04sT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUE7YUFDM0I7aUJBQUk7Z0JBQ0gsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQTthQUNyQjtTQUNGO0lBQ0gsQ0FBQztJQUVELFlBQ1UsV0FBK0IsRUFDL0IsSUFBZ0IsRUFDaEIsY0FBOEI7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QyxNQUFNLEVBQUUsTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUFDO1lBRTdELElBQUksV0FBVyxHQUFHLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMxQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDckMsV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDdEM7WUFFRCxJQUFJLFNBQVMsR0FBRyxJQUFJLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUM1QyxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQzVCO1FBRUQsSUFBSSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLEVBQUMsSUFBSSxFQUFFLFdBQVcsRUFBQyxDQUFDLENBQUM7UUFDckQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDOztBQXRxQmEsNEJBQU8sR0FBWSxJQUFJLE9BQU8sRUFBRSxDQUFDO2tIQURwQyxvQkFBb0I7c0hBQXBCLG9CQUFvQixjQUZuQixNQUFNOzRGQUVQLG9CQUFvQjtrQkFIaEMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vbi9odHRwXCI7XHJcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQge1xyXG4gIEFic3RyYWN0Q29udHJvbCxcclxuICBVbnR5cGVkRm9ybUJ1aWxkZXIsXHJcbiAgVW50eXBlZEZvcm1Db250cm9sLFxyXG4gIFVudHlwZWRGb3JtR3JvdXAsXHJcbiAgVmFsaWRhdG9yRm4sXHJcbiAgVmFsaWRhdG9ycyxcclxufSBmcm9tIFwiQGFuZ3VsYXIvZm9ybXNcIjtcclxuaW1wb3J0IHtcclxuICBCYXNlRmllbGQsXHJcbiAgQ29sU3BhblNpemVzRW51bSxcclxuICBGaWVsZEludmlzaWJpbGl0eUVudW0sXHJcbiAgRmllbGRUeXBlRW51bSxcclxufSBmcm9tIFwiLi4vbW9kZWxzL2Jhc2VGaWVsZC5tb2RlbFwiO1xyXG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4uL21vZGVscy9jb250ZXh0Lm1vZGVsXCI7XHJcbmltcG9ydCB7XHJcbiAgRW5kUG9pbnRDb25maWd1cmF0aW9uLFxyXG4gIEVuZFBvaW50RGF0YSxcclxuICBFbmRQb2ludERhdGFQYXJhbXMsXHJcbiAgUGFyYW1UeXBlRW51bSxcclxuICBSZXF1ZXN0TWV0aG9kRW51bSxcclxufSBmcm9tIFwiLi4vbW9kZWxzL2VuZFBvaW50Q29uZmlndXJhdGlvbi5tb2RlbFwiO1xyXG5pbXBvcnQgeyBBdHRhY2htZW50RmllbGQgfSBmcm9tIFwiLi4vbW9kZWxzL2ZpZWxkcy9hdHRhY2htZW50RmllbGQubW9kZWxcIjtcclxuaW1wb3J0IHsgSW1hZ2VGaWVsZCB9IGZyb20gXCIuLi9tb2RlbHMvZmllbGRzL2ltYWdlRmllbGQubW9kZWxcIjtcclxuaW1wb3J0IHsgTGlzdFZhbHVlRmllbGQgfSBmcm9tIFwiLi4vbW9kZWxzL2ZpZWxkcy9saXN0VmFsdWVGaWVsZC5tb2RlbFwiO1xyXG5pbXBvcnQgeyBUZXh0YXJlYUZpZWxkIH0gZnJvbSBcIi4uL21vZGVscy9maWVsZHMvdGV4dGFyZWFGaWVsZC5tb2RlbFwiO1xyXG5pbXBvcnQge1xyXG4gIFRleHRNYXNrRW51bSxcclxuICBUZXh0RmllbGQsXHJcbiAgVXJsUmVnZXgsXHJcbiAgVGVsUmVnZXgsXHJcbn0gZnJvbSBcIi4uL21vZGVscy9maWVsZHMvdGV4dEZpZWxkLm1vZGVsXCI7XHJcbmltcG9ydCB7IEZvcm0gfSBmcm9tIFwiLi4vbW9kZWxzL2Zvcm0ubW9kZWxcIjtcclxuaW1wb3J0IHsgUmVjb3JkIH0gZnJvbSBcIi4uL21vZGVscy9yZWNvcmQubW9kZWxcIjtcclxuaW1wb3J0IHsgQXJyYXlWYWxpZGF0b3JzIH0gZnJvbSBcIi4vY3VzdG9tLWZvcm0tdmFsaWRhdG9ycy5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IEVxcER5bmFtaWNNb2R1bGVEaWFsb2dTZXJ2aWNlIH0gZnJvbSBcIi4vZXFwLWR5bmFtaWMtbW9kdWxlLWRpYWxvZy5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFNwaW5uZXJTZXJ2aWNlIH0gZnJvbSBcIi4vc3Bpbm5lci5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IEdsb2JhbFNlcnZpY2UgfSBmcm9tIFwiLi9nbG9iYWwuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBJbWFnZVNlbGVjdG9yRmllbGQgfSBmcm9tIFwiLi4vbW9kZWxzL2ZpZWxkcy9pbWFnZVNlbGVjdG9yRmllbGQubW9kZWxcIjtcclxuaW1wb3J0IHsgRHluQXR0YWNobWVudCB9IGZyb20gXCIuLi9tb2RlbHMvZHluQXR0YWNobWVudFwiO1xyXG5cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46IFwicm9vdFwiLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgVXRpbGl0eUhlbHBlclNlcnZpY2Uge1xyXG4gIHB1YmxpYyBzdGF0aWMgY29udGV4dDogQ29udGV4dCA9IG5ldyBDb250ZXh0KCk7XHJcblxyXG4gIGRlYnVnTW9kZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIGRlYnVnTG9nKG1lc3NhZ2U6IHN0cmluZywgaXRlbT86IGFueSl7XHJcbiAgICBpZih0aGlzLmRlYnVnTW9kZSl7XHJcbiAgICAgIGlmKGl0ZW0pe1xyXG4gICAgICAgIGNvbnNvbGUubG9nKG1lc3NhZ2UsIGl0ZW0pXHJcbiAgICAgIH1lbHNle1xyXG4gICAgICAgIGNvbnNvbGUubG9nKG1lc3NhZ2UpXHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBmb3JtQnVpbGRlcjogVW50eXBlZEZvcm1CdWlsZGVyLFxyXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LFxyXG4gICAgcHJpdmF0ZSBzcGlubmVyU2VydmljZTogU3Bpbm5lclNlcnZpY2VcclxuICApIHt9XHJcblxyXG4gIHB1YmxpYyBzdGF0aWMgRXZhbHVhdGVGaWVsZEZvcm11bGEoXHJcbiAgICBmb3JtdWxhOiBzdHJpbmcsXHJcbiAgICByZWM6IFJlY29yZCxcclxuICAgIGN0eDogYW55XHJcbiAgKTogYW55IHtcclxuICAgIGNvbnN0IGV2YWx1YXRlZFZhbHVlID0gZXZhbChmb3JtdWxhKTtcclxuICAgIHJldHVybiBldmFsdWF0ZWRWYWx1ZSA/IGV2YWx1YXRlZFZhbHVlIDogbnVsbDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzdGF0aWMgU2V0Q29udGV4dChjdHg6IENvbnRleHQpIHtcclxuICAgIHRoaXMuY29udGV4dCA9IGN0eDtcclxuICB9XHJcbiAgcHVibGljIHN0YXRpYyBpc051bWVyaWMobikge1xyXG4gICAgcmV0dXJuICFpc05hTihuKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzdGF0aWMgaW5pdFN0eWxlcyhzdHlsZWNzcykge1xyXG4gICAgcmV0dXJuIHN0eWxlY3NzLnNwbGl0KFwiO1wiKS5yZWR1Y2UoKGEsIGIpID0+IHtcclxuICAgICAgY29uc3Qga2V5cGFyID0gYi5zcGxpdChcIjpcIik7XHJcbiAgICAgIGlmIChrZXlwYXIubGVuZ3RoID4gMSkgYVtrZXlwYXJbMF0udHJpbSgpXSA9IGtleXBhclsxXS50cmltKCk7XHJcbiAgICAgIHJldHVybiBhO1xyXG4gICAgfSwge30pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHN0YXRpYyBHZXRGaWVsZFR5cGUoZmllbGQ6IEJhc2VGaWVsZCkge1xyXG4gICAgc3dpdGNoIChmaWVsZC5GaWVsZFR5cGUpIHtcclxuICAgICAgY2FzZSBGaWVsZFR5cGVFbnVtW1wiQ2FtcG8gZGkgdGVzdG9cIl06IHtcclxuICAgICAgICBjb25zdCB0OiBUZXh0RmllbGQgPSBPYmplY3QuYXNzaWduKG5ldyBUZXh0RmllbGQoKSwgZmllbGQpO1xyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICAgIGRlZmF1bHQ6IHtcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWV0b2RvIHBlciBpbXBvc3RhcmUgaSB2YWxvcmkgZGEgc3VnZ2VyaXJlIG5lbGwnYXV0b2NvbXBsZXRlIHBlciBpIGNhbXBpIGluIGN1aSBsJ3V0ZW50ZSBkZXZlIHNjcml2ZXJlIGNvbWFuZGkgamF2YXNjcmlwdC5cclxuICAgKiBJbiBiYXNlIGFsbCd1bHRpbW8gY2FyYXR0ZXJlIGRpZ2l0YXRvIHZpZW5lIGltcG9zdGF0byB1biBlbGVuY28gZGkgb2dnZXR0aSBvIHByb3ByaWV0w6AgY2hlIGwndXRlbnRlIGhhIGEgZGlzcG9zaXppb25lIGluIHF1ZWwgbW9tZW50by5cclxuICAgKiBAcGFyYW0gZmllbGRzIEFycmF5IGRpIEJhc2VGaWVsZCBhZ2dpdW50aSBhbGxhIEZvcm1cclxuICAgKiBAcGFyYW0gdHlwZWRGb3JtdWxhIFN0cmluZ2EgZGlnaXRhdGEgZGFsbCd1dGVudGVcclxuICAgKiBAc3VtbWFyeSBJbCBtZXRvZG8gaW1wb3N0YSBpIHN1Z2dlcmltZW50aSBiYXNhbmRvc2kgc3UgMyBjYXNpOlxyXG4gICAqICAxKSBsJ3V0ZW50ZSBub24gaGEgZGlnaXRhdG8gbnVsbGEgbyBsYSBzdHJpbmdhIGRpZ2l0YXRhIGRhbGwndXRlbnRlIGZpbmlzY2UgY29uIHVubyBzcGF6aW8gdnVvdG9cclxuICAgKiAgMikgbGEgc3RyaW5nYSBkaWdpdGF0YSBkYWxsJ3V0ZW50ZSBmaW5pc2NlIGNvbiB1biBcIi5cIlxyXG4gICAqICAzKSBsYSBzdHJpbmdhIGRpZ2l0YXRhIGRhbGwndXRlbnRlIG5vbiBjb2luY2lkZSBjb24gbmVzc3VuIGFsdHJvIGNhc28gc29wcmEgKGZpbmlzY2UgY29uIHVuIGNhcmF0dGVyZSBxdWFsdW5xdWUpXHJcbiAgICovXHJcbiAgcHVibGljIHN0YXRpYyBHZXRBdXRvY29tcGxldGVPcHRpb25zKFxyXG4gICAgZmllbGRzOiBBcnJheTxCYXNlRmllbGQ+LFxyXG4gICAgdHlwZWRGb3JtdWxhOiBzdHJpbmdcclxuICApOiBBcnJheTx7IGxhYmVsOiBzdHJpbmc7IHZhbHVlOiBzdHJpbmcgfT4ge1xyXG4gICAgbGV0IGF1dG9jb21wbGV0ZU9wdGlvbnM6IEFycmF5PHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IHN0cmluZyB9PiA9IFtdO1xyXG5cclxuICAgIC8vIFJlY3VwZXJvIGkgbm9taSBkaSB0dXR0aSBpIGNhbXBpIGNyZWF0aSBmaW5vIGFkIG9yYSBuZWxsYSBmb3JtLlxyXG4gICAgY29uc3QgYXZhaWxhYmxlUmVjUHJvcGVydGllczogQXJyYXk8c3RyaW5nPiA9IGZpZWxkcy5tYXAoKGYpID0+XHJcbiAgICAgIGYuTGFiZWwuc3BsaXQoXCIgXCIpLmpvaW4oXCJfXCIpXHJcbiAgICApO1xyXG5cclxuICAgIC8vIE5lbCBjYXNpIGluIGN1aSBsJ3V0ZW50ZSBub24gaGEgaW5zZXJpdG8gbnVsbGEgb3BwdXJlIGxhIHN0cmluZ2EgZmluaXNjZSBjb24gdW5vIHNwYXppbyB2dW90byBvIHVuIHNpbWJvbG8gZGl2ZXJzbyBkYSBcIi5cIlxyXG4gICAgLy8gKHVuIGNhcmF0dGVyZSBub24gYWxmYW51bWVyaWNvKSBpbXBvc3RvIGNvbWUgc3VnZ2VyaW1lbnRpIHNvbG8gXCJyZWNcIiBlIFwiY3R4XCIsIG92dmVybyBnbGkgdW5pY2kgZHVlIG9nZ2V0dGkgYSBjdWkgbCd1dGVudGUgaGEgYWNjZXNzby5cclxuICAgIGlmIChcclxuICAgICAgIXR5cGVkRm9ybXVsYSB8fFxyXG4gICAgICAoIXR5cGVkRm9ybXVsYS5lbmRzV2l0aChcIi5cIikgJiZcclxuICAgICAgICBuZXcgUmVnRXhwKFwiW14wLTlhLXpBLVpfXVwiKS50ZXN0KFxyXG4gICAgICAgICAgdHlwZWRGb3JtdWxhLnN1YnN0cmluZyh0eXBlZEZvcm11bGEubGVuZ3RoIC0gMSwgdHlwZWRGb3JtdWxhLmxlbmd0aClcclxuICAgICAgICApKVxyXG4gICAgKSB7XHJcbiAgICAgIGF1dG9jb21wbGV0ZU9wdGlvbnMgPSBbXHJcbiAgICAgICAgeyBsYWJlbDogXCJyZWNcIiwgdmFsdWU6ICh0eXBlZEZvcm11bGEgPyB0eXBlZEZvcm11bGEgOiBcIlwiKSArIFwicmVjXCIgfSxcclxuICAgICAgICB7IGxhYmVsOiBcImN0eFwiLCB2YWx1ZTogKHR5cGVkRm9ybXVsYSA/IHR5cGVkRm9ybXVsYSA6IFwiXCIpICsgXCJjdHhcIiB9LFxyXG4gICAgICBdO1xyXG4gICAgfVxyXG4gICAgLy8gU2UgbGEgc3RyaW5nYSBmaW5pc2NlIGNvbiB1biBcIi5cIiB2dW9sIGRpcmUgY2hlIGwndXRlbnRlIHN0YSBjZXJjYW5kbyBkaSBhY2NlZGVyZSBhZCB1bmEgcHJvcHJpZXTDoCBkaSB1biBvZ2dldHRvXHJcbiAgICAvLyBhIHN1YSBkaXNwb3NpemlvbmUuIFJlY3VwZXJvIGlsIG5vbWUgZGVsbCd1bHRpbW8gb2dnZXR0byBkaWdpdGF0byBkYWxsJ3V0ZW50ZSBlIHNlIGwnb2dnZXR0byBzY2VsdG8gw6ggXCJyZWNcIiBvIFwiY3R4XCJcclxuICAgIC8vIGFsbG9yYSBzdWdnZXJpc2NvIGxlIHByb3ByaWV0w6AgY2hlIGVzaXN0b25vIGFsbCdpbnRlcm5vIGRpIHF1ZXN0aSBvZ2dldHRpIGFsdHJpbWVudGkgbm9uIG1vc3RybyBudWxsYS5cclxuICAgIGVsc2UgaWYgKHR5cGVkRm9ybXVsYS5lbmRzV2l0aChcIi5cIikpIHtcclxuICAgICAgY29uc3QgZm9ybXVsYVBpZWNlczogQXJyYXk8c3RyaW5nPiA9IHR5cGVkRm9ybXVsYVxyXG4gICAgICAgIC5zcGxpdChcIiBcIilcclxuICAgICAgICBbdHlwZWRGb3JtdWxhLnNwbGl0KFwiIFwiKS5sZW5ndGggLSAxXS5zcGxpdChcIi5cIik7XHJcbiAgICAgIGlmIChmb3JtdWxhUGllY2VzW2Zvcm11bGFQaWVjZXMubGVuZ3RoIC0gMl0gPT09IFwicmVjXCIpIHtcclxuICAgICAgICBhdXRvY29tcGxldGVPcHRpb25zID0gYXZhaWxhYmxlUmVjUHJvcGVydGllcy5tYXAoKGYpID0+IHtcclxuICAgICAgICAgIHJldHVybiB7IGxhYmVsOiBmLCB2YWx1ZTogdHlwZWRGb3JtdWxhICsgZiB9O1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2UgaWYgKGZvcm11bGFQaWVjZXNbZm9ybXVsYVBpZWNlcy5sZW5ndGggLSAyXSA9PT0gXCJjdHhcIikge1xyXG4gICAgICAgIGF1dG9jb21wbGV0ZU9wdGlvbnMgPSBPYmplY3Qua2V5cyhVdGlsaXR5SGVscGVyU2VydmljZS5jb250ZXh0KS5tYXAoXHJcbiAgICAgICAgICAoZikgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4geyBsYWJlbDogZiwgdmFsdWU6IHR5cGVkRm9ybXVsYSArIGYgfTtcclxuICAgICAgICAgIH1cclxuICAgICAgICApO1xyXG4gICAgICB9IGVsc2UgaWYgKFxyXG4gICAgICAgIGZvcm11bGFQaWVjZXMubGVuZ3RoID4gMiAmJlxyXG4gICAgICAgIGZvcm11bGFQaWVjZXNbZm9ybXVsYVBpZWNlcy5sZW5ndGggLSAzXSA9PT0gXCJjdHhcIiAmJlxyXG4gICAgICAgIGZvcm11bGFQaWVjZXNbZm9ybXVsYVBpZWNlcy5sZW5ndGggLSAyXSA9PT0gXCJVc2VyXCJcclxuICAgICAgKSB7XHJcbiAgICAgICAgYXV0b2NvbXBsZXRlT3B0aW9ucyA9IE9iamVjdC5rZXlzKFxyXG4gICAgICAgICAgVXRpbGl0eUhlbHBlclNlcnZpY2UuY29udGV4dC5Vc2VyXHJcbiAgICAgICAgKS5tYXAoKGYpID0+IHtcclxuICAgICAgICAgIHJldHVybiB7IGxhYmVsOiBmLCB2YWx1ZTogdHlwZWRGb3JtdWxhICsgZiB9O1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGF1dG9jb21wbGV0ZU9wdGlvbnMgPSBbXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gSW4gdHV0dGkgZ2xpIGFsdHJpIGNhc2ksIG92dmVybyBxdWFuZG8gbGEgc3RyaW5nYSBkaWdpdGF0YSBmaW5pc2NlIGNvbiB1biBjYXJhdHRlcmUgZGl2ZXJzbyBkYSBxdWVsbGlcclxuICAgIC8vIGNvbnRyb2xsYXRpIGZpbm9yYSwgdnVvbCBkaXJlIGNoZSBsJ3V0ZW50ZSBzdGEgZGlnaXRhbnRvIGlsIG5vbWUgZGkgdW4gb2dnZXR0bywgdW5hIHByb3ByaWV0w6AgbyB1bmFcclxuICAgIC8vIGZ1bnppb25lIGphdmFzY3JpcHQuIENvbnRyb2xsbyBsYSBwYXJvbGEgY2hlIGwndXRlbnRlIHN0YSBkaWdpdGFuZG8gZSBzZSBmYSBwYXJ0ZSBkaSB1bm8gZGVnbGkgb2dnZXR0aSBhIGRpc3Bvc2l6aW9uZVxyXG4gICAgLy8gbyB1bmEgcHJvcHJpZXTDoCBkaSBlc3NpIGFsbG9yYSBzdWdnZXJpc2NvIGkgcG9zc2liaWxpIG1hdGNoLlxyXG4gICAgZWxzZSB7XHJcbiAgICAgIGNvbnN0IGF2YWlsYWJsZU9wdGlvbnM6IEFycmF5PHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IHN0cmluZyB9PiA9IFtdO1xyXG5cclxuICAgICAgLy8gUHJlbmRvIHR1dHRpIGkgYmxvY2NoaSBkaSBjYXJhdHRlcmkgZGlnaXRhdGkgZGFsbCd1dGVudGVcclxuICAgICAgY29uc3QgYWxsRm9ybXVsYVdvcmRzOiBBcnJheTxzdHJpbmc+ID0gdHlwZWRGb3JtdWxhLnNwbGl0KFwiIFwiKTtcclxuICAgICAgLy8gUHJlbmRvIGwndWx0aW1vIGJsb2NjbyBkaSBjYXJhdHRlcmkgZGlnaXRhdG8gZGFsbCd1dGVudGVcclxuICAgICAgY29uc3QgbGFzdFR5cGVkU3RyaW5nOiBzdHJpbmcgPVxyXG4gICAgICAgIGFsbEZvcm11bGFXb3Jkc1thbGxGb3JtdWxhV29yZHMubGVuZ3RoIC0gMV07XHJcblxyXG4gICAgICAvLyBTZSBsYSBsJ3VsdGltYSBzdHJpbmdhIGRpZ2l0YXRhIG5vbiBjb250aWVuZSBjYXJhdHRlcmkgc3BlY2lhbGkgYWxsb3JhIHNwbGl0dG8gbGEgc3RyaW5nYVxyXG4gICAgICAvLyBzdWkgXCIuXCIgZSBpbXBvc3RvIGkgc3VnZ2VyaW1lbnRpIGluIGJhc2UgYWwgcGF0aCBkZWxsYSBwcm9ycGlldMOgIGNoZSBzaSBzdGEgZGlnaXRhbmRvLlxyXG4gICAgICBpZiAoIW5ldyBSZWdFeHAoXCJbXjAtOWEtekEtWl8uXVwiKS50ZXN0KGxhc3RUeXBlZFN0cmluZykpIHtcclxuICAgICAgICBjb25zdCBwcm9wZXJ0eVBhdGggPSBsYXN0VHlwZWRTdHJpbmcuc3BsaXQoXCIuXCIpO1xyXG4gICAgICAgIGNvbnN0IGxhc3RUeXBlZFdvcmsgPSBwcm9wZXJ0eVBhdGhbcHJvcGVydHlQYXRoLmxlbmd0aCAtIDFdO1xyXG5cclxuICAgICAgICBsZXQgcHJvcGVydGllc1RvQ2hlY2s6IEFycmF5PHN0cmluZz4gPSBbXTtcclxuXHJcbiAgICAgICAgaWYgKHByb3BlcnR5UGF0aC5sZW5ndGggPT0gMSkge1xyXG4gICAgICAgICAgcHJvcGVydGllc1RvQ2hlY2sgPSBbXCJyZWNcIiwgXCJjdHhcIl07XHJcbiAgICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICAgIHByb3BlcnR5UGF0aC5sZW5ndGggPiAxICYmXHJcbiAgICAgICAgICBwcm9wZXJ0eVBhdGhbcHJvcGVydHlQYXRoLmxlbmd0aCAtIDJdID09PSBcImN0eFwiXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICBwcm9wZXJ0aWVzVG9DaGVjayA9IE9iamVjdC5rZXlzKFV0aWxpdHlIZWxwZXJTZXJ2aWNlLmNvbnRleHQpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgICAgICBwcm9wZXJ0eVBhdGgubGVuZ3RoID4gMiAmJlxyXG4gICAgICAgICAgcHJvcGVydHlQYXRoW3Byb3BlcnR5UGF0aC5sZW5ndGggLSAzXSA9PT0gXCJjdHhcIiAmJlxyXG4gICAgICAgICAgcHJvcGVydHlQYXRoW3Byb3BlcnR5UGF0aC5sZW5ndGggLSAyXSA9PT0gXCJVc2VyXCJcclxuICAgICAgICApIHtcclxuICAgICAgICAgIHByb3BlcnRpZXNUb0NoZWNrID0gT2JqZWN0LmtleXMoVXRpbGl0eUhlbHBlclNlcnZpY2UuY29udGV4dC5Vc2VyKTtcclxuICAgICAgICB9IGVsc2UgaWYgKFxyXG4gICAgICAgICAgcHJvcGVydHlQYXRoLmxlbmd0aCA+IDEgJiZcclxuICAgICAgICAgIHByb3BlcnR5UGF0aFtwcm9wZXJ0eVBhdGgubGVuZ3RoIC0gMl0gPT09IFwicmVjXCJcclxuICAgICAgICApIHtcclxuICAgICAgICAgIHByb3BlcnRpZXNUb0NoZWNrID0gYXZhaWxhYmxlUmVjUHJvcGVydGllcztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEVzZWd1byBpbCBjb250cm9sbG8gc3VsbGUgcHJvcHJpZXTDoCByZWN1cGVyYXRlLCBhZ2dpdW5nbyBhaSBzdWdnZXJpbWVudGkgdHV0dGkgaSBub21pIGNoZSBpbml6aWFubyBjb25cclxuICAgICAgICAvLyBxdWVsbG8gY2hlIHN0YSBkaWdpdGFuZG8gbCd1dGVudGUuXHJcbiAgICAgICAgcHJvcGVydGllc1RvQ2hlY2suZm9yRWFjaCgocHJvcCkgPT4ge1xyXG4gICAgICAgICAgaWYgKHByb3Auc3RhcnRzV2l0aChsYXN0VHlwZWRXb3JrKSkge1xyXG4gICAgICAgICAgICBhdmFpbGFibGVPcHRpb25zLnB1c2goe1xyXG4gICAgICAgICAgICAgIGxhYmVsOiBwcm9wLFxyXG4gICAgICAgICAgICAgIHZhbHVlOlxyXG4gICAgICAgICAgICAgICAgdHlwZWRGb3JtdWxhICtcclxuICAgICAgICAgICAgICAgIHByb3Auc3Vic3RyaW5nKGxhc3RUeXBlZFdvcmsubGVuZ3RoLCBwcm9wLmxlbmd0aCksXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBhdXRvY29tcGxldGVPcHRpb25zID0gYXZhaWxhYmxlT3B0aW9ucztcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gYXV0b2NvbXBsZXRlT3B0aW9ucztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1ldG9kbyBpbnZvY2F0byBkYWxsJ2h0bWwgcGVyIGltcG9zdGFyZSBsZSBjbGFzc2kgY3NzIHBlciB2aXN1YWxpenphcmUgaWwgY2FtcG8gYWxsJ2ludGVybm8gZGVsbGEgZm9ybS5cclxuICAgKiBTZSBwZXIgaWwgZmllbGQgc29ubyBzdGF0ZSBzcGVjaWZpY2F0ZSBkZWxsZSBjbGFzc2kgYWxsb3JhIHZlbmdvbm8gYXBwbGNhdGUgcXVlbGxlLCBhbHRyaW1lbnRpIHZlbmdvbm8gdXNhdGVcclxuICAgKiBkZWxsZSBjbGFzc2kgZGkgZGVmYXVsdC5cclxuICAgKiBAcGFyYW0gZmllbGQgQmFzZUZpZWxkIGRhIHZpc3VhbGl6emFyZS5cclxuICAgKiBAcmV0dXJucyBSZXN0aXR1aXNjZSB1bmEgc3RyaW5nYSBjb250ZW5lbnRlIGxlIGNsYXNzaSBjc3MgZGEgYXBwbGljYXJlLlxyXG4gICAqL1xyXG4gIGdldEZpZWxkU3lsZUNsYXNzKGZpZWxkOiBCYXNlRmllbGQsIHNob3dBbGxGaWVsZHM6IGJvb2xlYW4gPSBmYWxzZSk6IHN0cmluZyB7XHJcbiAgICAgICAgXHJcbiAgICB2YXIgY29sc3BhbnZhbHVlcyA9IFwiXCI7XHJcbiAgICB2YXIgdmlzaWJpbGl0eXZhbHVlcyA9IFwiXCI7XHJcbiAgICBpZiAoZmllbGQuQ29sU3BhblNpemVzICYmIGZpZWxkLkNvbFNwYW5TaXplcy5sZW5ndGggPiAwKXtcclxuICAgICAgY29sc3BhbnZhbHVlcyA9IGZpZWxkLkNvbFNwYW5TaXplcy5tYXAoKHNpemUpID0+XHJcbiAgICAgIENvbFNwYW5TaXplc0VudW1bc2l6ZV0udG9TdHJpbmcoKSkuam9pbihcIiBcIik7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb2xzcGFudmFsdWVzID0gdGhpcy5nZXREZWZhdWx0U3R5bGVDbGFzcyhmaWVsZCwgJ2FsaWduLXNlbGYtZW5kJyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFmaWVsZC5Jbkxpc3RWaWV3ICYmICFzaG93QWxsRmllbGRzKXtcclxuICAgICAgaWYgKGZpZWxkLkludmlzaWJpbGl0eSA9PSBGaWVsZEludmlzaWJpbGl0eUVudW0uTkFTQ09TVE8peyB2aXNpYmlsaXR5dmFsdWVzID0gXCJ2aXNpYmlsaXR5X2hpZGRlblwiOyB9XHJcbiAgICAgIGlmIChmaWVsZC5JbnZpc2liaWxpdHkgPT0gRmllbGRJbnZpc2liaWxpdHlFbnVtW1wiTkFTQ09TVE8gQ09OIEFSRUEgVklTSUJJTEVcIl0peyB2aXNpYmlsaXR5dmFsdWVzID0gXCJ2aXNpYmlsaXR5X3RyYW5zcGFyZW50XCI7IH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gY29sc3BhbnZhbHVlcyArIFwiIFwiICsgdmlzaWJpbGl0eXZhbHVlcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1ldG9kbyBpbnZvY2F0byBkYWxsJ2h0bWwgcGVyIGltcG9zdGFyZSBsZSBjbGFzc2kgY3NzIHBlciB2aXN1YWxpenphcmUgaWwgY2FtcG8gYWxsJ2ludGVybm8gZGVsbGEgZm9ybS5cclxuICAgKiBTZSBwZXIgaWwgZmllbGQgc29ubyBzdGF0ZSBzcGVjaWZpY2F0ZSBkZWxsZSBjbGFzc2kgYWxsb3JhIHZlbmdvbm8gYXBwbGNhdGUgcXVlbGxlLCBhbHRyaW1lbnRpIHZlbmdvbm8gdXNhdGVcclxuICAgKiBkZWxsZSBjbGFzc2kgZGkgZGVmYXVsdC5cclxuICAgKiBAcGFyYW0gZmllbGQgQmFzZUZpZWxkIGRhIHZpc3VhbGl6emFyZS5cclxuICAgKiBAcmV0dXJucyBSZXN0aXR1aXNjZSB1bmEgc3RyaW5nYSBjb250ZW5lbnRlIGxlIGNsYXNzaSBjc3MgZGEgYXBwbGljYXJlLlxyXG4gICAqL1xyXG4gIGdldEZpZWxkQW5zd2VyU3R5bGVDbGFzcyhmaWVsZDogQmFzZUZpZWxkKTogc3RyaW5nIHtcclxuICAgICAgICBcclxuICAgIHZhciBjb2xzcGFudmFsdWVzID0gXCJcIjtcclxuICAgIHZhciB2aXNpYmlsaXR5dmFsdWVzID0gXCJcIjtcclxuXHJcbiAgICBpZiAoZmllbGQuQW5zd2VyU3R5bGUgJiYgZmllbGQuQW5zd2VyU3R5bGUuQ29sU3BhblNpemVzICYmIGZpZWxkLkFuc3dlclN0eWxlLkNvbFNwYW5TaXplcy5sZW5ndGggPiAwKXtcclxuXHJcbiAgICAgIGNvbHNwYW52YWx1ZXMgPSBmaWVsZC5BbnN3ZXJTdHlsZS5Db2xTcGFuU2l6ZXMubWFwKChzaXplKSA9PlxyXG4gICAgICAgIENvbFNwYW5TaXplc0VudW1bc2l6ZV0udG9TdHJpbmcoKVxyXG4gICAgICApLmpvaW4oXCIgXCIpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29sc3BhbnZhbHVlcyA9IHRoaXMuZ2V0RGVmYXVsdFN0eWxlQ2xhc3MoZmllbGQsICdhbGlnbi1zZWxmLXN0YXJ0Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFmaWVsZC5BbnN3ZXJTdHlsZS5Jbkxpc3RWaWV3KXtcclxuICAgICAgaWYgKGZpZWxkLkFuc3dlclN0eWxlLkludmlzaWJpbGl0eSA9PSBGaWVsZEludmlzaWJpbGl0eUVudW0uTkFTQ09TVE8peyB2aXNpYmlsaXR5dmFsdWVzID0gXCJ2aXNpYmlsaXR5X2hpZGRlblwiOyB9XHJcbiAgICAgIGlmIChmaWVsZC5BbnN3ZXJTdHlsZS5JbnZpc2liaWxpdHkgPT0gRmllbGRJbnZpc2liaWxpdHlFbnVtW1wiTkFTQ09TVE8gQ09OIEFSRUEgVklTSUJJTEVcIl0peyB2aXNpYmlsaXR5dmFsdWVzID0gXCJ2aXNpYmlsaXR5X3RyYW5zcGFyZW50XCI7IH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gY29sc3BhbnZhbHVlcyArIFwiIFwiICsgdmlzaWJpbGl0eXZhbHVlcztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0RGVmYXVsdFN0eWxlQ2xhc3MoZmllbGQ6IEJhc2VGaWVsZCwgZGVmYXVsdEFsaWduOiBzdHJpbmcpOiBzdHJpbmd7XHJcbiAgICBcclxuICAgIHN3aXRjaCAoZmllbGQuRmllbGRUeXBlKSB7XHJcbiAgICAgIGNhc2UgRmllbGRUeXBlRW51bVtcIkNhbXBvIGRpIHRlc3RvXCJdOlxyXG4gICAgICAgIC8vR2xvYmFsU2VydmljZS5kZWJ1Z0xvZygnQ2FtcG8gZGkgdGVzdG8nKVxyXG4gICAgICAgIHJldHVybiBcImNvbC1zbS0xMiBjb2wtbWQtNCBjb2wtbGctNCBcIiArIGRlZmF1bHRBbGlnbjtcclxuICAgICAgY2FzZSBGaWVsZFR5cGVFbnVtW1wiQXJlYSBkaSB0ZXN0b1wiXTpcclxuICAgICAgICAvL0dsb2JhbFNlcnZpY2UuZGVidWdMb2coJ0FyZWEgZGkgdGVzdG8nKVxyXG4gICAgICAgIHJldHVybiBcImNvbC1zbS0xMiBjb2wtbWQtMTIgY29sLWxnLTEyIFwiICsgZGVmYXVsdEFsaWduO1xyXG4gICAgICBjYXNlIEZpZWxkVHlwZUVudW1bXCJCb29sZWFub1wiXTpcclxuICAgICAgICAvL0dsb2JhbFNlcnZpY2UuZGVidWdMb2coJ0Jvb2xlYW5vJylcclxuICAgICAgICByZXR1cm4gXCJjb2wtc20tMTIgY29sLW1kLTQgY29sLWxnLTQgXCIgKyBkZWZhdWx0QWxpZ247XHJcbiAgICAgIGNhc2UgRmllbGRUeXBlRW51bVtcIkRhdGEgZS9vIG9yYVwiXTpcclxuICAgICAgICAvL0dsb2JhbFNlcnZpY2UuZGVidWdMb2coJ0RhdGEgZS9vIG9yYScpXHJcbiAgICAgICAgcmV0dXJuIFwiY29sLXNtLTEyIGNvbC1tZC00IGNvbC1sZy00IFwiICsgZGVmYXVsdEFsaWduO1xyXG4gICAgICBjYXNlIEZpZWxkVHlwZUVudW1bXCJDYW1wbyBudW1lcmljb1wiXTpcclxuICAgICAgICAvL0dsb2JhbFNlcnZpY2UuZGVidWdMb2coJ0NhbXBvIG51bWVyaWNvJylcclxuICAgICAgICByZXR1cm4gXCJjb2wtc20tMTIgY29sLW1kLTQgY29sLWxnLTQgXCIgKyBkZWZhdWx0QWxpZ247XHJcbiAgICAgIGNhc2UgRmllbGRUeXBlRW51bVtcIkFsbGVnYXRvXCJdOlxyXG4gICAgICAgIC8vR2xvYmFsU2VydmljZS5kZWJ1Z0xvZygnQWxsZWdhdG8nKVxyXG4gICAgICAgIGlmIChcclxuICAgICAgICAgIChmaWVsZCBhcyBBdHRhY2htZW50RmllbGQpLklzTXVsdGlBdHRhY2ggfHxcclxuICAgICAgICAgICgoZmllbGQgYXMgQXR0YWNobWVudEZpZWxkKS5NZXRhZGF0YUZpZWxkcyAmJlxyXG4gICAgICAgICAgICAoZmllbGQgYXMgQXR0YWNobWVudEZpZWxkKS5NZXRhZGF0YUZpZWxkcy5sZW5ndGggPiAwKVxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgcmV0dXJuIFwiY29sLXNtLTEyIGNvbC1tZC0xMiBjb2wtbGctMTIgXCIgKyBkZWZhdWx0QWxpZ247XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHJldHVybiBcImNvbC1zbS0xMiBjb2wtbWQtNCBjb2wtbGctNCBcIiArIGRlZmF1bHRBbGlnbjtcclxuICAgICAgICB9XHJcbiAgICAgIGNhc2UgRmllbGRUeXBlRW51bVtcIkltbWFnaW5lXCJdOlxyXG4gICAgICAgIC8vR2xvYmFsU2VydmljZS5kZWJ1Z0xvZygnSW1tYWdpbmUnKVxyXG4gICAgICAgIC8qXHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgKGZpZWxkIGFzIEltYWdlRmllbGQpLkF0dGFjaERlZmluaXRpb24uSXNNdWx0aUF0dGFjaCB8fFxyXG4gICAgICAgICAgKChmaWVsZCBhcyBJbWFnZUZpZWxkKS5BdHRhY2hEZWZpbml0aW9uLk1ldGFkYXRhRmllbGRzICYmXHJcbiAgICAgICAgICAgIChmaWVsZCBhcyBJbWFnZUZpZWxkKS5BdHRhY2hEZWZpbml0aW9uLk1ldGFkYXRhRmllbGRzLmxlbmd0aCA+IDApXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICByZXR1cm4gXCJjb2wtc20tMTIgY29sLW1kLTEyIGNvbC1sZy0xMiBcIiArIGRlZmF1bHRBbGlnbjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgcmV0dXJuIFwiY29sLXNtLTEyIGNvbC1tZC00IGNvbC1sZy00IFwiICsgZGVmYXVsdEFsaWduO1xyXG4gICAgICAgIH0qL1xyXG4gICAgICAgIFxyXG4gICAgICBjYXNlIEZpZWxkVHlwZUVudW1bXCJFbGVuY28gZ2VuZXJpY29cIl06XHJcbiAgICAgICAgLy9HbG9iYWxTZXJ2aWNlLmRlYnVnTG9nKCdFbGVuY28gZ2VuZXJpY28nKVxyXG4gICAgICAgIHJldHVybiBcImNvbC1zbS0xMiBjb2wtbWQtNCBjb2wtbGctNCBcIiArIGRlZmF1bHRBbGlnbjtcclxuICAgICAgY2FzZSBGaWVsZFR5cGVFbnVtW1wiTG9va3VwXCJdOlxyXG4gICAgICAgIC8vR2xvYmFsU2VydmljZS5kZWJ1Z0xvZygnTG9va3VwJylcclxuICAgICAgICByZXR1cm4gXCJjb2wtc20tMTIgY29sLW1kLTQgY29sLWxnLTQgXCIgKyBkZWZhdWx0QWxpZ247XHJcbiAgICAgIGNhc2UgRmllbGRUeXBlRW51bVtcIkZvcm0gZGkgZGV0dGFnbGlvXCJdOlxyXG4gICAgICAgIC8vR2xvYmFsU2VydmljZS5kZWJ1Z0xvZygnRm9ybSBkaSBkZXR0YWdsaW8nKVxyXG4gICAgICAgIHJldHVybiBcImNvbC1zbS0xMiBjb2wtbWQtMTIgY29sLWxnLTEyIFwiICsgZGVmYXVsdEFsaWduO1xyXG4gICAgICBjYXNlIEZpZWxkVHlwZUVudW1bXCJFbGVuY28gaW1tYWdpbmlcIl06XHJcbiAgICAgICAgcmV0dXJuIFwiY29sLXNtLTEyIGNvbC1tZC00IGNvbC1sZy00IFwiICsgZGVmYXVsdEFsaWduO1xyXG4gICAgICBjYXNlIEZpZWxkVHlwZUVudW1bXCJFdGljaGV0dGFcIl06XHJcbiAgICAgICAgcmV0dXJuIFwiY29sLXNtLTEyIGNvbC1tZC00IGNvbC1sZy00IFwiICsgZGVmYXVsdEFsaWduO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWV0b2RvIHBlciBjcmVhcmUgaWwgRm9ybUdyb3VwIGNoZSByYXBwcmVzZW50YSB1bmEgRm9ybSBhIHBhcnRpcmUgZGFpIHN1b2kgQmFzZUZpZWxkLlxyXG4gICAqIEBwYXJhbSBmb3JtRmllbGRzIExpc3RhIGRlaSBCYXNlRmllbGQgY2hlIGNvbXBvbmdvbm8gbGEgZm9ybS5cclxuICAgKiBAcGFyYW0gcmVjb3JkIE9nZ2V0dG8gZGkgdGlwbyBSZWNvcmQgY2hlIGNvbnRpZW5lIGkgdmFsb3JpIGRlaSBjYW1waS5cclxuICAgKiBAcGFyYW0gb25seVZpZXcgU2UgVFJVRSBkaXNhYmlsaXRhIGxhIGZvcm0gcGVyIHJlbmRlcmxhIGluIHNvbGEgbGV0dHVyYS5cclxuICAgKiBAcGFyYW0gaW5jbHVkZUN1cnJlbnRGb3JtSW5GaWVsZCBTZSBUUlVFIHBvcG9sYSBsYSBwcm9wcmlldMOgIEZvcm1Gb3JtR3JvdXAgYWxsJ2ludGVybm8gZGkgb2duaSBCYXNlRmllbGQgY29uIGlsIEZvcm1Hcm91cCBjb3JyZW50ZS5cclxuICAgKiBAcmV0dXJucyBSZXN0aXR1aXNjZSB1biBGb3JtR3JvdXAgcmFwcHJlc2VudGF0ZSBsYSBGb3JtIGEgY3VpIGFwcGFydGVuZ29ubyBpIEJhc2VGaWVsZCByaWNldnV0aSBpbiBpbnB1dC5cclxuICAgKi9cclxuICBwdWJsaWMgQ3JlYXRlRm9ybUZvcm1Hcm91cChcclxuICAgIGZvcm1GaWVsZHM6IEFycmF5PEJhc2VGaWVsZD4sXHJcbiAgICByZWNvcmQ6IFJlY29yZCxcclxuICAgIG9ubHlWaWV3ID0gZmFsc2UsXHJcbiAgICBpbmNsdWRlQ3VycmVudEZvcm1JbkZpZWxkID0gdHJ1ZVxyXG4gICk6IFVudHlwZWRGb3JtR3JvdXAge1xyXG4gICAgLy8gLy9HbG9iYWxTZXJ2aWNlLmRlYnVnTG9nKFwiZm9ybUZpZWxkc1wiLCBmb3JtRmllbGRzKTtcclxuICAgIC8vIC8vR2xvYmFsU2VydmljZS5kZWJ1Z0xvZyhcInJlY29yZFwiLCByZWNvcmQpO1xyXG4gICAgLy8gLy9HbG9iYWxTZXJ2aWNlLmRlYnVnTG9nKFwib25seVZpZXdcIiwgb25seVZpZXcpO1xyXG4gICAgLy8gLy9HbG9iYWxTZXJ2aWNlLmRlYnVnTG9nKFwiaW5jbHVkZUN1cnJlbnRGb3JtSW5GaWVsZFwiLCBpbmNsdWRlQ3VycmVudEZvcm1JbkZpZWxkKTtcclxuXHJcbiAgICBjb25zdCBmb3JtRm9ybTogVW50eXBlZEZvcm1Hcm91cCA9IHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoW10pO1xyXG5cclxuICAgIGZvcm1GaWVsZHMuZm9yRWFjaCgoZmllbGQpID0+IHtcclxuICAgIC8vICAgLy9HbG9iYWxTZXJ2aWNlLmRlYnVnTG9nKGZpZWxkKTtcclxuICAgICAgZm9ybUZvcm0uYWRkQ29udHJvbChcclxuICAgICAgICBmaWVsZC5OYW1lLFxyXG4gICAgICAgIHRoaXMuY3JlYXRlRmllbGRGb3JtQ29udHJvbChmaWVsZCwgcmVjb3JkKVxyXG4gICAgICApO1xyXG4gICAgICBpZiAoaW5jbHVkZUN1cnJlbnRGb3JtSW5GaWVsZCkge1xyXG4gICAgICAgIC8vIC8vR2xvYmFsU2VydmljZS5kZWJ1Z0xvZyhmaWVsZCk7XHJcbiAgICAgICAgICBcclxuICAgICAgICBmaWVsZC5Gb3JtRm9ybUdyb3VwID0gZm9ybUZvcm07XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgaWYgKG9ubHlWaWV3KSB7XHJcbiAgICAgIGZvcm1Gb3JtLmRpc2FibGUoKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZm9ybUZvcm07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBGdW56aW9uZSBwZXIgY3JlYXJlIGUgYWdnaXVuZ2VyZSBhbCBGb3JtR3JvdXAgcmFwcHJlc2VudGFudGUgbGEgZm9ybSB1biBudW92byBGb3JtQ29udHJvbCBhIHBhcnRpcmUgZGEgdW4gRmllbGQuXHJcbiAgICogSW4gbnVvdm8gRm9ybUNvbnRyb2wgYXZyw6AgaWwgbm9tZSBkZWwgY2FtcG8gcGFzc2F0byBlIHZlcnJhbm5vIGltcG9zdGF0aSBpIFZhbGlkYXRvcnMgaW4gYmFzZSBhbCB0aXBvIGRlbCBjYW1wbyBzdGVzc28uXHJcbiAgICogQHBhcmFtIGZpZWxkIEJhc2VGaWVsZCBwZXIgY3VpIGNyZWFyZSBpbCBGb3JtQ29udHJvbCBkYSBpbnNlcmlyZSBuZWwgRm9ybUdyb3VwIGRlbGEgZm9ybS5cclxuICAgKi9cclxuICBwcml2YXRlIGNyZWF0ZUZpZWxkRm9ybUNvbnRyb2woXHJcbiAgICBmaWVsZDogQmFzZUZpZWxkLFxyXG4gICAgcmVjb3JkOiBSZWNvcmRcclxuICApOiBBYnN0cmFjdENvbnRyb2wge1xyXG4gICAgY29uc3QgdmFsaWRhdG9yczogQXJyYXk8VmFsaWRhdG9yRm4+ID0gW107XHJcblxyXG4gICAgaWYgKGZpZWxkLlJlcXVpcmVkKSB2YWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5yZXF1aXJlZCk7XHJcblxyXG4gICAgc3dpdGNoIChmaWVsZC5GaWVsZFR5cGUpIHtcclxuICAgICAgY2FzZSBGaWVsZFR5cGVFbnVtW1wiQ2FtcG8gZGkgdGVzdG9cIl06XHJcbiAgICAgICAgaWYgKChmaWVsZCBhcyBUZXh0RmllbGQpLk1heExlbmdodCkge1xyXG4gICAgICAgICAgdmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMubWF4TGVuZ3RoKChmaWVsZCBhcyBUZXh0RmllbGQpLk1heExlbmdodCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoKGZpZWxkIGFzIFRleHRGaWVsZCkuTWluTGVuZ2h0KSB7XHJcbiAgICAgICAgICB2YWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5taW5MZW5ndGgoKGZpZWxkIGFzIFRleHRGaWVsZCkuTWluTGVuZ2h0KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHN3aXRjaCAoKGZpZWxkIGFzIFRleHRGaWVsZCkuVGV4dE1hc2spIHtcclxuICAgICAgICAgIGNhc2UgVGV4dE1hc2tFbnVtLlVybDpcclxuICAgICAgICAgICAgdmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMucGF0dGVybihVcmxSZWdleCkpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgVGV4dE1hc2tFbnVtLkVtYWlsOlxyXG4gICAgICAgICAgICB2YWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5lbWFpbCk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBUZXh0TWFza0VudW0uVGVsZWZvbm86XHJcbiAgICAgICAgICAgIHZhbGlkYXRvcnMucHVzaChWYWxpZGF0b3JzLnBhdHRlcm4oVGVsUmVnZXgpKTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlIEZpZWxkVHlwZUVudW1bXCJBcmVhIGRpIHRlc3RvXCJdOlxyXG4gICAgICAgIGlmICgoZmllbGQgYXMgVGV4dGFyZWFGaWVsZCkuTWF4TGVuZ2h0KSB7XHJcbiAgICAgICAgICB2YWxpZGF0b3JzLnB1c2goXHJcbiAgICAgICAgICAgIFZhbGlkYXRvcnMubWF4TGVuZ3RoKChmaWVsZCBhcyBUZXh0YXJlYUZpZWxkKS5NYXhMZW5naHQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoKGZpZWxkIGFzIFRleHRhcmVhRmllbGQpLk1pbkxlbmdodCkge1xyXG4gICAgICAgICAgdmFsaWRhdG9ycy5wdXNoKFxyXG4gICAgICAgICAgICBWYWxpZGF0b3JzLm1pbkxlbmd0aCgoZmllbGQgYXMgVGV4dGFyZWFGaWVsZCkuTWluTGVuZ2h0KVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgRmllbGRUeXBlRW51bS5BbGxlZ2F0bzpcclxuICAgICAgY2FzZSBGaWVsZFR5cGVFbnVtLkltbWFnaW5lOlxyXG4gICAgICAgIGlmIChmaWVsZC5SZXF1aXJlZCkgdmFsaWRhdG9ycy5wdXNoKEFycmF5VmFsaWRhdG9ycy5taW5MZW5naHQoMSkpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlIEZpZWxkVHlwZUVudW1bXCJFbGVuY28gZ2VuZXJpY29cIl06XHJcbiAgICAgICAgaWYgKChmaWVsZCBhcyBMaXN0VmFsdWVGaWVsZCkuSXNNdWx0aUNob2ljaGUpXHJcbiAgICAgICAgICBpZiAoZmllbGQuUmVxdWlyZWQpIHZhbGlkYXRvcnMucHVzaChBcnJheVZhbGlkYXRvcnMubWluTGVuZ2h0KDEpKTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSBGaWVsZFR5cGVFbnVtW1wiRWxlbmNvIGltbWFnaW5pXCJdOlxyXG4gICAgICAgIGlmICgoZmllbGQgYXMgSW1hZ2VTZWxlY3RvckZpZWxkKS5Jc011bHRpQ2hvaWNoZSlcclxuICAgICAgICAgIGlmIChmaWVsZC5SZXF1aXJlZCkgdmFsaWRhdG9ycy5wdXNoKEFycmF5VmFsaWRhdG9ycy5taW5MZW5naHQoMSkpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBuZXcgVW50eXBlZEZvcm1Db250cm9sKHJlY29yZFtmaWVsZC5OYW1lXSwgdmFsaWRhdG9ycyk7XHJcblxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWV0b2RvIHBlciBjb25maWd1cmFyZSBnbGkgZW5kcG9pbnQgZGEgdXNhcmUgZGkgZGVmYXVsdCBhIHBhcnRpcmUgZGFsbCd1cmwgYmFzZSBkZWwgc2VydmVyXHJcbiAgICogYSBjdWkgc2kgZGV2ZSBjb25uZXR0ZXJlIGUgYWwgdG9rZW4gZGEgcGFzc2FyZSBwZXIgYXV0ZW50aWNhcnNpLlxyXG4gICAqIEBwYXJhbSBiYXNlU2VydmVyVXJsIFN0cmluZ2EgZGVsbCd1cmwgYmFzZSBkZWwgc2VydmVyIChlczogXCJodHRwOi8vbG9jYWxob3N0OjUwMDBcIikuXHJcbiAgICogQHBhcmFtIHVzZXJUb2tlbiBUb2tlbiBkZWxsJ3V0ZW50ZSBsb2dnYXRvIGRhIHVzYXJlIHBlciBhdXRlbnRpY2Fyc2kgc2UgbmVjZXNzYXJpby5cclxuICAgKiBAcmV0dXJucyBSZXNpdHVpc2NlIGxhIGNvbmZpZ3VyYXppb25lIGNvbXBsZXRhIGRlZ2xpIGVuZFBvaW50IGRhIHVzYXJlIGRpIGRlZmF1bHQuXHJcbiAgICovXHJcbiAgcHVibGljIENvbmZpZ3VyZURlZmF1bHRFbmRQb2ludHMoXHJcbiAgICBiYXNlU2VydmVyVXJsOiBzdHJpbmcsXHJcbiAgICB1c2VyVG9rZW46IHN0cmluZ1xyXG4gICk6IEVuZFBvaW50Q29uZmlndXJhdGlvbiB7XHJcbiAgICBsZXQgZW5kUG9pbnRDb25maWd1cmF0aW9uOiBFbmRQb2ludENvbmZpZ3VyYXRpb24gPVxyXG4gICAgICBuZXcgRW5kUG9pbnRDb25maWd1cmF0aW9uKGJhc2VTZXJ2ZXJVcmwsIHVzZXJUb2tlbik7XHJcblxyXG4gICAgLy8gZW5kUG9pbnRDb25maWd1cmF0aW9uLlJlY29yZHMgPSB7XHJcbiAgICAvLyAgIEdldEJ5Rm9ybUlERW5kUG9pbnQ6IHtcclxuICAgIC8vICAgICBVcmw6IGJhc2VTZXJ2ZXJVcmwgKyBcIi9hcGkvdjEvZ2V0YWxsXCIsXHJcbiAgICAvLyAgICAgVG9rZW46IHVzZXJUb2tlbixcclxuICAgIC8vICAgICBSZXF1ZXN0TWV0aG9kOiBSZXF1ZXN0TWV0aG9kRW51bS5HRVQsXHJcbiAgICAvLyAgIH0sXHJcbiAgICAvLyAgIEdldEFsbEJ5RW50QW5kVXNlcklERW5kUG9pbnQ6IHtcclxuICAgIC8vICAgICBVcmw6IGJhc2VTZXJ2ZXJVcmwgKyBcIi9hcGkvdjEvR2V0QWxsQnlVc2VySURcIixcclxuICAgIC8vICAgICBUb2tlbjogdXNlclRva2VuLFxyXG4gICAgLy8gICAgIFJlcXVlc3RNZXRob2Q6IFJlcXVlc3RNZXRob2RFbnVtLkdFVCxcclxuICAgIC8vICAgfSxcclxuICAgIC8vICAgR2V0QnlJREVuZFBvaW50OiB7XHJcbiAgICAvLyAgICAgVXJsOiBiYXNlU2VydmVyVXJsICsgXCIvYXBpL3YxL2dldEJ5SURcIixcclxuICAgIC8vICAgICBUb2tlbjogdXNlclRva2VuLFxyXG4gICAgLy8gICAgIFJlcXVlc3RNZXRob2Q6IFJlcXVlc3RNZXRob2RFbnVtLkdFVCxcclxuICAgIC8vICAgfSxcclxuICAgIC8vICAgU2F2ZUVuZFBvaW50OiB7XHJcbiAgICAvLyAgICAgVXJsOiBiYXNlU2VydmVyVXJsICsgXCIvYXBpL3YxL3NhdmVcIixcclxuICAgIC8vICAgICBUb2tlbjogdXNlclRva2VuLFxyXG4gICAgLy8gICAgIFJlcXVlc3RNZXRob2Q6IFJlcXVlc3RNZXRob2RFbnVtLlBPU1QsXHJcbiAgICAvLyAgIH0sXHJcbiAgICAvLyAgIER1cGxpY2F0ZUVuZFBvaW50OiB7XHJcbiAgICAvLyAgICAgVXJsOiBiYXNlU2VydmVyVXJsICsgXCIvYXBpL3YxL2R1cGxpY2F0ZVwiLFxyXG4gICAgLy8gICAgIFRva2VuOiB1c2VyVG9rZW4sXHJcbiAgICAvLyAgICAgUmVxdWVzdE1ldGhvZDogUmVxdWVzdE1ldGhvZEVudW0uR0VULFxyXG4gICAgLy8gICB9LFxyXG4gICAgLy8gICBEZWxldGVFbmRQb2ludDoge1xyXG4gICAgLy8gICAgIFVybDogYmFzZVNlcnZlclVybCArIFwiL2FwaS92MS9kZWxldGVcIixcclxuICAgIC8vICAgICBUb2tlbjogdXNlclRva2VuLFxyXG4gICAgLy8gICAgIFJlcXVlc3RNZXRob2Q6IFJlcXVlc3RNZXRob2RFbnVtLkRFTEVURSxcclxuICAgIC8vICAgfSxcclxuICAgIC8vIH07XHJcbiAgICAvLyBlbmRQb2ludENvbmZpZ3VyYXRpb24uRm9ybXMgPSB7XHJcbiAgICAvLyAgIEdldEJ5SURFbmRQb2ludDoge1xyXG4gICAgLy8gICAgIFVybDogYmFzZVNlcnZlclVybCArIFwiL2FwaS9jb25mL2Zvcm1cIixcclxuICAgIC8vICAgICBUb2tlbjogdXNlclRva2VuLFxyXG4gICAgLy8gICAgIFJlcXVlc3RNZXRob2Q6IFJlcXVlc3RNZXRob2RFbnVtLkdFVCxcclxuICAgIC8vICAgfSxcclxuICAgIC8vICAgR2V0QnlJREFuZFZlcnNpb25FbmRQb2ludDoge1xyXG4gICAgLy8gICAgIFVybDogYmFzZVNlcnZlclVybCArIFwiL2FwaS9jb25mL0dldEJ5SURBbmRWZXJzaW9uXCIsXHJcbiAgICAvLyAgICAgVG9rZW46IHVzZXJUb2tlbixcclxuICAgIC8vICAgICBSZXF1ZXN0TWV0aG9kOiBSZXF1ZXN0TWV0aG9kRW51bS5HRVQsXHJcbiAgICAvLyAgIH0sXHJcbiAgICAvLyAgIFNhdmVFbmRQb2ludDoge1xyXG4gICAgLy8gICAgIFVybDogYmFzZVNlcnZlclVybCArIFwiL2FwaS9jb25mL2Zvcm1cIixcclxuICAgIC8vICAgICBUb2tlbjogdXNlclRva2VuLFxyXG4gICAgLy8gICAgIFJlcXVlc3RNZXRob2Q6IFJlcXVlc3RNZXRob2RFbnVtLlBPU1QsXHJcbiAgICAvLyAgIH0sXHJcbiAgICAvLyB9O1xyXG4gICAgcmV0dXJuIGVuZFBvaW50Q29uZmlndXJhdGlvbjtcclxuICB9XHJcbiAgLyoqXHJcbiAgICpcclxuICAgKiBAcGFyYW0gZXhwcmVzc2lvbiBwcmVuZGUgdW5hIHN0cmluZ2EgaW4gaW5wdXQgZSB2ZXJpZmljYSBjaGUgb2duaSBwYXJlbnRlc2kgYXBlcnRhIHZlbmdhIGFuY2hlIGNoaXVzYVxyXG4gICAqIEByZXR1cm5zIHRydWUgc2UgbGUgcGFyZW50ZXNpIHNvbm8gcGFyaSBlIG9nbmkgcGFyZW50ZXNpIGNoaXVkZSBzZSBzdGVzc2EsIGZhbHNlIHNlIG1hbmNhbm8gcGFyZW50ZXNpIG8gbm9uIHZlbmdvbm8gY2hpdXNlXHJcbiAgICovXHJcbiAgcHVibGljIHN0YXRpYyBzdHJpbmdDaGVja1BhcmVudGVzaXMoZXhwcmVzc2lvbiwgcmVxdWlyZWQgPSBmYWxzZSkge1xyXG4gICAgaWYgKGV4cHJlc3Npb24gPT0gdW5kZWZpbmVkIHx8IGV4cHJlc3Npb24gPT0gbnVsbCkge1xyXG4gICAgICByZXR1cm4gcmVxdWlyZWQgPyBmYWxzZSA6IHRydWU7XHJcbiAgICB9XHJcbiAgICBsZXQgc3RhY2sgPSBbXTtcclxuICAgIGxldCBjdXJyZW50O1xyXG4gICAgY29uc3QgbWF0Y2hMb29rdXAgPSB7XHJcbiAgICAgIFwiKFwiOiBcIilcIixcclxuICAgICAgXCJbXCI6IFwiXVwiLFxyXG4gICAgICBcIntcIjogXCJ9XCIsXHJcbiAgICB9O1xyXG5cclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwcmVzc2lvbi5sZW5ndGg7IGkrKykge1xyXG4gICAgICBjdXJyZW50ID0gZXhwcmVzc2lvbltpXTsgLy9lYXNpZXIgdGhhbiB3cml0aW5nIGl0IG92ZXIgYW5kIG92ZXJcclxuXHJcbiAgICAgIGlmIChjdXJyZW50ID09PSBcIihcIiB8fCBjdXJyZW50ID09PSBcIltcIiB8fCBjdXJyZW50ID09PSBcIntcIikge1xyXG4gICAgICAgIHN0YWNrLnB1c2goY3VycmVudCk7XHJcbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudCA9PT0gXCIpXCIgfHwgY3VycmVudCA9PT0gXCJdXCIgfHwgY3VycmVudCA9PT0gXCJ9XCIpIHtcclxuICAgICAgICBjb25zdCBsYXN0QnJhY2tldCA9IHN0YWNrLnBvcCgpO1xyXG5cclxuICAgICAgICBpZiAobWF0Y2hMb29rdXBbbGFzdEJyYWNrZXRdICE9PSBjdXJyZW50KSB7XHJcbiAgICAgICAgICAvL2lmIHRoZSBzdGFjayBpcyBlbXB0eSwgLnBvcCgpIHJldHVybnMgdW5kZWZpbmVkLCBzbyB0aGlzIGV4cHJlc3Npb24gaXMgc3RpbGwgY29ycmVjdFxyXG5cclxuICAgICAgICAgIHJldHVybiBmYWxzZTsgLy90ZXJtaW5hdGUgaW1tZWRpYXRlbHkgLSBubyBuZWVkIHRvIGNvbnRpbnVlIHNjYW5uaW5nIHRoZSBzdHJpbmdcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gc3RhY2subGVuZ3RoID09PSAwOyAvL2FueSBlbGVtZW50cyBtZWFuIGJyYWNrZXRzIGxlZnQgb3BlblxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTWV0b2RvIGNoZSBkYXRhIGxhIGNvbmZpZ3VyYXppb25lIGRpIHVuIGVuZHBvaW50IGNvc3RydWlzY2UgbCd1cmwgZGEgY2hpYW1hcmUsIGdsaSBldmVudHVhbGkgcGFyYW1ldHJpXHJcbiAgICogZGEgcGFzc2FyZSAobmVsIGJvZHkgbyBuZWxsYSByb3R0YSkgZWQgZWZmZXR0dWEgbGEgY2hpYW1hdGEuIEFsIHRlcm1pbmUgZGVsbGEgY2hpYW1hdGEgZXNlZ3VlIGxlIGV2ZW50dWFsaVxyXG4gICAqIGZ1bnppb25pIGRpIGNhbGxiYWNrIChzaWEgaW4gY2FzbyBkaSBzdWNjZXNzbyBjaGUgaW4gY2FzbyBkaSBlcnJvcmUpIHBhc3NhdGUgaW4gaW5wdXQuXHJcbiAgICogQHBhcmFtIGVuZFBvaW50RGF0YSBDb2ZpZ3VyYXppb25lIGRlbGwnZW5kcG9pbnQgZGEgY2hpYW1hcmUuXHJcbiAgICogQHBhcmFtIGR5bmFtaWNNb2R1bGVQYXJhbXMgQXJyYXkgZGVpIHBhcmFtZXRyaSBhZ2dpdW50aSBkYWwgbW9kdWxvIGRpbmFtaWNvIGEgcXVlbGxpIGdpw6AgY29uZmlndXJhdGlcclxuICAgKiAoYWQgZXNlbXBpbyBpbCByZWNvcmQgbyBsYSBmb3JtIGRhIHNhbHZhcmUgb3BwdXJlIGwnSUQgcGVyIHJlY3VwZXJhcmUgdW5hIHBhcnRpY29sYXJlIGVudGl0w6ApLlxyXG4gICAqIEBwYXJhbSBjYWxsYmFjayBNZXRvZG8gZGEgZXNlZ3VpcmUgaW4gY2FzbyBkaSBzdWNjZXNzbyBkb3BvIGxhIGNoaWFtYXRhIGh0dHAuXHJcbiAgICogTk9UQTogaW4gaW5wdXQgdmllbmUgcGFzc2F0YSBsYSByaXNwb3N0YSBkZWxsYSBjaGlhbWF0YSBzdGVzc2EuXHJcbiAgICogQHBhcmFtIGVycm9yQ2FsbEJhY2sgTWV0b2RvIGRhIGVzZWd1aXJlIGluIGNhc28gZGkgZXJyb3JlIGRvcG8gbGEgY2hpYW1hdGEgaHR0cC5cclxuICAgKiBOT1RBOiBpbiBpbnB1dCB2aWVuZSBwYXNzYXRvIGwnZXJyb3JlIGdlbmVyYXRvIGRlbGxhIGNoaWFtYXRhIHN0ZXNzYS5cclxuICAgKi9cclxuICBwdWJsaWMgUnVuRW5kUG9pbnRDYWxsKFxyXG4gICAgZW5kUG9pbnREYXRhOiBFbmRQb2ludERhdGEsXHJcbiAgICBkeW5hbWljTW9kdWxlUGFyYW1zOiBBcnJheTxFbmRQb2ludERhdGFQYXJhbXM+ID0gbnVsbCxcclxuICAgIGNhbGxiYWNrOiAoZTogRm9ybSB8IEFycmF5PEZvcm0+IHwgUmVjb3JkIHwgQXJyYXk8UmVjb3JkPiB8IER5bkF0dGFjaG1lbnQgfCBBcnJheTxEeW5BdHRhY2htZW50PiB8IHN0cmluZykgPT4gdm9pZCA9IG51bGwsXHJcbiAgICBlcnJvckNhbGxCYWNrOiAoZXJyOiB1bmtub3duKSA9PiB2b2lkID0gbnVsbFxyXG4gICk6IHZvaWQge1xyXG4gICAgdGhpcy5zcGlubmVyU2VydmljZS5hZGRSZXF1ZXN0Q291bnRlcigpO1xyXG5cclxuICAgIGxldCB1cmwgPSBgJHtlbmRQb2ludERhdGEuVXJsfWA7XHJcbiAgICBsZXQgcXVlcnlQYXJhbXM6IHN0cmluZyA9IG51bGw7XHJcbiAgICBjb25zdCBib2R5UGFyYW1zID0ge1xyXG4gICAgICBBZGRpdGlvbmFsUGFyYW1zOiB7fSxcclxuICAgIH07XHJcblxyXG4gICAgLy8jcmVnaW9uIG1lcmdlUGFyYW1cclxuICAgIC8vIHVuaXNjbyBpIGRhdGkgZGkgZGVmYXVsdCBkZWZpbml0aSBuZWxsYSBjb25maWd1cmF6aW9uZSBkZWxsYSBjaGlhbWF0YSBjb24gaSBkYXRpIGNoZSBpbXBvc3RvIG5lbGxhIGNoaWFtYXRhIHNwZWNpZmljYVxyXG4gICAgaWYgKGVuZFBvaW50RGF0YS5QYXJhbXMgPT0gdW5kZWZpbmVkIHx8IGVuZFBvaW50RGF0YS5QYXJhbXMgPT0gbnVsbCkge1xyXG4gICAgICBlbmRQb2ludERhdGEuUGFyYW1zID0gW107XHJcbiAgICB9XHJcbiAgICBpZiAoZHluYW1pY01vZHVsZVBhcmFtcyA9PSB1bmRlZmluZWQgfHwgZHluYW1pY01vZHVsZVBhcmFtcyA9PSBudWxsKSB7XHJcbiAgICAgIGR5bmFtaWNNb2R1bGVQYXJhbXMgPSBbXTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBtZXJnZWRQYXJhbXM6IEFycmF5PEVuZFBvaW50RGF0YVBhcmFtcz4gPSBbLi4uZW5kUG9pbnREYXRhLlBhcmFtc107XHJcblxyXG4gICAgZHluYW1pY01vZHVsZVBhcmFtcy5mb3JFYWNoKChvYmopID0+IHtcclxuICAgICAgY29uc3QgZXhpc3RpbmdJbmRleCA9IG1lcmdlZFBhcmFtcy5maW5kSW5kZXgoXHJcbiAgICAgICAgKGl0ZW0pID0+IGl0ZW0uUGFyYW1OYW1lID09PSBvYmouUGFyYW1OYW1lXHJcbiAgICAgICk7XHJcblxyXG4gICAgICBpZiAoZXhpc3RpbmdJbmRleCAhPT0gLTEpIHtcclxuICAgICAgICBtZXJnZWRQYXJhbXNbZXhpc3RpbmdJbmRleF0uUGFyYW1WYWx1ZSA9IG9iai5QYXJhbVZhbHVlO1xyXG4gICAgICAgIG1lcmdlZFBhcmFtc1tleGlzdGluZ0luZGV4XS5QYXJhbVR5cGUgPSBvYmouUGFyYW1UeXBlO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIG1lcmdlZFBhcmFtcy5wdXNoKG9iaik7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIGlmIChtZXJnZWRQYXJhbXMpIHtcclxuICAgICAgbWVyZ2VkUGFyYW1zLmZvckVhY2goKHBhcmFtKSA9PiB7XHJcbiAgICAgICAgc3dpdGNoIChwYXJhbS5QYXJhbVR5cGUpIHtcclxuICAgICAgICAgIGNhc2UgUGFyYW1UeXBlRW51bVtcIlF1ZXJ5IHBhcmFtXCJdOiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHN0cmluZ1BhcmFtOiBzdHJpbmcgPVxyXG4gICAgICAgICAgICAgIHBhcmFtLlBhcmFtTmFtZSArIFwiPVwiICsgcGFyYW0uUGFyYW1WYWx1ZTtcclxuICAgICAgICAgICAgcXVlcnlQYXJhbXMgPVxyXG4gICAgICAgICAgICAgIChxdWVyeVBhcmFtcyA9PSBudWxsID8gXCJcIiA6IHF1ZXJ5UGFyYW1zICsgXCImXCIpICsgc3RyaW5nUGFyYW07XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgY2FzZSBQYXJhbVR5cGVFbnVtW1wiSW4gcm91dGVcIl06IHtcclxuICAgICAgICAgICAgdXJsID0gdXJsICsgKHVybC5lbmRzV2l0aChcIi9cIikgPyBcIlwiIDogXCIvXCIpICsgcGFyYW0uUGFyYW1WYWx1ZTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBjYXNlIFBhcmFtVHlwZUVudW1bXCJJbiBCb2R5XCJdOiB7XHJcbiAgICAgICAgICAgIGJvZHlQYXJhbXNbcGFyYW0uUGFyYW1OYW1lXSA9IHBhcmFtLlBhcmFtVmFsdWU7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICAvLyNlbmRyZWdpb24gbWVyZ2VQYXJhbVxyXG5cclxuICAgIC8vI3JlZ2lvbiBhZGREZWZhdWx0UGFyYW1zXHJcbiAgICAvLyBTZSBuZWxsYSBjb25maWd1cmF6aW9uZSBzb25vIHN0YXRpIGRlZmluaXRpIHBhcmFtZXRyaSBkYSBhZ2dpdW5nZXJlIGFsbGEgY2hpYW1hdGEgcXVlc3RpIHZlbmdvbm8gY2ljbGF0aVxyXG4gICAgLy8gZSBhZ2dpdW50aSBuZWwgcHVudG8gaW4gY3VpIGRldm9ubyBlc3NlcmUgdXNhdGkuXHJcbiAgICAvLyBpZiAoZW5kUG9pbnREYXRhLlBhcmFtcykge1xyXG4gICAgLy8gICAgIGVuZFBvaW50RGF0YS5QYXJhbXMuZm9yRWFjaChwYXJhbSA9PiB7XHJcbiAgICAvLyAgICAgICAgIHN3aXRjaCAocGFyYW0uUGFyYW1UeXBlKSB7XHJcbiAgICAvLyAgICAgICAgICAgICBjYXNlIFBhcmFtVHlwZUVudW1bJ1F1ZXJ5IHBhcmFtJ106IHtcclxuICAgIC8vICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmdQYXJhbTogc3RyaW5nID0gcGFyYW0uUGFyYW1OYW1lICsgXCI9XCIgKyBwYXJhbS5QYXJhbVZhbHVlO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIHF1ZXJ5UGFyYW1zID0gKHF1ZXJ5UGFyYW1zID09IG51bGwgPyBcIlwiIDogcXVlcnlQYXJhbXMgKyBcIiZcIikgKyBzdHJpbmdQYXJhbTtcclxuICAgIC8vICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgIC8vICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgICAgIGNhc2UgUGFyYW1UeXBlRW51bVsnSW4gcm91dGUnXToge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIHVybCA9IHVybCArICh1cmwuZW5kc1dpdGgoXCIvXCIpID8gXCJcIiA6IFwiL1wiKSArIHBhcmFtLlBhcmFtVmFsdWU7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAvLyAgICAgICAgICAgICB9XHJcbiAgICAvLyAgICAgICAgICAgICBjYXNlIFBhcmFtVHlwZUVudW1bJ0luIEJvZHknXToge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIGJvZHlQYXJhbXMuQWRkaXRpb25hbFBhcmFtc1twYXJhbS5QYXJhbU5hbWVdID0gcGFyYW0uUGFyYW1WYWx1ZTtcclxuICAgIC8vICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgIC8vICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgfVxyXG4gICAgLy8gICAgIH0pO1xyXG4gICAgLy8gfVxyXG4gICAgLy8jZW5kcmVnaW9uIGFkZERlZmF1bHRQYXJhbXNcclxuXHJcbiAgICAvLyNyZWdpb24gYWRkU3BlY2lmaWNQYXJhbXNcclxuICAgIC8vIFNlIHNvbm8gc3RhdGkgcGFzc2F0aSBwYXJhbWV0cmkgZGEgYWdnaXVuZ2VyZSBhbGxhIGNoaWFtYXRhIGRlZmluaXRpIGFsbCdpbnRlcm5vIGRlbCBtb2R1bG8gZGluYW1pY29cclxuICAgIC8vIHZlbmdvbm8gY2ljbGF0aSBlIGFnZ2l1bnRpIG5lbCBwdW50byBpbiBjdWkgZGV2b25vIGVzc2VyZSB1c2F0aSBkb3BvIHF1ZWxsaSBkZWZpbml0aSBuZWxsYSBjb25maWd1cmF6aW9uZS5cclxuICAgIC8vIGlmIChkeW5hbWljTW9kdWxlUGFyYW1zKSB7XHJcbiAgICAvLyAgICAgZHluYW1pY01vZHVsZVBhcmFtcy5mb3JFYWNoKHBhcmFtID0+IHtcclxuICAgIC8vICAgICAgICAgc3dpdGNoIChwYXJhbS5QYXJhbVR5cGUpIHtcclxuICAgIC8vICAgICAgICAgICAgIGNhc2UgUGFyYW1UeXBlRW51bVsnUXVlcnkgcGFyYW0nXToge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZ1BhcmFtOiBzdHJpbmcgPSBwYXJhbS5QYXJhbU5hbWUgKyBcIj1cIiArIHBhcmFtLlBhcmFtVmFsdWU7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgcXVlcnlQYXJhbXMgPSAocXVlcnlQYXJhbXMgPT0gbnVsbCA/IFwiXCIgOiBxdWVyeVBhcmFtcyArIFwiJlwiKSArIHN0cmluZ1BhcmFtO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgLy8gICAgICAgICAgICAgfVxyXG4gICAgLy8gICAgICAgICAgICAgY2FzZSBQYXJhbVR5cGVFbnVtWydJbiByb3V0ZSddOiB7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgdXJsID0gdXJsICsgKHVybC5lbmRzV2l0aChcIi9cIikgPyBcIlwiIDogXCIvXCIpICsgcGFyYW0uUGFyYW1WYWx1ZTtcclxuICAgIC8vICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgIC8vICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgICAgIGNhc2UgUGFyYW1UeXBlRW51bVsnSW4gQm9keSddOiB7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgYm9keVBhcmFtc1twYXJhbS5QYXJhbU5hbWVdID0gcGFyYW0uUGFyYW1WYWx1ZTtcclxuICAgIC8vICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgIC8vICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgfVxyXG4gICAgLy8gICAgIH0pXHJcbiAgICAvLyB9XHJcbiAgICAvLyNlbmRyZWdpb24gYWRkU3BlY2lmaWNQYXJhbXNcclxuXHJcbiAgICBpZiAocXVlcnlQYXJhbXMgIT0gbnVsbCkge1xyXG4gICAgICB1cmwgPVxyXG4gICAgICAgICh1cmwuZW5kc1dpdGgoXCIvXCIpID8gdXJsLnN1YnN0cmluZygwLCB1cmwubGVuZ3RoIC0gMSkgOiB1cmwpICtcclxuICAgICAgICBcIj9cIiArXHJcbiAgICAgICAgcXVlcnlQYXJhbXM7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5odHRwXHJcbiAgICAgIC5yZXF1ZXN0KGVuZFBvaW50RGF0YS5SZXF1ZXN0TWV0aG9kLCB1cmwsIHtcclxuICAgICAgICBoZWFkZXJzOiBlbmRQb2ludERhdGEuVG9rZW5cclxuICAgICAgICAgID8geyBBdXRob3JpemF0aW9uOiBlbmRQb2ludERhdGEuVG9rZW4gfVxyXG4gICAgICAgICAgOiBudWxsLFxyXG4gICAgICAgIGJvZHk6ICFbUmVxdWVzdE1ldGhvZEVudW0uREVMRVRFLCBSZXF1ZXN0TWV0aG9kRW51bS5HRVRdLmluY2x1ZGVzKFxyXG4gICAgICAgICAgZW5kUG9pbnREYXRhLlJlcXVlc3RNZXRob2RcclxuICAgICAgICApXHJcbiAgICAgICAgICA/IGJvZHlQYXJhbXNcclxuICAgICAgICAgIDogbnVsbCxcclxuICAgICAgfSlcclxuICAgICAgLnN1YnNjcmliZShcclxuICAgICAgICAocmVzOiBGb3JtIHwgUmVjb3JkIHwgQXJyYXk8UmVjb3JkPikgPT4ge1xyXG4gICAgICAgICAgdGhpcy5zcGlubmVyU2VydmljZS5yZW1vdmVSZXF1ZXN0Q291bnRlcigpO1xyXG4gICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIGNhbGxiYWNrKHJlcyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICAoZXJyb3IpID0+IHtcclxuICAgICAgICAgIHRoaXMuc3Bpbm5lclNlcnZpY2UucmVtb3ZlUmVxdWVzdENvdW50ZXIoKTtcclxuICAgICAgICAgIGlmIChlcnJvckNhbGxCYWNrKSB7XHJcbiAgICAgICAgICAgIGVycm9yQ2FsbEJhY2soZXJyb3IpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgRXFwRHluYW1pY01vZHVsZURpYWxvZ1NlcnZpY2UuRXJyb3IoZXJyb3IubWVzc2FnZSk7XHJcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3IubWVzc2FnZSk7XHJcbiAgICAgICAgICAvL0dsb2JhbFNlcnZpY2UuZGVidWdMb2coXCJSdW5FbmRQb2ludENhbGwgLSBzdWJzY3JpYmUgLSBlbmRcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICApO1xyXG5cclxuICB9XHJcblxyXG4gIFxyXG4gIHN0YXRpYyBiYXNlNjRUb0Jsb2IoYjY0RGF0YSwgY29udGVudFR5cGU9JycsIHNsaWNlU2l6ZT01MTIpIHtcclxuICAgIGxldCBieXRlQ2hhcmFjdGVycyA9IGF0b2IoYjY0RGF0YSk7XHJcbiAgICBsZXQgYnl0ZUFycmF5cyA9IFtdO1xyXG5cclxuICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJ5dGVDaGFyYWN0ZXJzLmxlbmd0aDsgb2Zmc2V0ICs9IHNsaWNlU2l6ZSkge1xyXG4gICAgICBsZXQgc2xpY2UgPSBieXRlQ2hhcmFjdGVycy5zbGljZShvZmZzZXQsIG9mZnNldCArIHNsaWNlU2l6ZSk7XHJcblxyXG4gICAgICBsZXQgYnl0ZU51bWJlcnMgPSBuZXcgQXJyYXkoc2xpY2UubGVuZ3RoKTtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzbGljZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGJ5dGVOdW1iZXJzW2ldID0gc2xpY2UuY2hhckNvZGVBdChpKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgbGV0IGJ5dGVBcnJheSA9IG5ldyBVaW50OEFycmF5KGJ5dGVOdW1iZXJzKTtcclxuICAgICAgYnl0ZUFycmF5cy5wdXNoKGJ5dGVBcnJheSk7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IGJsb2IgPSBuZXcgQmxvYihieXRlQXJyYXlzLCB7dHlwZTogY29udGVudFR5cGV9KTtcclxuICAgIHJldHVybiBibG9iO1xyXG4gIH1cclxufVxyXG4iXX0=